]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Initialize date adapter with chart options (#6016)
authorBen McCann <322311+benmccann@users.noreply.github.com>
Thu, 21 Feb 2019 07:11:32 +0000 (23:11 -0800)
committerSimon Brunel <simonbrunel@users.noreply.github.com>
Thu, 21 Feb 2019 07:11:32 +0000 (08:11 +0100)
docs/axes/cartesian/time.md
docs/getting-started/integration.md
src/adapters/adapter.moment.js
src/core/core.adapters.js
src/scales/scale.time.js
test/specs/scale.time.tests.js

index 6349af4fcb4773e031d4f2e9fa12f4d7ad3d15c4..a3d3e016cab234c3a33596b4b67739cbfa1a1c78 100644 (file)
@@ -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)
index 4070955edb1b959c5ce96273871221824c7c4628..e07a4c747831a1167590369550935106822058d2 100644 (file)
@@ -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
index 2ae611dfe2ab98a485973415ce34e4808d7afa19..e028b52f3aeebc460742a32f10d4fee5ec246b61 100644 (file)
@@ -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() {
index 246f3b70d3eca68333ca5e8d52ed80910965fe9e..7073412d824b612f8fe657267a164b7afe3da8c5 100644 (file)
@@ -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;
index 3f9a616992a3282a93fdb3fb12f198a021cad0ce..7d1df171e0fa444f905ccebd9649fd333317de33 100644 (file)
@@ -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);
        },
 
        /**
index 8c5162975548fd97c3f351159cae0dcea48be8ca..5258fba5d385f840a78806af20c5f49b9425ed97 100755 (executable)
@@ -76,6 +76,7 @@ describe('Time scale tests', function() {
                        scaleLabel: Chart.defaults.scale.scaleLabel,
                        bounds: 'data',
                        distribution: 'linear',
+                       adapters: {},
                        ticks: {
                                beginAtZero: false,
                                minRotation: 0,