Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(axis): Fix x Axis tick fit for timeseries #795

Merged
merged 1 commit into from
Mar 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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