Skip to content

Commit

Permalink
fix(axis): Fix x Axis tick fit for timeseries
Browse files Browse the repository at this point in the history
- Use d3's tick scale behaviour when tick.fit options set false
- Adjust tick default format for timeseries

Fix #628
  • Loading branch information
netil authored Mar 6, 2019
1 parent c06d63f commit 9cda54f
Show file tree
Hide file tree
Showing 5 changed files with 247 additions and 20 deletions.
140 changes: 140 additions & 0 deletions demo/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,146 @@ var demos = {
"#XAxisTickPosition .bb-axis-x line, #XAxisTickPosition .bb-axis-x path { visibility: hidden; }"
]
},
XAxisTickTimeseries: {
options: {
data: {
x: "x",
json: {
"Temperature": [
"29.39",
"29.7",
"29.37",
"28.87",
"28.62",
"27.72",
"27.61",
"27.82",
"27.48",
"26.78",
"26.62",
"26.64",
"26.29",
"26.01",
"25.84",
"25.07",
"24.85",
"24.01",
"23.83",
"22.8",
"23",
"22.64",
"22.77",
"22.64",
"22.64",
"22.62",
"22.51",
"21.42",
"21.18",
"20.93",
"20.66",
"20.48",
"20.7",
"21.24",
"22.14",
"22.78",
"23.43",
"23.16",
"27.48",
"26.78",
"26.62",
"26.64",
"26.29",
"26.01",
"25.84",
"25.07",
"24.85",
"24.01"
],
"x": [
"01-01-2015 00:00",
"02-01-2015 00:00",
"03-01-2015 00:00",
"04-01-2015 00:00",
"05-01-2015 00:00",
"06-01-2015 00:00",
"07-01-2015 00:00",
"08-01-2015 00:00",
"09-01-2015 00:00",
"10-01-2015 00:00",
"11-01-2015 00:00",
"12-01-2015 00:00",
"01-01-2016 00:00",
"02-01-2016 00:00",
"03-01-2016 00:00",
"04-01-2016 00:00",
"05-01-2016 00:00",
"06-01-2016 00:00",
"07-01-2016 00:00",
"08-01-2016 00:00",
"09-01-2016 00:00",
"10-01-2016 00:00",
"11-01-2016 00:00",
"12-01-2016 00:00",
"01-01-2017 00:00",
"02-01-2017 00:00",
"03-01-2017 00:00",
"04-01-2017 00:00",
"05-01-2017 00:00",
"06-01-2017 00:00",
"07-01-2017 00:00",
"08-01-2017 00:00",
"09-01-2017 00:00",
"10-01-2017 00:00",
"11-01-2017 00:00",
"12-01-2017 00:00",
"01-01-2018 00:00",
"02-01-2018 00:00",
"03-01-2018 00:00",
"04-01-2018 00:00",
"05-01-2018 00:00",
"06-01-2018 00:00",
"07-01-2018 00:00",
"08-01-2018 00:00",
"09-01-2018 00:00",
"10-01-2018 00:00",
"11-01-2018 00:00",
"12-01-2018 00:00"
]
},
type: "area",
xFormat: "%m-%d-%Y %H:%M",
},
axis: {
x: {
tick: {
fit: false,
count: 5,
},
type: "timeseries"
}
},
zoom: {
enabled: {
type: "drag"
}
},
tooltip: {
format: {
title: function(x) {
return d3.timeFormat("%Y-%m-%d")(x);
}
}
},
point: {
r: 0,
focus: {
expand: {
r: 5
}
}
}
}
},
XAxisTickValues: {
options: {
data: {
Expand Down
73 changes: 73 additions & 0 deletions spec/interactions/zoom-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -476,4 +476,77 @@ describe("ZOOM", function() {
});
});
});

describe("zoom tick fit", () => {
before(() => {
args = {
data: {
x: "x",
json: {
"Temperature": [
"29.37",
"28.87",
"28.62",
"27.72",
"27.61",
"27.82",
"27.48",
"26.78",
"26.62",
"26.64",
"26.29",
"26.01"
],
"x": [
"01-01-2015 00:00",
"02-01-2015 00:00",
"03-01-2015 00:00",
"01-01-2016 00:00",
"02-01-2016 00:00",
"03-01-2016 00:00",
"01-01-2017 00:00",
"02-01-2017 00:00",
"03-01-2017 00:00",
"01-01-2018 00:00",
"02-01-2018 00:00",
"03-01-2018 00:00"
]
},
type: "area",
xFormat: "%m-%d-%Y %H:%M",
},
axis: {
x: {
tick: {
fit: false,
count: 5
},
type: "timeseries"
}
},
zoom: {
enabled: {
type: "drag"
}
}
};
});

it("check zoom-in tick format for timeseries", () => {
const selector = `.${CLASS.axisX} .tick text`;

chart.$.main.selectAll(selector).each(function(d, i) {
expect(+this.textContent).to.be.equal(2015 + i);
});

// when
chart.zoom([new Date("01-01-2016 00:00"), new Date("02-01-2016 00:00")]);

const expected = ["Jan 03", "Jan 10", "Jan 17", "Jan 24", "Jan 31"];

chart.$.main.selectAll(selector).each(function(d, i) {
expect(this.textContent).to.be.equal(expected[i]);
});
});
});
});
21 changes: 12 additions & 9 deletions src/axis/Axis.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ export default class Axis {
}
}

config.axis_x_tick_count && axis.ticks(config.axis_x_tick_count);

return axis;
}

Expand Down Expand Up @@ -214,25 +216,26 @@ export default class Axis {
updateXAxisTickValues(targets, axis) {
const $$ = this.owner;
const config = $$.config;
const xTickCount = config.axis_x_tick_count;
let tickValues;
const fit = config.axis_x_tick_fit;
const count = config.axis_x_tick_count;
let values;

if (config.axis_x_tick_fit || xTickCount) {
tickValues = this.generateTickValues(
if (fit || (count && fit)) {
values = this.generateTickValues(
$$.mapTargetsToUniqueXs(targets),
xTickCount,
count,
$$.isTimeSeries()
);
}

if (axis) {
axis.tickValues(tickValues);
axis.tickValues(values);
} else if ($$.xAxis) {
$$.xAxis.tickValues(tickValues);
$$.subXAxis.tickValues(tickValues);
$$.xAxis.tickValues(values);
$$.subXAxis.tickValues(values);
}

return tickValues;
return values;
}

getId(id) {
Expand Down
19 changes: 13 additions & 6 deletions src/config/Options.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ export default class Options {
* data: {
* xFormat: "%Y-%m-%d %H:%M:%S"
* }
* @see [D3's time specifier](https://npm.runkit.com/d3-time-format)
* @see [D3's time specifier](https://github.com/d3/d3-time-format#locale_format)
*/
data_xFormat: "%Y-%m-%d",

Expand Down Expand Up @@ -1448,8 +1448,9 @@ export default class Options {
* A function to format tick value. Format string is also available for timeseries data.
* @name axis․x․tick․format
* @memberof Options
* @type {Function}
* @type {Function|String}
* @default undefined
* @see [D3's time specifier](https://github.com/d3/d3-time-format#locale_format)
* @example
* axis: {
* x: {
Expand All @@ -1462,7 +1463,10 @@ export default class Options {
* // for category, index(Number) and categoryName(String) are given as parameter
* format: function(index, categoryName) {
* return categoryName.substr(0, 10);
* }
* },
*
* // for timeseries format specifier
* format: "%Y-%m-%d %H:%M:%S"
* }
* }
* }
Expand Down Expand Up @@ -1588,12 +1592,15 @@ export default class Options {
axis_x_tick_text_position: {x: 0, y: 0},

/**
* Fit x axis ticks.<br><br>
* If true set, the ticks will be positioned nicely. If false set, the ticks will be positioned according to x value of the data points.
* Fit x axis ticks.
* - **true**: ticks will be positioned nicely to have same intervals.
* - **false**: ticks will be positioned according to x value of the data points.
* @name axis․x․tick․fit
* @memberof Options
* @type {Boolean}
* @default true
* @see [Demo](http://jindo.com/git/billboard.js/demo/#Axis.XAxisTickFitting)
* @see [Demo: for timeseries zoom](https://naver.github.io/billboard.js/demo/#Axis.XAxisTickTimeseries)
* @example
* axis: {
* x: {
Expand Down Expand Up @@ -2661,7 +2668,7 @@ export default class Options {
* @property {Number|Function} [point.r=2.5] The radius size of each point.<br>
* - **NOTE:** Disabled for 'bubble' type
* @property {Boolean} [point.focus.expand.enabled=true] Whether to expand each point on focus.
* @property {Boolean} [point.focus.expand.r=point.r*1.75] The radius size of each point on focus.<br>
* @property {Number} [point.focus.expand.r=point.r*1.75] The radius size of each point on focus.<br>
* - **NOTE:** For 'bubble' type, the default is `bubbleSize*1.15`
* @property {Number} [point.select.r=point.r*4] The radius size of each point on selected.
* @property {String} [point.type="circle"] The type of point to be drawn<br>
Expand Down
14 changes: 9 additions & 5 deletions src/internals/ChartInternal.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,19 @@ export default class ChartInternal {
$$.dataTimeFormat = config.data_xLocaltime ? d3TimeParse : d3UtcParse;
$$.axisTimeFormat = config.axis_x_localtime ? d3TimeFormat : d3UtcFormat;

const isDragZoom = $$.config.zoom_enabled && $$.config.zoom_enabled.type === "drag";

$$.defaultAxisTimeFormat = d => {
const isZoomed = isDragZoom ? this.zoomScale :
this.zoomScale && $$.x.orgDomain().toString() !== this.zoomScale.domain().toString();

const specifier = (d.getMilliseconds() && ".%L") ||
(d.getSeconds() && ".:%S") ||
(d.getMinutes() && "%I:%M") ||
(d.getHours() && "%I %p") ||
((d.getDay() && d.getDate() !== 1) && "%-m/%-d") ||
(d.getDate() !== 1 && "%b %d") ||
(d.getMonth() && "%-m/%-d") ||
"%Y/%-m/%-d";
(isZoomed && d.getDate() === 1 && "%b\'%y") ||
(d.getMonth() && "%-m/%-d") || "%Y";

return $$.axisTimeFormat(specifier)(d);
};
Expand Down Expand Up @@ -752,8 +756,8 @@ export default class ChartInternal {
}
}

$$.svg.selectAll(`.${CLASS.axisX} .tick text`).each(function(e) {
const index = tickValues.indexOf(e);
$$.svg.selectAll(`.${CLASS.axisX} .tick text`).each(function(d) {
const index = tickValues.indexOf(d);

index >= 0 &&
d3Select(this).style("display", index % intervalForCulling ? "none" : "block");
Expand Down

0 comments on commit 9cda54f

Please sign in to comment.