Skip to content

Commit

Permalink
add axis.filter(), axis.grid.filter(), axis.ticks.filter(). close #305.
Browse files Browse the repository at this point in the history
  • Loading branch information
leeoniya committed Sep 16, 2020
1 parent e2285cc commit c898d24
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 52 deletions.
37 changes: 25 additions & 12 deletions dist/uPlot.cjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ function fnOrSelf(v) {
return typeof v == "function" ? v : function () { return v; };
}

function retArg1(_0, _1) {
return _1;
}

function incrRoundUp(num, incr) {
return ceil(num/incr)*incr;
}
Expand Down Expand Up @@ -800,6 +804,7 @@ var grid = {
stroke: "rgba(0,0,0,0.07)",
width: 2,
// dash: [],
filter: retArg1,
};

var ticks = assign({}, grid, {size: 10});
Expand All @@ -820,6 +825,7 @@ var xAxisOpts = {
// class: "x-vals",
// incrs: timeIncrs,
// values: timeVals,
// filter: retArg1,
grid: grid,
ticks: ticks,
font: font,
Expand All @@ -844,7 +850,7 @@ var xSeriesOpts = {
};

function numAxisVals(self, splits, axisIdx, foundSpace, foundIncr) {
return splits.map(fmtNum);
return splits.map(function (v) { return v == null ? "" : fmtNum(v); });
}

function numAxisSplits(self, axisIdx, scaleMin, scaleMax, foundIncr, foundSpace, forceMin) {
Expand Down Expand Up @@ -882,7 +888,7 @@ var RE_12357 = /[12357]/;
var RE_125 = /[125]/;
var RE_1 = /1/;

function logAxisVals(self, splits, axisIdx, foundSpace, foundIncr) {
function logAxisValsFilt(self, splits, axisIdx, foundSpace, foundIncr) {
var axis = self.axes[axisIdx];
var scaleKey = axis.scale;
var valToPos = self.valToPos;
Expand All @@ -898,7 +904,7 @@ function logAxisVals(self, splits, axisIdx, foundSpace, foundIncr) {
RE_1
);

return splits.map(function (v) { return re.test(v) ? fmtNum(v) : ""; });
return splits.map(function (v) { return re.test(v) ? v : null; });
}

function numSeriesVal(self, val) {
Expand All @@ -917,6 +923,7 @@ var yAxisOpts = {
// class: "y-vals",
// incrs: numIncrs,
// values: (vals, space) => vals,
// filter: retArg1,
grid: grid,
ticks: ticks,
font: font,
Expand Down Expand Up @@ -1323,7 +1330,8 @@ function uPlot(opts, data, then) {
axis.incrs = fnOrSelf(axis.incrs || ( sc.distr == 2 ? intIncrs : (isTime ? timeIncrs : numIncrs)));
axis.splits = fnOrSelf(axis.splits || (isTime && sc.distr == 1 ? _timeAxisSplits : sc.distr == 3 ? logAxisSplits : numAxisSplits));
var av = axis.values;
axis.values = isTime ? (isArr(av) ? timeAxisVals(_tzDate, timeAxisStamps(av, _fmtDate)) : av || _timeAxisVals) : av || (sc.distr == 3 ? logAxisVals : numAxisVals);
axis.values = isTime ? (isArr(av) ? timeAxisVals(_tzDate, timeAxisStamps(av, _fmtDate)) : av || _timeAxisVals) : av || numAxisVals;
axis.filter = fnOrSelf(axis.filter || ( sc.distr == 3 ? logAxisValsFilt : retArg1));

axis.font = pxRatioFont(axis.font);
axis.labelFont = pxRatioFont(axis.labelFont);
Expand Down Expand Up @@ -2017,7 +2025,7 @@ function uPlot(opts, data, then) {
return incrSpace;
}

function drawOrthoLines(offs, ori, side, pos0, len, width, stroke, dash) {
function drawOrthoLines(offs, filts, ori, side, pos0, len, width, stroke, dash) {
var offset = (width % 2) / 2;

ctx.translate(offset, offset);
Expand All @@ -2038,6 +2046,9 @@ function uPlot(opts, data, then) {
}

offs.forEach(function (off, i) {
if (filts[i] == null)
{ return; }

if (ori == 0)
{ x0 = x1 = off; }
else
Expand Down Expand Up @@ -2091,13 +2102,10 @@ function uPlot(opts, data, then) {

// tick labels
// BOO this assumes a specific data/series
var values = axis.values(
self,
scale.distr == 2 ? splits.map(function (i) { return data0[i]; }) : splits,
i,
space,
scale.distr == 2 ? data0[splits[1]] - data0[splits[0]] : incr
);
var _splits = scale.distr == 2 ? splits.map(function (i) { return data0[i]; }) : splits;
var _incr = scale.distr == 2 ? data0[splits[1]] - data0[splits[0]] : incr;

var values = axis.values(self, axis.filter(self, _splits, i, space, _incr), i, space, _incr);

// rotating of labels only supported on bottom x axis
var angle = side == 2 ? axis.rotate(self, values, i, space) * -PI/180 : 0;
Expand All @@ -2120,6 +2128,9 @@ function uPlot(opts, data, then) {
var lineHeight = axis.font[1] * lineMult;

values.forEach(function (val, i) {
if (val == null)
{ return; }

if (ori == 0)
{ x = canOffs[i]; }
else
Expand Down Expand Up @@ -2173,6 +2184,7 @@ function uPlot(opts, data, then) {
if (ticks.show) {
drawOrthoLines(
canOffs,
ticks.filter(self, _splits, i, space, _incr),
ori,
side,
basePos,
Expand All @@ -2188,6 +2200,7 @@ function uPlot(opts, data, then) {
if (grid.show) {
drawOrthoLines(
canOffs,
grid.filter(self, _splits, i, space, _incr),
ori,
ori == 0 ? 2 : 1,
ori == 0 ? plotTop : plotLft,
Expand Down
14 changes: 13 additions & 1 deletion dist/uPlot.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,9 @@ declare namespace uPlot {
max?: number,
}

/** must return an array of same length as splits, e.g. via splits.map() */
type AxisSplitsFilter = (self: uPlot, splits: number[], axisIdx: number, foundSpace: number, foundIncr: number) => Array<number|null>;

export interface Axis {
/** axis on/off */
show?: boolean;
Expand Down Expand Up @@ -437,8 +440,11 @@ declare namespace uPlot {
/** determines how and where the axis must be split for placing ticks, values, grid */
splits?: number[] | ((self: uPlot, axisIdx: number, scaleMin: number, scaleMax: number, foundIncr: number, pctSpace: number) => number[]);

/** can filter which splits are passed to axis.values() for rendering. e.g splits.map(v => v % 2 == 0 ? v : null) */
filter?: AxisSplitsFilter;

/** formats values for rendering */
values?: ((self: uPlot, splits: number[], axisIdx: number, foundSpace: number, foundIncr: number) => Array<string|number>) | (string | number | null)[][];
values?: ((self: uPlot, splits: number[], axisIdx: number, foundSpace: number, foundIncr: number) => Array<string|number|null>) | (string | number | null)[][];

/** values rotation in degrees off horizontal (only bottom axes w/ side: 2) */
rotate?: number | ((self: uPlot, values: Array<string|number>, axisIdx: number, foundSpace: number) => number);
Expand All @@ -448,6 +454,9 @@ declare namespace uPlot {
/** grid on/off */
show?: boolean; // true

/** can filter which splits render gridlines. e.g splits.map(v => v % 2 == 0 ? v : null) */
filter?: AxisSplitsFilter;

/** gridline color */
stroke?: CanvasRenderingContext2D['strokeStyle'];

Expand All @@ -463,6 +472,9 @@ declare namespace uPlot {
/** ticks on/off */
show?: boolean; // true

/** can filter which splits render ticks. e.g splits.map(v => v % 2 == 0 ? v : null) */
filter?: AxisSplitsFilter;

/** tick color */
stroke?: CanvasRenderingContext2D['strokeStyle'];

Expand Down
37 changes: 25 additions & 12 deletions dist/uPlot.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ function fnOrSelf(v) {
return typeof v == "function" ? v : () => v;
}

function retArg1(_0, _1) {
return _1;
}

function incrRoundUp(num, incr) {
return ceil(num/incr)*incr;
}
Expand Down Expand Up @@ -804,6 +808,7 @@ const grid = {
stroke: "rgba(0,0,0,0.07)",
width: 2,
// dash: [],
filter: retArg1,
};

const ticks = assign({}, grid, {size: 10});
Expand All @@ -824,6 +829,7 @@ const xAxisOpts = {
// class: "x-vals",
// incrs: timeIncrs,
// values: timeVals,
// filter: retArg1,
grid,
ticks,
font,
Expand All @@ -848,7 +854,7 @@ const xSeriesOpts = {
};

function numAxisVals(self, splits, axisIdx, foundSpace, foundIncr) {
return splits.map(fmtNum);
return splits.map(v => v == null ? "" : fmtNum(v));
}

function numAxisSplits(self, axisIdx, scaleMin, scaleMax, foundIncr, foundSpace, forceMin) {
Expand Down Expand Up @@ -886,7 +892,7 @@ const RE_12357 = /[12357]/;
const RE_125 = /[125]/;
const RE_1 = /1/;

function logAxisVals(self, splits, axisIdx, foundSpace, foundIncr) {
function logAxisValsFilt(self, splits, axisIdx, foundSpace, foundIncr) {
let axis = self.axes[axisIdx];
let scaleKey = axis.scale;
let valToPos = self.valToPos;
Expand All @@ -902,7 +908,7 @@ function logAxisVals(self, splits, axisIdx, foundSpace, foundIncr) {
RE_1
);

return splits.map(v => re.test(v) ? fmtNum(v) : "");
return splits.map(v => re.test(v) ? v : null);
}

function numSeriesVal(self, val) {
Expand All @@ -921,6 +927,7 @@ const yAxisOpts = {
// class: "y-vals",
// incrs: numIncrs,
// values: (vals, space) => vals,
// filter: retArg1,
grid,
ticks,
font,
Expand Down Expand Up @@ -1327,7 +1334,8 @@ function uPlot(opts, data, then) {
axis.incrs = fnOrSelf(axis.incrs || ( sc.distr == 2 ? intIncrs : (isTime ? timeIncrs : numIncrs)));
axis.splits = fnOrSelf(axis.splits || (isTime && sc.distr == 1 ? _timeAxisSplits : sc.distr == 3 ? logAxisSplits : numAxisSplits));
let av = axis.values;
axis.values = isTime ? (isArr(av) ? timeAxisVals(_tzDate, timeAxisStamps(av, _fmtDate)) : av || _timeAxisVals) : av || (sc.distr == 3 ? logAxisVals : numAxisVals);
axis.values = isTime ? (isArr(av) ? timeAxisVals(_tzDate, timeAxisStamps(av, _fmtDate)) : av || _timeAxisVals) : av || numAxisVals;
axis.filter = fnOrSelf(axis.filter || ( sc.distr == 3 ? logAxisValsFilt : retArg1));

axis.font = pxRatioFont(axis.font);
axis.labelFont = pxRatioFont(axis.labelFont);
Expand Down Expand Up @@ -2014,7 +2022,7 @@ function uPlot(opts, data, then) {
return incrSpace;
}

function drawOrthoLines(offs, ori, side, pos0, len, width, stroke, dash) {
function drawOrthoLines(offs, filts, ori, side, pos0, len, width, stroke, dash) {
let offset = (width % 2) / 2;

ctx.translate(offset, offset);
Expand All @@ -2035,6 +2043,9 @@ function uPlot(opts, data, then) {
}

offs.forEach((off, i) => {
if (filts[i] == null)
return;

if (ori == 0)
x0 = x1 = off;
else
Expand Down Expand Up @@ -2085,13 +2096,10 @@ function uPlot(opts, data, then) {

// tick labels
// BOO this assumes a specific data/series
let values = axis.values(
self,
scale.distr == 2 ? splits.map(i => data0[i]) : splits,
i,
space,
scale.distr == 2 ? data0[splits[1]] - data0[splits[0]] : incr,
);
let _splits = scale.distr == 2 ? splits.map(i => data0[i]) : splits;
let _incr = scale.distr == 2 ? data0[splits[1]] - data0[splits[0]] : incr;

let values = axis.values(self, axis.filter(self, _splits, i, space, _incr), i, space, _incr);

// rotating of labels only supported on bottom x axis
let angle = side == 2 ? axis.rotate(self, values, i, space) * -PI/180 : 0;
Expand All @@ -2114,6 +2122,9 @@ function uPlot(opts, data, then) {
let lineHeight = axis.font[1] * lineMult;

values.forEach((val, i) => {
if (val == null)
return;

if (ori == 0)
x = canOffs[i];
else
Expand Down Expand Up @@ -2167,6 +2178,7 @@ function uPlot(opts, data, then) {
if (ticks.show) {
drawOrthoLines(
canOffs,
ticks.filter(self, _splits, i, space, _incr),
ori,
side,
basePos,
Expand All @@ -2182,6 +2194,7 @@ function uPlot(opts, data, then) {
if (grid.show) {
drawOrthoLines(
canOffs,
grid.filter(self, _splits, i, space, _incr),
ori,
ori == 0 ? 2 : 1,
ori == 0 ? plotTop : plotLft,
Expand Down

0 comments on commit c898d24

Please sign in to comment.