Mercurial > bottledash
comparison modules/web_view/bottledash_graph.html @ 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 | |
children |
comparison
equal
deleted
inserted
replaced
42:8935152f5e19 | 43:2e2981af7d2d |
---|---|
1 <style type = text/css> | |
2 | |
3 * { | |
4 font-family: "Sans-serif"; | |
5 /*font-size: 20px;*/ | |
6 } | |
7 | |
8 .svg div{ | |
9 /*font: 10px;*/ | |
10 /*text-align: right;*/ | |
11 /*float: left;*/ | |
12 /*display: block;*/ | |
13 /*padding: 10px;*/ | |
14 /*margin: 10px;*/ | |
15 color: white; | |
16 } | |
17 | |
18 .axis path, | |
19 | |
20 .axis line { | |
21 fill: none; | |
22 stroke: lightgrey; | |
23 /*opacity: 0.7;*/ | |
24 stroke-width: 1px; | |
25 } | |
26 | |
27 .y.axis path { | |
28 display: none; | |
29 } | |
30 | |
31 .line { | |
32 fill: none; | |
33 stroke-width: 4px; | |
34 opacity: 1; | |
35 } | |
36 | |
37 .line.critical { | |
38 stroke: red; | |
39 } | |
40 | |
41 .line.critical.legend { | |
42 fill: red; | |
43 } | |
44 | |
45 .line.urgent { | |
46 stroke: orange; | |
47 } | |
48 | |
49 .line.urgent.legend { | |
50 fill: orange; | |
51 } | |
52 | |
53 .line.bug { | |
54 stroke: violet; | |
55 } | |
56 | |
57 .line.bug.legend { | |
58 fill: violet; | |
59 } | |
60 | |
61 .line.feature { | |
62 stroke: chartreuse; | |
63 style: stroke-dasharray; | |
64 } | |
65 | |
66 .line.feature.legend { | |
67 fill: chartreuse; | |
68 } | |
69 | |
70 .line.wish { | |
71 stroke: blue; | |
72 } | |
73 | |
74 .line.wish.legend { | |
75 fill: blue; | |
76 } | |
77 | |
78 .grid .tick { | |
79 stroke: lightgrey; | |
80 /*opacity: 0.7;*/ | |
81 } | |
82 | |
83 .grid path { | |
84 stroke-width: 0; | |
85 } | |
86 | |
87 </style> | |
88 | |
89 <!-- <div id="content" style="display: inline-block"></div> --> | |
90 <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script> --> | |
91 | |
92 <script type="text/javascript" src="static/d3.v3.min.js"></script> | |
93 | |
94 <script type="text/javascript"> | |
95 | |
96 var d3jsInjectionTarget="X"; | |
97 | |
98 // window.onresize = function(){ | |
99 // document.getElementById(d3jsInjectionTarget).innerHTML = ""; | |
100 // makeChart(); | |
101 // }; | |
102 | |
103 var critical=[]; | |
104 var urgent=[]; | |
105 var bug=[]; | |
106 var feature=[]; | |
107 var wish=[]; | |
108 var timestamp=[]; | |
109 | |
110 document.addEventListener("DOMContentLoaded", function(event) { | |
111 try { | |
112 document.getElementById(d3jsInjectionTarget).getElementsByClassName("svg")[0].innerHTML = "" | |
113 } catch (e) { | |
114 } | |
115 makeChart(); | |
116 }); | |
117 | |
118 function assignIssueToDate(issueArray, dateArray){ | |
119 a = []; | |
120 for (var i = 0; i < issueArray.length; i++) { | |
121 a.push({points: issueArray[i].points, date : dateArray[i].date}); | |
122 } | |
123 | |
124 return a; | |
125 } | |
126 | |
127 function limitDatesOnXAxis(limit){ | |
128 if (timestamp.length < limit){ | |
129 return timestamp.length; | |
130 } else { | |
131 return limit; | |
132 } | |
133 } | |
134 | |
135 function maxInObject( array ){ | |
136 var maxVal = 0; | |
137 for (var i = 0; i < array.length; i++) { | |
138 if (maxVal < array[i].points){ | |
139 maxVal = array[i].points; | |
140 } | |
141 } | |
142 return maxVal; | |
143 } | |
144 | |
145 | |
146 function getMaxIssues(){ | |
147 maxIssuesOfAllArrays = []; | |
148 maxIssuesOfAllArrays.push(maxInObject(critical)); | |
149 maxIssuesOfAllArrays.push(maxInObject(urgent)); | |
150 maxIssuesOfAllArrays.push(maxInObject(bug)); | |
151 maxIssuesOfAllArrays.push(maxInObject(feature)); | |
152 maxIssuesOfAllArrays.push(maxInObject(wish)); | |
153 | |
154 return Math.max.apply(Math, maxIssuesOfAllArrays)+1; | |
155 } | |
156 | |
157 | |
158 function dayDifference(first, second) { | |
159 "use strict"; | |
160 var difference = (second - first) / (1000 * 60 * 60 * 24); | |
161 | |
162 // just to avoid the get thousands of lines... would look ugly. | |
163 if (difference > 60){ | |
164 difference = 60; | |
165 } | |
166 | |
167 return difference; | |
168 } | |
169 | |
170 | |
171 // function for the grid lines | |
172 function makeGrid(direction, orientation, ticknumber) { | |
173 return d3.svg.axis() | |
174 .scale(direction) | |
175 .orient(orientation) | |
176 .ticks( ticknumber ); | |
177 } | |
178 | |
179 | |
180 //append a svg_path. pretty generic | |
181 function draw_line(svg, data_array, css_class, line_object){ | |
182 svg.append("path") | |
183 .datum(assignIssueToDate(data_array, timestamp)) | |
184 .attr("class", css_class) | |
185 .attr("d", line_object); | |
186 } | |
187 | |
188 | |
189 function makeLegend(svg, width){ | |
190 | |
191 var legend_distance = width+40; | |
192 var top_distance = 20; | |
193 var distance_steps = 50; | |
194 | |
195 | |
196 function set_propper_distance(steps){ | |
197 top_distance += steps; | |
198 return top_distance; | |
199 } | |
200 | |
201 function draw_legend_line(svg, width, Ypos, text, issues){ | |
202 svg.append("svg:text") | |
203 .attr("class", "legend") | |
204 .attr("x", width-30 ) | |
205 .attr("y", Ypos) | |
206 .text(text + ":"); | |
207 | |
208 svg.append("svg:text") | |
209 .attr("class", "legend") | |
210 .attr("x", width+35 ) | |
211 .attr("y", Ypos) | |
212 .text(issues); | |
213 | |
214 svg.append("rect") | |
215 .attr("class", "line " + text.toLowerCase() + " legend") | |
216 .attr("x", width-30) | |
217 .attr("y", Ypos-20) | |
218 .attr("width", 100) | |
219 .attr("height", 2); | |
220 } | |
221 | |
222 draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Critical", critical[critical.length-1].points); | |
223 draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Urgent", urgent[urgent.length-1].points); | |
224 draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Bug", bug[bug.length-1].points); | |
225 draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Feature", feature[feature.length-1].points); | |
226 draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Wish", wish[wish.length-1].points); | |
227 } | |
228 | |
229 | |
230 | |
231 //draw the chart | |
232 function makeChart(div_name){ | |
233 | |
234 //declaration | |
235 var targetDiv = document.getElementById(d3jsInjectionTarget) | |
236 // var sizeOfSystemBorders = 20; | |
237 | |
238 var margin = {top: 20, right: 10, bottom: 50, left:50} | |
239 | |
240 var width = targetDiv.clientWidth - margin.left - margin.right | |
241 var height = targetDiv.clientHeight - margin.top - margin.bottom | |
242 | |
243 var x = d3.time.scale() | |
244 .range([0, width]); | |
245 | |
246 var y = d3.scale.linear() | |
247 .range([height, 0]); | |
248 | |
249 var base_line = d3.svg.line() | |
250 .x(function(d) { return x(d.date); }) | |
251 .y(function(d) { return y(d.points); }); | |
252 | |
253 //lines | |
254 var criticalLine = base_line; | |
255 var urgentLine = base_line; | |
256 var bugLine = base_line; | |
257 var featureLine = base_line; | |
258 var wishLine = base_line; | |
259 var timestampLine = base_line; | |
260 | |
261 | |
262 //set domain of y axis | |
263 var yDomain = [ ]; | |
264 yDomain[0] = 0; | |
265 yDomain[1] = getMaxIssues(); | |
266 y.domain(d3.extent(yDomain, function(d){return d; })); | |
267 | |
268 //set domain of y axis | |
269 x.domain(d3.extent(timestamp, function(d){return d.date; })); | |
270 | |
271 | |
272 var xAxis = d3.svg.axis() | |
273 .scale(x) | |
274 .orient("bottom") | |
275 .ticks(limitDatesOnXAxis(10)) | |
276 .tickFormat(d3.time.format("%d.%m")); | |
277 | |
278 var yAxis = d3.svg.axis() | |
279 .scale(y) | |
280 .orient("left"); | |
281 | |
282 var svg = d3.select("#" + d3jsInjectionTarget) | |
283 .append("svg") | |
284 .attr("class", "svg") | |
285 .attr("width", width + margin.left + margin.right) | |
286 .attr("height", height + margin.top + margin.bottom) | |
287 .append("g") | |
288 .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
289 | |
290 | |
291 // creation | |
292 | |
293 | |
294 // Draw the x Grid lines | |
295 // svg.append("g") | |
296 // .attr("class", "grid") | |
297 // .attr("transform", "translate(0," + height + ")") | |
298 // .call(makeGrid(x, "bottom", timestamp.length) | |
299 // .tickSize(-height, 0, 0) | |
300 // .tickFormat("") | |
301 // ); | |
302 | |
303 | |
304 // Draw the y Grid lines | |
305 svg.append("g") | |
306 .attr("class", "grid") | |
307 .call(makeGrid(y, "left", function(){return Math.min(getMaxIssues(), 10);}()) | |
308 .tickSize(-width, 0, 0) | |
309 .tickFormat("") | |
310 ); | |
311 | |
312 | |
313 // Draw the x-axis | |
314 svg.append("g") | |
315 .attr("class", "x axis") | |
316 // .attr("transform", "translate(0, " + 20-height + ")") | |
317 .attr("transform", "translate(0," + height + ")") | |
318 .call(xAxis) | |
319 .selectAll("text") | |
320 // .style("text-anchor", "end") | |
321 // .attr("dx", "-.5em") | |
322 // .attr("dy", ".1em") | |
323 // .attr("transform", function() { | |
324 // return "rotate(-30)"; | |
325 // }); | |
326 | |
327 | |
328 // Draw the y-axis | |
329 svg.append("g") | |
330 .attr("class", "y axis") | |
331 .call(yAxis) | |
332 .append("text") | |
333 .attr("transform", "rotate(-90)") | |
334 // .attr("y", 6) | |
335 // .attr("dy", ".71em") | |
336 .style("text-anchor", "end"); | |
337 | |
338 | |
339 // Text for y-axis | |
340 // svg.append("text") | |
341 // .attr("transform", "rotate(-90)") | |
342 // .attr("y", 10 - margin.left) | |
343 // .attr("x", 0 - (height / 2)) | |
344 // .attr("dy", "1em") | |
345 // .style("text-anchor", "middle") | |
346 // .text("Issues"); | |
347 | |
348 | |
349 //Titel und Legende | |
350 // svg.append("svg:text") | |
351 // .attr("class", "text") | |
352 // .attr("x", 10) | |
353 // .attr("y", -5) | |
354 // .text("Issues Nach Zeit"); | |
355 | |
356 draw_line(svg, wish, "line wish", wishLine); | |
357 draw_line(svg, feature, "line feature", featureLine); | |
358 draw_line(svg, bug, "line bug", bugLine); | |
359 draw_line(svg, urgent, "line urgent", urgentLine); | |
360 draw_line(svg, critical, "line critical", criticalLine); | |
361 | |
362 | |
363 // makeLegend(svg, width); | |
364 } | |
365 // makeChart(); | |
366 | |
367 </script> |