Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Time axis ticks formatting for base and senior unit #4268

Merged
merged 16 commits into from Jun 15, 2017
Merged
17 changes: 15 additions & 2 deletions src/core/core.scale.js
@@ -1,5 +1,8 @@
'use strict';

var moment = require('moment');
moment = typeof(moment) === 'function' ? moment : window.moment;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with @etimberg's comment, Moment should not leak in core.scale.js but stays confined in scale.time.js


module.exports = function(Chart) {

var helpers = Chart.helpers;
Expand Down Expand Up @@ -503,6 +506,7 @@ module.exports = function(Chart) {

var tickFontColor = helpers.getValueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor);
var tickFont = parseFontOptions(optionTicks);
var majorTickFont = helpers.fontString(tickFont.size, 'bold', tickFont.family);

var tl = gridLines.drawTicks ? gridLines.tickMarkLength : 0;

Expand Down Expand Up @@ -651,7 +655,7 @@ module.exports = function(Chart) {
});

// Draw all of the tick labels, tick marks, and grid lines at the correct places
helpers.each(itemsToDraw, function(itemToDraw) {
helpers.each(itemsToDraw, function(itemToDraw, index) {
if (gridLines.display) {
context.save();
context.lineWidth = itemToDraw.glWidth;
Expand Down Expand Up @@ -681,7 +685,16 @@ module.exports = function(Chart) {
context.save();
context.translate(itemToDraw.labelX, itemToDraw.labelY);
context.rotate(itemToDraw.rotation);
context.font = tickFont.font;
var font = tickFont.font;
if (me.ticksAsTimestamps) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure that adding in this detail the core scale is the best way to go

// Add bold style to major units
var tickMoment = moment(me.ticksAsTimestamps[index]);
var tickMomentClone = tickMoment.clone();
if (me.majorUnit && tickMoment.valueOf() === tickMomentClone.startOf(me.majorUnit).valueOf()) {
font = majorTickFont;
}
}
context.font = font;
context.textBaseline = itemToDraw.textBaseline;
context.textAlign = itemToDraw.textAlign;

Expand Down
19 changes: 15 additions & 4 deletions src/scales/scale.time.js
Expand Up @@ -25,9 +25,9 @@ module.exports = function(Chart) {
displayFormats: {
millisecond: 'h:mm:ss.SSS a', // 11:20:01.123 AM,
second: 'h:mm:ss a', // 11:20:01 AM
minute: 'h:mm:ss a', // 11:20:01 AM
hour: 'MMM D, hA', // Sept 4, 5PM
day: 'll', // Sep 4 2015
minute: 'h:mm a', // 11:20 AM
hour: 'hA', // 5PM
day: 'MMM D', // Sep 4
week: 'll', // Week 46, or maybe "[W]WW - YYYY" ?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should change this to MMM D as well

month: 'MMM YYYY', // Sept 2015
quarter: '[Q]Q - YYYY', // Q3
Expand Down Expand Up @@ -182,7 +182,18 @@ module.exports = function(Chart) {
},
// Function to format an individual tick mark
tickFormatFunction: function(tick, index, ticks) {
var formattedTick = tick.format(this.displayFormat);
var formattedTick;
var tickClone = tick.clone();
if (this.majorUnit &&
this.majorDisplayFormat &&
tick.valueOf() === tickClone.startOf(this.majorUnit).valueOf()) {
// format as senior unit
formattedTick = tick.format(this.majorDisplayFormat);
} else {
// format as base unit
formattedTick = tick.format(this.displayFormat);
}

var tickOpts = this.options.ticks;
var callback = helpers.getValueOrDefault(tickOpts.callback, tickOpts.userCallback);

Expand Down
29 changes: 15 additions & 14 deletions test/specs/scale.time.tests.js
Expand Up @@ -96,14 +96,14 @@ describe('Time scale tests', function() {
displayFormats: {
millisecond: 'h:mm:ss.SSS a', // 11:20:01.123 AM
second: 'h:mm:ss a', // 11:20:01 AM
minute: 'h:mm:ss a', // 11:20:01 AM
hour: 'MMM D, hA', // Sept 4, 5PM
day: 'll', // Sep 4 2015
minute: 'h:mm a', // 11:20 AM
hour: 'hA', // 5PM
day: 'MMM D', // Sep 4
week: 'll', // Week 46, or maybe "[W]WW - YYYY" ?
month: 'MMM YYYY', // Sept 2015
quarter: '[Q]Q - YYYY', // Q3
year: 'YYYY' // 2015
}
},
}
});

Expand All @@ -125,7 +125,7 @@ describe('Time scale tests', function() {
var scaleOptions = Chart.scaleService.getScaleDefaults('time');
var scale = createScale(mockData, scaleOptions);
scale.update(1000, 200);
expect(scale.ticks).toEqual(['Jan 1, 2015', 'Jan 2, 2015', 'Jan 3, 2015', 'Jan 4, 2015', 'Jan 5, 2015', 'Jan 6, 2015', 'Jan 7, 2015', 'Jan 8, 2015', 'Jan 9, 2015', 'Jan 10, 2015', 'Jan 11, 2015']);
expect(scale.ticks).toEqual(['Jan 1', 'Jan 2', 'Jan 3', 'Jan 4, 2015', 'Jan 5', 'Jan 6', 'Jan 7', 'Jan 8', 'Jan 9', 'Jan 10', 'Jan 11, 2015']);
});

it('should accept labels as date objects', function() {
Expand All @@ -134,7 +134,7 @@ describe('Time scale tests', function() {
};
var scale = createScale(mockData, Chart.scaleService.getScaleDefaults('time'));
scale.update(1000, 200);
expect(scale.ticks).toEqual(['Jan 1, 2015', 'Jan 2, 2015', 'Jan 3, 2015', 'Jan 4, 2015', 'Jan 5, 2015', 'Jan 6, 2015', 'Jan 7, 2015', 'Jan 8, 2015', 'Jan 9, 2015', 'Jan 10, 2015', 'Jan 11, 2015']);
expect(scale.ticks).toEqual(['Jan 1', 'Jan 2', 'Jan 3', 'Jan 4, 2015', 'Jan 5', 'Jan 6', 'Jan 7', 'Jan 8', 'Jan 9', 'Jan 10', 'Jan 11, 2015']);
});

it('should accept data as xy points', function() {
Expand Down Expand Up @@ -180,7 +180,7 @@ describe('Time scale tests', function() {

var xScale = chart.scales.xScale0;
xScale.update(800, 200);
expect(xScale.ticks).toEqual(['Jan 1, 2015', 'Jan 2, 2015', 'Jan 3, 2015', 'Jan 4, 2015', 'Jan 5, 2015', 'Jan 6, 2015', 'Jan 7, 2015', 'Jan 8, 2015', 'Jan 9, 2015', 'Jan 10, 2015', 'Jan 11, 2015']);
expect(xScale.ticks).toEqual(['Jan 1', 'Jan 2', 'Jan 3', 'Jan 4, 2015', 'Jan 5', 'Jan 6', 'Jan 7', 'Jan 8', 'Jan 9', 'Jan 10', 'Jan 11, 2015']);
});
});

Expand Down Expand Up @@ -218,8 +218,8 @@ describe('Time scale tests', function() {
var xScale = chart.scales.xScale0;

// Counts down because the lines are drawn top to bottom
expect(xScale.ticks[0]).toEqualOneOf(['Nov 19, 1981', 'Nov 20, 1981', 'Nov 21, 1981']); // handle time zone changes
expect(xScale.ticks[1]).toEqualOneOf(['Nov 19, 1981', 'Nov 20, 1981', 'Nov 21, 1981']); // handle time zone changes
expect(xScale.ticks[0]).toEqualOneOf(['Nov 19', 'Nov 20', 'Nov 21']); // handle time zone changes
expect(xScale.ticks[1]).toEqualOneOf(['Nov 19', 'Nov 20', 'Nov 21']); // handle time zone changes
});

it('should build ticks using the config unit', function() {
Expand All @@ -233,7 +233,7 @@ describe('Time scale tests', function() {
var scale = createScale(mockData, config);
scale.update(2500, 200);

expect(scale.ticks).toEqual(['Jan 1, 8PM', 'Jan 1, 9PM', 'Jan 1, 10PM', 'Jan 1, 11PM', 'Jan 2, 12AM', 'Jan 2, 1AM', 'Jan 2, 2AM', 'Jan 2, 3AM', 'Jan 2, 4AM', 'Jan 2, 5AM', 'Jan 2, 6AM', 'Jan 2, 7AM', 'Jan 2, 8AM', 'Jan 2, 9AM', 'Jan 2, 10AM', 'Jan 2, 11AM', 'Jan 2, 12PM', 'Jan 2, 1PM', 'Jan 2, 2PM', 'Jan 2, 3PM', 'Jan 2, 4PM', 'Jan 2, 5PM', 'Jan 2, 6PM', 'Jan 2, 7PM', 'Jan 2, 8PM', 'Jan 2, 9PM']);
expect(scale.ticks).toEqual(['8PM', '9PM', '10PM', '11PM', 'Jan 2', '1AM', '2AM', '3AM', '4AM', '5AM', '6AM', '7AM', '8AM', '9AM', '10AM', '11AM', '12PM', '1PM', '2PM', '3PM', '4PM', '5PM', '6PM', '7PM', '8PM', '9PM']);
});

it('build ticks honoring the minUnit', function() {
Expand All @@ -245,7 +245,7 @@ describe('Time scale tests', function() {
config.time.minUnit = 'day';

var scale = createScale(mockData, config);
expect(scale.ticks).toEqual(['Jan 1, 2015', 'Jan 2, 2015', 'Jan 3, 2015']);
expect(scale.ticks).toEqual(['Jan 1', 'Jan 2', 'Jan 3']);
});

it('should build ticks using the config diff', function() {
Expand All @@ -261,7 +261,7 @@ describe('Time scale tests', function() {
scale.update(800, 200);

// last date is feb 15 because we round to start of week
expect(scale.ticks).toEqual(['Dec 28, 2014', 'Jan 4, 2015', 'Jan 11, 2015', 'Jan 18, 2015', 'Jan 25, 2015', 'Feb 1, 2015', 'Feb 8, 2015', 'Feb 15, 2015']);
expect(scale.ticks).toEqual(['Dec 28, 2014', 'Jan 4, 2015', 'Jan 11, 2015', 'Jan 18, 2015', 'Jan 25, 2015', 'Feb 2015', 'Feb 8, 2015', 'Feb 15, 2015']);
});

describe('when specifying limits', function() {
Expand All @@ -279,15 +279,16 @@ describe('Time scale tests', function() {
config.time.min = '2014-12-29T04:00:00';

var scale = createScale(mockData, config);
expect(scale.ticks[0]).toEqual('Dec 29, 2014');
expect(scale.ticks[0]).toEqual('Dec 29');
});

it('should use the max option', function() {
config.time.unit = 'day';
config.time.max = '2015-01-05T06:00:00';

var scale = createScale(mockData, config);
expect(scale.ticks[scale.ticks.length - 1]).toEqual('Jan 6, 2015');

expect(scale.ticks[scale.ticks.length - 1]).toEqual('Jan 6');
});
});

Expand Down