From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Thu, 21 Feb 2019 07:11:32 +0000 (-0800) Subject: Initialize date adapter with chart options (#6016) X-Git-Tag: v2.8.0-rc.1~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f2b099b835bf5d6dfe3a7d3097997ec11983c3ed;p=thirdparty%2FChart.js.git Initialize date adapter with chart options (#6016) --- diff --git a/docs/axes/cartesian/time.md b/docs/axes/cartesian/time.md index 6349af4fc..a3d3e016c 100644 --- a/docs/axes/cartesian/time.md +++ b/docs/axes/cartesian/time.md @@ -28,6 +28,7 @@ The following options are provided by the time scale. You may also set options p | Name | Type | Default | Description | ---- | ---- | ------- | ----------- +| `adapters.date` | `object` | `{}` | Options for adapter for external date library if that adapter needs or supports options | `distribution` | `string` | `'linear'` | How data is plotted. [more...](#scale-distribution) | `bounds` | `string` | `'data'` | Determines the scale bounds. [more...](#scale-bounds) | `ticks.source` | `string` | `'auto'` | How ticks are generated. [more...](#ticks-source) diff --git a/docs/getting-started/integration.md b/docs/getting-started/integration.md index 4070955ed..e07a4c747 100644 --- a/docs/getting-started/integration.md +++ b/docs/getting-started/integration.md @@ -25,7 +25,7 @@ import Chart from 'chart.js'; var myChart = new Chart(ctx, {...}); ``` -**Note:** Moment.js is installed along Chart.js as dependency. If you don't want to use Momemt.js (either because you use a different date adapter or simply because don't need time functionalities), you will have to configure your bundler to exclude this dependency (e.g. using [`externals` for Webpack](https://webpack.js.org/configuration/externals/) or [`external` for Rollup](https://rollupjs.org/guide/en#peer-dependencies)). +**Note:** Moment.js is installed along Chart.js as dependency. If you don't want to use Moment.js (either because you use a different date adapter or simply because don't need time functionalities), you will have to configure your bundler to exclude this dependency (e.g. using [`externals` for Webpack](https://webpack.js.org/configuration/externals/) or [`external` for Rollup](https://rollupjs.org/guide/en#peer-dependencies)). ```javascript // Webpack diff --git a/src/adapters/adapter.moment.js b/src/adapters/adapter.moment.js index 2ae611dfe..e028b52f3 100644 --- a/src/adapters/adapter.moment.js +++ b/src/adapters/adapter.moment.js @@ -3,8 +3,7 @@ 'use strict'; var moment = require('moment'); -var adapter = require('../core/core.adapters')._date; -var helpers = require('../helpers/helpers.core'); +var adapters = require('../core/core.adapters'); var FORMATS = { datetime: 'MMM D, YYYY, h:mm:ss a', @@ -19,7 +18,7 @@ var FORMATS = { year: 'YYYY' }; -helpers.merge(adapter, moment ? { +adapters._date.override(moment ? { _id: 'moment', // DEBUG ONLY formats: function() { diff --git a/src/core/core.adapters.js b/src/core/core.adapters.js index 246f3b70d..7073412d8 100644 --- a/src/core/core.adapters.js +++ b/src/core/core.adapters.js @@ -6,6 +6,8 @@ 'use strict'; +var helpers = require('../helpers/index'); + function abstract() { throw new Error( 'This method is not implemented: either no adapter can ' + @@ -27,8 +29,14 @@ function abstract() { * @name Unit */ -/** @lends Chart._adapters._date */ -module.exports._date = { +/** + * @class + */ +function DateAdapter(options) { + this.options = options || {}; +} + +helpers.extend(DateAdapter.prototype, /** @lends DateAdapter */ { /** * Returns a map of time formats for the supported formatting units defined * in Unit as well as 'datetime' representing a detailed date/time string. @@ -104,4 +112,10 @@ module.exports._date = { _create: function(value) { return value; } +}); + +DateAdapter.override = function(members) { + helpers.extend(DateAdapter.prototype, members); }; + +module.exports._date = DateAdapter; diff --git a/src/scales/scale.time.js b/src/scales/scale.time.js index 3f9a61699..7d1df171e 100644 --- a/src/scales/scale.time.js +++ b/src/scales/scale.time.js @@ -1,6 +1,6 @@ 'use strict'; -var adapter = require('../core/core.adapters')._date; +var adapters = require('../core/core.adapters'); var defaults = require('../core/core.defaults'); var helpers = require('../helpers/index'); var Scale = require('../core/core.scale'); @@ -177,7 +177,9 @@ function interpolate(table, skey, sval, tkey) { return prev[tkey] + offset; } -function toTimestamp(input, options) { +function toTimestamp(scale, input) { + var adapter = scale._adapter; + var options = scale.options.time; var parser = options.parser; var format = parser || options.format; var value = input; @@ -211,19 +213,19 @@ function toTimestamp(input, options) { return value; } -function parse(input, scale) { +function parse(scale, input) { if (helpers.isNullOrUndef(input)) { return null; } var options = scale.options.time; - var value = toTimestamp(scale.getRightValue(input), options); + var value = toTimestamp(scale, scale.getRightValue(input)); if (value === null) { return value; } if (options.round) { - value = +adapter.startOf(value, options.round); + value = +scale._adapter.startOf(value, options.round); } return value; @@ -276,13 +278,13 @@ function determineUnitForAutoTicks(minUnit, min, max, capacity) { /** * Figures out what unit to format a set of ticks with */ -function determineUnitForFormatting(ticks, minUnit, min, max) { +function determineUnitForFormatting(scale, ticks, minUnit, min, max) { var ilen = UNITS.length; var i, unit; for (i = ilen - 1; i >= UNITS.indexOf(minUnit); i--) { unit = UNITS[i]; - if (INTERVALS[unit].common && adapter.diff(max, min, unit) >= ticks.length) { + if (INTERVALS[unit].common && scale._adapter.diff(max, min, unit) >= ticks.length) { return unit; } } @@ -304,7 +306,9 @@ function determineMajorUnit(unit) { * Important: this method can return ticks outside the min and max range, it's the * responsibility of the calling code to clamp values if needed. */ -function generate(min, max, capacity, options) { +function generate(scale, min, max, capacity) { + var adapter = scale._adapter; + var options = scale.options; var timeOpts = options.time; var minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, capacity); var major = determineMajorUnit(minor); @@ -388,13 +392,13 @@ function computeOffsets(table, ticks, min, max, options) { return {start: start, end: end}; } -function ticksFromTimestamps(values, majorUnit) { +function ticksFromTimestamps(scale, values, majorUnit) { var ticks = []; var i, ilen, value, major; for (i = 0, ilen = values.length; i < ilen; ++i) { value = values[i]; - major = majorUnit ? value === +adapter.startOf(value, majorUnit) : false; + major = majorUnit ? value === +scale._adapter.startOf(value, majorUnit) : false; ticks.push({ value: value, @@ -426,6 +430,7 @@ var defaultConfig = { */ bounds: 'data', + adapters: {}, time: { parser: false, // false == a pattern string from https://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment format: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from https://momentjs.com/docs/#/parsing/string-format/ @@ -465,6 +470,7 @@ module.exports = Scale.extend({ var me = this; var options = me.options; var time = options.time || (options.time = {}); + var adapter = me._adapter = new adapters._date(options.adapters.date); // DEPRECATIONS: output a message only one time per update if (time.format) { @@ -493,6 +499,7 @@ module.exports = Scale.extend({ determineDataLimits: function() { var me = this; var chart = me.chart; + var adapter = me._adapter; var timeOpts = me.options.time; var unit = timeOpts.unit || 'day'; var min = MAX_INTEGER; @@ -505,7 +512,7 @@ module.exports = Scale.extend({ // Convert labels to timestamps for (i = 0, ilen = dataLabels.length; i < ilen; ++i) { - labels.push(parse(dataLabels[i], me)); + labels.push(parse(me, dataLabels[i])); } // Convert data to timestamps @@ -518,7 +525,7 @@ module.exports = Scale.extend({ datasets[i] = []; for (j = 0, jlen = data.length; j < jlen; ++j) { - timestamp = parse(data[j], me); + timestamp = parse(me, data[j]); timestamps.push(timestamp); datasets[i][j] = timestamp; } @@ -546,8 +553,8 @@ module.exports = Scale.extend({ max = Math.max(max, timestamps[timestamps.length - 1]); } - min = parse(timeOpts.min, me) || min; - max = parse(timeOpts.max, me) || max; + min = parse(me, timeOpts.min) || min; + max = parse(me, timeOpts.max) || max; // In case there is no valid min/max, set limits based on unit time option min = min === MAX_INTEGER ? +adapter.startOf(Date.now(), unit) : min; @@ -586,7 +593,7 @@ module.exports = Scale.extend({ break; case 'auto': default: - timestamps = generate(min, max, me.getLabelCapacity(min), options); + timestamps = generate(me, min, max, me.getLabelCapacity(min), options); } if (options.bounds === 'ticks' && timestamps.length) { @@ -595,8 +602,8 @@ module.exports = Scale.extend({ } // Enforce limits with user min/max options - min = parse(timeOpts.min, me) || min; - max = parse(timeOpts.max, me) || max; + min = parse(me, timeOpts.min) || min; + max = parse(me, timeOpts.max) || max; // Remove ticks outside the min/max range for (i = 0, ilen = timestamps.length; i < ilen; ++i) { @@ -610,7 +617,7 @@ module.exports = Scale.extend({ me.max = max; // PRIVATE - me._unit = timeOpts.unit || determineUnitForFormatting(ticks, timeOpts.minUnit, me.min, me.max); + me._unit = timeOpts.unit || determineUnitForFormatting(me, ticks, timeOpts.minUnit, me.min, me.max); me._majorUnit = determineMajorUnit(me._unit); me._table = buildLookupTable(me._timestamps.data, min, max, options.distribution); me._offsets = computeOffsets(me._table, ticks, min, max, options); @@ -619,11 +626,12 @@ module.exports = Scale.extend({ ticks.reverse(); } - return ticksFromTimestamps(ticks, me._majorUnit); + return ticksFromTimestamps(me, ticks, me._majorUnit); }, getLabelForIndex: function(index, datasetIndex) { var me = this; + var adapter = me._adapter; var data = me.chart.data; var timeOpts = me.options.time; var label = data.labels && index < data.labels.length ? data.labels[index] : ''; @@ -633,12 +641,12 @@ module.exports = Scale.extend({ label = me.getRightValue(value); } if (timeOpts.tooltipFormat) { - return adapter.format(toTimestamp(label, timeOpts), timeOpts.tooltipFormat); + return adapter.format(toTimestamp(me, label), timeOpts.tooltipFormat); } if (typeof label === 'string') { return label; } - return adapter.format(toTimestamp(label, timeOpts), timeOpts.displayFormats.datetime); + return adapter.format(toTimestamp(me, label), timeOpts.displayFormats.datetime); }, /** @@ -647,6 +655,7 @@ module.exports = Scale.extend({ */ tickFormatFunction: function(time, index, ticks, format) { var me = this; + var adapter = me._adapter; var options = me.options; var formats = options.time.displayFormats; var minorFormat = formats[me._unit]; @@ -696,7 +705,7 @@ module.exports = Scale.extend({ } if (time === null) { - time = parse(value, me); + time = parse(me, value); } if (time !== null) { @@ -719,7 +728,7 @@ module.exports = Scale.extend({ var time = interpolate(me._table, 'pos', pos, 'time'); // DEPRECATION, we should return time directly - return adapter._create(time); + return me._adapter._create(time); }, /** diff --git a/test/specs/scale.time.tests.js b/test/specs/scale.time.tests.js index 8c5162975..5258fba5d 100755 --- a/test/specs/scale.time.tests.js +++ b/test/specs/scale.time.tests.js @@ -76,6 +76,7 @@ describe('Time scale tests', function() { scaleLabel: Chart.defaults.scale.scaleLabel, bounds: 'data', distribution: 'linear', + adapters: {}, ticks: { beginAtZero: false, minRotation: 0,