diff --git a/lib/timeline/component/GraphGroup.js b/lib/timeline/component/GraphGroup.js index c1326e65..910ccb16 100644 --- a/lib/timeline/component/GraphGroup.js +++ b/lib/timeline/component/GraphGroup.js @@ -1,8 +1,5 @@ var util = require('../../util'); var DOMutil = require('../../DOMutil'); -var Line = require('./graph2d_types/line'); -var Bar = require('./graph2d_types/bar'); -var Points = require('./graph2d_types/points'); /** * /** @@ -16,7 +13,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']; this.options = util.selectiveBridgeObject(fields, options); this.usingDefaultStyle = group.className === undefined; this.groupsUsingDefaultStyles = groupsUsingDefaultStyles; @@ -29,7 +26,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]; @@ -59,9 +55,12 @@ GraphGroup.prototype.setItems = function (items) { } }; +GraphGroup.prototype.getItems = function () { + return this.itemsData; +} /** - * this is used for plotting barcharts, this way, we only have to calculate it once. + * this is used for barcharts and shading, this way, we only have to calculate it once. * @param pos */ GraphGroup.prototype.setZeroPosition = function (pos) { @@ -105,16 +104,6 @@ GraphGroup.prototype.setOptions = function (options) { } } } - - if (this.options.style == 'line') { - this.type = new Line(this.id, this.options); - } - else if (this.options.style == 'bar') { - this.type = new Bar(this.id, this.options); - } - else if (this.options.style == 'points') { - this.type = new Points(this.id, this.options); - } }; @@ -132,6 +121,8 @@ GraphGroup.prototype.update = function (group) { }; +//TODO: move these render functions into the type specific files and call them from LineGraph + /** * draw the icon for the legend. * @@ -216,11 +207,13 @@ GraphGroup.prototype.getLegend = function (iconWidth, iconHeight) { }; GraphGroup.prototype.getYRange = function (groupData) { - return this.type.getYRange(groupData); -}; - -GraphGroup.prototype.getData = function (groupData) { - return this.type.getData(groupData); + var yMin = groupData[0].y; + var yMax = groupData[0].y; + for (var j = 0; j < groupData.length; j++) { + yMin = yMin > groupData[j].y ? groupData[j].y : yMin; + yMax = yMax < groupData[j].y ? groupData[j].y : yMax; + } + return {min: yMin, max: yMax, yAxisOrientation: this.options.yAxisOrientation}; }; module.exports = GraphGroup; diff --git a/lib/timeline/component/LineGraph.js b/lib/timeline/component/LineGraph.js index 52bd9ebd..fad672dc 100644 --- a/lib/timeline/component/LineGraph.js +++ b/lib/timeline/component/LineGraph.js @@ -595,6 +595,9 @@ LineGraph.prototype._updateGraph = function () { var processedGroupData = {}; var groupRanges = {}; var changeCalled = false; + // this is the range of the SVG canvas + var minDate = this.body.util.toGlobalTime(-this.body.domProps.root.width); + var maxDate = this.body.util.toGlobalTime(2 * this.body.domProps.root.width); // getting group Ids var groupIds = []; @@ -607,9 +610,6 @@ LineGraph.prototype._updateGraph = function () { } } if (groupIds.length > 0) { - // this is the range of the SVG canvas - var minDate = this.body.util.toGlobalTime(-this.body.domProps.root.width); - var maxDate = this.body.util.toGlobalTime(2 * this.body.domProps.root.width); var groupsData = {}; // fill groups data, this only loads the data we require based on the timewindow @@ -778,15 +778,17 @@ LineGraph.prototype._getRelevantData = function (groupIds, groupsData, minDate, if (groupIds.length > 0) { for (i = 0; i < groupIds.length; i++) { group = this.groups[groupIds[i]]; - groupsData[groupIds[i]] = []; + var itemsData = group.getItems(); // optimization for sorted data if (group.options.sort == true) { - var dataContainer = groupsData[groupIds[i]]; - var guess = Math.max(0, util.binarySearchValue(group.itemsData, minDate, 'x', 'before')); - for (j = guess; j < group.itemsData.length; j++) { + var max = maxDate.getTime(); + var guess = Math.max(0, util.binarySearchValue(itemsData, minDate, 'x', 'before')); + var dataContainer = new Array(itemsData.length-guess); + for (j = guess; j < itemsData.length; j++) { item = group.itemsData[j]; - dataContainer.push(item); - if (item.x > maxDate) { + dataContainer[j-guess] = item; + if (item.x.getTime() > max) { + groupsData[groupIds[i]] = dataContainer.splice(0,j-guess); break; } } @@ -823,12 +825,12 @@ LineGraph.prototype._applySampling = function (groupIds, groupsData) { var pointsPerPixel = amountOfPoints / xDistance; increment = Math.min(Math.ceil(0.2 * amountOfPoints), Math.max(1, Math.round(pointsPerPixel))); - var sampledData = []; + var sampledData = new Array(amountOfPoints); for (var j = 0; j < amountOfPoints; j += increment) { - sampledData.push(dataContainer[j]); - + var idx = Math.round(j/increment); + sampledData[idx]=dataContainer[j]; } - groupsData[groupIds[i]] = sampledData; + groupsData[groupIds[i]] = sampledData.splice(0,Math.round(amountOfPoints/increment)); } } } @@ -858,10 +860,10 @@ LineGraph.prototype._getYRanges = function (groupIds, groupsData, groupRanges) { // if bar graphs are stacked, their range need to be handled differently and accumulated over all groups. if (options.stack === true && options.style === 'bar') { if (options.yAxisOrientation === 'left') { - combinedDataLeft = combinedDataLeft.concat(group.getData(groupData)); + combinedDataLeft = combinedDataLeft.concat(group.getItems()); } else { - combinedDataRight = combinedDataRight.concat(group.getData(groupData)); + combinedDataRight = combinedDataRight.concat(group.getItems()); } } else { @@ -873,10 +875,6 @@ LineGraph.prototype._getYRanges = function (groupIds, groupsData, groupRanges) { // if bar graphs are stacked, their range need to be handled differently and accumulated over all groups. Bars.getStackedYRange(combinedDataLeft, groupRanges, groupIds, '__barStackLeft', 'left'); Bars.getStackedYRange(combinedDataRight, groupRanges, groupIds, '__barStackRight', 'right'); - // if line graphs are stacked, their range need to be handled differently and accumulated over all groups. - //LineFunctions.getStackedYRange(combinedDataLeft , groupRanges, groupIds, '__lineStackLeft' , 'left' ); - //LineFunctions.getStackedYRange(combinedDataRight, groupRanges, groupIds, '__lineStackRight', 'right'); - } }; @@ -991,7 +989,7 @@ LineGraph.prototype._toggleAxisVisiblity = function (axisUsed, axis) { var changed = false; if (axisUsed == false) { if (axis.dom.frame.parentNode && axis.hidden == false) { - axis.hide() + axis.hide(); changed = true; } } @@ -1015,14 +1013,14 @@ LineGraph.prototype._toggleAxisVisiblity = function (axisUsed, axis) { * @private */ LineGraph.prototype._convertXcoordinates = function (datapoints) { - var extractedData = []; + var extractedData = new Array(datapoints.length); var xValue, yValue; var toScreen = this.body.util.toScreen; for (var i = 0; i < datapoints.length; i++) { xValue = toScreen(datapoints[i].x) + this.props.width; yValue = datapoints[i].y; - extractedData.push({x: xValue, y: yValue}); + extractedData[i] = {x: xValue, y: yValue}; } return extractedData; @@ -1040,8 +1038,8 @@ LineGraph.prototype._convertXcoordinates = function (datapoints) { * @private */ LineGraph.prototype._convertYcoordinates = function (datapoints, group) { - var extractedData = []; - var xValue, yValue; + var extractedData = new Array(datapoints.length); + var xValue, yValue, labelValue; var toScreen = this.body.util.toScreen; var axis = this.yAxisLeft; var svgHeight = Number(this.svg.style.height.replace('px', '')); @@ -1050,10 +1048,10 @@ LineGraph.prototype._convertYcoordinates = function (datapoints, group) { } for (var i = 0; i < datapoints.length; i++) { - var labelValue = datapoints[i].label ? datapoints[i].label : null; + labelValue = datapoints[i].label ? datapoints[i].label : null; xValue = toScreen(datapoints[i].x) + this.props.width; yValue = Math.round(axis.convertValue(datapoints[i].y)); - extractedData.push({x: xValue, y: yValue, label: labelValue}); + extractedData[i] = {x: xValue, y: yValue, label: labelValue}; } group.setZeroPosition(Math.min(svgHeight, axis.convertValue(0))); diff --git a/lib/timeline/component/graph2d_types/bar.js b/lib/timeline/component/graph2d_types/bar.js index 23c31c55..2bc81a32 100644 --- a/lib/timeline/component/graph2d_types/bar.js +++ b/lib/timeline/component/graph2d_types/bar.js @@ -2,35 +2,8 @@ var DOMutil = require('../../../DOMutil'); var Points = require('./points'); function Bargraph(groupId, options) { - this.groupId = groupId; - this.options = options; } -Bargraph.prototype.getYRange = function(groupData) { - var yMin = groupData[0].y; - var yMax = groupData[0].y; - for (var j = 0; j < groupData.length; j++) { - yMin = yMin > groupData[j].y ? groupData[j].y : yMin; - yMax = yMax < groupData[j].y ? groupData[j].y : yMax; - } - return {min: yMin, max: yMax, yAxisOrientation: this.options.yAxisOrientation}; -}; - - -Bargraph.prototype.getData = function(groupData) { - var combinedData = []; - for (var j = 0; j < groupData.length; j++) { - combinedData.push({ - x: groupData[j].x, - y: groupData[j].y, - groupId: this.groupId - }); - } - return combinedData; -} - - - /** * draw a bar graph * diff --git a/lib/timeline/component/graph2d_types/line.js b/lib/timeline/component/graph2d_types/line.js index af956f30..ae63871b 100644 --- a/lib/timeline/component/graph2d_types/line.js +++ b/lib/timeline/component/graph2d_types/line.js @@ -1,62 +1,8 @@ var DOMutil = require('../../../DOMutil'); function Line(groupId, options) { - this.groupId = groupId; - this.options = options; } -Line.prototype.getData = function (groupData) { - var combinedData = []; - for (var j = 0; j < groupData.length; j++) { - combinedData.push({ - x: groupData[j].x, - y: groupData[j].y, - groupId: this.groupId - }); - } - return combinedData; -} - -Line.prototype.getYRange = function (groupData) { - var yMin = groupData[0].y; - var yMax = groupData[0].y; - for (var j = 0; j < groupData.length; j++) { - yMin = yMin > groupData[j].y ? groupData[j].y : yMin; - yMax = yMax < groupData[j].y ? groupData[j].y : yMax; - } - return {min: yMin, max: yMax, yAxisOrientation: this.options.yAxisOrientation}; -}; - -/** - * Fill the intersections object with counters of how many datapoints share the same x coordinates - * @param intersections - * @param combinedData - * @private - */ -Line._getDataIntersections = function (intersections, combinedData) { - // get intersections - var coreDistance; - for (var i = 0; i < combinedData.length; i++) { - if (i + 1 < combinedData.length) { - coreDistance = Math.abs(combinedData[i + 1].x - combinedData[i].x); - } - if (i > 0) { - coreDistance = Math.min(coreDistance, Math.abs(combinedData[i - 1].x - combinedData[i].x)); - } - if (coreDistance === 0) { - if (intersections[combinedData[i].x] === undefined) { - intersections[combinedData[i].x] = { - amount: 0, - resolved: 0, - accumulatedPositive: 0, - accumulatedNegative: 0 - }; - } - intersections[combinedData[i].x].amount += 1; - } - } -}; - Line.calcPath = function (dataset, group) { if (dataset != null) { if (dataset.length > 0) { diff --git a/lib/timeline/component/graph2d_types/points.js b/lib/timeline/component/graph2d_types/points.js index 9e497f60..7604145b 100644 --- a/lib/timeline/component/graph2d_types/points.js +++ b/lib/timeline/component/graph2d_types/points.js @@ -1,25 +1,8 @@ var DOMutil = require('../../../DOMutil'); function Points(groupId, options) { - this.groupId = groupId; - this.options = options; } - -Points.prototype.getYRange = function(groupData) { - var yMin = groupData[0].y; - var yMax = groupData[0].y; - for (var j = 0; j < groupData.length; j++) { - yMin = yMin > groupData[j].y ? groupData[j].y : yMin; - yMax = yMax < groupData[j].y ? groupData[j].y : yMax; - } - return {min: yMin, max: yMax, yAxisOrientation: this.options.yAxisOrientation}; -}; - -Points.prototype.draw = function(dataset, group, framework, offset) { - Points.draw(dataset, group, framework, offset); -}; - /** * draw the data points *