Browse Source

Fixed #162: Implemented a new item type `background`

v3_develop
jos 10 years ago
parent
commit
5391f7c29d
13 changed files with 5383 additions and 5010 deletions
  1. +2
    -0
      HISTORY.md
  2. +15
    -1
      dist/vis.css
  3. +5122
    -4988
      dist/vis.js
  4. +1
    -1
      dist/vis.map
  5. +1
    -1
      dist/vis.min.css
  6. +12
    -11
      dist/vis.min.js
  7. +4
    -4
      docs/timeline.html
  8. +61
    -0
      examples/timeline/24_background_areas.html
  9. +1
    -0
      examples/timeline/index.html
  10. +1
    -0
      index.js
  11. +6
    -3
      lib/timeline/component/ItemSet.js
  12. +15
    -1
      lib/timeline/component/css/item.css
  13. +142
    -0
      lib/timeline/component/item/ItemBackground.js

+ 2
- 0
HISTORY.md View File

@ -16,6 +16,8 @@ http://visjs.org
### Timeline ### Timeline
- Implemented a new item type: `'background'`. This can be used to mark periods
with a background color and label.
- Implemented support for attaching HTML attributes to items. Thanks @dturkenk. - Implemented support for attaching HTML attributes to items. Thanks @dturkenk.
- Fixed moment.js url in localization example. - Fixed moment.js url in localization example.
- Fixed `className` of groups not being updated when changed. - Fixed `className` of groups not being updated when changed.

+ 15
- 1
dist/vis.css View File

@ -208,14 +208,28 @@
box-sizing: border-box; box-sizing: border-box;
} }
.vis.timeline .item.background {
overflow: hidden;
border: none;
background-color: rgba(213, 221, 246, 0.4);
box-sizing: border-box;
top: 0;
bottom: 0;
}
.vis.timeline .item.range .content { .vis.timeline .item.range .content {
position: relative; position: relative;
display: inline-block; display: inline-block;
overflow: hidden;
max-width: 100%;
} }
.vis.timeline .item.range .content {
.vis.timeline .item.background .content {
position: absolute;
display: inline-block;
overflow: hidden; overflow: hidden;
max-width: 100%; max-width: 100%;
margin: 5px;
} }
.vis.timeline .item.line { .vis.timeline .item.line {

+ 5122
- 4988
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


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


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


+ 4
- 4
docs/timeline.html View File

@ -242,8 +242,8 @@ var items = [
<td>type</td> <td>type</td>
<td>String</td> <td>String</td>
<td>'box'</td> <td>'box'</td>
<td>The type of the item. Can be 'box' (default), 'point', or 'range'.
Types 'box' and 'point' need a start date, and type 'range' needs both a start and end date.
<td>The type of the item. Can be 'box' (default), 'point', 'range', or 'background'.
Types 'box' and 'point' need a start date, the types 'range' and 'background' needs both a start and end date.
</td> </td>
</tr> </tr>
</table> </table>
@ -360,7 +360,7 @@ var options = {
<td>align</td> <td>align</td>
<td>String</td> <td>String</td>
<td>"center"</td> <td>"center"</td>
<td>Alignment of items with type 'box' and 'range'. Available values are 'auto' (default), 'center', 'left', or 'right'. For 'box' items, the 'auto' alignment is 'center'. For 'range' items, the auto alignment is dynamic: positioned left and shifted such that the contents is always visible on screen.</td>
<td>Alignment of items with type 'box', 'range', and 'background'. Available values are 'auto' (default), 'center', 'left', or 'right'. For 'box' items, the 'auto' alignment is 'center'. For 'range' items, the auto alignment is dynamic: positioned left and shifted such that the contents is always visible on screen.</td>
</tr> </tr>
<tr> <tr>
@ -668,7 +668,7 @@ var options = {
<td>type</td> <td>type</td>
<td>String</td> <td>String</td>
<td>none</td> <td>none</td>
<td>Specifies the default type for the timeline items. Choose from 'box', 'point', and 'range'. Note that individual items can override this default type. If undefined, the Timeline will auto detect the type from the items data: if a start and end date is available, a 'range' will be created, and else, a 'box' is created.
<td>Specifies the default type for the timeline items. Choose from 'box', 'point', 'range', and 'background'. Note that individual items can override this default type. If undefined, the Timeline will auto detect the type from the items data: if a start and end date is available, a 'range' will be created, and else, a 'box' is created. Items of type 'background' are not editable.
</td> </td>
</tr> </tr>

+ 61
- 0
examples/timeline/24_background_areas.html View File

@ -0,0 +1,61 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Timeline | Background areas</title>
<style>
body, html {
font-family: arial, sans-serif;
font-size: 11pt;
}
.vis.timeline .item.background.negative {
background-color: rgba(255, 0, 0, 0.2);
}
.vis.timeline .item.background.marker {
border-left: 2px solid green;
}
</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", see "Period A" and "Period B". The background areas can be styled with css.</p>
<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([
{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'},
{id: 2, content: 'item 2', start: '2014-01-18'},
{id: 3, content: 'item 3', start: '2014-01-21'},
{id: 4, content: 'item 4', start: '2014-01-19', end: '2014-01-24'},
{id: 5, content: 'item 5', start: '2014-01-28', type:'point'},
{id: 6, content: 'item 6', start: '2014-01-26'}
]);
var container = document.getElementById('visualization');
var options = {
start: '2014-01-10',
end: '2014-02-10',
editable: true
};
var timeline = new vis.Timeline(container, items, options);
</script>
</body>
</html>

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

@ -35,6 +35,7 @@
<p><a href="21_set_selection.html">21_set_selection.html</a></p> <p><a href="21_set_selection.html">21_set_selection.html</a></p>
<p><a href="22_window_adjustment.html">22_window_adjustment.html</a></p> <p><a href="22_window_adjustment.html">22_window_adjustment.html</a></p>
<p><a href="23_data_attributes.html">23_data_attributes.html</a></p> <p><a href="23_data_attributes.html">23_data_attributes.html</a></p>
<p><a href="24_background_areas.html">24_background_areas.html</a></p>
<p><a href="requirejs/requirejs_example.html">requirejs_example.html</a></p> <p><a href="requirejs/requirejs_example.html">requirejs_example.html</a></p>

+ 1
- 0
index.js View File

@ -29,6 +29,7 @@ exports.timeline = {
components: { components: {
items: { items: {
Item: require('./lib/timeline/component/item/Item'), Item: require('./lib/timeline/component/item/Item'),
ItemBackground: require('./lib/timeline/component/item/ItemBackground'),
ItemBox: require('./lib/timeline/component/item/ItemBox'), ItemBox: require('./lib/timeline/component/item/ItemBox'),
ItemPoint: require('./lib/timeline/component/item/ItemPoint'), ItemPoint: require('./lib/timeline/component/item/ItemPoint'),
ItemRange: require('./lib/timeline/component/item/ItemRange') ItemRange: require('./lib/timeline/component/item/ItemRange')

+ 6
- 3
lib/timeline/component/ItemSet.js View File

@ -7,6 +7,7 @@ var Group = require('./Group');
var ItemBox = require('./item/ItemBox'); var ItemBox = require('./item/ItemBox');
var ItemPoint = require('./item/ItemPoint'); var ItemPoint = require('./item/ItemPoint');
var ItemRange = require('./item/ItemRange'); var ItemRange = require('./item/ItemRange');
var ItemBackground = require('./item/ItemBackground');
var UNGROUPED = '__ungrouped__'; // reserved group id for ungrouped items var UNGROUPED = '__ungrouped__'; // reserved group id for ungrouped items
@ -24,7 +25,7 @@ function ItemSet(body, options) {
this.body = body; this.body = body;
this.defaultOptions = { this.defaultOptions = {
type: null, // 'box', 'point', 'range'
type: null, // 'box', 'point', 'range', 'background'
orientation: 'bottom', // 'top' or 'bottom' orientation: 'bottom', // 'top' or 'bottom'
align: 'auto', // alignment of box items align: 'auto', // alignment of box items
stack: true, stack: true,
@ -127,6 +128,7 @@ ItemSet.prototype = new Component();
// available item types will be registered here // available item types will be registered here
ItemSet.types = { ItemSet.types = {
background: ItemBackground,
box: ItemBox, box: ItemBox,
range: ItemRange, range: ItemRange,
point: ItemPoint point: ItemPoint
@ -198,8 +200,9 @@ ItemSet.prototype._create = function(){
* @param {Object} [options] The following options are available: * @param {Object} [options] The following options are available:
* {String} type * {String} type
* Default type for the items. Choose from 'box' * Default type for the items. Choose from 'box'
* (default), 'point', or 'range'. The default
* Style can be overwritten by individual items.
* (default), 'point', 'range', or 'background'.
* The default style can be overwritten by
* individual items.
* {String} align * {String} align
* Alignment for the items, only applicable for * Alignment for the items, only applicable for
* ItemBox. Choose 'center' (default), 'left', or * ItemBox. Choose 'center' (default), 'left', or

+ 15
- 1
lib/timeline/component/css/item.css View File

@ -49,14 +49,28 @@
box-sizing: border-box; box-sizing: border-box;
} }
.vis.timeline .item.background {
overflow: hidden;
border: none;
background-color: rgba(213, 221, 246, 0.4);
box-sizing: border-box;
top: 0;
bottom: 0;
}
.vis.timeline .item.range .content { .vis.timeline .item.range .content {
position: relative; position: relative;
display: inline-block; display: inline-block;
overflow: hidden;
max-width: 100%;
} }
.vis.timeline .item.range .content {
.vis.timeline .item.background .content {
position: absolute;
display: inline-block;
overflow: hidden; overflow: hidden;
max-width: 100%; max-width: 100%;
margin: 5px;
} }
.vis.timeline .item.line { .vis.timeline .item.line {

+ 142
- 0
lib/timeline/component/item/ItemBackground.js View File

@ -0,0 +1,142 @@
var Hammer = require('../../../module/hammer');
var Item = require('./Item');
var ItemRange = require('./ItemRange');
/**
* @constructor ItemBackground
* @extends Item
* @param {Object} data Object containing parameters start, end
* content, className.
* @param {{toScreen: function, toTime: function}} conversion
* Conversion functions from time to screen and vice versa
* @param {Object} [options] Configuration options
* // TODO: describe options
*/
// TODO: implement support for the ItemBackground just having a start, then being displayed as a sort of an annotation
function ItemBackground (data, conversion, options) {
this.props = {
content: {
width: 0
}
};
this.overflow = false; // if contents can overflow (css styling), this flag is set to true
// validate data
if (data) {
if (data.start == undefined) {
throw new Error('Property "start" missing in item ' + data.id);
}
if (data.end == undefined) {
throw new Error('Property "end" missing in item ' + data.id);
}
}
Item.call(this, data, conversion, options);
}
ItemBackground.prototype = new Item (null, null, null);
ItemBackground.prototype.baseClassName = 'item background';
/**
* Check whether this item is visible inside given range
* @returns {{start: Number, end: Number}} range with a timestamp for start and end
* @returns {boolean} True if visible
*/
ItemBackground.prototype.isVisible = function(range) {
// determine visibility
return (this.data.start < range.end) && (this.data.end > range.start);
};
/**
* Repaint the item
*/
ItemBackground.prototype.redraw = function() {
var dom = this.dom;
if (!dom) {
// create DOM
this.dom = {};
dom = this.dom;
// background box
dom.box = document.createElement('div');
// className is updated in redraw()
// contents box
dom.content = document.createElement('div');
dom.content.className = 'content';
dom.box.appendChild(dom.content);
// attach this item as attribute
dom.box['timeline-item'] = this;
this.dirty = true;
}
// append DOM to parent DOM
if (!this.parent) {
throw new Error('Cannot redraw item: no parent attached');
}
if (!dom.box.parentNode) {
var background = this.parent.dom.background;
if (!background) {
throw new Error('Cannot redraw time axis: parent has no background container element');
}
background.appendChild(dom.box);
}
this.displayed = true;
// Update DOM when item is marked dirty. An item is marked dirty when:
// - the item is not yet rendered
// - the item's data is changed
// - the item is selected/deselected
if (this.dirty) {
this._updateContents(this.dom.content);
this._updateTitle(this.dom.content);
this._updateDataAttributes(this.dom.content);
// update class
var className = (this.data.className ? (' ' + this.data.className) : '') +
(this.selected ? ' selected' : '');
dom.box.className = this.baseClassName + className;
// determine from css whether this box has overflow
this.overflow = window.getComputedStyle(dom.content).overflow !== 'hidden';
// recalculate size
this.props.content.width = this.dom.content.offsetWidth;
this.height = 0; // set height zero, so this item will be ignored when stacking items
this.dirty = false;
}
};
/**
* Show the item in the DOM (when not already visible). The items DOM will
* be created when needed.
*/
ItemBackground.prototype.show = ItemRange.prototype.show;
/**
* Hide the item from the DOM (when visible)
* @return {Boolean} changed
*/
ItemBackground.prototype.hide = ItemRange.prototype.hide;
/**
* Reposition the item horizontally
* @Override
*/
ItemBackground.prototype.repositionX = ItemRange.prototype.repositionX;
/**
* Reposition the item vertically
* @Override
*/
ItemBackground.prototype.repositionY = function() {
var onTop = this.options.orientation === 'top';
this.dom.content.style.top = onTop ? '' : '0';
this.dom.content.style.bottom = onTop ? '0' : '';
};
module.exports = ItemBackground;

Loading…
Cancel
Save