|
|
- /**
- * Create a timeline visualization
- * @param {HTMLElement} container
- * @param {DataSet | Array | DataTable} [data]
- * @param {Object} [options] See Timeline.setOptions for the available options.
- * @constructor
- */
- function Timeline (container, data, options) {
- var me = this;
- this.options = {
- orientation: 'bottom',
- zoomMin: 10, // milliseconds
- zoomMax: 1000 * 60 * 60 * 24 * 365 * 10000, // milliseconds
- moveable: true,
- zoomable: true
- };
-
- // controller
- this.controller = new Controller();
-
- // main panel
- if (!container) {
- throw new Error('No container element provided');
- }
- this.main = new RootPanel(container, {
- autoResize: false
- });
- this.controller.add(this.main);
-
- // range
- var now = moment().hours(0).minutes(0).seconds(0).milliseconds(0);
- this.range = new Range({
- start: now.clone().add('days', -3).valueOf(),
- end: now.clone().add('days', 4).valueOf()
- });
- // TODO: reckon with options moveable and zoomable
- this.range.subscribe(this.main, 'move', 'horizontal');
- this.range.subscribe(this.main, 'zoom', 'horizontal');
- this.range.on('rangechange', function () {
- var force = true;
- me.controller.requestReflow(force);
- });
- this.range.on('rangechanged', function () {
- var force = true;
- me.controller.requestReflow(force);
- });
-
- // TODO: put the listeners in setOptions, be able to dynamically change with options moveable and zoomable
-
- // time axis
- this.timeaxis = new TimeAxis(this.main, [], {
- orientation: this.options.orientation,
- range: this.range
- });
- this.timeaxis.setRange(this.range);
- this.controller.add(this.timeaxis);
-
- // items panel
- this.itemset = new ItemSet(this.main, [this.timeaxis], {
- orientation: this.options.orientation
- });
- this.itemset.setRange(this.range);
- this.controller.add(this.itemset);
-
- // set options (must take place before setting the data)
- this.setOptions(options);
-
- // set data
- if (data) {
- this.setData(data);
- }
- }
-
- /**
- * Set options
- * @param {Object} options TODO: describe the available options
- */
- Timeline.prototype.setOptions = function (options) {
- util.extend(this.options, options);
-
- // update options the timeaxis
- this.timeaxis.setOptions(this.options);
-
- // update options for the range
- this.range.setOptions(this.options);
-
- // update options the itemset
- var itemsTop,
- itemsHeight,
- mainHeight,
- maxHeight,
- me = this;
-
- if (this.options.orientation == 'top') {
- itemsTop = function () {
- return me.timeaxis.height;
- }
- }
- else {
- itemsTop = function () {
- return me.main.height - me.timeaxis.height - me.itemset.height;
- }
- }
-
- if (options.height) {
- // fixed height
- mainHeight = options.height;
- itemsHeight = function () {
- return me.main.height - me.timeaxis.height;
- };
- }
- else {
- // auto height
- mainHeight = function () {
- return me.timeaxis.height + me.itemset.height;
- };
- itemsHeight = null;
- }
-
- // TODO: maxHeight should be a string in px or % (currently only accepts a number)
- if (this.options.maxHeight) {
- if (!util.isNumber(this.options.maxHeight)) {
- throw new TypeError('Number expected for property maxHeight');
- }
- maxHeight = function () {
- return me.options.maxHeight - me.timeaxis.height;
- }
- }
-
- this.main.setOptions({
- height: mainHeight
- });
-
- this.itemset.setOptions({
- orientation: this.options.orientation,
- top: itemsTop,
- height: itemsHeight,
- maxHeight: maxHeight
- });
-
- this.controller.repaint();
- };
-
- /**
- * Set data
- * @param {DataSet | Array | DataTable} data
- */
- Timeline.prototype.setData = function(data) {
- var dataset = this.itemset.data;
- if (!dataset) {
- // first load of data
- this.itemset.setData(data);
-
- if (this.options.start == undefined || this.options.end == undefined) {
- // apply the data range as range
- var dataRange = this.itemset.getDataRange();
-
- // add 5% on both sides
- var min = dataRange.min;
- var max = dataRange.max;
- if (min != null && max != null) {
- var interval = (max.valueOf() - min.valueOf());
- min = new Date(min.valueOf() - interval * 0.05);
- max = new Date(max.valueOf() + interval * 0.05);
- }
-
- // override specified start and/or end date
- if (this.options.start != undefined) {
- min = new Date(this.options.start.valueOf());
- }
- if (this.options.end != undefined) {
- max = new Date(this.options.end.valueOf());
- }
-
- // apply range if there is a min or max available
- if (min != null || max != null) {
- this.range.setRange(min, max);
- }
- }
- }
- else {
- // updated data
- this.itemset.setData(data);
- }
- };
|