From 31281fbfef7cd1dd3a880684f3e34e727e0041cc Mon Sep 17 00:00:00 2001 From: Ben McCann Date: Fri, 21 Jul 2017 23:33:22 -0700 Subject: [PATCH] Allow specifying the time axis via t attribute (#4533) For time series charts it may make more sense to specify the horizontal axis using the variable `t`. This change will make it much easier to use the time scale with the financial chart, which takes in the data points `{t, o, h, l, c}`. --- docs/axes/cartesian/time.md | 29 +++++++++++++++----- src/core/core.scale.js | 11 +++++--- src/scales/scale.time.js | 10 +++++++ test/specs/scale.time.tests.js | 48 ++++++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 11 deletions(-) diff --git a/docs/axes/cartesian/time.md b/docs/axes/cartesian/time.md index dc4a2bb42d0..6e107d515a5 100644 --- a/docs/axes/cartesian/time.md +++ b/docs/axes/cartesian/time.md @@ -2,6 +2,25 @@ The time scale is used to display times and dates. When building its ticks, it will automatically calculate the most comfortable unit base on the size of the scale. +## Data Sets + +### Input Data + +The x-axis data points may additionally be specified via the `t` attribute when using the time scale. + + data: [{ + x: new Date(), + y: 1 + }, { + t: new Date(), + y: 10 + }] + + +### Date Formats + +When providing data for the time scale, Chart.js supports all of the formats that Moment.js accepts. See [Moment.js docs](http://momentjs.com/docs/#/parsing/) for details. + ## Configuration Options The following options are provided by the time scale. They are all located in the `time` sub options. These options extend the [common tick configuration](README.md#tick-configuration). @@ -19,11 +38,7 @@ The following options are provided by the time scale. They are all located in th | `stepSize` | `Number` | `1` | The number of units between grid lines. | `minUnit` | `String` | `'millisecond'` | The minimum display format to be used for a time unit. -## Date Formats - -When providing data for the time scale, Chart.js supports all of the formats that Moment.js accepts. See [Moment.js docs](http://momentjs.com/docs/#/parsing/) for details. - -## Time Units +### Time Units The following time measurements are supported. The names can be passed as strings to the `time.unit` config option to force a certain unit. @@ -55,7 +70,7 @@ var chart = new Chart(ctx, { }) ``` -## Display Formats +### Display Formats The following display formats are used to configure how different time units are formed into strings for the axis tick marks. See [moment.js](http://momentjs.com/docs/#/displaying/format/) for the allowable format strings. Name | Default | Example @@ -91,7 +106,7 @@ var chart = new Chart(ctx, { }) ``` -## Parser +### Parser If this property is defined as a string, it is interpreted as a custom format to be used by moment to parse the date. If this is a function, it must return a moment.js object given the appropriate data value. diff --git a/src/core/core.scale.js b/src/core/core.scale.js index 0fcc95c4766..27a0f0596fe 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -442,11 +442,14 @@ module.exports = function(Chart) { return NaN; } // If it is in fact an object, dive in one more level - if (typeof(rawValue) === 'object') { - if ((rawValue instanceof Date) || (rawValue.isValid)) { - return rawValue; + if (rawValue) { + if (this.isHorizontal()) { + if (rawValue.x !== undefined) { + return this.getRightValue(rawValue.x); + } + } else if (rawValue.y !== undefined) { + return this.getRightValue(rawValue.y); } - return this.getRightValue(this.isHorizontal() ? rawValue.x : rawValue.y); } // Value is good, return it diff --git a/src/scales/scale.time.js b/src/scales/scale.time.js index 93e49887b03..8b3dc97437b 100644 --- a/src/scales/scale.time.js +++ b/src/scales/scale.time.js @@ -176,6 +176,16 @@ module.exports = function(Chart) { Chart.Scale.prototype.initialize.call(this); }, + /** + * Allows data to be referenced via 't' attribute + */ + getRightValue: function(rawValue) { + if (rawValue && rawValue.t !== undefined) { + rawValue = rawValue.t; + } + return Chart.Scale.prototype.getRightValue.call(this, rawValue); + }, + determineDataLimits: function() { var me = this; var chart = me.chart; diff --git a/test/specs/scale.time.tests.js b/test/specs/scale.time.tests.js index c5ca74fa926..057521ab406 100755 --- a/test/specs/scale.time.tests.js +++ b/test/specs/scale.time.tests.js @@ -205,6 +205,54 @@ describe('Time scale tests', function() { expect(ticks).toEqual(['Jan 2015', 'Jan 2', 'Jan 3', 'Jan 4', 'Jan 5', 'Jan 6', 'Jan 7', 'Jan 8', 'Jan 9', 'Jan 10', 'Jan 11']); }); + + it('should accept data as ty points', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [{ + xAxisID: 'tScale0', + data: [{ + t: newDateFromRef(0), + y: 1 + }, { + t: newDateFromRef(1), + y: 10 + }, { + t: newDateFromRef(2), + y: 0 + }, { + t: newDateFromRef(4), + y: 5 + }, { + t: newDateFromRef(6), + y: 77 + }, { + t: newDateFromRef(7), + y: 9 + }, { + t: newDateFromRef(9), + y: 5 + }] + }], + }, + options: { + scales: { + xAxes: [{ + id: 'tScale0', + type: 'time', + position: 'bottom' + }], + } + } + }); + + var tScale = chart.scales.tScale0; + tScale.update(800, 200); + var ticks = getTicksValues(tScale.ticks); + + expect(ticks).toEqual(['Jan 2015', 'Jan 2', 'Jan 3', 'Jan 4', 'Jan 5', 'Jan 6', 'Jan 7', 'Jan 8', 'Jan 9', 'Jan 10', 'Jan 11']); + }); }); it('should allow custom time parsers', function() {