mirror of
https://github.com/chartjs/Chart.js.git
synced 2025-12-08 20:36:08 +00:00
Initialize date adapter with chart options (#6016)
This commit is contained in:
parent
20c26455ba
commit
f2b099b835
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@ -76,6 +76,7 @@ describe('Time scale tests', function() {
|
||||
scaleLabel: Chart.defaults.scale.scaleLabel,
|
||||
bounds: 'data',
|
||||
distribution: 'linear',
|
||||
adapters: {},
|
||||
ticks: {
|
||||
beginAtZero: false,
|
||||
minRotation: 0,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user