From 925659c509cb74eb469bc5b311d03f0b238733e2 Mon Sep 17 00:00:00 2001 From: Ben McCann Date: Sat, 29 Jul 2017 16:14:41 -0700 Subject: [PATCH] Allow tooltipFormat to be a function. Provide a default tooltipFormat --- docs/axes/cartesian/time.md | 11 +++++--- src/scales/scale.time.js | 49 ++++++++++++++++++++++++++++------ test/specs/scale.time.tests.js | 1 + 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/docs/axes/cartesian/time.md b/docs/axes/cartesian/time.md index 9d15b5e2674..7fb5b5eb4e8 100644 --- a/docs/axes/cartesian/time.md +++ b/docs/axes/cartesian/time.md @@ -36,7 +36,7 @@ The following options are provided by the time scale. You may also set options p | `time.min` | [Time](#date-formats) | | If defined, this will override the data minimum | `time.parser` | `String/Function` | | Custom parser for dates. [more...](#parser) | `time.round` | `String` | `false` | If defined, dates will be rounded to the start of this unit. See [Time Units](#time-units) below for the allowed units. -| `time.tooltipFormat` | `String` | | The moment js format string to use for the tooltip. +| `time.tooltipFormat` | `String/Function` | | The moment js format string to use for the tooltip. [more...](#tooltip-format) | `time.unit` | `String` | `false` | If defined, will force the unit to be a certain type. See [Time Units](#time-units) section below for details. | `time.stepSize` | `Number` | `1` | The number of units between grid lines. | `time.minUnit` | `String` | `'millisecond'` | The minimum display format to be used for a time unit. @@ -147,6 +147,11 @@ The `ticks.source` property controls the ticks generation * `'labels'`: generates ticks from user given `data.labels` values ONLY ### Parser -If this property is defined as a string, it is interpreted as a custom format to be used by moment to parse the date. +If this property is defined as a string, it is interpreted as a custom format to be used by Moment.js to parse the date. -If this is a function, it must return a moment.js object given the appropriate data value. +If this is a function, it must return a Moment.js object given the appropriate data value. + +### Tooltip Format +If this property is defined as a string, it is interpreted as a custom format to be used by Moment.js to format the date. + +If this is a function, it must return a custom format to be used by Moment.js to format the date. diff --git a/src/scales/scale.time.js b/src/scales/scale.time.js index 4fe39b81082..7871a1ca408 100644 --- a/src/scales/scale.time.js +++ b/src/scales/scale.time.js @@ -231,6 +231,11 @@ function parse(input, scale) { /** * Returns the number of unit to skip to be able to display up to `capacity` number of ticks * in `unit` for the given `min` / `max` range and respecting the interval steps constraints. + * @param min {number} minimum tick millis + * @param max {number} maximum tick millis + * @param unit {string} the time unit the ticks are being displayed as + * @param capacity {number} the number of labels we have room to display + * @return {string} the number of ticks to skip before displaying the next one */ function determineStepSize(min, max, unit, capacity) { var range = max - min; @@ -403,6 +408,21 @@ function ticksFromTimestamps(values, majorUnit) { return ticks; } +/** + * Show the most specific time format by default + */ +function defaultTooltipFormat(context) { + var value = context.dataset.data[context.dataIndex]; + var momentDate = momentify(value, context.options.time); + if (momentDate.millisecond() !== 0) { + return 'MMM D, YYYY h:mm:ss.SSS a'; + } + if (momentDate.second() !== 0 || momentDate.minute() !== 0 || momentDate.hour() !== 0) { + return 'MMM D, YYYY h:mm:ss a'; + } + return 'MMM D, YYYY'; +} + module.exports = function(Chart) { var defaultConfig = { @@ -434,6 +454,7 @@ module.exports = function(Chart) { displayFormat: false, // DEPRECATED isoWeekday: false, // override week start day - see http://momentjs.com/docs/#/get-set/iso-weekday/ minUnit: 'millisecond', + tooltipFormat: defaultTooltipFormat, // defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/ displayFormats: { @@ -626,19 +647,31 @@ module.exports = function(Chart) { getLabelForIndex: function(index, datasetIndex) { var me = this; - var data = me.chart.data; - var timeOpts = me.options.time; + var chart = me.chart; + var data = chart.data; + var options = me.options; + var timeOpts = options.time; + var tooltipFormat = timeOpts.tooltipFormat; var label = data.labels && index < data.labels.length ? data.labels[index] : ''; var value = data.datasets[datasetIndex].data[index]; + var context = { + chart: chart, + options: options, + dataIndex: index, + dataset: chart.data.datasets[datasetIndex], + datasetIndex: datasetIndex + }; + var momentDate; - if (helpers.isObject(value)) { - label = me.getRightValue(value); - } - if (timeOpts.tooltipFormat) { - label = momentify(label, timeOpts).format(timeOpts.tooltipFormat); + if (!helpers.isObject(value)) { + return label; } - return label; + momentDate = momentify(me.getRightValue(value), timeOpts); + tooltipFormat = typeof tooltipFormat === 'function' + ? tooltipFormat.call(me, context) + : tooltipFormat; + return momentDate.format(tooltipFormat); }, /** diff --git a/test/specs/scale.time.tests.js b/test/specs/scale.time.tests.js index 19189040ee4..bbbdcd81860 100755 --- a/test/specs/scale.time.tests.js +++ b/test/specs/scale.time.tests.js @@ -102,6 +102,7 @@ describe('Time scale tests', function() { isoWeekday: false, displayFormat: false, minUnit: 'millisecond', + tooltipFormat: defaultConfig.time.tooltipFormat, displayFormats: { millisecond: 'h:mm:ss.SSS a', // 11:20:01.123 AM second: 'h:mm:ss a', // 11:20:01 AM