Browse Source

Fix React support for group and item templates and add example (#2206)

* Hide vertically hidden ranged items in groups that are not visible
* Add element to templates options
* Fix comment typo
* Add documentation for react mounting
* add react example
* Fix typo
* fix title
* Fix review comments
codeClimate
yotamberk 8 years ago
committed by Alexander Wunschik
parent
commit
d9598432d3
3 changed files with 156 additions and 25 deletions
  1. +123
    -0
      examples/timeline/other/usingReact.html
  2. +9
    -7
      lib/timeline/component/Group.js
  3. +24
    -18
      lib/timeline/component/item/Item.js

+ 123
- 0
examples/timeline/other/usingReact.html View File

@ -0,0 +1,123 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>React Components in templates</title>
</head>
<body>
<div id='root'></div>
<!--
For ease of use, we are including the React, ReactDOM and Babel CDN
builds to make getting started as fast as possible.
In production, you'll want to instead look at using something
like Gulp, Grunt or WebPack (my personal recommendation)
to compile JSX into JavaScript. Also, check out:
http://facebook.github.io/react/docs/tooling-integration.html
-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
<script src="../../../dist/vis.js"></script>
<link href="../../../dist/vis.css" rel="stylesheet" type="text/css" />
<!--
This is where you link to your React code. Can be .js or .jsx
extension, doesn't really matter.
-->
<script type="text/babel">
var timeline;
// create groups
var numberOfGroups = 25;
var groups = new vis.DataSet()
for (var i = 0; i < numberOfGroups; i++) {
groups.add({
id: i,
content: 'Truck ' + i
})
}
// create items
var numberOfItems = 1000;
var items = new vis.DataSet();
var itemsPerGroup = Math.round(numberOfItems/numberOfGroups);
for (var truck = 0; truck < numberOfGroups; truck++) {
var date = new Date();
for (var order = 0; order < itemsPerGroup; order++) {
date.setHours(date.getHours() + 4 * (Math.random() < 0.2));
var start = new Date(date);
date.setHours(date.getHours() + 2 + Math.floor(Math.random()*4));
var end = new Date(date);
items.add({
id: order + itemsPerGroup * truck,
group: truck,
start: start,
end: end,
content: 'Order ' + order
});
}
}
var GroupTemplate = React.createClass({
render: function() {
var { group } = this.props;
return <div>
<label>{group.content}</label>
</div>
}
})
var ItemTemplate = React.createClass({
render: function() {
var { item } = this.props;
return <div>
<label>{item.content}</label>
</div>
}
})
// specify options
var options = {
orientation: 'top',
maxHeight: 400,
start: new Date(),
end: new Date(1000*60*60*24 + (new Date()).valueOf()),
editable: true,
template: function (item, element) {
ReactDOM.unmountComponentAtNode(element);
return ReactDOM.render(<ItemTemplate item={item} />, element);
},
groupTemplate: function (group, element) {
ReactDOM.unmountComponentAtNode(element);
return ReactDOM.render(<GroupTemplate group={group} />, element);
}
}
var VisTimeline = React.createClass({
componentDidMount: function() {
return initTimeline();
},
render: function() {
return <div>
<h1>Vis timline with React</h1>
<h2>Using react components for items and group templates</h2>
<div id="mytimeline"></div>
</div>
}
});
function initTimeline() {
var container = document.getElementById('mytimeline');
timeline = new vis.Timeline(container, items, groups, options);
}
ReactDOM.render(<VisTimeline />, document.getElementById('root'));
</script>
</body>
</html>

+ 9
- 7
lib/timeline/component/Group.js View File

@ -87,10 +87,12 @@ Group.prototype._create = function() {
Group.prototype.setData = function(data) {
// update contents
var content;
var templateFunction;
if (this.itemSet.options && this.itemSet.options.groupTemplate) {
content = this.itemSet.options.groupTemplate(data, this.dom.inner);
}
else {
templateFunction = this.itemSet.options.groupTemplate.bind(this);
content = templateFunction(data, this.dom.inner);
} else {
content = data && data.content;
}
@ -100,11 +102,11 @@ Group.prototype.setData = function(data) {
this.dom.inner.removeChild(this.dom.inner.firstChild);
}
this.dom.inner.appendChild(content);
}
else if (content !== undefined && content !== null) {
} else if (content instanceof Object) {
templateFunction(data, this.dom.inner);
} else if (content !== undefined && content !== null) {
this.dom.inner.innerHTML = content;
}
else {
} else {
this.dom.inner.innerHTML = this.groupId || ''; // groupId can be null
}

+ 24
- 18
lib/timeline/component/item/Item.js View File

@ -187,31 +187,37 @@ Item.prototype._repaintDeleteButton = function (anchor) {
*/
Item.prototype._updateContents = function (element) {
var content;
var templateFunction;
if (this.options.template) {
var itemData = this.parent.itemSet.itemsData.get(this.id); // get a clone of the data from the dataset
content = this.options.template(itemData, element);
}
else {
templateFunction = this.options.template.bind(this);
content = templateFunction(itemData, element);
} else {
content = this.data.content;
}
var changed = this._contentToString(this.content) !== this._contentToString(content);
if (changed) {
// only replace the content when changed
if (content instanceof Element) {
element.innerHTML = '';
element.appendChild(content);
}
else if (content != undefined) {
element.innerHTML = content;
}
else {
if (!(this.data.type == 'background' && this.data.content === undefined)) {
throw new Error('Property "content" missing in item ' + this.id);
if (content instanceof Object) {
templateFunction(itemData, element)
} else {
var changed = this._contentToString(this.content) !== this._contentToString(content);
if (changed) {
// only replace the content when changed
if (content instanceof Element) {
element.innerHTML = '';
element.appendChild(content);
}
else if (content != undefined) {
element.innerHTML = content;
}
else {
if (!(this.data.type == 'background' && this.data.content === undefined)) {
throw new Error('Property "content" missing in item ' + this.id);
}
}
}
this.content = content;
this.content = content;
}
}
};

Loading…
Cancel
Save