Browse Source

Implementation of a week scale feature (#3009)

* Add Gitter badge (#2179)

* do not generate source-maps in distribution version

* add 'dist' folder for deployment

* added Badges

* added codeclimate badge

* added @Tooa to the support team

* added badges from isitmaintained.com (#2517)

* do not ignore dist and test folders in master

* generated dist files for v4.18.0

* generated dist files for v4.18.1

* Cheap fix for bug #2795

* Update to PR #2826 to use newline format

* changed to v4.18.1-SNAPSHOT

* chore(docs): general improvements (#2652)

* removed NOTICE file

* updated license date range to include 2017

* chore(docs): updated support team members

* chore: updated dependencies and devDependencies (#2649)

* Fixes instanceof Object statements for objects from other windows and iFrames. (#2631)

* Replaces instanceof Object checks with typeof to prevent cross tab issues.

* Adds missing space.

* chore: removed google-analytics from all examples (#2670)

* chore(docs): Add note that PRs should be submitted against the `develop` branch (#2623)

Related to: https://github.com/almende/vis/pull/2618
Related to: https://github.com/almende/vis/pull/2620

* feat(timeline): Change setCustomTimeTitle title parameter to be a string or a function (#2611)

* change setCustomTimeTitle title parameter, Now could be an string or a function
* Fixed indent and spacing

* feat(timeline): refactor tooltip to only use one dom-element (#2662)

* feat(network): Allow for image nodes to have a selected or broken image (#2601)

* feat(tests): run mocha tests in travis ci (#2687)

* Added showX(YZ)Axis options to Graph3d (#2686)

* Added showX(YZ)Axis to Graph3d

* Added show_Axis options to docs and playground example

* Resolved merge conflict

* Added show_Axis options to docs and playground example

* fix(build): use babel version compatible with webpack@1.14 (#2693)

fixes #2685

* feat(docs): use babel preset2015 for custom builds (#2678)

* add link to a mentioned example (#2709)

* chore(lint): added support for eslint (#2695)

* Trivial typo fix in how_to_help doc. (#2714)

* fix(timeline): #2598 Flickering onUpdateTimeTooltip (#2702)

* Fix redraw order
* Fix error when option is not defined
* Allow template labels
* Add .travis.yml file
* Add experiment travis code
* Fix react example
* Add animation to onUpdateTooltip

* fix(timeline): #778 Tooltip does not work with background items in timeline (#2703)

* Fix redraw order
* Fix error when option is not defined
* Allow template labels
* Add .travis.yml file
* Add experiment travis code
* Fix react example
* Make items z-index default to 1

* Add initial tests for Timeline PointItem (#2716)

* fix(timeline): #2679 TypeError: Cannot read property 'hasOwnProperty' of null (#2735)

* Fix redraw order
* Fix error when option is not defined
* Allow template labels
* Add .travis.yml file
* Add experiment travis code
* Fix react example
* Fix bug in item editable

* feat(timeline): #2647 Dynamic rolling mode option (#2705)

* Fix redraw order
* Fix error when option is not defined
* Allow template labels
* Add .travis.yml file
* Add experiment travis code
* Fix react example
* Add toggleRollingMode option
* Update docs with toggleRollingMode option

* fixes timestep next issue (#2732)

* feat(timeline): added new locales for french and espanol (#2723)

* Fix eslint problem on Travis. (#2744)

* fix: Range.js "event" is undeclared (#2749)

* fix(timeline): #2720 Problems with option editable (#2743)

Clean up and centralise edit status for Timeline Items.

* feat(network): Improve the performance of the network layout engine (#2729)

* Improve the performance of the network layout engine

Short-cut the execution of a number of methods in LayoutEngine to make them
handle highly-connected graphs better.

* Demonstrations of layouts of large networks

* Added support to supply an end to bar charts to have them scale (#2760)

* Added support to supply an X2 to bar charts to have them scale

* Fixed graph2d stacking issue.  It no longer takes into account hidden items

* Changed x2 to end per recommendation and added this to the docs

* Initial tests for timeline ItemSet. (#2750)

Somewhat more complicated setup, associated with the need for a real window.

* [Timeline] Modify redraw logic to treat scroll as needing restack. (#2774)

This addresses #1982 and #1417.

It possibly reduces performance, but correctness seems better.

* fix(timeline): #2672 Item events original event (#2704)

* Fix redraw order

* Fix error when option is not defined

* Allow template labels

* Add .travis.yml file

* Add experiment travis code

* Fix react example

* Fix events returned from mouse events

* Fix example

* Rename censor to stringifyObject in example

* [timeline] Update examples to use ISOString format. (#2791)

Resolves #2790

* [timeline] Update serialization example to use ISOString dates. (#2789)

Resolves #2696

* added github templates for issues and pull-requests (#2787)

fixes #2418

* feat(timeline): Add item data as argument to the template function (#2799)

* Fix regression introduced in #2743. (#2796)

* Fix for issue #2536 (#2803)

* Fix for issue #2536

* Adjusted documentation for fix.

* Adjustments due to review

* Grrrrr whitespace

* Fixed Travis issue

* Cheap fix for bug #2795

* Update to PR #2826 to use newline format

* Update to gitignore to reflect changes on remote

* clean dist folder

* Local gitignore update

* Just a first example file for the week scale feature

* Allowing sourcemap creation

* Initial (non-functional) commit to ensure we insert code at the right places (check TODOs)

* Functional, not bug-free version which works with locale aware week numbers.

* Locale-aware implementation and simplified major labels to a full year

* Trying to make the major labels show the correct start date

* Working implementation of week numbers using localization.

* removing development leftovers

* Updated package.json

* Reintagrate package.json from accidental deletion

* Updates for package.json

* Fixing package.json

* Integrate the week numbers feature in the documentation.

* Reverting local changes to .gitignore

* Reverting local changes

* Extending examples to cover the case when 1st day of week and 1st day of month align; Fixing display bug so that week numbers are not repeated in minorLabels

* Putting the examples into a loop
gemini
Marco Schnüriger 7 years ago
committed by yotamberk
parent
commit
0a64249ce6
5 changed files with 187 additions and 8 deletions
  1. +11
    -2
      docs/timeline/index.html
  2. +111
    -0
      examples/timeline/styling/weekStyling.html
  3. +55
    -4
      lib/timeline/TimeStep.js
  4. +5
    -1
      lib/timeline/component/TimeAxis.js
  5. +5
    -1
      lib/timeline/optionsTimeline.js

+ 11
- 2
docs/timeline/index.html View File

@ -612,6 +612,7 @@ function (option, path) {
hour: 'HH:mm',
weekday: 'ddd D',
day: 'D',
week: 'w',
month: 'MMM',
year: 'YYYY'
},
@ -622,6 +623,7 @@ function (option, path) {
hour: 'ddd D MMMM',
weekday: 'MMMM YYYY',
day: 'MMMM YYYY',
week: 'MMMM YYYY',
month: 'YYYY',
year: ''
}
@ -1044,7 +1046,7 @@ function (option, path) {
<td>function</td>
<td>When moving items on the Timeline, they will be snapped to nice dates like full hours or days, depending on the current scale. The <code>snap</code> function can be replaced with a custom function, or can be set to <code>null</code> to disable snapping. The signature of the snap function is:
<pre class="prettyprint lang-js">function snap(date: Date, scale: string, step: number) : Date or number</pre>
The parameter <code>scale</code> can be can be 'millisecond', 'second', 'minute', 'hour', 'weekday, 'day, 'month, or 'year'. The parameter <code>step</code> is a number like 1, 2, 4, 5.
The parameter <code>scale</code> can be can be 'millisecond', 'second', 'minute', 'hour', 'weekday, 'week', 'day, 'month, or 'year'. The parameter <code>step</code> is a number like 1, 2, 4, 5.
</td>
</tr>
@ -1088,10 +1090,11 @@ function (option, path) {
<td class="indent">timeAxis.scale</td>
<td>String</td>
<td>none</td>
<td>Set a fixed scale for the time axis of the Timeline. Choose from <code>'millisecond'</code>, <code>'second'</code>, <code>'minute'</code>, <code>'hour'</code>, <code>'weekday'</code>, <code>'day'</code>, <code>'month'</code>, <code>'year'</code>. Example usage:
<td>Set a fixed scale for the time axis of the Timeline. Choose from <code>'millisecond'</code>, <code>'second'</code>, <code>'minute'</code>, <code>'hour'</code>, <code>'weekday'</code>, <code>'week'</code>, <code>'day'</code>, <code>'month'</code>, <code>'year'</code>. Example usage:
<pre class="prettyprint lang-js">var options = {
timeAxis: {scale: 'minute', step: 5}
}</pre>
<p>Note: The 'week' scale only works properly when <a href="#Localization">locales</a> are enabled.</p>
</td>
</tr>
@ -2023,6 +2026,9 @@ var options = {
<tr>
<td>Days</td><td><code>vis-day1</code>, <code>vis-day2</code>, ..., <code>vis-day31</code></td>
</tr>
<tr>
<td>Week</td><td><code>vis-week1</code>, <code>vis-week2</code>, ..., <code>vis-week53</code></td>
</tr>
<tr>
<td>Months</td><td><code>vis-january</code>, <code>vis-february</code>, <code>vis-march</code>, <code>vis-april</code>, <code>vis-may</code>, <code>vis-june</code>, <code>vis-july</code>, <code>vis-august</code>, <code>vis-september</code>, <code>vis-october</code>, <code>vis-november</code>, <code>vis-december</code></td>
</tr>
@ -2030,6 +2036,9 @@ var options = {
<td>Years</td><td><code>vis-year2014</code>, <code>vis-year2015</code>, ...</td>
</tr>
</table>
<p>
Note: the 'week' scale is not included in the automatic zoom levels as its scale is not a direct logical successor of 'days' nor a logical predecessor of 'months'
</p>
<p>Examples:</p>

+ 111
- 0
examples/timeline/styling/weekStyling.html View File

@ -0,0 +1,111 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Timeline | Grid styling</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment-with-locales.min.js"></script>
<script src="../../../dist/vis.js"></script>
<link href="../../../dist/vis-timeline-graph2d.min.css" rel="stylesheet" type="text/css"/>
<style type="text/css">
body, html {
font-family: sans-serif;
}
/* alternating column backgrounds */
.vis-time-axis .vis-grid.vis-odd {
background: #f5f5f5;
}
</style>
</head>
<body>
<p>
Week numbers are calculated based on locales. For this to properly work, the timeline must be loaded with a version
of moment.js including locales.</p>
<p>To set a locale for the timeline, specify the option
<code>{locale: STRING}</code>.</p>
<p>To set the scale to use week numbers, use for example <code>{scale: 'week', step: 1}</code>.</p>
<p>The following timeline is initialized with the 'de' locale and items are added with locally localized moment.js
objects. The timeline locale can be switched to another locale at runtime. If you choose the 'en' locale, the week
numbers will be calculated according to the US week calendar numbering scheme.</p>
<p>
<label for="locale">Select a locale:</label>
<select id="locale">
<option value="en">en</option>
<option value="it">it</option>
<option value="nl">nl</option>
<option value="de" selected>de</option>
</select>
</p>
<div id="visualization"></div>
<script type="text/javascript">
var itemCount = 26;
// DOM element where the Timeline will be attached
var container = document.getElementById('visualization');
// just a group for the effects
var groups = new vis.DataSet();
groups.add([{id: 1, content: "ISO Weeks"}, {id: 2, content: "US Weeks"}]);
// Create a DataSet (allows two way data-binding)
var items = new vis.DataSet();
// create a localized moment object based on the current date
var USdate = moment().locale('en').hours(0).minutes(0).seconds(0).milliseconds(0);
// use the locale-aware weekday function to move to the begin of the current week
USdate.weekday(0);
// Iterate and just add a week to use it again in the next iteration
for (var i = 0; i < itemCount; i++) {
var USweekNumber = USdate.format('w');
var USweekStart = USdate.format();
var USweekEnd = USdate.add(1, 'week').format();
items.add({
id: i,
group: 2,
content: 'US week ' + USweekNumber,
start: USweekStart,
end: USweekEnd
});
}
// create another localized moment object - the 'de' locale works according to the ISO8601 leap week calendar system
var DEdate = moment().locale('de').hours(0).minutes(0).seconds(0).milliseconds(0);
DEdate.weekday(0);
for (var j = 0; j < itemCount; j++) {
var DEweekNumber = DEdate.format('w');
var DEweekStart = DEdate.format();
var DEweekEnd = DEdate.add(1, 'week').format();
items.add({
id: itemCount + j,
group: 1,
content: 'ISO week ' + DEweekNumber,
start: DEweekStart,
end: DEweekEnd
});
}
// Configuration for the Timeline
var options = {timeAxis: {scale: 'week', step: 1}, locale: 'de'};
// Create a Timeline
var timeline = new vis.Timeline(container, items, groups, options);
// update the locale when changing the select box value
var select = document.getElementById('locale');
select.onchange = function () {
timeline.setOptions({
locale: this.value
});
};
select.onchange();
</script>
</body>
</html>

+ 55
- 4
lib/timeline/TimeStep.js View File

@ -69,6 +69,7 @@ TimeStep.FORMAT = {
hour: 'HH:mm',
weekday: 'ddd D',
day: 'D',
week: 'w',
month: 'MMM',
year: 'YYYY'
},
@ -79,6 +80,7 @@ TimeStep.FORMAT = {
hour: 'ddd D MMMM',
weekday: 'MMMM YYYY',
day: 'MMMM YYYY',
week: 'MMMM YYYY',
month: 'YYYY',
year: ''
}
@ -101,7 +103,7 @@ TimeStep.prototype.setMoment = function (moment) {
/**
* Set custom formatting for the minor an major labels of the TimeStep.
* Both `minorLabels` and `majorLabels` are an Object with properties:
* 'millisecond', 'second', 'minute', 'hour', 'weekday', 'day', 'month', 'year'.
* 'millisecond', 'second', 'minute', 'hour', 'weekday', 'day', 'week', 'month', 'year'.
* @param {{minorLabels: Object, majorLabels: Object}} format
*/
TimeStep.prototype.setFormat = function (format) {
@ -153,6 +155,7 @@ TimeStep.prototype.roundToMinor = function() {
this.current.year(this.step * Math.floor(this.current.year() / this.step));
this.current.month(0);
case 'month': this.current.date(1);
case 'week': this.current.weekday(0);
case 'day': // intentional fall through
case 'weekday': this.current.hours(0);
case 'hour': this.current.minutes(0);
@ -170,6 +173,7 @@ TimeStep.prototype.roundToMinor = function() {
case 'hour': this.current.subtract(this.current.hours() % this.step, 'hours'); break;
case 'weekday': // intentional fall through
case 'day': this.current.subtract((this.current.date() - 1) % this.step, 'day'); break;
case 'week': this.current.subtract(this.current.week() % this.step, 'week'); break;
case 'month': this.current.subtract(this.current.month() % this.step, 'month'); break;
case 'year': this.current.subtract(this.current.year() % this.step, 'year'); break;
default: break;
@ -210,6 +214,21 @@ TimeStep.prototype.next = function() {
break;
case 'weekday': // intentional fall through
case 'day': this.current.add(this.step, 'day'); break;
case 'week':
if (this.current.weekday() !== 0){ // we had a month break not correlating with a week's start before
this.current.weekday(0); // switch back to week cycles
this.current.add(this.step, 'week');
} else { // first day of the week
var nextWeek = this.current.clone();
nextWeek.add(1, 'week');
if(nextWeek.isSame(this.current, 'month')){ // is the first day of the next week in the same month?
this.current.add(this.step, 'week'); // the default case
} else { // inject a step at each first day of the month
this.current.add(this.step, 'week');
this.current.date(1);
}
}
break;
case 'month': this.current.add(this.step, 'month'); break;
case 'year': this.current.add(this.step, 'year'); break;
default: break;
@ -224,6 +243,7 @@ TimeStep.prototype.next = function() {
case 'hour': if(this.current.hours() > 0 && this.current.hours() < this.step) this.current.hours(0); break;
case 'weekday': // intentional fall through
case 'day': if(this.current.date() < this.step+1) this.current.date(1); break;
case 'week': if(this.current.week() < this.step) this.current.week(1); break; // week numbering starts at 1, not 0
case 'month': if(this.current.month() < this.step) this.current.month(0); break;
case 'year': break; // nothing to do for year
default: break;
@ -260,7 +280,7 @@ TimeStep.prototype.getCurrent = function() {
* @param {{scale: string, step: number}} params
* An object containing two properties:
* - A string 'scale'. Choose from 'millisecond', 'second',
* 'minute', 'hour', 'weekday', 'day', 'month', 'year'.
* 'minute', 'hour', 'weekday', 'day', 'week', 'month', 'year'.
* - A number 'step'. A step size, by default 1.
* Choose for example 1, 2, 5, or 10.
*/
@ -338,7 +358,7 @@ TimeStep.prototype.setMinimumStep = function(minimumStep) {
* Static function
* @param {Date} date the date to be snapped.
* @param {string} scale Current scale, can be 'millisecond', 'second',
* 'minute', 'hour', 'weekday, 'day', 'month', 'year'.
* 'minute', 'hour', 'weekday, 'day', 'week', 'month', 'year'.
* @param {number} step Current step (1, 2, 4, 5, ...
* @return {Date} snappedDate
*/
@ -370,6 +390,20 @@ TimeStep.snap = function(date, scale, step) {
clone.seconds(0);
clone.milliseconds(0);
}
else if (scale == 'week') {
if (clone.weekday() > 2) { // doing it the momentjs locale aware way
clone.weekday(0);
clone.add(1, 'week');
}
else {
clone.weekday(0);
}
clone.hours(0);
clone.minutes(0);
clone.seconds(0);
clone.milliseconds(0);
}
else if (scale == 'day') {
//noinspection FallthroughInSwitchStatementJS
switch (step) {
@ -452,6 +486,7 @@ TimeStep.prototype.isMajor = function() {
switch (this.scale) {
case 'year':
case 'month':
case 'week':
case 'weekday':
case 'day':
case 'hour':
@ -465,6 +500,7 @@ TimeStep.prototype.isMajor = function() {
}
else if (this.switchedMonth == true) {
switch (this.scale) {
case 'week':
case 'weekday':
case 'day':
case 'hour':
@ -501,6 +537,8 @@ TimeStep.prototype.isMajor = function() {
case 'weekday': // intentional fall through
case 'day':
return (date.date() == 1);
case 'week':
return (date.date() == 1);
case 'month':
return (date.month() == 0);
case 'year':
@ -530,7 +568,15 @@ TimeStep.prototype.getLabelMinor = function(date) {
}
var format = this.format.minorLabels[this.scale];
return (format && format.length > 0) ? this.moment(date).format(format) : '';
// noinspection FallThroughInSwitchStatementJS
switch (this.scale) {
case 'week':
if(this.isMajor() && date.weekday() !== 0){
return "";
}
default:
return (format && format.length > 0) ? this.moment(date).format(format) : '';
}
};
/**
@ -624,6 +670,11 @@ TimeStep.prototype.getClassName = function() {
classNames.push(this.step <= 2 ? 'vis-' + current.format('dddd').toLowerCase() : '');
classNames.push(even(current.date() - 1));
break;
case 'week':
classNames.push('vis-week' + current.format('w'));
classNames.push(currentWeek(current));
classNames.push(even(current.week()));
break;
case 'month':
classNames.push('vis-' + current.format('MMMM').toLowerCase());
classNames.push(currentMonth(current));

+ 5
- 1
lib/timeline/component/TimeAxis.js View File

@ -227,6 +227,7 @@ TimeAxis.prototype._repaintLabels = function () {
var x;
var xNext;
var isMajor, nextIsMajor;
var showMinorGrid;
var width = 0, prevWidth;
var line;
var labelMinor;
@ -255,7 +256,10 @@ TimeAxis.prototype._repaintLabels = function () {
prevWidth = width;
width = xNext - x;
var showMinorGrid = (width >= prevWidth * 0.4); // prevent displaying of the 31th of the month on a scale of 5 days
switch (step.scale) {
case 'week': showMinorGrid = true; break;
default: showMinorGrid = (width >= prevWidth * 0.4); break; // prevent displaying of the 31th of the month on a scale of 5 days
}
if (this.options.showMinorLabels && showMinorGrid) {
var label = this._repaintMinorText(x, labelMinor, orientation, className);

+ 5
- 1
lib/timeline/optionsTimeline.js View File

@ -54,6 +54,7 @@ let allOptions = {
hour: {string,'undefined': 'undefined'},
weekday: {string,'undefined': 'undefined'},
day: {string,'undefined': 'undefined'},
week: {string,'undefined': 'undefined'},
month: {string,'undefined': 'undefined'},
year: {string,'undefined': 'undefined'},
__type__: {object, 'function': 'function'}
@ -65,6 +66,7 @@ let allOptions = {
hour: {string,'undefined': 'undefined'},
weekday: {string,'undefined': 'undefined'},
day: {string,'undefined': 'undefined'},
week: {string,'undefined': 'undefined'},
month: {string,'undefined': 'undefined'},
year: {string,'undefined': 'undefined'},
__type__: {object, 'function': 'function'}
@ -181,6 +183,7 @@ let configureOptions = {
hour: 'HH:mm',
weekday: 'ddd D',
day: 'D',
week: 'w',
month: 'MMM',
year: 'YYYY'
},
@ -191,6 +194,7 @@ let configureOptions = {
hour: 'ddd D MMMM',
weekday: 'MMMM YYYY',
day: 'MMMM YYYY',
week: 'MMMM YYYY',
month: 'YYYY',
year: ''
}
@ -236,7 +240,7 @@ let configureOptions = {
start: '',
//template: {'function': 'function'},
//timeAxis: {
// scale: ['millisecond', 'second', 'minute', 'hour', 'weekday', 'day', 'month', 'year'],
// scale: ['millisecond', 'second', 'minute', 'hour', 'weekday', 'day', 'week', 'month', 'year'],
// step: [1, 1, 10, 1]
//},
tooltip: {

Loading…
Cancel
Save