diff --git a/examples/index.html b/examples/index.html index ec9ab6b..28ab9b6 100644 --- a/examples/index.html +++ b/examples/index.html @@ -12,12 +12,12 @@
diff --git a/examples/index2.html b/examples/index2.html index a930de8..9d1deb6 100644 --- a/examples/index2.html +++ b/examples/index2.html @@ -12,15 +12,15 @@
diff --git a/examples/index3.html b/examples/index3.html index 7d13f89..2d3ea4b 100644 --- a/examples/index3.html +++ b/examples/index3.html @@ -12,12 +12,12 @@
diff --git a/examples/index4.html b/examples/index4.html index 5a41cde..0535e3d 100644 --- a/examples/index4.html +++ b/examples/index4.html @@ -12,12 +12,12 @@
diff --git a/examples/index5.html b/examples/index5.html index 76670ea..22ded15 100644 --- a/examples/index5.html +++ b/examples/index5.html @@ -12,12 +12,12 @@
diff --git a/examples/index6.html b/examples/index6.html index f4f9c0e..7535323 100644 --- a/examples/index6.html +++ b/examples/index6.html @@ -12,12 +12,12 @@
diff --git a/examples/index7.html b/examples/index7.html index 0909b42..11857d9 100644 --- a/examples/index7.html +++ b/examples/index7.html @@ -12,12 +12,12 @@
diff --git a/timeline.js b/timeline.js index b41bbbd..9baac54 100644 --- a/timeline.js +++ b/timeline.js @@ -13,32 +13,32 @@ * --------------------------------------------------------------------------------- */ -var SVG = {}; -SVG.ns = "http://www.w3.org/2000/svg"; -SVG.xlinkns = "http://www.w3.org/1999/xlink"; +var Timeline = {}; +Timeline.ns = "http://www.w3.org/2000/svg"; +Timeline.xlinkns = "http://www.w3.org/1999/xlink"; -SVG.marginBottom = 10; -SVG.marginTop = 15; -SVG.marginLeft = 10; -SVG.marginRight = 10; -SVG.rounded = false; -SVG.x_axis = false; -SVG.fill = true; -SVG.line = 'line'; -SVG.dashed_style = '5, 5'; +Timeline.marginBottom = 10; +Timeline.marginTop = 15; +Timeline.marginLeft = 10; +Timeline.marginRight = 10; +Timeline.rounded = false; +Timeline.x_axis = false; +Timeline.fill = true; +Timeline.line = 'line'; +Timeline.dashed_style = '5, 5'; -SVG.parent_holder = false; -SVG.holder = false; -SVG.g = false; -SVG.axis = false; -SVG.graphs = []; -SVG.raw_points = []; -SVG.x_callback = false; +Timeline.parent_holder = false; +Timeline.holder = false; +Timeline.g = false; +Timeline.axis = false; +Timeline.graphs = []; +Timeline.raw_points = []; +Timeline.x_callback = false; // Create an element "element" with the attributes "attrs" -SVG.createElement = function (element, attrs) { - var el = document.createElementNS(SVG.ns, element); +Timeline.createElement = function (element, attrs) { + var el = document.createElementNS(Timeline.ns, element); for(attr in attrs) { el.setAttribute(attr, attrs[attr]); } @@ -47,18 +47,18 @@ SVG.createElement = function (element, attrs) { }; // Check wether the element "element" has class "class" -SVG.hasClass = function (element, cls) { +Timeline.hasClass = function (element, cls) { return (' ' + element.getAttribute('class') + ' ').indexOf(' ' + cls + ' ') > -1; }; -// Add a new graph to the SVG -SVG.addGraph = function (graph, color) { - SVG.graphs[graph] = color; +// Add a new graph to the Timeline +Timeline.addGraph = function (graph, color) { + Timeline.graphs[graph] = color; }; // Test wether a graph of name "graph" already exists -SVG.hasGraph = function (graph) { - if(typeof(SVG.graphs[graph]) === 'undefined') { +Timeline.hasGraph = function (graph) { + if(typeof(Timeline.graphs[graph]) === 'undefined') { return false; } else { @@ -67,22 +67,22 @@ SVG.hasGraph = function (graph) { }; // Clear the specified graph data, or completely clear all the graph data -SVG.clearGraph = function (graph) { +Timeline.clearGraph = function (graph) { if(typeof(graph) === 'undefined') { - SVG.raw_points = []; - SVG.graphs = []; + Timeline.raw_points = []; + Timeline.graphs = []; } else { - for(var i = 0; i < SVG.raw_points.length; i++) { - if(SVG.raw_points[i].graph === graph) { - SVG.raw_points[i] = undefined; + for(var i = 0; i < Timeline.raw_points.length; i++) { + if(Timeline.raw_points[i].graph === graph) { + Timeline.raw_points[i] = undefined; } } } }; // Add points to the specified graph -SVG.addPoints = function (graph, data) { +Timeline.addPoints = function (graph, data) { for(var point = 0; point < data.length; point++) { var insert = {'graph': graph, 'x': data[point].x, 'y': data[point].y}; if(typeof(data[point].label) !== 'undefined') { @@ -97,10 +97,10 @@ SVG.addPoints = function (graph, data) { else { insert.click = false; } - SVG.raw_points.push(insert); + Timeline.raw_points.push(insert); } - SVG.raw_points.sort(function (a, b) { + Timeline.raw_points.sort(function (a, b) { if(a.x < b.x) { return -1; } @@ -114,23 +114,23 @@ SVG.addPoints = function (graph, data) { }; // Compute new coordinates, knowing the min and max value to fit the graph in the container -SVG.newCoordinate = function(value, min, max, minValue, maxValue) { +Timeline.newCoordinate = function(value, min, max, minValue, maxValue) { var a = (maxValue - minValue) / (max - min); return a *(value - min) + minValue; }; // Compute new X and Y values -SVG.getNewXY = function (minX, maxX, minY, maxY) { +Timeline.getNewXY = function (minX, maxX, minY, maxY) { return function (x, y) { return { - 'x': SVG.newCoordinate(x, minX, maxX, SVG.marginLeft, SVG.parent_holder.offsetWidth - SVG.marginRight), - 'y': SVG.newCoordinate(y, minY, maxY, 2*SVG.marginBottom, SVG.parent_holder.offsetHeight - SVG.marginTop) + 'x': Timeline.newCoordinate(x, minX, maxX, Timeline.marginLeft, Timeline.parent_holder.offsetWidth - Timeline.marginRight), + 'y': Timeline.newCoordinate(y, minY, maxY, 2*Timeline.marginBottom, Timeline.parent_holder.offsetHeight - Timeline.marginTop) }; }; }; // Get the necessary control points to smoothen the graph, is rounded is true -SVG.getControlPoints = function (data) { +Timeline.getControlPoints = function (data) { // From http://www.particleincell.com/wp-content/uploads/2012/06/bezier-spline.js var p1 = new Array(); var p2 = new Array(); @@ -196,79 +196,79 @@ SVG.getControlPoints = function (data) { * x_callback = function(args) { } or false is called to display the legend on the x axis * fill = true / false to fill below the graph or not */ -SVG.init = function (arg) { - if(!document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1")) { - alert("ERROR : Your browser does not support embedded SVG."); +Timeline.init = function (arg) { + if(!document.implementation.hasFeature("http://www.w3.org/TR/Timeline11/feature#Image", "1.1")) { + alert("ERROR : Your browser does not support embedded Timeline."); } - SVG.parent_holder = document.getElementById(arg.id); + Timeline.parent_holder = document.getElementById(arg.id); - var svg = SVG.createElement('svg:svg', { 'width': arg.width, 'height': arg.height }); - svg.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xlink', SVG.xlinkns); - SVG.parent_holder.appendChild(svg); + var svg = Timeline.createElement('svg:svg', { 'width': arg.width, 'height': arg.height }); + svg.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xlink', Timeline.xlinkns); + Timeline.parent_holder.appendChild(svg); - SVG.holder = SVG.parent_holder.querySelector('svg'); + Timeline.holder = Timeline.parent_holder.querySelector('svg'); - defs = SVG.createElement('defs', {}); - SVG.holder.appendChild(defs); + defs = Timeline.createElement('defs', {}); + Timeline.holder.appendChild(defs); if(arg.grid === 'small' || arg.grid === 'both') { - var small_grid_pattern = SVG.createElement('pattern', { 'id': 'smallGrid', 'width': 8, 'height': 8, 'patternUnits': 'userSpaceOnUse' }); + var small_grid_pattern = Timeline.createElement('pattern', { 'id': 'smallGrid', 'width': 8, 'height': 8, 'patternUnits': 'userSpaceOnUse' }); - var small_grid_path = SVG.createElement('path', { 'd': 'M 8 0 L 0 0 0 8', 'fill': 'none', 'stroke': 'gray', 'stroke-width': '0.5' }); + var small_grid_path = Timeline.createElement('path', { 'd': 'M 8 0 L 0 0 0 8', 'fill': 'none', 'stroke': 'gray', 'stroke-width': '0.5' }); small_grid_pattern.appendChild(small_grid_path); defs.appendChild(small_grid_pattern); } if(arg.grid === 'big' || arg.grid === 'both') { - var grid_pattern = SVG.createElement('pattern', { 'id': 'grid', 'width': 80, 'height': 80, 'patternUnits': 'userSpaceOnUse' }); + var grid_pattern = Timeline.createElement('pattern', { 'id': 'grid', 'width': 80, 'height': 80, 'patternUnits': 'userSpaceOnUse' }); if(arg.grid === 'both') { - var grid_rect = SVG.createElement('rect', {'width': 80, 'height': 80, 'fill': 'url(#smallGrid)' }); + var grid_rect = Timeline.createElement('rect', {'width': 80, 'height': 80, 'fill': 'url(#smallGrid)' }); grid_pattern.appendChild(grid_rect); } - var grid_path = SVG.createElement('path', {'d': 'M 80 0 L 0 0 0 80', 'fill': 'none', 'stroke': 'gray', 'stroke-width': '1'}); + var grid_path = Timeline.createElement('path', {'d': 'M 80 0 L 0 0 0 80', 'fill': 'none', 'stroke': 'gray', 'stroke-width': '1'}); grid_pattern.appendChild(grid_path); defs.appendChild(grid_pattern); } - SVG.grid = arg.grid; + Timeline.grid = arg.grid; - var marker = SVG.createElement('marker', {'id': 'markerArrow', 'markerWidth': 13, 'markerHeight': 13, 'refX': 2, 'refY': 6, 'orient': 'auto' }); - var marker_path = SVG.createElement('path', {'d': 'M2,2 L2,11 L10,6 L2,2', 'fill': 'gray' }); + var marker = Timeline.createElement('marker', {'id': 'markerArrow', 'markerWidth': 13, 'markerHeight': 13, 'refX': 2, 'refY': 6, 'orient': 'auto' }); + var marker_path = Timeline.createElement('path', {'d': 'M2,2 L2,11 L10,6 L2,2', 'fill': 'gray' }); marker.appendChild(marker_path); defs.appendChild(marker); - SVG.g = SVG.createElement('g', {'transform': 'translate(0, ' + SVG.parent_holder.offsetHeight + ') scale(1, -1)'}); - SVG.holder.appendChild(SVG.g); + Timeline.g = Timeline.createElement('g', {'transform': 'translate(0, ' + Timeline.parent_holder.offsetHeight + ') scale(1, -1)'}); + Timeline.holder.appendChild(Timeline.g); if(arg.x_axis === true) { - SVG.axis = SVG.createElement('line', {'x1': SVG.marginLeft, 'y1': SVG.parent_holder.offsetHeight / 2 + 1.5, 'x2': SVG.parent_holder.offsetWidth - 13 - SVG.marginRight, 'y2': SVG.parent_holder.offsetHeight / 2 + 1.5, 'stroke': 'gray', 'stroke-width': 3, 'marker-end': 'url("#markerArrow")'}); - SVG.g.appendChild(SVG.axis); + Timeline.axis = Timeline.createElement('line', {'x1': Timeline.marginLeft, 'y1': Timeline.parent_holder.offsetHeight / 2 + 1.5, 'x2': Timeline.parent_holder.offsetWidth - 13 - Timeline.marginRight, 'y2': Timeline.parent_holder.offsetHeight / 2 + 1.5, 'stroke': 'gray', 'stroke-width': 3, 'marker-end': 'url("#markerArrow")'}); + Timeline.g.appendChild(Timeline.axis); } - if(SVG.grid !== "none") { - var grid = SVG.createElement('rect', {'width': '100%', 'height': '100%'}); - if(SVG.grid === 'big' || SVG.grid === 'both') { + if(Timeline.grid !== "none") { + var grid = Timeline.createElement('rect', {'width': '100%', 'height': '100%'}); + if(Timeline.grid === 'big' || Timeline.grid === 'both') { grid.setAttribute('fill', 'url(#grid)'); } else { grid.setAttribute('fill', 'url(#smallGrid)'); } - SVG.g.appendChild(grid); + Timeline.g.appendChild(grid); } - SVG.rounded = arg.rounded; - SVG.x_axis = arg.x_axis; - SVG.line = arg.line; - SVG.fill = arg.fill; + Timeline.rounded = arg.rounded; + Timeline.x_axis = arg.x_axis; + Timeline.line = arg.line; + Timeline.fill = arg.fill; - SVG.x_callback = arg.x_callback; + Timeline.x_callback = arg.x_callback; }; // Get the scale so that graph fits with window -SVG.scale = function(data) { +Timeline.scale = function(data) { var empty = true; for(graph in data) { empty = false; @@ -299,12 +299,12 @@ SVG.scale = function(data) { } // Scale the grid, if needed - var scale = SVG.getNewXY(minX, maxX, minY, maxY); + var scale = Timeline.getNewXY(minX, maxX, minY, maxY); var tmp = scale(Math.pow(10, Math.floor(Math.log(maxX - minX) / Math.log(10))), Math.pow(10, Math.floor(Math.log(maxY - minY) / Math.log(10)))); var origin = scale(0, 0); var coordinates = {'x': tmp.x - origin.x, 'y': tmp.y - origin.y }; - if(SVG.grid === 'big' || SVG.grid === 'both') { - var grid = SVG.holder.getElementById('grid'); + if(Timeline.grid === 'big' || Timeline.grid === 'both') { + var grid = Timeline.holder.getElementById('grid'); grid.setAttribute('width', coordinates.x); grid.setAttribute('height', coordinates.y); var big_coords = scale(Math.floor(minX / Math.pow(10, Math.floor(Math.log(maxX - minX) / Math.log(10)))) * Math.pow(10, Math.floor(Math.log(maxX - minX) / Math.log(10))), Math.floor(minY / Math.pow(10, Math.floor(Math.log(maxY - minY) / Math.log(10)))) * Math.pow(10, Math.floor(Math.log(maxY - minY) / Math.log(10)))); @@ -312,18 +312,18 @@ SVG.scale = function(data) { grid.setAttribute('x', big_coords.x); grid.querySelector('path').setAttribute('d', 'M '+coordinates.x+' 0 L 0 0 0 '+coordinates.y); - if(SVG.grid === 'both') { + if(Timeline.grid === 'both') { grid.querySelector('rect').setAttribute('width', coordinates.x); grid.querySelector('rect').setAttribute('height', coordinates.y); } } - if(SVG.grid === 'small' || SVG.grid === 'both') { + if(Timeline.grid === 'small' || Timeline.grid === 'both') { coordinates.x = coordinates.x / 10; coordinates.y = coordinates.y / 10; - var grid = SVG.holder.getElementById('smallGrid'); + var grid = Timeline.holder.getElementById('smallGrid'); grid.setAttribute('width', coordinates.x); grid.setAttribute('height', coordinates.y); - if(SVG.grid === 'small') { + if(Timeline.grid === 'small') { var small_coords = scale(Math.floor(minX / Math.pow(10, Math.floor(Math.log(maxX - minX) / Math.log(10)))) * Math.pow(10, Math.floor(Math.log(maxX - minX) / Math.log(10))), Math.floor(minY / Math.pow(10, Math.floor(Math.log(maxY - minY) / Math.log(10)))) * Math.pow(10, Math.floor(Math.log(maxY - minY) / Math.log(10)))); grid.setAttribute('y', small_coords.y); grid.setAttribute('x', small_coords.x); @@ -332,41 +332,41 @@ SVG.scale = function(data) { } /* Draw axis */ - if(SVG.x_axis === true) { + if(Timeline.x_axis === true) { y = scale(0, 0).y; - SVG.axis.setAttribute('y1', y); - SVG.axis.setAttribute('y2', y); + Timeline.axis.setAttribute('y1', y); + Timeline.axis.setAttribute('y2', y); } return scale; }; // Draw graphs -SVG.draw = function() { - var scale = SVG.scale(SVG.raw_points); +Timeline.draw = function() { + var scale = Timeline.scale(Timeline.raw_points); var points = [], path; var px, py; var element; - for(var point = 0; point < SVG.raw_points.length; point++) { - var tmp = scale(SVG.raw_points[point].x, SVG.raw_points[point].y); - points.push({'id': point, 'x': tmp.x, 'y': tmp.y, 'graph': SVG.raw_points[point].graph, 'click': SVG.raw_points[point].click, 'label': SVG.raw_points[point].label}); + for(var point = 0; point < Timeline.raw_points.length; point++) { + var tmp = scale(Timeline.raw_points[point].x, Timeline.raw_points[point].y); + points.push({'id': point, 'x': tmp.x, 'y': tmp.y, 'graph': Timeline.raw_points[point].graph, 'click': Timeline.raw_points[point].click, 'label': Timeline.raw_points[point].label}); } // Draw each graph - for(var graph in SVG.graphs) { + for(var graph in Timeline.graphs) { var filtered_points = points.filter(function(el) { return el.graph == graph; }); path = ''; // Draw line - if(SVG.rounded === true) { + if(Timeline.rounded === true) { var x = new Array(), y = new Array(); for(var point = 0; point < filtered_points.length; point++) { x.push(filtered_points[point].x); y.push(filtered_points[point].y); } - px = SVG.getControlPoints(x); - py = SVG.getControlPoints(y); + px = Timeline.getControlPoints(x); + py = Timeline.getControlPoints(y); for(var point = 0; point < filtered_points.length - 1; point++) { path += 'C '+px.p1[point]+' '+py.p1[point]+' '+px.p2[point]+' '+py.p2[point]+' '+filtered_points[point+1].x+' '+filtered_points[point+1].y+' '; } @@ -377,25 +377,25 @@ SVG.draw = function() { } } - if(SVG.line !== 'none') { - element = SVG.createElement('path', {'class': 'line', 'stroke': SVG.graphs[graph], 'stroke-width': 2, 'fill': 'none', 'd': 'M '+filtered_points[0].x+' '+filtered_points[0].y+' '+path}); - if(SVG.line === 'dashed') { - element.setAttribute('style', 'stroke-dasharray: '+SVG.dashed_style); + if(Timeline.line !== 'none') { + element = Timeline.createElement('path', {'class': 'line', 'stroke': Timeline.graphs[graph], 'stroke-width': 2, 'fill': 'none', 'd': 'M '+filtered_points[0].x+' '+filtered_points[0].y+' '+path}); + if(Timeline.line === 'dashed') { + element.setAttribute('style', 'stroke-dasharray: '+Timeline.dashed_style); } - SVG.g.appendChild(element); + Timeline.g.appendChild(element); } // Draw fill - if(SVG.fill) { - element = SVG.createElement('path', {'class': 'graph', 'fill': SVG.graphs[graph], 'opacity': '0.25', 'stroke': 'none', 'd': 'M '+filtered_points[0].x+' '+2*SVG.marginBottom+' L '+filtered_points[0].x+' '+filtered_points[0].y+' '+ path + ' L '+filtered_points[filtered_points.length - 1].x+' '+2*SVG.marginBottom+' Z' }); - SVG.g.insertBefore(element, SVG.g.querySelectorAll('.over')[0]); + if(Timeline.fill) { + element = Timeline.createElement('path', {'class': 'graph', 'fill': Timeline.graphs[graph], 'opacity': '0.25', 'stroke': 'none', 'd': 'M '+filtered_points[0].x+' '+2*Timeline.marginBottom+' L '+filtered_points[0].x+' '+filtered_points[0].y+' '+ path + ' L '+filtered_points[filtered_points.length - 1].x+' '+2*Timeline.marginBottom+' Z' }); + Timeline.g.insertBefore(element, Timeline.g.querySelectorAll('.over')[0]); } } // Hover effect var prev = 0; for(var point = 0; point < points.length;) { - var rect = SVG.createElement('rect', {'class': 'over', 'id': 'over_'+point, 'y': 0, 'fill': 'white', 'opacity': 0, 'height': '100%'}); + var rect = Timeline.createElement('rect', {'class': 'over', 'id': 'over_'+point, 'y': 0, 'fill': 'white', 'opacity': 0, 'height': '100%'}); var currents = [point]; var next = point + 1; @@ -420,47 +420,47 @@ SVG.draw = function() { } if(point == points.length - 1) { - rect.setAttribute('width', SVG.parent_holder.offsetWidth - (points[point].x + points[point - 1].x)/2 + 1); + rect.setAttribute('width', Timeline.parent_holder.offsetWidth - (points[point].x + points[point - 1].x)/2 + 1); } else if(point == 0) { - rect.setAttribute('width', (points[1].x + points[0].x)/2 + SVG.marginLeft + 1); + rect.setAttribute('width', (points[1].x + points[0].x)/2 + Timeline.marginLeft + 1); } else { rect.setAttribute('width', (points[next].x - points[prev].x)/2 + 1); } - SVG.g.appendChild(rect); + Timeline.g.appendChild(rect); rect.addEventListener('mouseover', (function(arg) { return function() { for(var i = 0; i < arg.length; i++) { - SVG.holder.getElementById('point_'+arg[i]).setAttribute('r', '6'); - SVG.holder.getElementById('label_'+arg[i]).setAttribute('display', 'block'); + Timeline.holder.getElementById('point_'+arg[i]).setAttribute('r', '6'); + Timeline.holder.getElementById('label_'+arg[i]).setAttribute('display', 'block'); } }; })(currents)); rect.addEventListener('mouseout', function() { // Reinitialize all states - [].forEach.call(SVG.holder.querySelectorAll('.point'), function(el) { + [].forEach.call(Timeline.holder.querySelectorAll('.point'), function(el) { el.setAttribute('r', '4'); }); - [].forEach.call(SVG.holder.querySelectorAll('.label'), function(el) { + [].forEach.call(Timeline.holder.querySelectorAll('.label'), function(el) { el.setAttribute('display', 'none'); }); }); - if(SVG.x_callback !== false && points[point].x + 2.5 < SVG.parent_holder.offsetWidth - SVG.marginRight) { - element = SVG.createElement('text', {'class': 'legend_x', 'fill': 'gray', 'transform': 'translate(0, ' + SVG.parent_holder.offsetHeight + ') scale(1, -1)'}); - element.appendChild(document.createTextNode(SVG.x_callback(SVG.raw_points[point].x))); - SVG.g.appendChild(element); + if(Timeline.x_callback !== false && points[point].x + 2.5 < Timeline.parent_holder.offsetWidth - Timeline.marginRight) { + element = Timeline.createElement('text', {'class': 'legend_x', 'fill': 'gray', 'transform': 'translate(0, ' + Timeline.parent_holder.offsetHeight + ') scale(1, -1)'}); + element.appendChild(document.createTextNode(Timeline.x_callback(Timeline.raw_points[point].x))); + Timeline.g.appendChild(element); element.setAttribute('x', points[point].x - element.getBoundingClientRect().width / 2 + 2.5); var y_zero = scale(0, 0).y; - element.setAttribute('y', SVG.parent_holder.offsetHeight - SVG.marginBottom - y_zero); + element.setAttribute('y', Timeline.parent_holder.offsetHeight - Timeline.marginBottom - y_zero); - element = SVG.createElement('line', {'class': 'legend_x', 'stroke': 'gray', 'stroke-width': 2, 'x1': points[point].x, 'x2': points[point].x, 'y1': y_zero - 5, 'y2': y_zero + 5}); - SVG.g.appendChild(element); + element = Timeline.createElement('line', {'class': 'legend_x', 'stroke': 'gray', 'stroke-width': 2, 'x1': points[point].x, 'x2': points[point].x, 'y1': y_zero - 5, 'y2': y_zero + 5}); + Timeline.g.appendChild(element); } prev = next - 1; @@ -468,12 +468,12 @@ SVG.draw = function() { } // Draw points and labels - for(var graph in SVG.graphs) { + for(var graph in Timeline.graphs) { var filtered_points = points.filter(function(el) { return el.graph == graph; }); for(var point = 0; point < filtered_points.length; point++) { - element = SVG.createElement('circle', {'class': 'point', 'id': 'point_'+filtered_points[point].id, 'cx': filtered_points[point].x, 'cy': filtered_points[point].y, 'r': 4, 'fill': '#333', 'stroke': SVG.graphs[graph], 'stroke-width': 2}); - SVG.g.insertBefore(element, SVG.g.querySelectorAll('.label')[0]); + element = Timeline.createElement('circle', {'class': 'point', 'id': 'point_'+filtered_points[point].id, 'cx': filtered_points[point].x, 'cy': filtered_points[point].y, 'r': 4, 'fill': '#333', 'stroke': Timeline.graphs[graph], 'stroke-width': 2}); + Timeline.g.insertBefore(element, Timeline.g.querySelectorAll('.label')[0]); if(filtered_points[point].click !== false) { element.onclick = filtered_points[point].click; @@ -481,63 +481,63 @@ SVG.draw = function() { element.addEventListener('mouseover', function() { this.setAttribute('r', '6'); - SVG.holder.getElementById(this.getAttribute('id').replace('point', 'label')).setAttribute('display', 'block'); + Timeline.holder.getElementById(this.getAttribute('id').replace('point', 'label')).setAttribute('display', 'block'); }); if(filtered_points[point].label !== '') { - var g = SVG.createElement('g', { 'class': 'label', 'id': 'label_'+filtered_points[point].id, 'transform': 'translate(0, ' + SVG.parent_holder.offsetHeight + ') scale(1, -1)'}); - SVG.g.appendChild(g); + var g = Timeline.createElement('g', { 'class': 'label', 'id': 'label_'+filtered_points[point].id, 'transform': 'translate(0, ' + Timeline.parent_holder.offsetHeight + ') scale(1, -1)'}); + Timeline.g.appendChild(g); g.addEventListener('mouseover', function() { - SVG.holder.getElementById(this.getAttribute('id').replace('label', 'point')).setAttribute('r', '6'); + Timeline.holder.getElementById(this.getAttribute('id').replace('label', 'point')).setAttribute('r', '6'); this.setAttribute('display', 'block'); }); - element = SVG.createElement('text', {}); + element = Timeline.createElement('text', {}); var text = filtered_points[point].label.replace('', '').split(''); for(var i = 0; i < text.length; i++) { - text[i] = text[i].replace(/(<([^>]+)>)/ig,"").replace('%y', SVG.raw_points[filtered_points[point].id].y).replace('%x', SVG.raw_points[filtered_points[point].id].x); + text[i] = text[i].replace(/(<([^>]+)>)/ig,"").replace('%y', Timeline.raw_points[filtered_points[point].id].y).replace('%x', Timeline.raw_points[filtered_points[point].id].x); if(i % 2 == 0) { element.appendChild(document.createTextNode(text[i])); } else { - var tmp = SVG.createElement('tspan', {'dy': '-5'}); + var tmp = Timeline.createElement('tspan', {'dy': '-5'}); tmp.appendChild(document.createTextNode(text[i])); element.appendChild(tmp); } } - path = SVG.createElement('path', {'stroke': 'black', 'stroke-width': 2, 'fill': 'white', 'opacity': 0.5}); + path = Timeline.createElement('path', {'stroke': 'black', 'stroke-width': 2, 'fill': 'white', 'opacity': 0.5}); // Append here to have them with the good z-index, update their attributes later g.appendChild(path); g.appendChild(element); var x_text = filtered_points[point].x - element.getBoundingClientRect().width / 2; - var y_text = SVG.parent_holder.offsetHeight - filtered_points[point].y - 20; + var y_text = Timeline.parent_holder.offsetHeight - filtered_points[point].y - 20; var element_width = element.getBoundingClientRect().width; var element_height = element.getBoundingClientRect().height; if(filtered_points[point].x - element.getBoundingClientRect().width / 2 < 0) { x_text = filtered_points[point].x + 20; - y_text = SVG.parent_holder.offsetHeight - filtered_points[point].y + 5; + y_text = Timeline.parent_holder.offsetHeight - filtered_points[point].y + 5; path.setAttribute('d', 'M '+(x_text - 5)+' '+(y_text + 5)+' L '+(x_text - 5)+' '+(y_text - element_height/2 + 7.5)+' L '+(x_text - 10)+' '+(y_text - element_height/2 + 5)+' L '+(x_text - 5)+' '+(y_text - element_height/2 + 2.5)+' L '+(x_text - 5)+' '+(y_text - element_height + 5)+' L '+(x_text + element_width + 5)+' '+(y_text - element_height + 5)+' L '+(x_text + element_width + 5)+' '+(y_text + 5)+' Z'); } - else if(filtered_points[point].y + element.getBoundingClientRect().height + 12 > SVG.parent_holder.offsetHeight) { + else if(filtered_points[point].y + element.getBoundingClientRect().height + 12 > Timeline.parent_holder.offsetHeight) { x_text = filtered_points[point].x + 20; - y_text = SVG.parent_holder.offsetHeight - filtered_points[point].y + 5; + y_text = Timeline.parent_holder.offsetHeight - filtered_points[point].y + 5; path.setAttribute('d', 'M '+(x_text - 5)+' '+(y_text + 5)+' L '+(x_text - 5)+' '+(y_text - element_height/2 + 7.5)+' L '+(x_text - 10)+' '+(y_text - element_height/2 + 5)+' L '+(x_text - 5)+' '+(y_text - element_height/2 + 2.5)+' L '+(x_text - 5)+' '+(y_text - element_height + 5)+' L '+(x_text + element_width + 5)+' '+(y_text - element_height + 5)+' L '+(x_text + element_width + 5)+' '+(y_text + 5)+' Z'); - if(x_text + element_width > SVG.parent_holder.offsetWidth) { + if(x_text + element_width > Timeline.parent_holder.offsetWidth) { x_text = filtered_points[point].y - element_width - 20; - y_text = SVG.parent_holder.offsetHeight - filtered_points[point].y + 5; + y_text = Timeline.parent_holder.offsetHeight - filtered_points[point].y + 5; path.setAttribute('d', 'M '+(x_text - 5)+' '+(y_text + 5)+' L '+(x_text - 5)+' '+(y_text - element_height + 5)+' L '+(x_text + element_width + 5)+' '+(y_text - element_height + 5)+' L '+(x_text + element_width + 5)+' '+(y_text - element_height/2 + 2.5)+' L '+(x_text + element_width + 10)+' '+(y_text - element_height/2 + 5)+' L '+(x_text + element_width + 5)+' '+(y_text - element_height/2 + 7.5)+' L '+(x_text + element_width + 5)+' '+(y_text + 5)+' Z'); } } - else if(filtered_points[point].x + element_width / 2 + 12 > SVG.parent_holder.offsetWidth) { + else if(filtered_points[point].x + element_width / 2 + 12 > Timeline.parent_holder.offsetWidth) { x_text = filtered_points[point].x - element_width - 20; - y_text = SVG.parent_holder.offsetHeight - filtered_points[point].y + 5; + y_text = Timeline.parent_holder.offsetHeight - filtered_points[point].y + 5; path.setAttribute('d', 'M '+(x_text - 5)+' '+(y_text + 5)+' L '+(x_text - 5)+' '+(y_text - element_height + 5)+' L '+(x_text + element_width + 5)+' '+(y_text - element_height + 5)+' L '+(x_text + element_width + 5)+' '+(y_text - element_height/2 + 2.5)+' L '+(x_text + element_width + 10)+' '+(y_text - element_height/2 + 5)+' L '+(x_text + element_width + 5)+' '+(y_text - element_height/2 + 7.5)+' L '+(x_text + element_width + 5)+' '+(y_text + 5)+' Z'); } else { @@ -556,15 +556,15 @@ SVG.draw = function() { var old = window.onresize || function () {}; window.onresize = function() { old(); - // Redraw the SVG to fit the new size - if(SVG.g !== false) { - SVG.g.setAttribute('transform', 'translate(0, ' + SVG.parent_holder.offsetHeight + ') scale(1, -1)'); - if(SVG.x_axis === true) { - SVG.axis.setAttribute('x2', SVG.parent_holder.offsetWidth - 13 - SVG.marginRight); + // Redraw the Timeline to fit the new size + if(Timeline.g !== false) { + Timeline.g.setAttribute('transform', 'translate(0, ' + Timeline.parent_holder.offsetHeight + ') scale(1, -1)'); + if(Timeline.x_axis === true) { + Timeline.axis.setAttribute('x2', Timeline.parent_holder.offsetWidth - 13 - Timeline.marginRight); } - [].forEach.call(SVG.holder.querySelectorAll('.label, .over, .point, .line, .graph, .legend_x'), function(el) { + [].forEach.call(Timeline.holder.querySelectorAll('.label, .over, .point, .line, .graph, .legend_x'), function(el) { el.parentNode.removeChild(el); }); - SVG.draw(); + Timeline.draw(); } }; diff --git a/timeline.min.js b/timeline.min.js index 7c6c482..beec710 100644 --- a/timeline.min.js +++ b/timeline.min.js @@ -1 +1 @@ -var SVG={};SVG.ns="http://www.w3.org/2000/svg";SVG.xlinkns="http://www.w3.org/1999/xlink";SVG.marginBottom=10;SVG.marginTop=15;SVG.marginLeft=10;SVG.marginRight=10;SVG.rounded=false;SVG.x_axis=false;SVG.fill=true;SVG.line="line";SVG.dashed_style="5, 5";SVG.parent_holder=false;SVG.holder=false;SVG.g=false;SVG.axis=false;SVG.graphs=[];SVG.raw_points=[];SVG.x_callback=false;SVG.createElement=function(b,a){var c=document.createElementNS(SVG.ns,b);for(attr in a){c.setAttribute(attr,a[attr])}return c};SVG.hasClass=function(b,a){return(" "+b.getAttribute("class")+" ").indexOf(" "+a+" ")>-1};SVG.addGraph=function(b,a){SVG.graphs[b]=a};SVG.hasGraph=function(a){if(typeof(SVG.graphs[a])==="undefined"){return false}else{return true}};SVG.clearGraph=function(b){if(typeof(b)==="undefined"){SVG.raw_points=[];SVG.graphs=[]}else{for(var a=0;a=0;--g){p[g]=(d[g]-j[g]*p[g+1])/k[g]}for(var g=0;gc||c===false){c=j[p].x}if(j[p].yb||b===false){b=j[p].y}}var f=SVG.getNewXY(g,c,e,b);var i=f(Math.pow(10,Math.floor(Math.log(c-g)/Math.log(10))),Math.pow(10,Math.floor(Math.log(b-e)/Math.log(10))));var o=f(0,0);var n={x:i.x-o.x,y:i.y-o.y};if(SVG.grid==="big"||SVG.grid==="both"){var a=SVG.holder.getElementById("grid");a.setAttribute("width",n.x);a.setAttribute("height",n.y);var h=f(Math.floor(g/Math.pow(10,Math.floor(Math.log(c-g)/Math.log(10))))*Math.pow(10,Math.floor(Math.log(c-g)/Math.log(10))),Math.floor(e/Math.pow(10,Math.floor(Math.log(b-e)/Math.log(10))))*Math.pow(10,Math.floor(Math.log(b-e)/Math.log(10))));a.setAttribute("y",h.y);a.setAttribute("x",h.x);a.querySelector("path").setAttribute("d","M "+n.x+" 0 L 0 0 0 "+n.y);if(SVG.grid==="both"){a.querySelector("rect").setAttribute("width",n.x);a.querySelector("rect").setAttribute("height",n.y)}}if(SVG.grid==="small"||SVG.grid==="both"){n.x=n.x/10;n.y=n.y/10;var a=SVG.holder.getElementById("smallGrid");a.setAttribute("width",n.x);a.setAttribute("height",n.y);if(SVG.grid==="small"){var m=f(Math.floor(g/Math.pow(10,Math.floor(Math.log(c-g)/Math.log(10))))*Math.pow(10,Math.floor(Math.log(c-g)/Math.log(10))),Math.floor(e/Math.pow(10,Math.floor(Math.log(b-e)/Math.log(10))))*Math.pow(10,Math.floor(Math.log(b-e)/Math.log(10))));a.setAttribute("y",m.y);a.setAttribute("x",m.x)}a.querySelector("path").setAttribute("d","M "+n.x+" 0 L 0 0 0 "+n.y)}if(SVG.x_axis===true){y=f(0,0).y;SVG.axis.setAttribute("y1",y);SVG.axis.setAttribute("y2",y)}return f};SVG.draw=function(){var A=SVG.scale(SVG.raw_points);var t=[],o;var n,m;var d;for(var r=0;rt.length){break}q++}}for(var u=p+1;u","").split("");for(var u=0;u]+)>)/ig,"").replace("%y",SVG.raw_points[j[r].id].y).replace("%x",SVG.raw_points[j[r].id].x);if(u%2==0){d.appendChild(document.createTextNode(l[u]))}else{var w=SVG.createElement("tspan",{dy:"-5"});w.appendChild(document.createTextNode(l[u]));d.appendChild(w)}}o=SVG.createElement("path",{stroke:"black","stroke-width":2,fill:"white",opacity:0.5});v.appendChild(o);v.appendChild(d);var z=j[r].x-d.getBoundingClientRect().width/2;var a=SVG.parent_holder.offsetHeight-j[r].y-20;var f=d.getBoundingClientRect().width;var s=d.getBoundingClientRect().height;if(j[r].x-d.getBoundingClientRect().width/2<0){z=j[r].x+20;a=SVG.parent_holder.offsetHeight-j[r].y+5;o.setAttribute("d","M "+(z-5)+" "+(a+5)+" L "+(z-5)+" "+(a-s/2+7.5)+" L "+(z-10)+" "+(a-s/2+5)+" L "+(z-5)+" "+(a-s/2+2.5)+" L "+(z-5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a+5)+" Z")}else{if(j[r].y+d.getBoundingClientRect().height+12>SVG.parent_holder.offsetHeight){z=j[r].x+20;a=SVG.parent_holder.offsetHeight-j[r].y+5;o.setAttribute("d","M "+(z-5)+" "+(a+5)+" L "+(z-5)+" "+(a-s/2+7.5)+" L "+(z-10)+" "+(a-s/2+5)+" L "+(z-5)+" "+(a-s/2+2.5)+" L "+(z-5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a+5)+" Z");if(z+f>SVG.parent_holder.offsetWidth){z=j[r].y-f-20;a=SVG.parent_holder.offsetHeight-j[r].y+5;o.setAttribute("d","M "+(z-5)+" "+(a+5)+" L "+(z-5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a-s/2+2.5)+" L "+(z+f+10)+" "+(a-s/2+5)+" L "+(z+f+5)+" "+(a-s/2+7.5)+" L "+(z+f+5)+" "+(a+5)+" Z")}}else{if(j[r].x+f/2+12>SVG.parent_holder.offsetWidth){z=j[r].x-f-20;a=SVG.parent_holder.offsetHeight-j[r].y+5;o.setAttribute("d","M "+(z-5)+" "+(a+5)+" L "+(z-5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a-s/2+2.5)+" L "+(z+f+10)+" "+(a-s/2+5)+" L "+(z+f+5)+" "+(a-s/2+7.5)+" L "+(z+f+5)+" "+(a+5)+" Z")}else{o.setAttribute("d","M "+(z-5)+" "+(a+5)+" L "+(z-5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a+5)+" L "+(z+f/2+2.5)+" "+(a+5)+" L "+(z+f/2)+" "+(a+10)+" L "+(z+f/2-2.5)+" "+(a+5)+" Z")}}}d.setAttribute("x",z);d.setAttribute("y",a);v.setAttribute("display","none")}}}};var old=window.onresize||function(){};window.onresize=function(){old();if(SVG.g!==false){SVG.g.setAttribute("transform","translate(0, "+SVG.parent_holder.offsetHeight+") scale(1, -1)");if(SVG.x_axis===true){SVG.axis.setAttribute("x2",SVG.parent_holder.offsetWidth-13-SVG.marginRight)}[].forEach.call(SVG.holder.querySelectorAll(".label, .over, .point, .line, .graph, .legend_x"),function(a){a.parentNode.removeChild(a)});SVG.draw()}}; \ No newline at end of file +var Timeline={};Timeline.ns="http://www.w3.org/2000/svg";Timeline.xlinkns="http://www.w3.org/1999/xlink";Timeline.marginBottom=10;Timeline.marginTop=15;Timeline.marginLeft=10;Timeline.marginRight=10;Timeline.rounded=false;Timeline.x_axis=false;Timeline.fill=true;Timeline.line="line";Timeline.dashed_style="5, 5";Timeline.parent_holder=false;Timeline.holder=false;Timeline.g=false;Timeline.axis=false;Timeline.graphs=[];Timeline.raw_points=[];Timeline.x_callback=false;Timeline.createElement=function(b,a){var c=document.createElementNS(Timeline.ns,b);for(attr in a){c.setAttribute(attr,a[attr])}return c};Timeline.hasClass=function(b,a){return(" "+b.getAttribute("class")+" ").indexOf(" "+a+" ")>-1};Timeline.addGraph=function(b,a){Timeline.graphs[b]=a};Timeline.hasGraph=function(a){if(typeof(Timeline.graphs[a])==="undefined"){return false}else{return true}};Timeline.clearGraph=function(b){if(typeof(b)==="undefined"){Timeline.raw_points=[];Timeline.graphs=[]}else{for(var a=0;a=0;--g){p[g]=(d[g]-j[g]*p[g+1])/k[g]}for(var g=0;gc||c===false){c=j[p].x}if(j[p].yb||b===false){b=j[p].y}}var f=Timeline.getNewXY(g,c,e,b);var i=f(Math.pow(10,Math.floor(Math.log(c-g)/Math.log(10))),Math.pow(10,Math.floor(Math.log(b-e)/Math.log(10))));var o=f(0,0);var n={x:i.x-o.x,y:i.y-o.y};if(Timeline.grid==="big"||Timeline.grid==="both"){var a=Timeline.holder.getElementById("grid");a.setAttribute("width",n.x);a.setAttribute("height",n.y);var h=f(Math.floor(g/Math.pow(10,Math.floor(Math.log(c-g)/Math.log(10))))*Math.pow(10,Math.floor(Math.log(c-g)/Math.log(10))),Math.floor(e/Math.pow(10,Math.floor(Math.log(b-e)/Math.log(10))))*Math.pow(10,Math.floor(Math.log(b-e)/Math.log(10))));a.setAttribute("y",h.y);a.setAttribute("x",h.x);a.querySelector("path").setAttribute("d","M "+n.x+" 0 L 0 0 0 "+n.y);if(Timeline.grid==="both"){a.querySelector("rect").setAttribute("width",n.x);a.querySelector("rect").setAttribute("height",n.y)}}if(Timeline.grid==="small"||Timeline.grid==="both"){n.x=n.x/10;n.y=n.y/10;var a=Timeline.holder.getElementById("smallGrid");a.setAttribute("width",n.x);a.setAttribute("height",n.y);if(Timeline.grid==="small"){var m=f(Math.floor(g/Math.pow(10,Math.floor(Math.log(c-g)/Math.log(10))))*Math.pow(10,Math.floor(Math.log(c-g)/Math.log(10))),Math.floor(e/Math.pow(10,Math.floor(Math.log(b-e)/Math.log(10))))*Math.pow(10,Math.floor(Math.log(b-e)/Math.log(10))));a.setAttribute("y",m.y);a.setAttribute("x",m.x)}a.querySelector("path").setAttribute("d","M "+n.x+" 0 L 0 0 0 "+n.y)}if(Timeline.x_axis===true){y=f(0,0).y;Timeline.axis.setAttribute("y1",y);Timeline.axis.setAttribute("y2",y)}return f};Timeline.draw=function(){var A=Timeline.scale(Timeline.raw_points);var t=[],o;var n,m;var d;for(var r=0;rt.length){break}q++}}for(var u=p+1;u","").split("");for(var u=0;u]+)>)/ig,"").replace("%y",Timeline.raw_points[j[r].id].y).replace("%x",Timeline.raw_points[j[r].id].x);if(u%2==0){d.appendChild(document.createTextNode(l[u]))}else{var w=Timeline.createElement("tspan",{dy:"-5"});w.appendChild(document.createTextNode(l[u]));d.appendChild(w)}}o=Timeline.createElement("path",{stroke:"black","stroke-width":2,fill:"white",opacity:0.5});v.appendChild(o);v.appendChild(d);var z=j[r].x-d.getBoundingClientRect().width/2;var a=Timeline.parent_holder.offsetHeight-j[r].y-20;var f=d.getBoundingClientRect().width;var s=d.getBoundingClientRect().height;if(j[r].x-d.getBoundingClientRect().width/2<0){z=j[r].x+20;a=Timeline.parent_holder.offsetHeight-j[r].y+5;o.setAttribute("d","M "+(z-5)+" "+(a+5)+" L "+(z-5)+" "+(a-s/2+7.5)+" L "+(z-10)+" "+(a-s/2+5)+" L "+(z-5)+" "+(a-s/2+2.5)+" L "+(z-5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a+5)+" Z")}else{if(j[r].y+d.getBoundingClientRect().height+12>Timeline.parent_holder.offsetHeight){z=j[r].x+20;a=Timeline.parent_holder.offsetHeight-j[r].y+5;o.setAttribute("d","M "+(z-5)+" "+(a+5)+" L "+(z-5)+" "+(a-s/2+7.5)+" L "+(z-10)+" "+(a-s/2+5)+" L "+(z-5)+" "+(a-s/2+2.5)+" L "+(z-5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a+5)+" Z");if(z+f>Timeline.parent_holder.offsetWidth){z=j[r].y-f-20;a=Timeline.parent_holder.offsetHeight-j[r].y+5;o.setAttribute("d","M "+(z-5)+" "+(a+5)+" L "+(z-5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a-s/2+2.5)+" L "+(z+f+10)+" "+(a-s/2+5)+" L "+(z+f+5)+" "+(a-s/2+7.5)+" L "+(z+f+5)+" "+(a+5)+" Z")}}else{if(j[r].x+f/2+12>Timeline.parent_holder.offsetWidth){z=j[r].x-f-20;a=Timeline.parent_holder.offsetHeight-j[r].y+5;o.setAttribute("d","M "+(z-5)+" "+(a+5)+" L "+(z-5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a-s/2+2.5)+" L "+(z+f+10)+" "+(a-s/2+5)+" L "+(z+f+5)+" "+(a-s/2+7.5)+" L "+(z+f+5)+" "+(a+5)+" Z")}else{o.setAttribute("d","M "+(z-5)+" "+(a+5)+" L "+(z-5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a-s+5)+" L "+(z+f+5)+" "+(a+5)+" L "+(z+f/2+2.5)+" "+(a+5)+" L "+(z+f/2)+" "+(a+10)+" L "+(z+f/2-2.5)+" "+(a+5)+" Z")}}}d.setAttribute("x",z);d.setAttribute("y",a);v.setAttribute("display","none")}}}};var old=window.onresize||function(){};window.onresize=function(){old();if(Timeline.g!==false){Timeline.g.setAttribute("transform","translate(0, "+Timeline.parent_holder.offsetHeight+") scale(1, -1)");if(Timeline.x_axis===true){Timeline.axis.setAttribute("x2",Timeline.parent_holder.offsetWidth-13-Timeline.marginRight)}[].forEach.call(Timeline.holder.querySelectorAll(".label, .over, .point, .line, .graph, .legend_x"),function(a){a.parentNode.removeChild(a)});Timeline.draw()}}; \ No newline at end of file