From 66047acd637409d6f0b21fb3189c44a1668cd68a Mon Sep 17 00:00:00 2001 From: yotamberk Date: Fri, 9 Dec 2016 19:55:40 +0200 Subject: [PATCH 1/7] fix: #2370 IE10 drag-and-drop support (#2426) * Fix redraw order * Fix IE10 support for dnd --- lib/timeline/component/ItemSet.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/timeline/component/ItemSet.js b/lib/timeline/component/ItemSet.js index 1036b316..a7e50cd2 100644 --- a/lib/timeline/component/ItemSet.js +++ b/lib/timeline/component/ItemSet.js @@ -1850,7 +1850,7 @@ ItemSet.prototype._onAddItem = function (event) { }; if (event.type == 'drop') { - var itemData = JSON.parse(event.dataTransfer.getData("text/plain")) + var itemData = JSON.parse(event.dataTransfer.getData("text")) newItemData.content = itemData.content; // content is required newItemData.type = itemData.type || 'box'; newItemData[this.itemsData._fieldId] = itemData.id || util.randomUUID(); From 58cc1d93e601a82f3962959173393ff8802a2dd8 Mon Sep 17 00:00:00 2001 From: yotamberk Date: Fri, 9 Dec 2016 19:56:48 +0200 Subject: [PATCH 2/7] fix: #2422 Timeline onMove callback (#2427) * Fix redraw order * Fix calling dragStart mote than once --- lib/timeline/component/ItemSet.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/timeline/component/ItemSet.js b/lib/timeline/component/ItemSet.js index a7e50cd2..5ae07ade 100644 --- a/lib/timeline/component/ItemSet.js +++ b/lib/timeline/component/ItemSet.js @@ -1213,6 +1213,7 @@ ItemSet.prototype._getGroupIndex = function(groupId) { * @private */ ItemSet.prototype._onDragStart = function (event) { + if (this.touchParams.itemIsDragging) { return; } var item = this.touchParams.item || null; var me = this; var props; From 3311b9b17e931286a688114afe39068853d63b0d Mon Sep 17 00:00:00 2001 From: yotamberk Date: Sun, 11 Dec 2016 16:30:03 +0200 Subject: [PATCH 3/7] feat: #1746 rolling mode (#2439) * Add initial support for rolling mode * Add rollingModeBtn and simplify example * Make icon in css: * Remove icon btn * Add docs * Fix zoom in rolling mode and initial start/end times --- docs/timeline/index.html | 9 ++- .../timeline/interaction/rollingMode.html | 45 +++++++++++ lib/timeline/Core.js | 6 ++ lib/timeline/Range.js | 77 +++++++++++++++++-- lib/timeline/Timeline.js | 6 +- lib/timeline/component/css/currenttime.css | 23 ++++++ lib/timeline/optionsTimeline.js | 1 + 7 files changed, 154 insertions(+), 13 deletions(-) create mode 100644 examples/timeline/interaction/rollingMode.html diff --git a/docs/timeline/index.html b/docs/timeline/index.html index 9a623722..321ef258 100644 --- a/docs/timeline/index.html +++ b/docs/timeline/index.html @@ -943,7 +943,14 @@ function (option, path) { Orientation of the timeline items: 'top' or 'bottom' (default). Determines whether items are aligned to the top or bottom of the Timeline. - + + rollingMode + boolean + false + If true, the timeline will initial in a rolling mode - the current time will always be centered. I the user drags the timeline, the timeline will go out of rolling mode and a toggle button will appear. Clicking that button will go back to rolling mode. Zooming in rolling mode will zoom in to the center without consideration of the mouse position. + + + rtl boolean false diff --git a/examples/timeline/interaction/rollingMode.html b/examples/timeline/interaction/rollingMode.html new file mode 100644 index 00000000..80b599f4 --- /dev/null +++ b/examples/timeline/interaction/rollingMode.html @@ -0,0 +1,45 @@ + + + Timeline | rolling mode Option + + + + + + + + + +

Timeline rolling mode option

+ +
+ + + + + + diff --git a/lib/timeline/Core.js b/lib/timeline/Core.js index a5034479..9441b77c 100644 --- a/lib/timeline/Core.js +++ b/lib/timeline/Core.js @@ -50,6 +50,7 @@ Core.prototype._create = function (container) { this.dom.shadowBottomLeft = document.createElement('div'); this.dom.shadowTopRight = document.createElement('div'); this.dom.shadowBottomRight = document.createElement('div'); + this.dom.rollingModeBtn = document.createElement('div'); this.dom.root.className = 'vis-timeline'; this.dom.background.className = 'vis-panel vis-background'; @@ -69,6 +70,7 @@ Core.prototype._create = function (container) { this.dom.shadowBottomLeft.className = 'vis-shadow vis-bottom'; this.dom.shadowTopRight.className = 'vis-shadow vis-top'; this.dom.shadowBottomRight.className = 'vis-shadow vis-bottom'; + this.dom.rollingModeBtn.className = 'vis-rolling-mode-btn'; this.dom.root.appendChild(this.dom.background); this.dom.root.appendChild(this.dom.backgroundVertical); @@ -78,6 +80,8 @@ Core.prototype._create = function (container) { this.dom.root.appendChild(this.dom.rightContainer); this.dom.root.appendChild(this.dom.top); this.dom.root.appendChild(this.dom.bottom); + this.dom.root.appendChild(this.dom.bottom); + this.dom.root.appendChild(this.dom.rollingModeBtn); this.dom.centerContainer.appendChild(this.dom.center); this.dom.leftContainer.appendChild(this.dom.left); @@ -311,6 +315,8 @@ Core.prototype.setOptions = function (options) { ]; util.selectiveExtend(fields, this.options, options); + this.dom.rollingModeBtn.style.visibility = 'hidden'; + if (this.options.rtl) { this.dom.container.style.direction = "rtl"; this.dom.backgroundVertical.className = 'vis-panel vis-background vis-vertical-rtl'; diff --git a/lib/timeline/Range.js b/lib/timeline/Range.js index 3e250f38..577e0863 100644 --- a/lib/timeline/Range.js +++ b/lib/timeline/Range.js @@ -14,8 +14,9 @@ var DateUtil = require('./DateUtil'); */ function Range(body, options) { var now = moment().hours(0).minutes(0).seconds(0).milliseconds(0); - this.start = now.clone().add(-3, 'days').valueOf(); // Number - this.end = now.clone().add(4, 'days').valueOf(); // Number + this.start = options.start || now.clone().add(-3, 'days').valueOf(); + this.end = options.end || now.clone().add(4, 'days').valueOf(); + this.rolling = false; this.body = body; this.deltaDifference = 0; @@ -55,6 +56,9 @@ function Range(body, options) { this.body.emitter.on('touch', this._onTouch.bind(this)); this.body.emitter.on('pinch', this._onPinch.bind(this)); + // on click of rolling mode button + this.body.dom.rollingModeBtn.addEventListener('click', this.startRolling.bind(this)); + this.setOptions(options); } @@ -80,11 +84,14 @@ Range.prototype.setOptions = function (options) { if (options) { // copy the options that we know var fields = [ - 'direction', 'min', 'max', 'zoomMin', 'zoomMax', 'moveable', 'zoomable', - 'moment', 'activate', 'hiddenDates', 'zoomKey', 'rtl', 'horizontalScroll' + 'animation', 'direction', 'min', 'max', 'zoomMin', 'zoomMax', 'moveable', 'zoomable', + 'moment', 'activate', 'hiddenDates', 'zoomKey', 'rtl', 'showCurrentTime', 'rollMode', 'horizontalScroll' ]; util.selectiveExtend(fields, this.options, options); + if (options.rollingMode) { + this.startRolling(); + } if ('start' in options || 'end' in options) { // apply a new range. both start and end are optional this.setRange(options.start, options.end); @@ -103,6 +110,52 @@ function validateDirection (direction) { } } +/** + * Start auto refreshing the current time bar + */ +Range.prototype.startRolling = function() { + var me = this; + + + function update () { + me.stopRolling(); + me.rolling = true; + + + var interval = me.end - me.start; + var t = util.convert(new Date(), 'Date').valueOf(); + + var start = t - interval / 2; + var end = t + interval / 2; + var animation = (me.options && me.options.animation !== undefined) ? me.options.animation : true; + + me.setRange(start, end, false); + + // determine interval to refresh + var scale = me.conversion(me.body.domProps.center.width).scale; + var interval = 1 / scale / 10; + if (interval < 30) interval = 30; + if (interval > 1000) interval = 1000; + + me.body.dom.rollingModeBtn.style.visibility = "hidden"; + // start a renderTimer to adjust for the new time + me.currentTimeTimer = setTimeout(update, interval); + } + + update(); +}; + +/** + * Stop auto refreshing the current time bar + */ +Range.prototype.stopRolling = function() { + if (this.currentTimeTimer !== undefined) { + clearTimeout(this.currentTimeTimer); + this.rolling = false; + this.body.dom.rollingModeBtn.style.visibility = "visible"; + } +}; + /** * Set a new start and end range * @param {Date | Number | String} [start] @@ -388,6 +441,8 @@ Range.prototype._onDragStart = function(event) { // when releasing the fingers in opposite order from the touch screen if (!this.props.touch.allowDragging) return; + this.stopRolling(); + this.props.touch.start = this.start; this.props.touch.end = this.end; this.props.touch.dragging = true; @@ -520,7 +575,7 @@ Range.prototype._onMouseWheel = function(event) { // Prevent default actions caused by mouse wheel // (else the page and timeline both scroll) event.preventDefault(); - + // calculate a single scroll jump relative to the range scale var diff = delta * (this.end - this.start) / 20; // calculate new start and end @@ -555,9 +610,13 @@ Range.prototype._onMouseWheel = function(event) { } // calculate center, the date to zoom around - var pointer = this.getPointer({x: event.clientX, y: event.clientY}, this.body.dom.center); - var pointerDate = this._pointerToDate(pointer); - + var pointerDate + if (this.rolling) { + pointerDate = (this.start + this.end) / 2; + } else { + var pointer = this.getPointer({x: event.clientX, y: event.clientY}, this.body.dom.center); + pointerDate = this._pointerToDate(pointer); + } this.zoom(scale, pointerDate, delta, event); // Prevent default actions caused by mouse wheel @@ -594,6 +653,8 @@ Range.prototype._onPinch = function (event) { this.props.touch.center = this.getPointer(event.center, this.body.dom.center); } + this.stopRolling(); + var scale = 1 / (event.scale + this.scaleOffset); var centerDate = this._pointerToDate(this.props.touch.center); diff --git a/lib/timeline/Timeline.js b/lib/timeline/Timeline.js index 7f5d463c..8abe0182 100644 --- a/lib/timeline/Timeline.js +++ b/lib/timeline/Timeline.js @@ -58,10 +58,8 @@ function Timeline (container, items, groups, options) { }; this.options = util.deepExtend({}, this.defaultOptions); - // Create the DOM, props, and emitter this._create(container); - if (!options || (options && typeof options.rtl == "undefined")) { var directionFromDom, domNode = this.dom.root; while (!directionFromDom && domNode) { @@ -72,6 +70,7 @@ function Timeline (container, items, groups, options) { } else { this.options.rtl = options.rtl; } + this.options.rollingMode = options.rollingMode; // all components listed here will be repainted automatically this.components = []; @@ -134,7 +133,7 @@ function Timeline (container, items, groups, options) { //Single time autoscale/fit this.fitDone = false; this.on('changed', function (){ - if (this.itemsData == null) return; + if (this.itemsData == null || this.options.rollingMode) return; if (!me.fitDone) { me.fitDone = true; if (me.options.start != undefined || me.options.end != undefined) { @@ -144,7 +143,6 @@ function Timeline (container, items, groups, options) { var start = me.options.start != undefined ? me.options.start : range.min; var end = me.options.end != undefined ? me.options.end : range.max; - me.setWindow(start, end, {animation: false}); } else { diff --git a/lib/timeline/component/css/currenttime.css b/lib/timeline/component/css/currenttime.css index 7d3547a1..658fdfef 100644 --- a/lib/timeline/component/css/currenttime.css +++ b/lib/timeline/component/css/currenttime.css @@ -3,4 +3,27 @@ width: 2px; z-index: 1; pointer-events: none; +} + +.vis-rolling-mode-btn { + height: 40px; + width: 40px; + position: absolute; + top: 7px; + right: 20px; + border-radius: 50%; + font-size: 28px; + cursor: pointer; + opacity: 0.8; + color: white; + font-weight: bold; + text-align: center; + background: #3876c2; +} +.vis-rolling-mode-btn:before { + content: "\26F6"; +} + +.vis-rolling-mode-btn:hover { + opacity: 1; } \ No newline at end of file diff --git a/lib/timeline/optionsTimeline.js b/lib/timeline/optionsTimeline.js index aadcf2ff..4354a213 100644 --- a/lib/timeline/optionsTimeline.js +++ b/lib/timeline/optionsTimeline.js @@ -26,6 +26,7 @@ let allOptions = { //globals : align: {string}, rtl: {boolean, 'undefined': 'undefined'}, + rollingMode: {boolean, 'undefined': 'undefined'}, verticalScroll: {boolean, 'undefined': 'undefined'}, horizontalScroll: {boolean, 'undefined': 'undefined'}, autoResize: {boolean}, From 3bc182b26aa7774e1cdcfece90b53dc2995eda91 Mon Sep 17 00:00:00 2001 From: Uli Fahrer Date: Fri, 16 Dec 2016 23:33:23 +0100 Subject: [PATCH 4/7] Fix Range ctor with optional options parameter (#2468) --- lib/timeline/Range.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/timeline/Range.js b/lib/timeline/Range.js index 577e0863..e49951d4 100644 --- a/lib/timeline/Range.js +++ b/lib/timeline/Range.js @@ -14,8 +14,17 @@ var DateUtil = require('./DateUtil'); */ function Range(body, options) { var now = moment().hours(0).minutes(0).seconds(0).milliseconds(0); - this.start = options.start || now.clone().add(-3, 'days').valueOf(); - this.end = options.end || now.clone().add(4, 'days').valueOf(); + var start = now.clone().add(-3, 'days').valueOf(); + var end = now.clone().add(-3, 'days').valueOf(); + + if(options === undefined) { + this.start = start; + this.end = end; + } else { + this.start = options.start || start + this.end = options.end || end + } + this.rolling = false; this.body = body; From a093bc4ac0ce196d1b9fbd768a79ad9811e2ff74 Mon Sep 17 00:00:00 2001 From: yotamberk Date: Sat, 17 Dec 2016 00:37:36 +0200 Subject: [PATCH 5/7] 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 --- docs/timeline/index.html | 14 +++- .../items/visibleFrameTemplateContent.html | 67 +++++++++++++++++++ lib/timeline/component/ItemSet.js | 4 +- lib/timeline/component/css/item.css | 4 ++ lib/timeline/component/item/Item.js | 39 ++++++++++- lib/timeline/component/item/RangeItem.js | 7 +- lib/timeline/optionsTimeline.js | 1 + 7 files changed, 129 insertions(+), 7 deletions(-) create mode 100644 examples/timeline/items/visibleFrameTemplateContent.html diff --git a/docs/timeline/index.html b/docs/timeline/index.html index 321ef258..e0d3291c 100644 --- a/docs/timeline/index.html +++ b/docs/timeline/index.html @@ -679,7 +679,7 @@ function (option, path) { groupTemplate function none - 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 content. See section Templates for a detailed explanation. + 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 content. See section Templates for a detailed explanation. @@ -1025,7 +1025,15 @@ function (option, path) { template function none - 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 content. See section Templates for a detailed explanation. + 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 content. See section Templates for a detailed explanation. + + + + visibleFrameTemplate + function + none + 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 content. See section Templates 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: vis-item-overflow which is overflow:hidden. @@ -1072,7 +1080,7 @@ function (option, path) { template Function none - 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 Templates for a detailed explanation. + 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 Templates for a detailed explanation. diff --git a/examples/timeline/items/visibleFrameTemplateContent.html b/examples/timeline/items/visibleFrameTemplateContent.html new file mode 100644 index 00000000..67715766 --- /dev/null +++ b/examples/timeline/items/visibleFrameTemplateContent.html @@ -0,0 +1,67 @@ + + + + Timeline | Dynamic Content + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/lib/timeline/component/ItemSet.js b/lib/timeline/component/ItemSet.js index 5ae07ade..53de50af 100644 --- a/lib/timeline/component/ItemSet.js +++ b/lib/timeline/component/ItemSet.js @@ -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); diff --git a/lib/timeline/component/css/item.css b/lib/timeline/component/css/item.css index 37f05533..67221d23 100644 --- a/lib/timeline/component/css/item.css +++ b/lib/timeline/component/css/item.css @@ -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; diff --git a/lib/timeline/component/item/Item.js b/lib/timeline/component/item/Item.js index 9057dd66..a7522921 100644 --- a/lib/timeline/component/item/Item.js +++ b/lib/timeline/component/item/Item.js @@ -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 { diff --git a/lib/timeline/component/item/RangeItem.js b/lib/timeline/component/item/RangeItem.js index a840b529..bc586e8f 100644 --- a/lib/timeline/component/item/RangeItem.js +++ b/lib/timeline/component/item/RangeItem.js @@ -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'); diff --git a/lib/timeline/optionsTimeline.js b/lib/timeline/optionsTimeline.js index 4354a213..5ef426b4 100644 --- a/lib/timeline/optionsTimeline.js +++ b/lib/timeline/optionsTimeline.js @@ -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} From c584a754acb1a424bd72d73ea8e113135c45dd3f Mon Sep 17 00:00:00 2001 From: Uli Fahrer Date: Fri, 16 Dec 2016 23:45:03 +0100 Subject: [PATCH 6/7] Fix graph2D render issue (#2470) --- lib/timeline/Core.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/timeline/Core.js b/lib/timeline/Core.js index 9441b77c..d3376e1e 100644 --- a/lib/timeline/Core.js +++ b/lib/timeline/Core.js @@ -124,7 +124,7 @@ Core.prototype._create = function (container) { this._redraw = util.throttle(this._origRedraw); this.on('_change', function (properties) { - if (me.itemSet.initialItemSetDrawn && properties && properties.queue == true) { + if (me.itemSet && me.itemSet.initialItemSetDrawn && properties && properties.queue == true) { me._redraw() } else { me._origRedraw(); From 9692d0df498184a940fe8345ed465261b63cfc9d Mon Sep 17 00:00:00 2001 From: Uli Fahrer Date: Sat, 17 Dec 2016 00:23:12 +0100 Subject: [PATCH 7/7] Fix error on click for graph2D when no data is provided (#2472) --- docs/graph2d/index.html | 2 +- lib/timeline/Graph2d.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/graph2d/index.html b/docs/graph2d/index.html index 8f07e20a..66a488f0 100644 --- a/docs/graph2d/index.html +++ b/docs/graph2d/index.html @@ -1162,7 +1162,7 @@ function (option, path) {
  • x (Number): relative horizontal position of the click event.
  • y (Number): relative vertical position of the click event.
  • time (Date): Date of the clicked event.
  • -
  • value (Number[]): The data value of the click event. The array contains one value when there is one data axis visible, and two values when there are two visible data axes.
  • +
  • value (Number[]): The data value of the click event. The array contains one value when there is one data axis visible, and two values when there are two visible data axes. It is empty when no data is provided.
  • what (String or null): name of the clicked thing: background, axis, dat-axis, custom-time, or current-time, legend.
  • event (Object): the original click event.
  • diff --git a/lib/timeline/Graph2d.js b/lib/timeline/Graph2d.js index cd350ec3..0e294592 100644 --- a/lib/timeline/Graph2d.js +++ b/lib/timeline/Graph2d.js @@ -299,10 +299,10 @@ Graph2d.prototype.getEventProperties = function (event) { var value = []; var yAxisLeft = this.linegraph.yAxisLeft; var yAxisRight = this.linegraph.yAxisRight; - if (!yAxisLeft.hidden) { + if (!yAxisLeft.hidden && this.itemsData.length > 0) { value.push(yAxisLeft.screenToValue(y)); } - if (!yAxisRight.hidden) { + if (!yAxisRight.hidden && this.itemsData.length > 0) { value.push(yAxisRight.screenToValue(y)); }