From 1dcd61562692e2d1bf825cdf5769cd3b16e0f3bd Mon Sep 17 00:00:00 2001 From: josdejong Date: Tue, 7 May 2013 13:53:46 +0200 Subject: [PATCH] Some fixes/improvements in calculating the height of the stacked items --- package.json | 1 - src/component/itemset.js | 16 ++++----- src/util.js | 2 +- src/visualization/timeline.js | 9 +++-- test/timeline.html | 1 + vis.js | 67 +++++++++++++++++++++++++++-------- 6 files changed, 67 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index c5e3e39f..2c967c8a 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "devDependencies": { "jake": "latest", "jake-utils": "latest", - "node-watch": "latest", "moment": "latest" } } diff --git a/src/component/itemset.js b/src/component/itemset.js index 0d6163c7..3978b976 100644 --- a/src/component/itemset.js +++ b/src/component/itemset.js @@ -312,21 +312,19 @@ ItemSet.prototype.reflow = function reflow () { } else { // height is not specified, determine the height from the height and positioned items - height = 0; var visibleItems = this.stack.ordered; // TODO: not so nice way to get the filtered items - if (options.orientation == 'top') { + if (visibleItems.length) { + var min = visibleItems[0].top; + var max = visibleItems[0].top + visibleItems[0].height; util.forEach(visibleItems, function (item) { - height = Math.max(height, item.top + item.height); + min = Math.min(min, item.top); + max = Math.max(max, (item.top + item.height)); }); + height = (max - min) + options.margin.axis + options.margin.item; } else { - // orientation == 'bottom' - var frameHeight = this.height; - util.forEach(visibleItems, function (item) { - height = Math.max(height, frameHeight - item.top); - }); + height = options.margin.axis + options.margin.item; } - height += options.margin.axis; } if (maxHeight != null) { height = Math.min(height, maxHeight); diff --git a/src/util.js b/src/util.js index aac97993..95474292 100644 --- a/src/util.js +++ b/src/util.js @@ -571,7 +571,7 @@ util.option.asNumber = function (value, defaultValue) { } if (value != null) { - return Number(value); + return Number(value) || defaultValue || null; } return defaultValue || null; diff --git a/src/visualization/timeline.js b/src/visualization/timeline.js index 53260a1b..85af8b6a 100644 --- a/src/visualization/timeline.js +++ b/src/visualization/timeline.js @@ -117,10 +117,13 @@ Timeline.prototype.setOptions = function (options) { itemsHeight = null; } - // TODO: maxHeight should be a string in px or % - if (options.maxHeight) { + // 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 options.maxHeight - me.timeaxis.height; + return me.options.maxHeight - me.timeaxis.height; } } diff --git a/test/timeline.html b/test/timeline.html index 14c7a02e..18ca8231 100644 --- a/test/timeline.html +++ b/test/timeline.html @@ -63,6 +63,7 @@ //end: now.clone().add('days', 7).valueOf(), min: moment('2013-01-01').valueOf(), max: moment('2013-12-31').valueOf(), + //maxHeight: 150, zoomMin: 1000 * 60 * 60 * 24, // 1 day zoomMax: 1000 * 60 * 60 * 24 * 30 * 6 // 6 months }; diff --git a/vis.js b/vis.js index b80bfee6..ce7caaa8 100644 --- a/vis.js +++ b/vis.js @@ -5,7 +5,7 @@ * A dynamic, browser-based visualization library. * * @version 0.0.8 - * @date 2013-05-03 + * @date 2013-05-07 * * @license * Copyright (C) 2011-2013 Almende B.V, http://almende.com @@ -602,7 +602,7 @@ util.option.asNumber = function (value, defaultValue) { } if (value != null) { - return Number(value); + return Number(value) || defaultValue || null; } return defaultValue || null; @@ -1853,7 +1853,7 @@ DataSet.prototype.clear = function (senderId) { /** * Find the item with maximum value of a specified field * @param {String} field - * @return {Object} item Item containing max value, or null if no items + * @return {Object | null} item Item containing max value, or null if no items */ DataSet.prototype.max = function (field) { var data = this.data, @@ -1876,6 +1876,7 @@ DataSet.prototype.max = function (field) { /** * Find the item with minimum value of a specified field * @param {String} field + * @return {Object | null} item Item containing max value, or null if no items */ DataSet.prototype.min = function (field) { var data = this.data, @@ -1895,6 +1896,41 @@ DataSet.prototype.min = function (field) { return min; }; +/** + * Find all distinct values of a specified field + * @param {String} field + * @return {Array} values Array containing all distinct values. If the data + * items do not contain the specified field, an array + * containing a single value undefined is returned. + * The returned array is unordered. + */ +DataSet.prototype.distinct = function (field) { + var data = this.data, + values = [], + fieldType = this.options.fieldTypes[field], + count = 0; + + for (var prop in data) { + if (data.hasOwnProperty(prop)) { + var item = data[prop]; + var value = util.cast(item[field], fieldType); + var exists = false; + for (var i = 0; i < count; i++) { + if (values[i] == value) { + exists = true; + break; + } + } + if (!exists) { + values[count] = value; + count++; + } + } + } + + return values; +}; + /** * Add a single item * @param {Object} item @@ -4219,21 +4255,19 @@ ItemSet.prototype.reflow = function reflow () { } else { // height is not specified, determine the height from the height and positioned items - height = 0; var visibleItems = this.stack.ordered; // TODO: not so nice way to get the filtered items - if (options.orientation == 'top') { + if (visibleItems.length) { + var min = visibleItems[0].top; + var max = visibleItems[0].top + visibleItems[0].height; util.forEach(visibleItems, function (item) { - height = Math.max(height, item.top + item.height); + min = Math.min(min, item.top); + max = Math.max(max, (item.top + item.height)); }); + height = (max - min) + options.margin.axis + options.margin.item; } else { - // orientation == 'bottom' - var frameHeight = this.height; - util.forEach(visibleItems, function (item) { - height = Math.max(height, frameHeight - item.top); - }); + height = options.margin.axis + options.margin.item; } - height += options.margin.axis; } if (maxHeight != null) { height = Math.min(height, maxHeight); @@ -5437,10 +5471,13 @@ Timeline.prototype.setOptions = function (options) { itemsHeight = null; } - // TODO: maxHeight should be a string in px or % - if (options.maxHeight) { + // 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 options.maxHeight - me.timeaxis.height; + return me.options.maxHeight - me.timeaxis.height; } }