Browse Source

Background areas can now be draw in a specific group or spread over the whole Timeline.

v3_develop
jos 10 years ago
parent
commit
00328965e7
10 changed files with 4811 additions and 4507 deletions
  1. +4579
    -4448
      dist/vis.js
  2. +1
    -1
      dist/vis.map
  3. +12
    -12
      dist/vis.min.js
  4. +1
    -10
      examples/timeline/25_background_areas.html
  5. +56
    -0
      examples/timeline/31_background_areas_with_groups.html
  6. +1
    -0
      examples/timeline/index.html
  7. +1
    -0
      index.js
  8. +57
    -0
      lib/timeline/component/BackgroundGroup.js
  9. +37
    -24
      lib/timeline/component/Group.js
  10. +66
    -12
      lib/timeline/component/ItemSet.js

+ 4579
- 4448
dist/vis.js
File diff suppressed because it is too large
View File


+ 1
- 1
dist/vis.map
File diff suppressed because it is too large
View File


+ 12
- 12
dist/vis.min.js
File diff suppressed because it is too large
View File


+ 1
- 10
examples/timeline/25_background_areas.html View File

@ -27,16 +27,7 @@
<div id="visualization"></div>
<script>
// create a dataset with items
// we specify the type of the fields `start` and `end` here to be strings
// containing an ISO date. The fields will be outputted as ISO dates
// automatically getting data from the DataSet via items.get().
var items = new vis.DataSet({
type: { start: 'ISODate', end: 'ISODate' }
});
// add items to the DataSet
items.add([
var items = new vis.DataSet([
{id: 'A', content: 'Period A', start: '2014-01-16', end: '2014-01-22', type: 'background'},
{id: 'B', content: 'Period B', start: '2014-01-25', end: '2014-01-30', type: 'background', className: 'negative'},
{id: 1, content: 'item 1<br>start', start: '2014-01-23'},

+ 56
- 0
examples/timeline/31_background_areas_with_groups.html View File

@ -0,0 +1,56 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Timeline | Background areas with groups</title>
<style>
body, html {
font-family: arial, sans-serif;
font-size: 11pt;
}
</style>
<script src="../../dist/vis.js"></script>
<link href="../../dist/vis.css" rel="stylesheet" type="text/css" />
</head>
<body>
<p>This example demonstrates the item type "background" when using groups.</p>
<ul>
<li>Background items having a group are displayed in that group</li>
<li>Background items without a group are spread over the whole timeline</li>
<li>Background items with a non-existing group are not displayed</li>
</ul>
<div id="visualization"></div>
<script>
var items = new vis.DataSet([
{id: 'A', content: 'Period A', start: '2014-01-16', end: '2014-01-22', type: 'background', group: 1},
{id: 'B', content: 'Period B', start: '2014-01-23', end: '2014-01-26', type: 'background', group: 2},
{id: 'C', content: 'Period C', start: '2014-01-27', end: '2014-02-03', type: 'background'}, // no group
{id: 'D', content: 'Period D', start: '2014-01-14', end: '2014-01-20', type: 'background', group: 'non-existing'},
{id: 1, content: 'item 1<br>start', start: '2014-01-30', group: 1},
{id: 2, content: 'item 2', start: '2014-01-18', group: 1},
{id: 3, content: 'item 3', start: '2014-01-21', group: 2},
{id: 4, content: 'item 4', start: '2014-01-17', end: '2014-01-21', group: 2},
{id: 5, content: 'item 5', start: '2014-01-28', type:'point', group: 2},
{id: 6, content: 'item 6', start: '2014-01-25', group: 2}
]);
var groups = new vis.DataSet([
{id: 1, content: 'Group 1'},
{id: 2, content: 'Group 2'}
]);
var container = document.getElementById('visualization');
var options = {
start: '2014-01-10',
end: '2014-02-10',
editable: true
};
var timeline = new vis.Timeline(container, items, groups, options);
</script>
</body>
</html>

+ 1
- 0
examples/timeline/index.html View File

@ -41,6 +41,7 @@
<p><a href="27_templates.html">27_templates.html</a></p>
<p><a href="29_hiding_times.html">29_hiding_times.html</a></p>
<p><a href="30_subgroups.html">30_subgroups.html</a></p>
<p><a href="31_background_areas_with_groups.html">31_background_areas_with_groups.html</a></p>
<p><a href="requirejs/requirejs_example.html">requirejs_example.html</a></p>

+ 1
- 0
index.js View File

@ -42,6 +42,7 @@ exports.timeline = {
DataAxis: require('./lib/timeline/component/DataAxis'),
GraphGroup: require('./lib/timeline/component/GraphGroup'),
Group: require('./lib/timeline/component/Group'),
BackgroundGroup: require('./lib/timeline/component/BackgroundGroup'),
ItemSet: require('./lib/timeline/component/ItemSet'),
Legend: require('./lib/timeline/component/Legend'),
LineGraph: require('./lib/timeline/component/LineGraph'),

+ 57
- 0
lib/timeline/component/BackgroundGroup.js View File

@ -0,0 +1,57 @@
var util = require('../../util');
var Group = require('./Group');
/**
* @constructor BackgroundGroup
* @param {Number | String} groupId
* @param {Object} data
* @param {ItemSet} itemSet
*/
function BackgroundGroup (groupId, data, itemSet) {
Group.call(this, groupId, data, itemSet);
this.width = 0;
this.height = 0;
this.top = 0;
this.left = 0;
}
BackgroundGroup.prototype = Object.create(Group.prototype);
/**
* Repaint this group
* @param {{start: number, end: number}} range
* @param {{item: {horizontal: number, vertical: number}, axis: number}} margin
* @param {boolean} [restack=false] Force restacking of all items
* @return {boolean} Returns true if the group is resized
*/
BackgroundGroup.prototype.redraw = function(range, margin, restack) {
var resized = false;
this.visibleItems = this._updateVisibleItems(this.orderedItems, this.visibleItems, range);
// calculate actual size
this.width = this.dom.background.offsetWidth;
// apply new height (just always zero for BackgroundGroup
this.dom.background.style.height = '0';
// update vertical position of items after they are re-stacked and the height of the group is calculated
for (var i = 0, ii = this.visibleItems.length; i < ii; i++) {
var item = this.visibleItems[i];
item.repositionY(margin);
}
return resized;
};
/**
* Show this group: attach to the DOM
*/
BackgroundGroup.prototype.show = function() {
if (!this.dom.background.parentNode) {
this.itemSet.dom.background.appendChild(this.dom.background);
}
};
module.exports = BackgroundGroup;

+ 37
- 24
lib/timeline/component/Group.js View File

@ -167,6 +167,41 @@ Group.prototype.redraw = function(range, margin, restack) {
stack.nostack(this.visibleItems, margin, this.subgroups);
}
// recalculate the height of the group
var height = this._calculateHeight(margin);
// calculate actual size and position
var foreground = this.dom.foreground;
this.top = foreground.offsetTop;
this.left = foreground.offsetLeft;
this.width = foreground.offsetWidth;
resized = util.updateProperty(this, 'height', height) || resized;
// recalculate size of label
resized = util.updateProperty(this.props.label, 'width', this.dom.inner.clientWidth) || resized;
resized = util.updateProperty(this.props.label, 'height', this.dom.inner.clientHeight) || resized;
// apply new height
this.dom.background.style.height = height + 'px';
this.dom.foreground.style.height = height + 'px';
this.dom.label.style.height = height + 'px';
// update vertical position of items after they are re-stacked and the height of the group is calculated
for (var i = 0, ii = this.visibleItems.length; i < ii; i++) {
var item = this.visibleItems[i];
item.repositionY(margin);
}
return resized;
};
/**
* recalculate the height of the group
* @param {{item: {horizontal: number, vertical: number}, axis: number}} margin
* @returns {number} Returns the height
* @private
*/
Group.prototype._calculateHeight = function (margin) {
// recalculate the height of the group
var height;
var visibleItems = this.visibleItems;
@ -204,29 +239,7 @@ Group.prototype.redraw = function(range, margin, restack) {
}
height = Math.max(height, this.props.label.height);
// calculate actual size and position
var foreground = this.dom.foreground;
this.top = foreground.offsetTop;
this.left = foreground.offsetLeft;
this.width = foreground.offsetWidth;
resized = util.updateProperty(this, 'height', height) || resized;
// recalculate size of label
resized = util.updateProperty(this.props.label, 'width', this.dom.inner.clientWidth) || resized;
resized = util.updateProperty(this.props.label, 'height', this.dom.inner.clientHeight) || resized;
// apply new height
this.dom.background.style.height = height + 'px';
this.dom.foreground.style.height = height + 'px';
this.dom.label.style.height = height + 'px';
// update vertical position of items after they are re-stacked and the height of the group is calculated
for (var i = 0, ii = this.visibleItems.length; i < ii; i++) {
var item = this.visibleItems[i];
item.repositionY(margin);
}
return resized;
return height;
};
/**
@ -304,7 +317,7 @@ Group.prototype.resetSubgroups = function() {
this.subgroups[subgroup].visible = false;
}
}
}
};
/**
* Remove an item from the group

+ 66
- 12
lib/timeline/component/ItemSet.js View File

@ -4,14 +4,15 @@ var DataSet = require('../../DataSet');
var DataView = require('../../DataView');
var Component = require('./Component');
var Group = require('./Group');
var BackgroundGroup = require('./BackgroundGroup');
var BoxItem = require('./item/BoxItem');
var PointItem = require('./item/PointItem');
var RangeItem = require('./item/RangeItem');
var BackgroundItem = require('./item/BackgroundItem');
var DateUtil = require('../DateUtil');
var UNGROUPED = '__ungrouped__'; // reserved group id for ungrouped items
var UNGROUPED = '__ungrouped__'; // reserved group id for ungrouped items
var BACKGROUND = '__background__'; // reserved group id for background items without group
/**
* An ItemSet holds a set of items and ranges which can be displayed in a
@ -171,6 +172,11 @@ ItemSet.prototype._create = function(){
// create ungrouped Group
this._updateUngrouped();
// create background Group
var backgroundGroup = new BackgroundGroup(BACKGROUND, null, this);
backgroundGroup.show();
this.groups[BACKGROUND] = backgroundGroup;
// attach event listeners
// Note: we bind to the centerContainer for the case where the height
// of the center container is larger than of the ItemSet, so we
@ -497,7 +503,10 @@ ItemSet.prototype.redraw = function() {
this.lastVisibleInterval = visibleInterval;
this.props.lastWidth = this.props.width;
// redraw all groups
// redraw the background group
this.groups[BACKGROUND].redraw(range, nonFirstMargin, restack);
// redraw all regular groups
var restack = this.stackDirty,
firstGroup = this._firstGroup(),
firstMargin = {
@ -560,12 +569,24 @@ ItemSet.prototype._firstGroup = function() {
*/
ItemSet.prototype._updateUngrouped = function() {
var ungrouped = this.groups[UNGROUPED];
var background = this.groups[BACKGROUND];
var item, itemId;
if (this.groupsData) {
// remove the group holding all ungrouped items
if (ungrouped) {
ungrouped.hide();
delete this.groups[UNGROUPED];
// var background = this.groups[BACKGROUND];
// for (itemId in this.items) {
// if (this.items.hasOwnProperty(itemId)) {
// item = this.items[itemId];
// if ((item instanceof BackgroundItem)) {
// background.add(item);
// }
// }
// }
}
}
else {
@ -576,9 +597,15 @@ ItemSet.prototype._updateUngrouped = function() {
ungrouped = new Group(id, data, this);
this.groups[UNGROUPED] = ungrouped;
for (var itemId in this.items) {
for (itemId in this.items) {
if (this.items.hasOwnProperty(itemId)) {
ungrouped.add(this.items[itemId]);
item = this.items[itemId];
if (item instanceof BackgroundItem) {
background.add(item);
}
else {
ungrouped.add(item);
}
}
}
@ -730,6 +757,33 @@ ItemSet.prototype.removeItem = function(id) {
}
};
/**
* Get the time of an item based on it's data and options.type
* @param {Object} itemData
* @returns {string} Returns the type
* @private
*/
ItemSet.prototype._getType = function (itemData) {
return itemData.type || this.options.type || (itemData.end ? 'range' : 'box');
};
/**
* Get the group id for an item
* @param {Object} itemData
* @returns {string} Returns the groupId
* @private
*/
ItemSet.prototype._getGroupId = function (itemData) {
var type = this._getType(itemData);
if (type == 'background') {
return itemData.group != undefined ? itemData.group : BACKGROUND;
}
else {
return this.groupsData ? itemData.group : UNGROUPED;
}
};
/**
* Handle updated items
* @param {Number[]} ids
@ -739,9 +793,9 @@ ItemSet.prototype._onUpdate = function(ids) {
var me = this;
ids.forEach(function (id) {
var itemData = me.itemsData.get(id, me.itemOptions),
item = me.items[id],
type = itemData.type || me.options.type || (itemData.end ? 'range' : 'box');
var itemData = me.itemsData.get(id, me.itemOptions);
var item = me.items[id];
var type = me._getType(itemData);
var constructor = ItemSet.types[type];
@ -846,7 +900,7 @@ ItemSet.prototype._onAddGroups = function(ids) {
if (!group) {
// check for reserved ids
if (id == UNGROUPED) {
if (id == UNGROUPED || id == BACKGROUND) {
throw new Error('Illegal group id. ' + id + ' is a reserved id.');
}
@ -945,7 +999,7 @@ ItemSet.prototype._addItem = function(item) {
this.items[item.id] = item;
// add to group
var groupId = this.groupsData ? item.data.group : UNGROUPED;
var groupId = this._getGroupId(item.data);
var group = this.groups[groupId];
if (group) group.add(item);
};
@ -967,7 +1021,7 @@ ItemSet.prototype._updateItem = function(item, itemData) {
var oldGroup = this.groups[oldGroupId];
if (oldGroup) oldGroup.remove(item);
var groupId = this.groupsData ? item.data.group : UNGROUPED;
var groupId = this._getGroupId(item.data);
var group = this.groups[groupId];
if (group) group.add(item);
}
@ -991,7 +1045,7 @@ ItemSet.prototype._removeItem = function(item) {
if (index != -1) this.selection.splice(index, 1);
// remove from group
var groupId = this.groupsData ? item.data.group : UNGROUPED;
var groupId = this._getGroupId(item.data);
var group = this.groups[groupId];
if (group) group.remove(item);
};

Loading…
Cancel
Save