From: Tom Duncalf Date: Wed, 11 May 2016 08:34:22 +0000 (+0100) Subject: Add isoWeekday option to allow time scale ticks in 'week' unit mode to start on a... X-Git-Tag: v2.1.3~2^2^2 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=refs%2Fpull%2F2515%2Fhead;p=thirdparty%2FChart.js.git Add isoWeekday option to allow time scale ticks in 'week' unit mode to start on a specified day of the week --- diff --git a/docs/01-Scales.md b/docs/01-Scales.md index fd6c27dda..c938e5ea5 100644 --- a/docs/01-Scales.md +++ b/docs/01-Scales.md @@ -41,7 +41,7 @@ afterUpdate | Function | undefined | Callback that runs at the end of the update *gridLines*.zeroLineColor | Color | "rgba(0, 0, 0, 0.25)" | Stroke color of the grid line for the first index (index 0). *gridLines*.offsetGridLines | Boolean | false | If true, offset labels from grid lines. **scaleLabel** | Object | | Title for the entire axis. -*scaleLabel*.display | Boolean | false | +*scaleLabel*.display | Boolean | false | *scaleLabel*.labelString | String | "" | The text for the title. (i.e. "# of People", "Response Choices") *scaleLabel*.fontColor | Color | "#666" | Font color for the scale title. *scaleLabel*.fontFamily| String | "Helvetica Neue" | Font family for the scale title, follows CSS font-family options. @@ -62,7 +62,7 @@ afterUpdate | Function | undefined | Callback that runs at the end of the update *ticks*.display | Boolean | true | If true, show the ticks. *ticks*.suggestedMin | Number | - | User defined minimum number for the scale, overrides minimum value *except for if* it is higher than the minimum value. *ticks*.suggestedMax | Number | - | User defined maximum number for the scale, overrides maximum value *except for if* it is lower than the maximum value. -*ticks*.min | Number | - | User defined minimum number for the scale, overrides minimum value. +*ticks*.min | Number | - | User defined minimum number for the scale, overrides minimum value. *ticks*.max | Number | - | User defined minimum number for the scale, overrides maximum value *ticks*.autoSkip | Boolean | true | If true, automatically calculates how many labels that can be shown and hides labels accordingly. Turn it off to show all labels no matter what *ticks*.callback | Function | `function(value) { return '' + value; } ` | Returns the string representation of the tick value as it should be displayed on the chart. @@ -181,7 +181,10 @@ The time scale extends the core scale class with the following tick template: // string - By default, no rounding is applied. To round, set to a supported time unit eg. 'week', 'month', 'year', etc. round: false, - + + // Number - By default, the week and therefore the scale starts on the locale defined week if the unit is 'week'. To override the start day of the week, set this to an integer between 1 and 7 - see http://momentjs.com/docs/#/get-set/iso-weekday/ + isoWeekday: false, + // Moment js for each of the units. Replaces `displayFormat` // To override, use a pattern string from http://momentjs.com/docs/#/displaying/format/ displayFormats: { @@ -310,4 +313,4 @@ Chart.scaleService.updateScaleDefaults('linear', { min: 0 } }) -``` \ No newline at end of file +``` diff --git a/src/scales/scale.time.js b/src/scales/scale.time.js index 1a2fccf0d..daf18814f 100644 --- a/src/scales/scale.time.js +++ b/src/scales/scale.time.js @@ -47,6 +47,7 @@ module.exports = function(Chart) { unit: false, // false == automatic or override with week, month, year, etc. round: false, // none, or override with week, month, year, etc. displayFormat: false, // DEPRECATED + isoWeekday: false, // override week start day - see http://momentjs.com/docs/#/get-set/iso-weekday/ // defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/ displayFormats: { @@ -77,6 +78,13 @@ module.exports = function(Chart) { getLabelMoment: function(datasetIndex, index) { return this.labelMoments[datasetIndex][index]; }, + getMomentStartOf: function(tick) { + if (this.options.time.unit === 'week' && this.options.time.isoWeekday !== false) { + return tick.clone().startOf('isoWeek').isoWeekday(this.options.time.isoWeekday); + } else { + return tick.clone().startOf(this.tickUnit); + } + }, determineDataLimits: function() { this.labelMoments = []; @@ -208,8 +216,8 @@ module.exports = function(Chart) { unitDefinition = time.units[unitDefinitionIndex]; this.tickUnit = unitDefinition.name; - var leadingUnitBuffer = this.firstTick.diff(this.firstTick.clone().startOf(this.tickUnit), this.tickUnit, true); - var trailingUnitBuffer = this.lastTick.clone().add(1, this.tickUnit).startOf(this.tickUnit).diff(this.lastTick, this.tickUnit, true); + var leadingUnitBuffer = this.firstTick.diff(this.getMomentStartOf(this.firstTick), this.tickUnit, true); + var trailingUnitBuffer = this.getMomentStartOf(this.lastTick.clone().add(1, this.tickUnit)).diff(this.lastTick, this.tickUnit, true); this.scaleSizeInUnits = this.lastTick.diff(this.firstTick, this.tickUnit, true) + leadingUnitBuffer + trailingUnitBuffer; this.displayFormat = this.options.time.displayFormats[unitDefinition.name]; } @@ -220,18 +228,18 @@ module.exports = function(Chart) { // Only round the first tick if we have no hard minimum if (!this.options.time.min) { - this.firstTick.startOf(this.tickUnit); + this.firstTick = this.getMomentStartOf(this.firstTick); roundedStart = this.firstTick; } else { - roundedStart = this.firstTick.clone().startOf(this.tickUnit); + roundedStart = this.getMomentStartOf(this.firstTick); } // Only round the last tick if we have no hard maximum if (!this.options.time.max) { - var roundedEnd = this.lastTick.clone().startOf(this.tickUnit); + var roundedEnd = this.getMomentStartOf(this.lastTick); if (roundedEnd.diff(this.lastTick, this.tickUnit, true) !== 0) { // Do not use end of because we need this to be in the next time unit - this.lastTick.add(1, this.tickUnit).startOf(this.tickUnit); + this.lastTick = this.getMomentStartOf(this.lastTick.add(1, this.tickUnit)); } } @@ -278,7 +286,7 @@ module.exports = function(Chart) { this.scaleSizeInUnits = this.lastTick.diff(this.firstTick, this.tickUnit, true); } } - + this.ctx.restore(); }, // Get tooltip label diff --git a/test/scale.time.tests.js b/test/scale.time.tests.js index 207a11a69..72ddbb985 100644 --- a/test/scale.time.tests.js +++ b/test/scale.time.tests.js @@ -78,6 +78,7 @@ describe('Time scale tests', function() { format: false, unit: false, round: false, + isoWeekday: false, displayFormat: false, displayFormats: { 'millisecond': 'h:mm:ss.SSS a', // 11:20:01.123 AM @@ -327,6 +328,36 @@ describe('Time scale tests', function() { expect(scale.ticks).toEqual([ 'Jan 1, 2015', 'Jan 5, 2015' ]); }); + it('Should use the isoWeekday option', function() { + var scaleID = 'myScale'; + + var mockData = { + labels: [ + "2015-01-01T20:00:00", // Thursday + "2015-01-02T20:00:00", // Friday + "2015-01-03T20:00:00" // Saturday + ] + }; + + var mockContext = window.createMockContext(); + var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('time')); + config.time.unit = 'week'; + // Wednesday + config.time.isoWeekday = 3; + var Constructor = Chart.scaleService.getScaleConstructor('time'); + var scale = new Constructor({ + ctx: mockContext, + options: config, // use default config for scale + chart: { + data: mockData + }, + id: scaleID + }); + + scale.update(400, 50); + expect(scale.ticks).toEqual([ 'Dec 31, 2014', 'Jan 7, 2015' ]); + }); + it('should get the correct pixel for a value', function() { chartInstance = window.acquireChart({ type: 'line',