changeset 43:2e2981af7d2d

Use bottledash-specific graph template This version differs from roundup_cc's graph.html in that is not a complete HTML file but a snippet.
author Gernot Schulz <gernot@intevation.de>
date Sun, 31 Jan 2016 15:21:18 +0100
parents 8935152f5e19
children b47fc5eb9e01
files modules/web_view/bottledash_graph.html modules/web_view/display_issues_techintern.py
diffstat 2 files changed, 371 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/web_view/bottledash_graph.html	Sun Jan 31 15:21:18 2016 +0100
@@ -0,0 +1,367 @@
+<style type = text/css>
+
+	* {
+		font-family: "Sans-serif";
+		/*font-size: 20px;*/
+	}
+
+	.svg div{
+			/*font: 10px;*/
+			/*text-align: right;*/
+			/*float: left;*/
+			/*display: block;*/
+			/*padding: 10px;*/
+			/*margin: 10px;*/
+			color: white;
+	}
+
+	.axis path,
+
+	.axis line {
+			fill: none;
+			stroke: lightgrey;
+			/*opacity: 0.7;*/
+			stroke-width: 1px;
+	}
+
+	.y.axis path {
+	  display: none;
+	}
+
+	.line {
+			fill: none;
+			stroke-width: 4px;
+			opacity: 1;
+	}
+
+	.line.critical {
+			stroke: red;
+	}
+
+	.line.critical.legend {
+			fill: red;
+	}
+
+	.line.urgent {
+			stroke: orange;
+	}
+
+	.line.urgent.legend {
+			fill: orange;
+	}
+
+	.line.bug {
+			stroke: violet;
+	}
+
+	.line.bug.legend {
+			fill: violet;
+	}
+
+	.line.feature {
+			stroke: chartreuse;
+			style: stroke-dasharray;
+	}
+
+	.line.feature.legend {
+			fill: chartreuse;
+	}
+
+	.line.wish {
+			stroke: blue;
+	}
+
+	.line.wish.legend {
+			fill: blue;
+	}
+
+	.grid .tick {
+			stroke: lightgrey;
+			/*opacity: 0.7;*/
+	}
+
+	.grid path {
+			stroke-width: 0;
+	}
+
+</style>
+
+<!-- <div id="content" style="display: inline-block"></div> -->
+<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script> -->
+
+<script type="text/javascript" src="static/d3.v3.min.js"></script>
+
+<script type="text/javascript">
+
+	var d3jsInjectionTarget="X";
+
+	// window.onresize = function(){
+	// 	document.getElementById(d3jsInjectionTarget).innerHTML = "";
+	// 	makeChart();
+	// };
+
+	var critical=[];
+	var urgent=[];
+	var bug=[];
+	var feature=[];
+	var wish=[];
+	var timestamp=[];
+
+	document.addEventListener("DOMContentLoaded", function(event) {
+		try {
+			document.getElementById(d3jsInjectionTarget).getElementsByClassName("svg")[0].innerHTML = ""
+		} catch (e) {
+		}
+		makeChart();
+	});
+
+	function assignIssueToDate(issueArray, dateArray){
+		a = [];
+		for (var i = 0; i < issueArray.length; i++) {
+			a.push({points: issueArray[i].points, date : dateArray[i].date});
+		}
+
+		return a;
+	}
+
+	function limitDatesOnXAxis(limit){
+		if (timestamp.length < limit){
+			return timestamp.length;
+		} else {
+			return limit;
+		}
+	}
+
+	function maxInObject( array ){
+		var maxVal = 0;
+		for (var i = 0; i < array.length; i++) {
+			if (maxVal < array[i].points){
+				maxVal = array[i].points;
+			}
+		}
+		return maxVal;
+	}
+
+
+	function getMaxIssues(){
+		maxIssuesOfAllArrays = [];
+		maxIssuesOfAllArrays.push(maxInObject(critical));
+		maxIssuesOfAllArrays.push(maxInObject(urgent));
+		maxIssuesOfAllArrays.push(maxInObject(bug));
+		maxIssuesOfAllArrays.push(maxInObject(feature));
+		maxIssuesOfAllArrays.push(maxInObject(wish));
+
+		return Math.max.apply(Math, maxIssuesOfAllArrays)+1;
+	}
+
+
+	function dayDifference(first, second) {
+		"use strict";
+		var difference = (second - first) / (1000 * 60 * 60 * 24);
+
+		// just to avoid the get thousands of lines... would look ugly.
+		if (difference > 60){
+			difference = 60;
+		}
+
+		return difference;
+	}
+
+
+	// function for the grid lines
+	function makeGrid(direction, orientation, ticknumber) {
+		return d3.svg.axis()
+			.scale(direction)
+			.orient(orientation)
+			.ticks( ticknumber );
+	}
+
+
+	//append a svg_path. pretty generic
+	function draw_line(svg, data_array, css_class, line_object){
+		svg.append("path")
+			.datum(assignIssueToDate(data_array, timestamp))
+			.attr("class", css_class)
+			.attr("d", line_object);
+	}
+
+
+	function makeLegend(svg, width){
+
+		var legend_distance = width+40;
+		var top_distance = 20;
+		var distance_steps = 50;
+
+
+		function set_propper_distance(steps){
+			top_distance += steps;
+			return top_distance;
+		}
+
+		function draw_legend_line(svg, width, Ypos, text, issues){
+			svg.append("svg:text")
+				.attr("class", "legend")
+				.attr("x", width-30	)
+				.attr("y", Ypos)
+				.text(text + ":");
+
+			svg.append("svg:text")
+				.attr("class", "legend")
+				.attr("x", width+35	)
+				.attr("y", Ypos)
+				.text(issues);
+
+			svg.append("rect")
+				.attr("class", "line " + text.toLowerCase() + " legend")
+				.attr("x", width-30)
+				.attr("y", Ypos-20)
+				.attr("width", 100)
+				.attr("height", 2);
+		}
+
+		draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Critical", critical[critical.length-1].points);
+		draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Urgent", urgent[urgent.length-1].points);
+		draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Bug", bug[bug.length-1].points);
+		draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Feature", feature[feature.length-1].points);
+		draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Wish", wish[wish.length-1].points);
+	}
+
+
+
+	//draw the chart
+	function makeChart(div_name){
+
+		//declaration
+		var targetDiv = document.getElementById(d3jsInjectionTarget)
+		// var sizeOfSystemBorders = 20;
+
+		var margin = {top: 20, right: 10, bottom: 50, left:50}
+
+		var width = targetDiv.clientWidth - margin.left - margin.right
+		var height = targetDiv.clientHeight - margin.top - margin.bottom
+
+		var x = d3.time.scale()
+			.range([0, width]);
+
+		var y = d3.scale.linear()
+			.range([height, 0]);
+
+		var base_line = d3.svg.line()
+			.x(function(d) { return x(d.date); })
+			.y(function(d) { return y(d.points); });
+
+		//lines
+		var criticalLine = base_line;
+		var urgentLine = base_line;
+		var bugLine = base_line;
+		var featureLine = base_line;
+		var wishLine = base_line;
+		var timestampLine = base_line;
+
+
+		//set domain of y axis
+		var yDomain = [	];
+		yDomain[0] = 0;
+		yDomain[1] = getMaxIssues();
+		y.domain(d3.extent(yDomain, function(d){return d; }));
+
+		//set domain of y axis
+		x.domain(d3.extent(timestamp, function(d){return d.date; }));
+
+
+		var xAxis = d3.svg.axis()
+			.scale(x)
+			.orient("bottom")
+			.ticks(limitDatesOnXAxis(10))
+			.tickFormat(d3.time.format("%d.%m"));
+
+		var yAxis = d3.svg.axis()
+			.scale(y)
+			.orient("left");
+
+		var svg = d3.select("#" + d3jsInjectionTarget)
+			.append("svg")
+			.attr("class", "svg")
+			.attr("width", width + margin.left + margin.right)
+			.attr("height", height + margin.top + margin.bottom)
+			.append("g")
+			.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
+
+
+		// creation
+
+
+		// Draw the x Grid lines
+		// svg.append("g")
+		// 	.attr("class", "grid")
+		// 	.attr("transform", "translate(0," + height + ")")
+		// 	.call(makeGrid(x, "bottom", timestamp.length)
+		// 		.tickSize(-height, 0, 0)
+		// 		.tickFormat("")
+		// 	);
+
+
+		// Draw the y Grid lines
+		svg.append("g")
+			.attr("class", "grid")
+			.call(makeGrid(y, "left", function(){return Math.min(getMaxIssues(), 10);}())
+				.tickSize(-width, 0, 0)
+				.tickFormat("")
+			);
+
+
+		// Draw the x-axis
+		svg.append("g")
+			.attr("class", "x axis")
+			// .attr("transform", "translate(0, " + 20-height + ")")
+			.attr("transform", "translate(0," + height + ")")
+			.call(xAxis)
+			.selectAll("text")
+			// .style("text-anchor", "end")
+			// .attr("dx", "-.5em")
+			// .attr("dy", ".1em")
+			// .attr("transform", function() {
+			// 	return "rotate(-30)";
+			// });
+
+
+		// Draw the y-axis
+		svg.append("g")
+			.attr("class", "y axis")
+			.call(yAxis)
+			.append("text")
+			.attr("transform", "rotate(-90)")
+			// .attr("y", 6)
+			// .attr("dy", ".71em")
+			.style("text-anchor", "end");
+
+
+		// Text for y-axis
+		// svg.append("text")
+		// 	.attr("transform", "rotate(-90)")
+		// 	.attr("y", 10 - margin.left)
+		// 	.attr("x", 0 - (height / 2))
+		// 	.attr("dy", "1em")
+		// 	.style("text-anchor", "middle")
+		// 	.text("Issues");
+
+
+		//Titel und Legende
+		// svg.append("svg:text")
+		// 	.attr("class", "text")
+		// 	.attr("x", 10)
+		// 	.attr("y", -5)
+		// 	.text("Issues Nach Zeit");
+
+		draw_line(svg, wish, "line wish", wishLine);
+		draw_line(svg, feature, "line feature", featureLine);
+		draw_line(svg, bug, "line bug", bugLine);
+		draw_line(svg, urgent, "line urgent", urgentLine);
+		draw_line(svg, critical, "line critical", criticalLine);
+
+
+		// makeLegend(svg, width);
+	}
+	// makeChart();
+
+</script>
--- a/modules/web_view/display_issues_techintern.py	Sun Jan 31 13:18:51 2016 +0100
+++ b/modules/web_view/display_issues_techintern.py	Sun Jan 31 15:21:18 2016 +0100
@@ -22,10 +22,13 @@
 
 from display_issues import *
 
+graph = os.path.dirname(os.path.realpath(__file__)) + '/bottledash_graph.html'
+
 def get_chart(target_div_name):
     html_string = compile_db_stats_html(
         rcd.DATABASE_TECH_INTERN,
-        rcd.SELECT_ALL
+        rcd.SELECT_ALL,
+        graph
     )
 
     html_string = html_string.replace(
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)