Browse Source

Add visibleFrameTemplate option for higher item dom content (#2437)

* Fix redraw order

* Add initial itemVisibleFrame

* Add visibleFrameTemplate option

* Improve example

* Rename and fix example

* Fix comments from PR

* Fix example
readme-improvements
yotamberk 7 years ago
committed by GitHub
parent
commit
a093bc4ac0
7 changed files with 129 additions and 7 deletions
  1. +11
    -3
      docs/timeline/index.html
  2. +67
    -0
      examples/timeline/items/visibleFrameTemplateContent.html
  3. +2
    -2
      lib/timeline/component/ItemSet.js
  4. +4
    -0
      lib/timeline/component/css/item.css
  5. +38
    -1
      lib/timeline/component/item/Item.js
  6. +6
    -1
      lib/timeline/component/item/RangeItem.js
  7. +1
    -0
      lib/timeline/optionsTimeline.js

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

@ -679,7 +679,7 @@ function (option, path) {
<td>groupTemplate</td>
<td>function</td>
<td>none</td>
<td>A template function used to generate the contents of the groups. The function is called by the Timeline with a groups data as the first argument and the group element as the second, and must return HTML code as result. When the option groupTemplate is specified, the groups do not need to have a field <code>content</code>. See section <a href="#Templates">Templates</a> for a detailed explanation.</td>
<td>A template function used to generate the contents of the groups. The function is called by the Timeline with a groups data as the first argument and the group element as the second, and must return HTML code, a string or a template as result. When the option groupTemplate is specified, the groups do not need to have a field <code>content</code>. See section <a href="#Templates">Templates</a> for a detailed explanation.</td>
</tr>
<tr>
@ -1025,7 +1025,15 @@ function (option, path) {
<td>template</td>
<td>function</td>
<td>none</td>
<td>A template function used to generate the contents of the items. The function is called by the Timeline with an items data as the first argument and the item element as the second, and must return HTML code as result. When the option template is specified, the items do not need to have a field <code>content</code>. See section <a href="#Templates">Templates</a> for a detailed explanation.</td>
<td>A template function used to generate the contents of the items. The function is called by the Timeline with an items' data as the first argument and the item element as the second, and must return HTML code, a string or a template as result. When the option template is specified, the items do not need to have a field <code>content</code>. See section <a href="#Templates">Templates</a> for a detailed explanation.</td>
</tr>
<tr>
<td>visibleFrameTemplate</td>
<td>function</td>
<td>none</td>
<td>A template function used to generate the visible frame of the items. The function is called by the Timeline with an items' data as the first argument and the item frame element as the second, and must return HTML code, a string or a template as result. When the option template is specified, the items do not need to have a field <code>content</code>. See section <a href="#Templates">Templates</a> for a detailed explanation.
This would be used as an additional way to add content that is constant in size with the visible frame of the item and does not get visibly hidden with the item's internal container: <code>vis-item-overflow</code> which is <code>overflow:hidden</code>.</td>
</tr>
<tr class='toggle collapsible' onclick="toggleTable('optionTable','timeAxis', this);">
@ -1072,7 +1080,7 @@ function (option, path) {
<td class="indent">template</td>
<td>Function</td>
<td>none</td>
<td>A template function used to generate the contents of the tooltip. The function is called by the Timeline with an item data as the first argument, and must return HTML code as result. See section <a href="#Templates">Templates</a> for a detailed explanation.
<td>A template function used to generate the contents of the tooltip. The function is called by the Timeline with an item data as the first argument, and must return HTML code, a string or a template as result. See section <a href="#Templates">Templates</a> for a detailed explanation.
</td>
</tr>
<tr>

+ 67
- 0
examples/timeline/items/visibleFrameTemplateContent.html View File

@ -0,0 +1,67 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Timeline | Dynamic Content</title>
<script src="../../../dist/vis.js"></script>
<link href="../../../dist/vis.min.css" rel="stylesheet" type="text/css" />
<style type="text/css">
.progress-wrapper {
background: white;
width: 100%;
height: 18px;
text-align: center;
position: relative;
overflow: hidden;
}
.progress {
height: 100%;
width: 60%;
position: absolute;
left: 0px;
top: 0px;
background: #63ed63;
}
.progress-label {
position: absolute;
z-index: 1;
}
</style>
</head>
<body>
<div id="myTimeline"></div>
<script type="text/javascript">
// DOM element where the Timeline will be attached
var container = document.getElementById('myTimeline');
// Create a DataSet (allows two way data-binding)
var items = new vis.DataSet([
{id: 1, value: 0.2, content: 'item 1', start: '2014-04-20', end: '2014-04-26'},
{id: 2, value: 0.6, content: 'item 2', start: '2014-05-14', end: '2014-05-18'},
{id: 3, type: 'point', content: 'item 3', start: '2014-04-15', end: '2014-05-18'},
{id: 4, content: 'item 4 with visibleFramTemplate in item', start: '2014-04-16', end: '2014-04-26', visibleFramTemplate: '<div class="progress-wrapper"><div class="progress"></div><label class="progress-label">80%<label></div>'
}
]);
// Configuration for the Timeline
var options = {
visibleFrameTemplate: function(item) {
if (item.visibleFramTemplate) {
return item.visibleFramTemplate;
}
var percentage = item.value * 100 + '%';
return '<div class="progress-wrapper"><div class="progress"></div><label class="progress-label">' + percentage + '<label></div>';
}
};
// Create a Timeline
var timeline = new vis.Timeline(container, items, options);
</script>
</body>
</html>

+ 2
- 2
lib/timeline/component/ItemSet.js View File

@ -321,8 +321,8 @@ ItemSet.prototype.setOptions = function(options) {
// copy all options that we know
var fields = [
'type', 'rtl', 'align', 'order', 'stack', 'selectable', 'multiselect', 'itemsAlwaysDraggable',
'multiselectPerGroup', 'groupOrder', 'dataAttributes', 'template', 'groupTemplate', 'hide', 'snap',
'groupOrderSwap', 'tooltipOnItemUpdateTime'
'multiselectPerGroup', 'groupOrder', 'dataAttributes', 'template', 'groupTemplate', 'visibleFrameTemplate',
'hide', 'snap', 'groupOrderSwap', 'tooltipOnItemUpdateTime'
];
util.selectiveExtend(fields, this.options, options);

+ 4
- 0
lib/timeline/component/css/item.css View File

@ -66,6 +66,10 @@
overflow: hidden;
}
.vis-item-visible-frame {
white-space: nowrap;
}
.vis-item.vis-range .vis-item-content {
position: relative;
display: inline-block;

+ 38
- 1
lib/timeline/component/item/Item.js View File

@ -325,9 +325,46 @@ Item.prototype._repaintOnItemUpdateTimeTooltip = function (anchor) {
Item.prototype._updateContents = function (element) {
var content;
var templateFunction;
var itemVisibleFrameContent;
var visibleFrameTemplateFunction;
var itemData = this.parent.itemSet.itemsData.get(this.id); // get a clone of the data from the dataset
var frameElement = this.dom.box || this.dom.point;
var itemVisibleFrameContentElement = frameElement.getElementsByClassName('vis-item-visible-frame')[0]
if (this.options.visibleFrameTemplate) {
visibleFrameTemplateFunction = this.options.visibleFrameTemplate.bind(this);
itemVisibleFrameContent = visibleFrameTemplateFunction(itemData, frameElement);
} else {
itemVisibleFrameContent = '';
}
if (itemVisibleFrameContentElement) {
if ((itemVisibleFrameContent instanceof Object) && !(itemVisibleFrameContent instanceof Element)) {
visibleFrameTemplateFunction(itemData, itemVisibleFrameContentElement)
} else {
var changed = this._contentToString(this.itemVisibleFrameContent) !== this._contentToString(itemVisibleFrameContent);
if (changed) {
// only replace the content when changed
if (itemVisibleFrameContent instanceof Element) {
itemVisibleFrameContentElement.innerHTML = '';
itemVisibleFrameContentElement.appendChild(itemVisibleFrameContent);
}
else if (itemVisibleFrameContent != undefined) {
itemVisibleFrameContentElement.innerHTML = itemVisibleFrameContent;
}
else {
if (!(this.data.type == 'background' && this.data.content === undefined)) {
throw new Error('Property "content" missing in item ' + this.id);
}
}
this.itemVisibleFrameContent = itemVisibleFrameContent;
}
}
}
if (this.options.template) {
var itemData = this.parent.itemSet.itemsData.get(this.id); // get a clone of the data from the dataset
templateFunction = this.options.template.bind(this);
content = templateFunction(itemData, element);
} else {

+ 6
- 1
lib/timeline/component/item/RangeItem.js View File

@ -60,10 +60,15 @@ RangeItem.prototype.redraw = function() {
dom.box = document.createElement('div');
// className is updated in redraw()
// frame box (to prevent the item contents from overflowing
// frame box (to prevent the item contents from overflowing)
dom.frame = document.createElement('div');
dom.frame.className = 'vis-item-overflow';
dom.box.appendChild(dom.frame);
// visible frame box (showing the frame that is always visible)
dom.visibleFrame = document.createElement('div');
dom.visibleFrame.className = 'vis-item-visible-frame';
dom.box.appendChild(dom.visibleFrame);
// contents box
dom.content = document.createElement('div');

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

@ -128,6 +128,7 @@ let allOptions = {
start: {date, number, string, moment},
template: {'function': 'function'},
groupTemplate: {'function': 'function'},
visibleFrameTemplate: {string, 'function': 'function'},
tooltipOnItemUpdateTime: {
template: {'function': 'function'},
__type__: {boolean, object}

Loading…
Cancel
Save