Skip to content

Commit 6fc7998

Browse files
authored
Implement adapter to abstract date/time features (chartjs#5960)
1 parent b1346f6 commit 6fc7998

File tree

6 files changed

+360
-94
lines changed

6 files changed

+360
-94
lines changed

src/adapters/adapter.moment.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// TODO v3 - make this adapter external (chartjs-adapter-moment)
2+
3+
'use strict';
4+
5+
var moment = require('moment');
6+
var adapter = require('../core/core.adapters')._date;
7+
var helpers = require('../helpers/helpers.core');
8+
9+
var FORMATS = {
10+
millisecond: 'h:mm:ss.SSS a',
11+
second: 'h:mm:ss a',
12+
minute: 'h:mm a',
13+
hour: 'hA',
14+
day: 'MMM D',
15+
week: 'll',
16+
month: 'MMM YYYY',
17+
quarter: '[Q]Q - YYYY',
18+
year: 'YYYY'
19+
};
20+
21+
var PRESETS = {
22+
full: 'MMM D, YYYY h:mm:ss.SSS a',
23+
time: 'MMM D, YYYY h:mm:ss a',
24+
date: 'MMM D, YYYY'
25+
};
26+
27+
helpers.merge(adapter, moment ? {
28+
_id: 'moment', // DEBUG ONLY
29+
30+
formats: function() {
31+
return FORMATS;
32+
},
33+
34+
presets: function() {
35+
return PRESETS;
36+
},
37+
38+
parse: function(value, format) {
39+
if (typeof value === 'string' && typeof format === 'string') {
40+
value = moment(value, format);
41+
} else if (!(value instanceof moment)) {
42+
value = moment(value);
43+
}
44+
return value.isValid() ? +value : null;
45+
},
46+
47+
format: function(time, format) {
48+
return moment(time).format(format);
49+
},
50+
51+
add: function(time, amount, unit) {
52+
return +moment(time).add(amount, unit);
53+
},
54+
55+
diff: function(max, min, unit) {
56+
return moment.duration(moment(max).diff(moment(min))).as(unit);
57+
},
58+
59+
startOf: function(time, unit, weekday) {
60+
time = moment(time);
61+
if (unit === 'isoWeek') {
62+
return +time.isoWeekday(weekday);
63+
}
64+
return +time.startOf(unit);
65+
},
66+
67+
endOf: function(time, unit) {
68+
return +moment(time).endOf(unit);
69+
},
70+
71+
// DEPRECATIONS
72+
73+
/**
74+
* Provided for backward compatibility with scale.getValueForPixel().
75+
* @deprecated since version 2.8.0
76+
* @todo remove at version 3
77+
* @private
78+
*/
79+
_create: function(time) {
80+
return moment(time);
81+
},
82+
} : {});

src/adapters/index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
'use strict';
2+
3+
// -----------------------------------------------------------------------------
4+
// IMPORTANT: do NOT submit new adapters to this repository, instead
5+
// create an external library named `chartjs-adapter-{lib-name}`
6+
// -----------------------------------------------------------------------------
7+
8+
// Built-in moment adapter that we need to keep for backward compatibility
9+
// https://github.com/chartjs/Chart.js/issues/5542
10+
require('./adapter.moment');

src/chart.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Chart.helpers = require('./helpers/index');
88
// @todo dispatch these helpers into appropriated helpers/helpers.* file and write unit tests!
99
require('./core/core.helpers')(Chart);
1010

11+
Chart._adapters = require('./core/core.adapters');
1112
Chart.Animation = require('./core/core.animation');
1213
Chart.animationService = require('./core/core.animations');
1314
Chart.controllers = require('./controllers/index');
@@ -30,6 +31,9 @@ Chart.helpers.each(scales, function(scale, type) {
3031
Chart.scaleService.registerScaleType(type, scale, scale._defaults);
3132
});
3233

34+
// Load to register built-in adapters (as side effects)
35+
require('./adapters');
36+
3337
// Loading built-in plugins
3438
var plugins = require('./plugins');
3539
for (var k in plugins) {

src/core/core.adapters.js

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/**
2+
* @namespace Chart._adapters
3+
* @since 2.8.0
4+
* @private
5+
*/
6+
7+
'use strict';
8+
9+
function abstract() {
10+
throw new Error(
11+
'This method is not implemented: either no adapter can ' +
12+
'be found or an incomplete integration was provided.'
13+
);
14+
}
15+
16+
/**
17+
* Date adapter (current used by the time scale)
18+
* @namespace Chart._adapters._date
19+
* @memberof Chart._adapters
20+
* @private
21+
*/
22+
23+
/**
24+
* Currently supported unit string values.
25+
* @typedef {('millisecond'|'second'|'minute'|'hour'|'day'|'week'|'month'|'quarter'|'year')}
26+
* @memberof Chart._adapters._date
27+
* @name Unit
28+
*/
29+
30+
/** @lends Chart._adapters._date */
31+
module.exports._date = {
32+
/**
33+
* Returns a map of time formats for the supported units.
34+
* @returns {{string: string}}
35+
*/
36+
formats: abstract,
37+
38+
/**
39+
* Returns a map of date/time formats for the following presets:
40+
* 'full': date + time + millisecond
41+
* 'time': date + time
42+
* 'date': date
43+
* @returns {{string: string}}
44+
*/
45+
presets: abstract,
46+
47+
/**
48+
* Parses the given `value` and return the associated timestamp.
49+
* @param {any} value - the value to parse (usually comes from the data)
50+
* @param {string} [format] - the expected data format
51+
* @returns {(number|null)}
52+
* @function
53+
*/
54+
parse: abstract,
55+
56+
/**
57+
* Returns the formatted date in the specified `format` for a given `timestamp`.
58+
* @param {number} timestamp - the timestamp to format
59+
* @param {string} format - the date/time token
60+
* @return {string}
61+
* @function
62+
*/
63+
format: abstract,
64+
65+
/**
66+
* Adds the specified `amount` of `unit` to the given `timestamp`.
67+
* @param {number} timestamp - the input timestamp
68+
* @param {number} amount - the amount to add
69+
* @param {Unit} unit - the unit as string
70+
* @return {number}
71+
* @function
72+
*/
73+
add: abstract,
74+
75+
/**
76+
* Returns the number of `unit` between the given timestamps.
77+
* @param {number} max - the input timestamp (reference)
78+
* @param {number} min - the timestamp to substract
79+
* @param {Unit} unit - the unit as string
80+
* @return {number}
81+
* @function
82+
*/
83+
diff: abstract,
84+
85+
/**
86+
* Returns start of `unit` for the given `timestamp`.
87+
* @param {number} timestamp - the input timestamp
88+
* @param {Unit} unit - the unit as string
89+
* @param {number} [weekday] - the ISO day of the week with 1 being Monday
90+
* and 7 being Sunday (only needed if param *unit* is `isoWeek`).
91+
* @function
92+
*/
93+
startOf: abstract,
94+
95+
/**
96+
* Returns end of `unit` for the given `timestamp`.
97+
* @param {number} timestamp - the input timestamp
98+
* @param {Unit} unit - the unit as string
99+
* @function
100+
*/
101+
endOf: abstract,
102+
103+
// DEPRECATIONS
104+
105+
/**
106+
* Provided for backward compatibility for scale.getValueForPixel(),
107+
* this method should be overridden only by the moment adapter.
108+
* @deprecated since version 2.8.0
109+
* @todo remove at version 3
110+
* @private
111+
*/
112+
_create: function(value) {
113+
return value;
114+
}
115+
};

0 commit comments

Comments
 (0)