From 5249806fbd1fb027a6e084554f615532e8bc833e Mon Sep 17 00:00:00 2001 From: Ludo Stellingwerff Date: Thu, 10 Dec 2015 14:37:05 +0100 Subject: [PATCH] Introducing a zindex option to control the svg render order. Provide the DataView.map() method similar to the DataSet one. --- lib/DataView.js | 43 ++++++++++++++++++++++++++++ lib/timeline/component/GraphGroup.js | 17 ++--------- lib/timeline/component/LineGraph.js | 42 +++++++++++++++++++-------- lib/timeline/optionsGraph2d.js | 5 +++- lib/util.js | 17 +++++++++++ 5 files changed, 97 insertions(+), 27 deletions(-) diff --git a/lib/DataView.js b/lib/DataView.js index 7d5b2316..32a7325a 100644 --- a/lib/DataView.js +++ b/lib/DataView.js @@ -230,6 +230,49 @@ DataView.prototype.getIds = function (options) { return ids; }; +/** + * Map every item in the dataset. + * @param {function} callback + * @param {Object} [options] Available options: + * {Object.} [type] + * {String[]} [fields] filter fields + * {function} [filter] filter items + * {String | function} [order] Order the items by + * a field name or custom sort function. + * @return {Object[]} mappedItems + */ +DataView.prototype.map = function (callback,options) { + var mappedItems = []; + if (this._data) { + var defaultFilter = this._options.filter; + var filter; + + if (options && options.filter) { + if (defaultFilter) { + filter = function (item) { + return defaultFilter(item) && options.filter(item); + } + } + else { + filter = options.filter; + } + } + else { + filter = defaultFilter; + } + + mappedItems = this._data.map(callback,{ + filter: filter, + order: options && options.order + }); + } + else { + mappedItems = []; + } + + return mappedItems; +}; + /** * Get the DataSet to which this DataView is connected. In case there is a chain * of multiple DataViews, the root DataSet of this chain is returned. diff --git a/lib/timeline/component/GraphGroup.js b/lib/timeline/component/GraphGroup.js index 37917fc3..c0061bda 100644 --- a/lib/timeline/component/GraphGroup.js +++ b/lib/timeline/component/GraphGroup.js @@ -16,7 +16,7 @@ var Points = require('./graph2d_types/points'); */ function GraphGroup(group, groupId, options, groupsUsingDefaultStyles) { this.id = groupId; - var fields = ['sampling', 'style', 'sort', 'yAxisOrientation', 'barChart', 'drawPoints', 'shaded', 'interpolation']; + var fields = ['sampling', 'style', 'sort', 'yAxisOrientation', 'barChart', 'drawPoints', 'shaded', 'interpolation', 'zIndex']; this.options = util.selectiveBridgeObject(fields, options); this.usingDefaultStyle = group.className === undefined; this.groupsUsingDefaultStyles = groupsUsingDefaultStyles; @@ -29,17 +29,6 @@ function GraphGroup(group, groupId, options, groupsUsingDefaultStyles) { this.visible = group.visible === undefined ? true : group.visible; } -function insertionSort (a,compare) { - for (var i = 0; i < a.length; i++) { - var k = a[i]; - for (var j = i; j > 0 && compare(k,a[j - 1])<0; j--) { - a[j] = a[j - 1]; - } - a[j] = k; - } - return a; -} - /** * this loads a reference to all items in this group into this group. * @param {array} items @@ -48,7 +37,7 @@ GraphGroup.prototype.setItems = function (items) { if (items != null) { this.itemsData = items; if (this.options.sort == true) { - insertionSort(this.itemsData,function (a, b) { + util.insertSort(this.itemsData,function (a, b) { return a.x > b.x ? 1 : -1; }); } @@ -76,7 +65,7 @@ GraphGroup.prototype.setZeroPosition = function (pos) { */ GraphGroup.prototype.setOptions = function (options) { if (options !== undefined) { - var fields = ['sampling', 'style', 'sort', 'yAxisOrientation', 'barChart', 'excludeFromLegend', 'excludeFromStacking']; + var fields = ['sampling', 'style', 'sort', 'yAxisOrientation', 'barChart', 'excludeFromLegend', 'excludeFromStacking', 'zIndex']; util.selectiveDeepExtend(fields, this.options, options); // if the group's drawPoints is a function delegate the callback to the onRender property diff --git a/lib/timeline/component/LineGraph.js b/lib/timeline/component/LineGraph.js index edf29781..447ddc0d 100644 --- a/lib/timeline/component/LineGraph.js +++ b/lib/timeline/component/LineGraph.js @@ -26,6 +26,7 @@ function LineGraph(body, options) { this.defaultOptions = { yAxisOrientation: 'left', defaultGroup: 'default', + groupOrder: 'order', sort: true, sampling: true, stack: false, @@ -312,7 +313,6 @@ LineGraph.prototype.setItems = function (items) { ids = this.itemsData.getIds(); this._onAdd(ids); } - this.redraw(true); }; @@ -333,7 +333,9 @@ LineGraph.prototype.setGroups = function (groups) { // remove all drawn groups ids = this.groupsData.getIds(); this.groupsData = null; - this._onRemoveGroups(ids); // note: this will cause a redraw + for (var i = 0; i < groupIds.length; i++) { + this._removeGroup(groupIds[i]); + } } // replace the dataset @@ -358,7 +360,6 @@ LineGraph.prototype.setGroups = function (groups) { ids = this.groupsData.getIds(); this._onAddGroups(ids); } - this._onUpdate(); }; LineGraph.prototype._onUpdate = function (ids) { @@ -593,6 +594,31 @@ LineGraph.prototype.redraw = function (forceGraphUpdate) { }; +LineGraph.prototype._getSortedGroupIds = function(){ + // getting group Ids + var grouplist = []; + for (var groupId in this.groups) { + if (this.groups.hasOwnProperty(groupId)) { + var group = this.groups[groupId]; + if (group.visible == true && (this.options.groups.visibility[groupId] === undefined || this.options.groups.visibility[groupId] == true)) { + grouplist.push({id:groupId,zIndex:group.options.zIndex}); + } + } + } + util.insertSort(grouplist,function(a,b){ + var az = a.zIndex; + var bz = b.zIndex; + if (az === undefined) az=0; + if (bz === undefined) bz=0; + return az==bz? 0: (az 0) { var groupsData = {}; diff --git a/lib/timeline/optionsGraph2d.js b/lib/timeline/optionsGraph2d.js index 883c4da1..ef139c20 100644 --- a/lib/timeline/optionsGraph2d.js +++ b/lib/timeline/optionsGraph2d.js @@ -27,6 +27,7 @@ let allOptions = { //globals : yAxisOrientation: {string:['left','right']}, defaultGroup: {string}, + groupOrder: {string, 'function': 'function'}, sort: {boolean}, sampling: {boolean}, stack:{boolean}, @@ -162,6 +163,7 @@ let allOptions = { zoomKey: {string: ['ctrlKey', 'altKey', 'metaKey', '']}, zoomMax: {number}, zoomMin: {number}, + zIndex: {number}, __type__: {object} }; @@ -265,7 +267,8 @@ let configureOptions = { zoomable: true, zoomKey: ['ctrlKey', 'altKey', 'metaKey', ''], zoomMax: [315360000000000, 10, 315360000000000, 1], - zoomMin: [10, 10, 315360000000000, 1] + zoomMin: [10, 10, 315360000000000, 1], + zIndex: 0 } }; diff --git a/lib/util.js b/lib/util.js index 9b1999f0..8fac4aee 100644 --- a/lib/util.js +++ b/lib/util.js @@ -1253,6 +1253,23 @@ exports.bridgeObject = function (referenceObject) { } }; +/** + * This method provides a stable sort implementation, very fast for presorted data + * + * @param a the array + * @param a order comparator + * @returns {the array} + */ +exports.insertSort = function (a,compare) { + for (var i = 0; i < a.length; i++) { + var k = a[i]; + for (var j = i; j > 0 && compare(k,a[j - 1])<0; j--) { + a[j] = a[j - 1]; + } + a[j] = k; + } + return a; +} /** * this is used to set the options of subobjects in the options object. A requirement of these subobjects