From 0f86680971dd5e7bc5279d82b76dcd2b490dceb6 Mon Sep 17 00:00:00 2001 From: josdejong Date: Fri, 10 May 2013 14:19:51 +0200 Subject: [PATCH] Implemented methods show/hide for components --- examples/timeline/01_basic.html | 4 +- examples/timeline/02_dataset.html | 6 +- examples/timeline/03_much_data.html | 8 +-- examples/timeline/04_html_data.html | 4 +- src/component/component.js | 42 ++++++++++--- src/component/itemset.js | 97 +++++++++++++++++++++-------- src/visualization/timeline.js | 60 +++++++++++------- 7 files changed, 154 insertions(+), 67 deletions(-) diff --git a/examples/timeline/01_basic.html b/examples/timeline/01_basic.html index 420cb93a..d8a5f50e 100644 --- a/examples/timeline/01_basic.html +++ b/examples/timeline/01_basic.html @@ -16,7 +16,7 @@ \ No newline at end of file diff --git a/examples/timeline/02_dataset.html b/examples/timeline/02_dataset.html index 3f94c8b6..81c1d0dd 100644 --- a/examples/timeline/02_dataset.html +++ b/examples/timeline/02_dataset.html @@ -25,13 +25,13 @@ var now = moment().minutes(0).seconds(0).milliseconds(0); // create a dataset with items - var data = new vis.DataSet({ + var items = new vis.DataSet({ fieldTypes: { start: 'Date', end: 'Date' } }); - data.add([ + items.add([ {id: 1, content: 'item 1
start', start: now.clone().add('days', 4)}, {id: 2, content: 'item 2', start: now.clone().add('days', -2)}, {id: 3, content: 'item 3', start: now.clone().add('days', 2)}, @@ -47,7 +47,7 @@ height: '100%' }; - var timeline = new vis.Timeline(container, data, options); + var timeline = new vis.Timeline(container, items, options); diff --git a/examples/timeline/03_much_data.html b/examples/timeline/03_much_data.html index 16ab501a..36221ad7 100644 --- a/examples/timeline/03_much_data.html +++ b/examples/timeline/03_much_data.html @@ -26,7 +26,7 @@ diff --git a/examples/timeline/04_html_data.html b/examples/timeline/04_html_data.html index 65875eae..c01dbfcc 100644 --- a/examples/timeline/04_html_data.html +++ b/examples/timeline/04_html_data.html @@ -54,7 +54,7 @@ // create data and a Timeline var container = document.getElementById('visualization'); - var data = [ + var items = [ {id: 1, content: item1, start: '2013-04-20'}, {id: 2, content: item2, start: '2013-04-14'}, {id: 3, content: item3, start: '2013-04-18'}, @@ -63,7 +63,7 @@ {id: 6, content: item6, start: '2013-04-27'} ]; var options = {}; - var timeline = new vis.Timeline(container, data, options); + var timeline = new vis.Timeline(container, items, options); \ No newline at end of file diff --git a/src/component/component.js b/src/component/component.js index 411a7c4a..dc21e795 100644 --- a/src/component/component.js +++ b/src/component/component.js @@ -26,7 +26,7 @@ function Component () { * {String | Number | function} [width] * {String | Number | function} [height] */ -Component.prototype.setOptions = function(options) { +Component.prototype.setOptions = function setOptions(options) { if (!options) { return; } @@ -45,7 +45,7 @@ Component.prototype.setOptions = function(options) { * that case null is returned. * @returns {HTMLElement | null} container */ -Component.prototype.getContainer = function () { +Component.prototype.getContainer = function getContainer() { // should be implemented by the component return null; }; @@ -54,7 +54,7 @@ Component.prototype.getContainer = function () { * Get the frame element of the component, the outer HTML DOM element. * @returns {HTMLElement | null} frame */ -Component.prototype.getFrame = function () { +Component.prototype.getFrame = function getFrame() { return this.frame; }; @@ -62,7 +62,7 @@ Component.prototype.getFrame = function () { * Repaint the component * @return {Boolean} changed */ -Component.prototype.repaint = function () { +Component.prototype.repaint = function repaint() { // should be implemented by the component return false; }; @@ -71,15 +71,43 @@ Component.prototype.repaint = function () { * Reflow the component * @return {Boolean} resized */ -Component.prototype.reflow = function () { +Component.prototype.reflow = function reflow() { // should be implemented by the component return false; }; +/** + * Hide the component from the DOM + * @return {Boolean} changed + */ +Component.prototype.hide = function hide() { + if (this.frame && this.frame.parentNode) { + this.frame.parentNode.removeChild(this.frame); + return true; + } + else { + return false; + } +}; + +/** + * Show the component in the DOM (when not already visible). + * A repaint will be executed when the component is not visible + * @return {Boolean} changed + */ +Component.prototype.show = function show() { + if (!this.frame || !this.frame.parentNode) { + return this.repaint(); + } + else { + return false; + } +}; + /** * Request a repaint. The controller will schedule a repaint */ -Component.prototype.requestRepaint = function () { +Component.prototype.requestRepaint = function requestRepaint() { if (this.controller) { this.controller.requestRepaint(); } @@ -92,7 +120,7 @@ Component.prototype.requestRepaint = function () { /** * Request a reflow. The controller will schedule a reflow */ -Component.prototype.requestReflow = function () { +Component.prototype.requestReflow = function requestReflow() { if (this.controller) { this.controller.requestReflow(); } diff --git a/src/component/itemset.js b/src/component/itemset.js index a54b00d3..564dd0c3 100644 --- a/src/component/itemset.js +++ b/src/component/itemset.js @@ -50,7 +50,9 @@ function ItemSet(parent, depends, options) { this.stack = new Stack(this); this.conversion = null; - this.setOptions(options); + if (options) { + this.setOptions(options); + } } ItemSet.prototype = new Panel(); @@ -344,10 +346,30 @@ ItemSet.prototype.reflow = function reflow () { }; /** - * Set data - * @param {DataSet | Array | DataTable} data + * Hide this component from the DOM + * @return {Boolean} changed + */ +ItemSet.prototype.hide = function hide() { + var changed = false; + + // remove the DOM + if (this.frame && this.frame.parentNode) { + this.frame.parentNode.removeChild(this.frame); + changed = true; + } + if (this.dom.axis && this.dom.axis.parentNode) { + this.dom.axis.parentNode.removeChild(this.dom.axis); + changed = true; + } + + return changed; +}; + +/** + * Set items + * @param {vis.DataSet | Array | DataTable | null} data */ -ItemSet.prototype.setData = function setData(data) { +ItemSet.prototype.setItems = function setItems(data) { var me = this, dataItems, ids; @@ -369,7 +391,10 @@ ItemSet.prototype.setData = function setData(data) { } // replace the dataset - if (data instanceof DataSet) { + if (!data) { + this.data = null; + } + else if (data instanceof DataSet) { this.data = data; } else { @@ -382,21 +407,30 @@ ItemSet.prototype.setData = function setData(data) { this.data.add(data); } - // subscribe to new dataset - var id = this.id; - util.forEach(this.listeners, function (callback, event) { - me.data.subscribe(event, callback, id); - }); + if (this.data) { + // subscribe to new dataset + var id = this.id; + util.forEach(this.listeners, function (callback, event) { + me.data.subscribe(event, callback, id); + }); - // draw all new items - dataItems = this.data.get({fields: ['id']}); - ids = []; - util.forEach(dataItems, function (dataItem, index) { - ids[index] = dataItem.id; - }); - this._onAdd(ids); + // draw all new items + dataItems = this.data.get({fields: ['id']}); + ids = []; + util.forEach(dataItems, function (dataItem, index) { + ids[index] = dataItem.id; + }); + this._onAdd(ids); + } }; +/** + * Get the current items data + * @returns {vis.DataSet} + */ +ItemSet.prototype.getItems = function getItems() { + return this.data; +}; /** * Get the data range of the item set. @@ -404,22 +438,31 @@ ItemSet.prototype.setData = function setData(data) { * When no minimum is found, min==null * When no maximum is found, max==null */ -ItemSet.prototype.getDataRange = function getDataRange() { +ItemSet.prototype.getItemRange = function getItemRange() { // calculate min from start filed var data = this.data; - var min = data.min('start'); - min = min ? min.start.valueOf() : null; + var minItem = data.min('start'); + var min = minItem ? minItem.start.valueOf() : null; // calculate max of both start and end fields - var maxStart = data.max('start'); - var maxEnd = data.max('end'); - maxStart = maxStart ? maxStart.start.valueOf() : null; - maxEnd = maxEnd ? maxEnd.end.valueOf() : null; - var max = Math.max(maxStart, maxEnd); + var max = null; + var maxStartItem = data.max('start'); + if (maxStartItem) { + max = maxStartItem.start.valueOf(); + } + var maxEndItem = data.max('end'); + if (maxEndItem) { + if (max == null) { + max = maxEndItem.end.valueOf(); + } + else { + max = Math.max(max, maxEndItem.end.valueOf()); + } + } return { - min: new Date(min), - max: new Date(max) + min: (min != null) ? new Date(min) : null, + max: (max != null) ? new Date(max) : null }; }; diff --git a/src/visualization/timeline.js b/src/visualization/timeline.js index 85af8b6a..2419c788 100644 --- a/src/visualization/timeline.js +++ b/src/visualization/timeline.js @@ -1,11 +1,11 @@ /** * Create a timeline visualization * @param {HTMLElement} container - * @param {DataSet | Array | DataTable} [data] + * @param {vis.DataSet | Array | DataTable} [items] * @param {Object} [options] See Timeline.setOptions for the available options. * @constructor */ -function Timeline (container, data, options) { +function Timeline (container, items, options) { var me = this; this.options = { orientation: 'bottom', @@ -55,19 +55,25 @@ function Timeline (container, data, options) { this.timeaxis.setRange(this.range); this.controller.add(this.timeaxis); - // items panel - this.itemset = new ItemSet(this.main, [this.timeaxis], { + // contents panel containing the items. + // Is an ItemSet by default, can be changed to a GroupSet + this.content = new ItemSet(this.main, [this.timeaxis], { orientation: this.options.orientation }); - this.itemset.setRange(this.range); - this.controller.add(this.itemset); + this.content.setRange(this.range); + this.controller.add(this.content); + + this.items = null; // data + this.groups = null; // data // set options (must take place before setting the data) - this.setOptions(options); + if (options) { + this.setOptions(options); + } // set data - if (data) { - this.setData(data); + if (items) { + this.setItems(items); } } @@ -84,7 +90,7 @@ Timeline.prototype.setOptions = function (options) { // update options for the range this.range.setOptions(this.options); - // update options the itemset + // update options the content var itemsTop, itemsHeight, mainHeight, @@ -98,7 +104,7 @@ Timeline.prototype.setOptions = function (options) { } else { itemsTop = function () { - return me.main.height - me.timeaxis.height - me.itemset.height; + return me.main.height - me.timeaxis.height - me.content.height; } } @@ -112,7 +118,7 @@ Timeline.prototype.setOptions = function (options) { else { // auto height mainHeight = function () { - return me.timeaxis.height + me.itemset.height; + return me.timeaxis.height + me.content.height; }; itemsHeight = null; } @@ -131,7 +137,7 @@ Timeline.prototype.setOptions = function (options) { height: mainHeight }); - this.itemset.setOptions({ + this.content.setOptions({ orientation: this.options.orientation, top: itemsTop, height: itemsHeight, @@ -142,18 +148,18 @@ Timeline.prototype.setOptions = function (options) { }; /** - * Set data - * @param {DataSet | Array | DataTable} data + * Set items + * @param {vis.DataSet | Array | DataTable} items */ -Timeline.prototype.setData = function(data) { - var dataset = this.itemset.data; - if (!dataset) { - // first load of data - this.itemset.setData(data); +Timeline.prototype.setItems = function(items) { + var current = this.content.getItems(); + if (!current) { + // initial load of data + this.content.setItems(items); if (this.options.start == undefined || this.options.end == undefined) { // apply the data range as range - var dataRange = this.itemset.getDataRange(); + var dataRange = this.content.getItemRange(); // add 5% on both sides var min = dataRange.min; @@ -180,6 +186,16 @@ Timeline.prototype.setData = function(data) { } else { // updated data - this.itemset.setData(data); + this.content.setItems(items); } }; + +/** + * Set groups + * @param {vis.DataSet | Array | DataTable} groups + */ +Timeline.prototype.setGroups = function(groups) { + // TODO: cleanup previous groups or itemset + + this.groups = groups; +};