Skip to content

Commit

Permalink
Implement adapter to abstract date/time features (#5960)
Browse files Browse the repository at this point in the history
  • Loading branch information
simonbrunel committed Jan 11, 2019
1 parent b50a1c2 commit 8a3eb85
Show file tree
Hide file tree
Showing 6 changed files with 360 additions and 94 deletions.
82 changes: 82 additions & 0 deletions src/adapters/adapter.moment.js
@@ -0,0 +1,82 @@
// TODO v3 - make this adapter external (chartjs-adapter-moment)

'use strict';

var moment = require('moment');
var adapter = require('../core/core.adapters')._date;
var helpers = require('../helpers/helpers.core');

var FORMATS = {
millisecond: 'h:mm:ss.SSS a',
second: 'h:mm:ss a',
minute: 'h:mm a',
hour: 'hA',
day: 'MMM D',
week: 'll',
month: 'MMM YYYY',
quarter: '[Q]Q - YYYY',
year: 'YYYY'
};

var PRESETS = {
full: 'MMM D, YYYY h:mm:ss.SSS a',
time: 'MMM D, YYYY h:mm:ss a',
date: 'MMM D, YYYY'
};

helpers.merge(adapter, moment ? {
_id: 'moment', // DEBUG ONLY

formats: function() {
return FORMATS;
},

presets: function() {
return PRESETS;
},

parse: function(value, format) {
if (typeof value === 'string' && typeof format === 'string') {
value = moment(value, format);
} else if (!(value instanceof moment)) {
value = moment(value);
}
return value.isValid() ? +value : null;
},

format: function(time, format) {
return moment(time).format(format);
},

add: function(time, amount, unit) {
return +moment(time).add(amount, unit);
},

diff: function(max, min, unit) {
return moment.duration(moment(max).diff(moment(min))).as(unit);
},

startOf: function(time, unit, weekday) {
time = moment(time);
if (unit === 'isoWeek') {
return +time.isoWeekday(weekday);
}
return +time.startOf(unit);
},

endOf: function(time, unit) {
return +moment(time).endOf(unit);
},

// DEPRECATIONS

/**
* Provided for backward compatibility with scale.getValueForPixel().
* @deprecated since version 2.8.0
* @todo remove at version 3
* @private
*/
_create: function(time) {
return moment(time);
},
} : {});
10 changes: 10 additions & 0 deletions src/adapters/index.js
@@ -0,0 +1,10 @@
'use strict';

// -----------------------------------------------------------------------------
// IMPORTANT: do NOT submit new adapters to this repository, instead
// create an external library named `chartjs-adapter-{lib-name}`
// -----------------------------------------------------------------------------

// Built-in moment adapter that we need to keep for backward compatibility
// https://github.com/chartjs/Chart.js/issues/5542
require('./adapter.moment');
4 changes: 4 additions & 0 deletions src/chart.js
Expand Up @@ -8,6 +8,7 @@ Chart.helpers = require('./helpers/index');
// @todo dispatch these helpers into appropriated helpers/helpers.* file and write unit tests!
require('./core/core.helpers')(Chart);

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

// Load to register built-in adapters (as side effects)
require('./adapters');

// Loading built-in plugins
var plugins = require('./plugins');
for (var k in plugins) {
Expand Down
115 changes: 115 additions & 0 deletions src/core/core.adapters.js
@@ -0,0 +1,115 @@
/**
* @namespace Chart._adapters
* @since 2.8.0
* @private
*/

'use strict';

function abstract() {
throw new Error(
'This method is not implemented: either no adapter can ' +
'be found or an incomplete integration was provided.'
);
}

/**
* Date adapter (current used by the time scale)
* @namespace Chart._adapters._date
* @memberof Chart._adapters
* @private
*/

/**
* Currently supported unit string values.
* @typedef {('millisecond'|'second'|'minute'|'hour'|'day'|'week'|'month'|'quarter'|'year')}
* @memberof Chart._adapters._date
* @name Unit
*/

/** @lends Chart._adapters._date */
module.exports._date = {
/**
* Returns a map of time formats for the supported units.
* @returns {{string: string}}
*/
formats: abstract,

/**
* Returns a map of date/time formats for the following presets:
* 'full': date + time + millisecond
* 'time': date + time
* 'date': date
* @returns {{string: string}}
*/
presets: abstract,

/**
* Parses the given `value` and return the associated timestamp.
* @param {any} value - the value to parse (usually comes from the data)
* @param {string} [format] - the expected data format
* @returns {(number|null)}
* @function
*/
parse: abstract,

/**
* Returns the formatted date in the specified `format` for a given `timestamp`.
* @param {number} timestamp - the timestamp to format
* @param {string} format - the date/time token
* @return {string}
* @function
*/
format: abstract,

/**
* Adds the specified `amount` of `unit` to the given `timestamp`.
* @param {number} timestamp - the input timestamp
* @param {number} amount - the amount to add
* @param {Unit} unit - the unit as string
* @return {number}
* @function
*/
add: abstract,

/**
* Returns the number of `unit` between the given timestamps.
* @param {number} max - the input timestamp (reference)
* @param {number} min - the timestamp to substract
* @param {Unit} unit - the unit as string
* @return {number}
* @function
*/
diff: abstract,

/**
* Returns start of `unit` for the given `timestamp`.
* @param {number} timestamp - the input timestamp
* @param {Unit} unit - the unit as string
* @param {number} [weekday] - the ISO day of the week with 1 being Monday
* and 7 being Sunday (only needed if param *unit* is `isoWeek`).
* @function
*/
startOf: abstract,

/**
* Returns end of `unit` for the given `timestamp`.
* @param {number} timestamp - the input timestamp
* @param {Unit} unit - the unit as string
* @function
*/
endOf: abstract,

// DEPRECATIONS

/**
* Provided for backward compatibility for scale.getValueForPixel(),
* this method should be overridden only by the moment adapter.
* @deprecated since version 2.8.0
* @todo remove at version 3
* @private
*/
_create: function(value) {
return value;
}
};

0 comments on commit 8a3eb85

Please sign in to comment.