diff --git a/examples/svgTimeline/03_much_data.html b/examples/svgTimeline/03_much_data.html new file mode 100644 index 00000000..002d2989 --- /dev/null +++ b/examples/svgTimeline/03_much_data.html @@ -0,0 +1,65 @@ + + + + Timeline | a lot of data + + + + + + + + + + + + +

+ Test with a lot of data +

+

+ + + +

+
+ + + + \ No newline at end of file diff --git a/src/svgTimeline/Item.js b/src/svgTimeline/Item.js index 373ccd6b..c1d1f885 100644 --- a/src/svgTimeline/Item.js +++ b/src/svgTimeline/Item.js @@ -26,9 +26,16 @@ function Item(properties, constants) { this.end = 0; this.content = "no content"; this.class = ""; + this.level = 0; this.active = false; this.setProperties(properties, constants); + + this.timeX = 0; + this.drawX = 0; + this.y = 0; + this.width = 40; + this.convertDatesToUNIX(); this.duration = 0; @@ -38,7 +45,6 @@ function Item(properties, constants) { this.svg = null; this.svgLine = null; - } @@ -67,7 +73,12 @@ Item.prototype.setProperties = function(properties, constants) { Item.prototype.convertDatesToUNIX = function() { this.start = moment(this.start,"YYYY-MM-DD").valueOf(); - if (this.end != null) { + if (this.end != 0) { this.end = moment(this.end,"YYYY-MM-DD").valueOf(); } +} + +Item.prototype.getLength = function(msPerPixel) { + this.width = Math.max(40,this.duration/msPerPixel); + return this.width; } \ No newline at end of file diff --git a/src/svgTimeline/svgTimeline.js b/src/svgTimeline/svgTimeline.js index b3e0dedd..f2e5a4a0 100644 --- a/src/svgTimeline/svgTimeline.js +++ b/src/svgTimeline/svgTimeline.js @@ -148,7 +148,10 @@ function SvgTimeline (container, items, options) { } this.items = {}; + this.sortedItems = []; this.activeItems = {}; + this.sortedActiveItems = []; + this._createItems(items); this.container = container; @@ -175,6 +178,8 @@ function SvgTimeline (container, items, options) { this.hammer.on('mousemove', me._onMouseMoveTitle.bind(me) ); //this._drawLines(); + this._update(); + } SvgTimeline.prototype._createSVG = function() { @@ -188,15 +193,15 @@ SvgTimeline.prototype._createSVG = function() { SvgTimeline.prototype._createItems = function (items) { for (var i = 0; i < items.length; i++) { this.items[items[i].id] = new Item(items[i], this.constants); + this.sortedItems.push(this.items[items[i].id]); } + this._sortItems(this.sortedItems); +} + +SvgTimeline.prototype._sortItems = function (items) { + items.sort(function(a,b) {return a.start - b.start}); } -/** - * Get the pointer location from a touch location - * @param {{pageX: Number, pageY: Number}} touch - * @return {{x: Number, y: Number}} pointer - * @private - */ SvgTimeline.prototype._getPointer = function (touch) { return { x: touch.pageX, @@ -260,6 +265,7 @@ SvgTimeline.prototype._onMouseMoveTitle = function() {}; SvgTimeline.prototype._update = function() { this.axis._update(); this._getActiveItems(); + this._updateItems(); }; SvgTimeline.prototype._getActiveItems = function() { @@ -269,19 +275,24 @@ SvgTimeline.prototype._getActiveItems = function() { } } + this.sortedActiveItems = [] + var rangeStart = this.range.start-200*this.axis.msPerPixel + var rangeEnd = (this.range.end+200*this.axis.msPerPixel) for (var itemId in this.items) { if (this.items.hasOwnProperty(itemId)) { - if (this.items[itemId].start >= this.range.start && this.items[itemId].start < this.range.end || - this.items[itemId].end >= this.range.start && this.items[itemId].end < this.range.end - ) { + if (this.items[itemId].start >= rangeStart && this.items[itemId].start < rangeEnd || + this.items[itemId].end >= rangeStart && this.items[itemId].end < rangeEnd) { if (this.items[itemId].active == false) { this.activeItems[itemId] = this.items[itemId]; } this.activeItems[itemId].active = true; + this.sortedActiveItems.push(this.activeItems[itemId]); } } } + this._sortItems(this.sortedActiveItems); + // cleanup for (var itemId in this.activeItems) { if (this.activeItems.hasOwnProperty(itemId)) { if (this.activeItems[itemId].active == false) { @@ -297,26 +308,57 @@ SvgTimeline.prototype._getActiveItems = function() { SvgTimeline.prototype._updateItems = function() { - for (var itemId in this.activeItems) { - if (this.activeItems.hasOwnProperty(itemId)) { - var item = this.activeItems[itemId]; - if (item.svg == null) { - item.svg = d3.select("svg#main") - .append("rect") - .attr("x") + for (var i = 0; i < this.sortedActiveItems.length; i++) { + var item = this.sortedActiveItems[i]; + if (item.svg == null) { + item.svg = d3.select("svg#main") + .append("rect") + .attr("class","item") + .style("stroke", "rgb(6,120,155)") + .style("fill", "rgb(6,120,155)"); + + if (item.end == 0) { item.svgLine = d3.select("svg#main") - .append("line") - + .append("line") + .attr("y1",this.constants.barHeight) + .style("stroke", "rgb(200,200,255)") + .style("stroke-width", 3) } } + item.svg.attr('width',item.getLength(this.axis.msPerPixel)) + .attr("x",this._getXforItem(item)) + .attr("y",this._getYforItem(item, i)) + + .attr('height',25) + if (item.end == 0) { + item.svgLine.attr('y2',item.y) + .attr('x1',item.timeX) + .attr('x2',item.timeX) + } } }; -SvgTimeline.prototype._getXforTime = function(time) { - -} - -SvgTimeline.prototype._getLengthforDuration = function(time) { - +SvgTimeline.prototype._getXforItem = function(item) { + item.timeX = (item.start - this.range.start)/this.axis.msPerPixel; + if (item.end == 0) { + item.drawX = item.timeX - item.width * 0.5; + } + else { + item.drawX = item.timeX; + } + return item.drawX; } +SvgTimeline.prototype._getYforItem = function(item, index) { + var bounds = 10; + var startIndex = Math.max(0,index-bounds); + item.level = 0; + for (var i = startIndex; i < index; i++) { + var item2 = this.sortedActiveItems[i]; + if (item.drawX <= (item2.drawX + item2.width + 5) && item2.level == item.level) { + item.level += 1; + } + } + item.y = 100 + 50*item.level; + return item.y; +} \ No newline at end of file