From 3ecc98fffc36dfd2ad49d8d21ad9fcaa0c67b57e Mon Sep 17 00:00:00 2001 From: Brad Hards Date: Sun, 2 Apr 2017 06:33:06 +1000 Subject: [PATCH] [Timeline fix #2814] Do not corrupt class names at high zoom levels. (#2909) This takes a more robust approach to produce the list of class names. --- lib/timeline/TimeStep.js | 73 ++++++++++++++++++++-------------------- test/TimeStep.test.js | 44 ++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 37 deletions(-) create mode 100644 test/TimeStep.test.js diff --git a/lib/timeline/TimeStep.js b/lib/timeline/TimeStep.js index d0f230f69..e3f6ff7b8 100644 --- a/lib/timeline/TimeStep.js +++ b/lib/timeline/TimeStep.js @@ -560,6 +560,7 @@ TimeStep.prototype.getClassName = function() { var m = this.moment(this.current); var current = m.locale ? m.locale('en') : m.lang('en'); // old versions of moment have .lang() function var step = this.step; + var classNames = []; function even(value) { return (value / step % 2 == 0) ? ' vis-even' : ' vis-odd'; @@ -592,51 +593,49 @@ TimeStep.prototype.getClassName = function() { switch (this.scale) { case 'millisecond': - return today(current) + - even(current.milliseconds()).trim(); - + classNames.push(today(current)); + classNames.push(even(current.milliseconds())); + break; case 'second': - return today(current) + - even(current.seconds()).trim(); - + classNames.push(today(current)); + classNames.push(even(current.seconds())); + break; case 'minute': - return today(current) + - even(current.minutes()).trim(); - + classNames.push(today(current)); + classNames.push(even(current.minutes())); + break; case 'hour': - return 'vis-h' + current.hours() + - (this.step == 4 ? '-h' + (current.hours() + 4) : '') + - today(current) + - even(current.hours()); - + classNames.push('vis-h' + current.hours() + this.step == 4 ? '-h' + (current.hours() + 4) : ''); + classNames.push(today(current)); + classNames.push(even(current.hours())); + break; case 'weekday': - return 'vis-' + current.format('dddd').toLowerCase() + - today(current) + - currentWeek(current) + - even(current.date()); - + classNames.push('vis-' + current.format('dddd').toLowerCase()); + classNames.push(today(current)); + classNames.push(currentWeek(current)); + classNames.push(even(current.date())); + break; case 'day': - return 'vis-day' + current.date() + - ' vis-' + current.format('MMMM').toLowerCase() + - today(current) + - currentMonth(current) + - (this.step <= 2 ? today(current) : '') + - (this.step <= 2 ? ' vis-' + current.format('dddd').toLowerCase() : '' + even(current.date() - 1)); - + classNames.push('vis-day' + current.date()); + classNames.push('vis-' + current.format('MMMM').toLowerCase()); + classNames.push(today(current)); + classNames.push(currentMonth(current)); + classNames.push(this.step <= 2 ? today(current) : ''); + classNames.push(this.step <= 2 ? 'vis-' + current.format('dddd').toLowerCase() : ''); + classNames.push(even(current.date() - 1)); + break; case 'month': - return 'vis-' + current.format('MMMM').toLowerCase() + - currentMonth(current) + - even(current.month()); - + classNames.push('vis-' + current.format('MMMM').toLowerCase()); + classNames.push(currentMonth(current)); + classNames.push(even(current.month())); + break; case 'year': - var year = current.year(); - return 'vis-year' + year + - currentYear(current) + - even(year); - - default: - return ''; + classNames.push('vis-year' + current.year()); + classNames.push(currentYear(current)); + classNames.push(even(current.year())); + break; } + return classNames.filter(String).join(" "); }; module.exports = TimeStep; diff --git a/test/TimeStep.test.js b/test/TimeStep.test.js new file mode 100644 index 000000000..4ab3b2ca2 --- /dev/null +++ b/test/TimeStep.test.js @@ -0,0 +1,44 @@ +var assert = require('assert'); +var vis = require('../dist/vis'); +var jsdom = require('mocha-jsdom') +var moment = vis.moment; +var timeline = vis.timeline; +var TimeStep = timeline.TimeStep; +var TestSupport = require('./TestSupport'); + +describe('TimeStep', function () { + + jsdom(); + + it('should work with just start and end dates', function () { + var timestep = new TimeStep(new Date(2017, 3, 3), new Date(2017, 3, 5)); + assert.equal(timestep.autoScale, true, "should autoscale if scale not specified"); + assert.equal(timestep.scale, "day", "should default to day scale if scale not specified"); + assert.equal(timestep.step, 1, "should default to 1 day step if scale not specified"); + }); + + it('should work with specified scale (just under 1 second)', function () { + var timestep = new TimeStep(new Date(2017, 3, 3), new Date(2017, 3, 5), 999); + assert.equal(timestep.scale, "second", "should have right scale"); + assert.equal(timestep.step, 1, "should have right step size"); + }); + + // TODO: check this - maybe should work for 1000? + it('should work with specified scale (1 second)', function () { + var timestep = new TimeStep(new Date(2017, 3, 3), new Date(2017, 3, 5), 1001); + assert.equal(timestep.scale, "second", "should have right scale"); + assert.equal(timestep.step, 5, "should have right step size"); + }); + + it('should work with specified scale (2 seconds)', function () { + var timestep = new TimeStep(new Date(2017, 3, 3), new Date(2017, 3, 5), 2000); + assert.equal(timestep.scale, "second", "should have right scale"); + assert.equal(timestep.step, 5, "should have right step size"); + }); + + it('should work with specified scale (5 seconds)', function () { + var timestep = new TimeStep(new Date(2017, 3, 3), new Date(2017, 3, 5), 5001); + assert.equal(timestep.scale, "second", "should have right scale"); + assert.equal(timestep.step, 10, "should have right step size"); + }); +}); \ No newline at end of file