Browse Source

[Timeline] Added HTML tool-tip support (#2498)

* Added HTML tooltip support for Timeline

* Fixed tooltip position on Firefox

* Added Timeline tooltip example

* Updated tooltip location to be next to the mouse

* Added HTML element to example
readme-improvements
Lewis B 8 years ago
committed by yotamberk
parent
commit
c9f586195a
11 changed files with 102 additions and 15 deletions
  1. +1
    -1
      docs/timeline/index.html
  2. +49
    -0
      examples/timeline/items/tooltip.html
  3. +1
    -1
      lib/network/modules/InteractionHandler.js
  4. +1
    -1
      lib/shared/Popup.js
  5. +4
    -2
      lib/shared/tooltip.css
  6. +20
    -0
      lib/timeline/component/ItemSet.js
  7. +1
    -1
      lib/timeline/component/item/BackgroundItem.js
  8. +1
    -1
      lib/timeline/component/item/BoxItem.js
  9. +22
    -6
      lib/timeline/component/item/Item.js
  10. +1
    -1
      lib/timeline/component/item/PointItem.js
  11. +1
    -1
      lib/timeline/component/item/RangeItem.js

+ 1
- 1
docs/timeline/index.html View File

@ -324,7 +324,7 @@ var items = new vis.DataSet([
<td>String</td> <td>String</td>
<td>none</td> <td>none</td>
<td>Add a title for the item, displayed when holding the mouse on the item. <td>Add a title for the item, displayed when holding the mouse on the item.
The title can only contain plain text.
The title can be an HTML element or a string containing plain text or HTML.
</td> </td>
</tr> </tr>
<tr> <tr>

+ 49
- 0
examples/timeline/items/tooltip.html View File

@ -0,0 +1,49 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Timeline | Tooltips</title>
<style type="text/css">
body, html {
font-family: sans-serif;
max-width: 800px;
}
</style>
<script src="../../../dist/vis.js"></script>
<link href="../../../dist/vis-timeline-graph2d.min.css" rel="stylesheet" type="text/css" />
<script src="../../googleAnalytics.js"></script>
</head>
<body>
<h1>Tooltips</h1>
<p>
Setting the tooltip in various ways.
</p>
<div id="tooltips"></div>
<script type="text/javascript">
// Create a DataSet (allows two way data-binding)
var items = new vis.DataSet([
{id: 1, content: 'Item 1', start: '2016-01-01', end: '2016-01-02',
title: 'Normal text'},
{id: 2, content: 'Item 2', start: '2016-01-02', title: '<b>Bold</b>'},
{id: 3, content: 'Item 3', start: '2016-01-03', type: 'point',
title: '<span style="color: red">Red</span> text'},
{id: 4, content: '<h1>HTML</h1> Item', start: '2016-01-03', end: '2016-01-04',
title: '<table border="1"><tr><td>Cell 1</td><td>Cell 2</td></tr></table>'}
]);
// Options
var options = {};
// Timeline object
var timelineTooltips = new vis.Timeline(document.getElementById('tooltips'),
items, options
);
</script>
</body>
</html>

+ 1
- 1
lib/network/modules/InteractionHandler.js View File

@ -1,7 +1,7 @@
let util = require('../../util'); let util = require('../../util');
import NavigationHandler from './components/NavigationHandler' import NavigationHandler from './components/NavigationHandler'
import Popup from './components/Popup'
import Popup from './../../shared/Popup'
class InteractionHandler { class InteractionHandler {
constructor(body, canvas, selectionHandler) { constructor(body, canvas, selectionHandler) {

lib/network/modules/components/Popup.js → lib/shared/Popup.js View File

@ -18,7 +18,7 @@ class Popup {
// create the frame // create the frame
this.frame = document.createElement('div'); this.frame = document.createElement('div');
this.frame.className = 'vis-network-tooltip';
this.frame.className = 'vis-tooltip';
this.container.appendChild(this.frame); this.container.appendChild(this.frame);
} }

lib/network/css/network-tooltip.css → lib/shared/tooltip.css View File

@ -1,4 +1,4 @@
div.vis-network-tooltip {
div.vis-tooltip {
position: absolute; position: absolute;
visibility: hidden; visibility: hidden;
padding: 5px; padding: 5px;
@ -16,4 +16,6 @@ div.vis-network-tooltip {
box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.2); box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.2);
pointer-events: none; pointer-events: none;
}
z-index: 5;
}

+ 20
- 0
lib/timeline/component/ItemSet.js View File

@ -10,6 +10,7 @@ var BoxItem = require('./item/BoxItem');
var PointItem = require('./item/PointItem'); var PointItem = require('./item/PointItem');
var RangeItem = require('./item/RangeItem'); var RangeItem = require('./item/RangeItem');
var BackgroundItem = require('./item/BackgroundItem'); var BackgroundItem = require('./item/BackgroundItem');
import Popup from '../../shared/Popup';
var UNGROUPED = '__ungrouped__'; // reserved group id for ungrouped items var UNGROUPED = '__ungrouped__'; // reserved group id for ungrouped items
@ -1872,6 +1873,20 @@ ItemSet.prototype._onSelectItem = function (event) {
ItemSet.prototype._onMouseOver = function (event) { ItemSet.prototype._onMouseOver = function (event) {
var item = this.itemFromTarget(event); var item = this.itemFromTarget(event);
if (!item) return; if (!item) return;
if (item.getTitle()) {
if (item.popup == null) {
item.setPopup(new Popup(this.body.dom.root));
}
var container = this.body.dom.centerContainer;
item.popup.setPosition(
event.clientX - util.getAbsoluteLeft(container),
event.clientY - util.getAbsoluteTop(container)
);
item.popup.show();
}
this.body.emitter.emit('itemover', { this.body.emitter.emit('itemover', {
item: item.id, item: item.id,
event: util.elementsCensor(event) event: util.elementsCensor(event)
@ -1880,6 +1895,11 @@ ItemSet.prototype._onMouseOver = function (event) {
ItemSet.prototype._onMouseOut = function (event) { ItemSet.prototype._onMouseOut = function (event) {
var item = this.itemFromTarget(event); var item = this.itemFromTarget(event);
if (!item) return; if (!item) return;
if (item.popup != null) {
item.popup.hide();
}
this.body.emitter.emit('itemout', { this.body.emitter.emit('itemout', {
item: item.id, item: item.id,
event: util.elementsCensor(event) event: util.elementsCensor(event)

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

@ -100,7 +100,7 @@ BackgroundItem.prototype.redraw = function() {
// - the item is selected/deselected // - the item is selected/deselected
if (this.dirty) { if (this.dirty) {
this._updateContents(this.dom.content); this._updateContents(this.dom.content);
this._updateTitle(this.dom.content);
this._updateTitle();
this._updateDataAttributes(this.dom.content); this._updateDataAttributes(this.dom.content);
this._updateStyle(this.dom.box); this._updateStyle(this.dom.box);

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

@ -119,7 +119,7 @@ BoxItem.prototype.redraw = function() {
// - the item is selected/deselected // - the item is selected/deselected
if (this.dirty) { if (this.dirty) {
this._updateContents(this.dom.content); this._updateContents(this.dom.content);
this._updateTitle(this.dom.box);
this._updateTitle();
this._updateDataAttributes(this.dom.box); this._updateDataAttributes(this.dom.box);
this._updateStyle(this.dom.box); this._updateStyle(this.dom.box);

+ 22
- 6
lib/timeline/component/item/Item.js View File

@ -23,6 +23,7 @@ function Item (data, conversion, options) {
this.displayed = false; this.displayed = false;
this.groupShowing = true; this.groupShowing = true;
this.dirty = true; this.dirty = true;
this.popup = null;
this.top = null; this.top = null;
this.right = null; this.right = null;
@ -398,15 +399,13 @@ Item.prototype._updateContents = function (element) {
/** /**
* Set HTML contents for the item * Set HTML contents for the item
* @param {Element} element HTML element to fill with the contents
* @private * @private
*/ */
Item.prototype._updateTitle = function (element) {
Item.prototype._updateTitle = function () {
if (this.data.title != null) { if (this.data.title != null) {
element.title = this.data.title || '';
}
else {
element.removeAttribute('vis-title');
if (this.popup != null) {
this.popup.setText(this.data.title || '');
}
} }
}; };
@ -491,4 +490,21 @@ Item.prototype.getWidthRight = function () {
return 0; return 0;
}; };
/**
* Return the title of the item
* @return {string | undefined}
*/
Item.prototype.getTitle = function () {
return this.data.title;
};
/**
* Set the popup object, and update the title
* @param {Popup} popup
*/
Item.prototype.setPopup = function (popup) {
this.popup = popup;
this._updateTitle();
};
module.exports = Item; module.exports = Item;

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

@ -97,7 +97,7 @@ PointItem.prototype.redraw = function() {
// - the item is selected/deselected // - the item is selected/deselected
if (this.dirty) { if (this.dirty) {
this._updateContents(this.dom.content); this._updateContents(this.dom.content);
this._updateTitle(this.dom.point);
this._updateTitle();
this._updateDataAttributes(this.dom.point); this._updateDataAttributes(this.dom.point);
this._updateStyle(this.dom.point); this._updateStyle(this.dom.point);

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

@ -100,7 +100,7 @@ RangeItem.prototype.redraw = function() {
// - the item is selected/deselected // - the item is selected/deselected
if (this.dirty) { if (this.dirty) {
this._updateContents(this.dom.content); this._updateContents(this.dom.content);
this._updateTitle(this.dom.box);
this._updateTitle();
this._updateDataAttributes(this.dom.box); this._updateDataAttributes(this.dom.box);
this._updateStyle(this.dom.box); this._updateStyle(this.dom.box);

Loading…
Cancel
Save