sean@0: <!DOCTYPE html>
sean@0: <html>
sean@0: 	<head>
sean@0: 		<title> Issues </title>
sean@0: 		<style type = text/css>
sean@1: 
sean@1: 			* {
sean@1: 				font-family: "Sans-serif";
sean@1: 				font-size: 14px;
sean@1: 			}
sean@1: 
sean@0: 			.svg div{
sean@1: 					font: 10px;
sean@0: 					text-align: right;
sean@0: 					float: left;
sean@0: 					display: block;
sean@0: 					padding: 10px;
sean@0: 					margin: 10px;
sean@0: 					color: white;
sean@0: 			}
sean@0: 
sean@0: 			.axis path,
sean@0: 
sean@0: 			.axis line {
sean@0: 					fill: none;
sean@0: 					stroke: black;
sean@0: 					stroke-width: 1px;
sean@0: 			}
sean@0: 
sean@0: 			.line {
sean@0: 					fill: none;
sean@1: 					stroke-width: 3px;
sean@1: 					opacity: 1;
sean@0: 			}
sean@0: 
sean@0: 			.line.critical {
sean@0: 					stroke: red;
sean@0: 			}
sean@0: 
sean@0: 			.line.critical.legend {
sean@0: 					fill: red;
sean@0: 			}
sean@0: 
sean@0: 			.line.urgent {
sean@0: 					stroke: orange;
sean@0: 			}
sean@0: 
sean@0: 			.line.urgent.legend {
sean@0: 					fill: orange;
sean@0: 			}
sean@0: 
sean@0: 			.line.bug {
sean@0: 					stroke: violet;
sean@0: 			}
sean@0: 
sean@0: 			.line.bug.legend {
sean@0: 					fill: violet;
sean@0: 			}
sean@0: 
sean@0: 			.line.feature {
sean@1: 					stroke: chartreuse;
sean@1: 					style: stroke-dasharray;
sean@0: 			}
sean@0: 
sean@0: 			.line.feature.legend {
sean@1: 					fill: chartreuse;
sean@0: 			}
sean@0: 
sean@0: 			.line.wish {
sean@0: 					stroke: blue;
sean@0: 			}
sean@0: 
sean@0: 			.line.wish.legend {
sean@0: 					fill: blue;
sean@0: 			}
sean@0: 
sean@0: 			.grid .tick {
sean@0: 					stroke: lightgrey;
sean@0: 					opacity: 0.7;
sean@0: 			}
sean@0: 
sean@0: 			.grid path {
sean@0: 					stroke-width: 0;
sean@0: 			}
sean@0: 
sean@0: 		</style>
sean@0: 	</head>
sean@0: 	<body>
sean@1: 		<div id="content" style="display: inline-block"></div>
sean@0: 		<script type="text/javascript" src="d3.v3.min.js"></script>
sean@0: 		<script type="text/javascript">
sean@0: 
sean@1: 			window.onresize = function(){
sean@1: 				document.getElementById("content").innerHTML = "";
sean@1: 				makeChart();
sean@1: 			};
sean@0: 
sean@0: 			var critical=[];
sean@0: 			var urgent=[];
sean@0: 			var bug=[];
sean@0: 			var feature=[];
sean@0: 			var wish=[];
sean@0: 			var timestamp=[];
sean@0: 
sean@1: 
sean@1: 
sean@0: 			function assignIssueToDate(issueArray, dateArray){
sean@0: 				a = [];
sean@0: 				for (var i = 0; i < issueArray.length; i++) {
sean@0: 					a.push({points: issueArray[i].points, date : dateArray[i].date});
sean@0: 				}
sean@0: 
sean@0: 				return a;
sean@0: 			}
sean@0: 
sean@1: 			function limitDatesOnXAxis(limit){
sean@1: 				if ( timestamp.length < limit ){
sean@1: 					return timestamp.length;
sean@1: 				} else {
sean@1: 					return limit;
sean@1: 				}
sean@1: 			}
sean@0: 
sean@0: 			function maxInObject( array ){
sean@0: 				var maxVal = 0;
sean@0: 				for (var i = 0; i < array.length; i++) {
sean@0: 					if (maxVal < array[i].points){
sean@0: 						maxVal = array[i].points;
sean@0: 					}
sean@0: 				}
sean@0: 				return maxVal;
sean@0: 			}
sean@0: 
sean@0: 
sean@0: 			function getMaxIssues(){
sean@0: 				maxIssuesOfAllArrays = [];
sean@0: 				maxIssuesOfAllArrays.push(maxInObject(critical));
sean@0: 				maxIssuesOfAllArrays.push(maxInObject(urgent));
sean@0: 				maxIssuesOfAllArrays.push(maxInObject(bug));
sean@0: 				maxIssuesOfAllArrays.push(maxInObject(feature));
sean@0: 				maxIssuesOfAllArrays.push(maxInObject(wish));
sean@0: 
sean@0: 				return Math.max.apply(Math, maxIssuesOfAllArrays)+1;
sean@0: 			}
sean@0: 
sean@0: 
sean@0: 			function dayDifference(first, second) {
sean@0: 				"use strict";
sean@0: 				var difference = (second - first) / (1000 * 60 * 60 * 24);
sean@0: 
sean@0: 				// just to avoid the get thousands of lines... would look ugly.
sean@0: 				if (difference > 60){
sean@0: 					difference = 60;
sean@0: 				}
sean@0: 
sean@0: 				return difference;
sean@0: 			}
sean@0: 
sean@0: 
sean@0: 			// function for the grid lines
sean@0: 			function makeGrid(direction, orientation, ticknumber) {
sean@0: 				return d3.svg.axis()
sean@0: 					.scale(direction)
sean@0: 					.orient(orientation)
sean@0: 					.ticks( ticknumber );
sean@0: 			}
sean@0: 
sean@0: 
sean@0: 			//append a svg_path. pretty generic
sean@1: 			function draw_line(svg, data_array, css_class, line_object, lineShape){
sean@0: 				svg.append("path")
sean@0: 					.datum(assignIssueToDate(data_array, timestamp))
sean@0: 					.attr("class", css_class)
sean@1: 					.style("stroke-dasharray", (lineShape))
sean@0: 					.attr("d", line_object);
sean@0: 			}
sean@0: 
sean@0: 
sean@1: 			function makeLegend(svg, width){
sean@0: 
sean@1: 				var legend_distance = width+40;
sean@1: 				var top_distance = 20;
sean@1: 				var distance_steps = 50;
sean@1: 
sean@1: 
sean@1: 				function set_propper_distance(steps){
sean@1: 					top_distance += steps;
sean@1: 					return top_distance;
sean@1: 				}
sean@1: 
sean@1: 				function draw_legend_line(svg, width, Ypos, text, issues){
sean@1: 					svg.append("svg:text")
sean@1: 						.attr("class", "legend")
sean@1: 						.attr("x", width-30	)
sean@1: 						.attr("y", Ypos)
sean@1: 						.text(text + ":");
sean@1: 
sean@1: 					svg.append("svg:text")
sean@1: 						.attr("class", "legend")
sean@1: 						.attr("x", width+35	)
sean@1: 						.attr("y", Ypos)
sean@1: 						.text(issues);
sean@1: 
sean@1: 					svg.append("rect")
sean@1: 						.attr("class", "line " + text.toLowerCase() + " legend")
sean@1: 						.attr("x", width-30)
sean@1: 						.attr("y", Ypos-20)
sean@1: 						.attr("width", 100)
sean@1: 						.attr("height", 2);
sean@1: 				}
sean@1: 
sean@1: 				draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Critical", critical[critical.length-1].points);
sean@1: 				draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Urgent", urgent[urgent.length-1].points);
sean@1: 				draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Bug", bug[bug.length-1].points);
sean@1: 				draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Feature", feature[feature.length-1].points);
sean@1: 				draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Wish", wish[wish.length-1].points);
sean@0: 			}
sean@0: 
sean@0: 
sean@1: 
sean@0: 			//draw the chart
sean@0: 			function makeChart(){
sean@0: 
sean@0: 				//declaration
sean@0: 				var sizeOfSystemBorders = 50;
sean@1: 				var margin = {top: 20, right: 100, bottom: 90, left: 60},
sean@0: 					width = (document.documentElement.clientWidth-sizeOfSystemBorders) - margin.left - margin.right,
sean@1: 					height = (document.documentElement.clientHeight-sizeOfSystemBorders) - margin.top - margin.bottom;
sean@0: 
sean@0: 				var x = d3.time.scale()
sean@0: 					.range([0, width]);
sean@0: 
sean@0: 				var y = d3.scale.linear()
sean@0: 					.range([height, 0]);
sean@0: 
sean@0: 				var base_line = d3.svg.line()
sean@0: 					.x(function(d) { return x(d.date); })
sean@0: 					.y(function(d) { return y(d.points); });
sean@0: 
sean@0: 				//lines
sean@0: 				var criticalLine = base_line;
sean@0: 				var urgentLine = base_line;
sean@0: 				var bugLine = base_line;
sean@0: 				var featureLine = base_line;
sean@0: 				var wishLine = base_line;
sean@0: 				var timestampLine = base_line;
sean@0: 
sean@0: 
sean@0: 				//set domain of y axis
sean@0: 				var yDomain = [	];
sean@0: 				yDomain[0] = 0;
sean@0: 				yDomain[1] = getMaxIssues();
sean@0: 				y.domain(d3.extent(yDomain, function(d){return d; }));
sean@0: 
sean@0: 				//set domain of y axis
sean@0: 				x.domain(d3.extent(timestamp, function(d){return d.date; }));
sean@0: 
sean@0: 
sean@0: 				var xAxis = d3.svg.axis()
sean@0: 					.scale(x)
sean@0: 					.orient("bottom")
sean@1: 					.ticks(limitDatesOnXAxis(10))
sean@1: 					.tickFormat(d3.time.format("%d.%m:%H:%M"));
sean@1: 					// .tickFormat(d3.time.format("%X"));
sean@1: 					// .tickFormat(d3.time.format.iso);
sean@0: 
sean@0: 
sean@0: 				var yAxis = d3.svg.axis()
sean@0: 					.scale(y)
sean@0: 					.orient("left");
sean@0: 
sean@0: 
sean@1: 				var svg = d3.select("#content")
sean@0: 					.append("svg")
sean@0: 					.attr("class", "svg")
sean@0: 					.attr("width", width + margin.left + margin.right)
sean@0: 					.attr("height", height + margin.top + margin.bottom)
sean@0: 					.append("g")
sean@0: 					.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
sean@0: 
sean@0: 
sean@0: 				// creation
sean@0: 
sean@0: 
sean@0: 				// Draw the x Grid lines
gernot@11: 				// svg.append("g")
gernot@11: 				// 	.attr("class", "grid")
gernot@11: 				// 	.attr("transform", "translate(0," + height + ")")
gernot@11: 				// 	.call(makeGrid(x, "bottom", timestamp.length)
gernot@11: 				// 		.tickSize(-height, 0, 0)
gernot@11: 				// 		.tickFormat("")
gernot@11: 				// 	);
sean@0: 
sean@0: 
sean@0: 				// Draw the y Grid lines
sean@0: 				svg.append("g")
sean@0: 					.attr("class", "grid")
sean@1: 					.call(makeGrid(y, "left", function(){return Math.min(getMaxIssues(), 50);}())
sean@0: 						.tickSize(-width, 0, 0)
sean@0: 						.tickFormat("")
sean@0: 					);
sean@0: 
sean@0: 
sean@0: 				// Draw the x-axis
sean@0: 				svg.append("g")
sean@0: 					.attr("class", "x axis")
sean@0: 					.attr("transform", "translate(0," + height + ")")
sean@0: 					.call(xAxis)
sean@0: 					.selectAll("text")
sean@0: 					.style("text-anchor", "end")
sean@1: 					.attr("dx", "-.5em")
sean@1: 					.attr("dy", ".1em")
sean@0: 					.attr("transform", function() {
sean@0: 						return "rotate(-65)";
sean@0: 					});
sean@0: 
sean@0: 
sean@0: 				// Draw the y-axis
sean@0: 				svg.append("g")
sean@0: 					.attr("class", "y axis")
sean@0: 					.call(yAxis)
sean@0: 					.append("text")
sean@0: 					.attr("transform", "rotate(-90)")
sean@0: 					.attr("y", 6)
sean@0: 					.attr("dy", ".71em")
sean@0: 					.style("text-anchor", "end");
sean@0: 
sean@0: 
sean@0: 				// Text for y-axis
sean@0: 				svg.append("text")
sean@0: 					.attr("transform", "rotate(-90)")
sean@0: 					.attr("y", 10 - margin.left)
sean@0: 					.attr("x", 0 - (height / 2))
sean@0: 					.attr("dy", "1em")
sean@0: 					.style("text-anchor", "middle")
sean@0: 					.text("Issues");
sean@0: 
sean@0: 
sean@0: 				//Titel und Legende
sean@0: 
sean@0: 				svg.append("svg:text")
sean@1: 					.attr("class", "text")
sean@0: 					.attr("x", 10)
sean@0: 					.attr("y", -5)
sean@0: 					.text("Issues Nach Zeit");
sean@0: 
sean@0: 
sean@1: 				draw_line(svg, wish, "line wish", wishLine, "0, 0");
sean@1: 				draw_line(svg, feature, "line feature", featureLine, "3, 3");
sean@1: 				draw_line(svg, bug, "line bug", bugLine, "7, 7");
sean@1: 				draw_line(svg, urgent, "line urgent", urgentLine, "13, 13");
sean@1: 				draw_line(svg, critical, "line critical", criticalLine, "17, 17");
sean@0: 
sean@0: 
sean@1: 				makeLegend(svg, width);
sean@1: 
sean@0: 
sean@0: 			}
sean@0: 
sean@0: 			makeChart();
sean@0: 
sean@0: 
sean@0: 		</script>
sean@0: 	</body>
sean@0: </html>