Mercurial > bottledash
annotate modules/roundup_cc/graph.html @ 13:63b9f41c3008
made the charts a bit more modular - can now define the div_name and the script name in the .conf data
author | sean |
---|---|
date | Wed, 05 Aug 2015 12:37:33 +0200 |
parents | 50f4c64834cb |
children |
rev | line source |
---|---|
11 | 1 <style type = text/css> |
2 | |
3 * { | |
4 font-family: "Sans-serif"; | |
5 font-size: 14px; | |
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: 3px; | |
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 <script type="text/javascript"> | |
92 | |
93 // window.onresize = function(){ | |
94 // document.getElementsByClassName("chart")[0].innerHTML = ""; | |
95 // makeChart(); | |
96 // }; | |
97 | |
13
63b9f41c3008
made the charts a bit more modular - can now define the div_name and the script name in the .conf data
sean
parents:
12
diff
changeset
|
98 var d3jsInjectionTarget="X"; |
63b9f41c3008
made the charts a bit more modular - can now define the div_name and the script name in the .conf data
sean
parents:
12
diff
changeset
|
99 |
11 | 100 var critical=[]; |
12 | 101 var urgent=[]; |
102 var bug=[]; | |
103 var feature=[]; | |
104 var wish=[]; | |
105 var timestamp=[]; | |
11 | 106 |
107 // var critical=[ | |
108 // {points: 4}, | |
109 // {points: 12}, | |
110 // {points: 8}, | |
111 // {points: 2} | |
112 // ] | |
113 // | |
114 // var urgent=[ | |
115 // {points: 3}, | |
116 // {points: 24}, | |
117 // {points: 17}, | |
118 // {points: 19} | |
119 // ] | |
120 // | |
121 // var bug=[ | |
122 // {points: 10}, | |
123 // {points: 2}, | |
124 // {points: 2}, | |
125 // {points: 12} | |
126 // ] | |
127 // | |
128 // var feature=[ | |
129 // {points: 4}, | |
130 // {points: 21}, | |
131 // {points: 12}, | |
132 // {points: 4} | |
133 // ] | |
134 // | |
135 // var wish=[ | |
136 // {points: 22}, | |
137 // {points: 18}, | |
138 // {points: 32}, | |
139 // {points: 10} | |
140 // ] | |
141 // | |
142 // | |
143 // var timestamp=[ | |
144 // {date : new Date('2015-06-30T12:36:47')}, | |
145 // {date : new Date('2015-07-01T12:37:26')}, | |
146 // {date : new Date('2015-07-02T12:38:26')}, | |
147 // {date : new Date('2015-07-03T12:39:26')} | |
148 // ] | |
149 | |
150 document.addEventListener("DOMContentLoaded", function(event) { | |
151 makeChart(); | |
152 }); | |
153 | |
154 function assignIssueToDate(issueArray, dateArray){ | |
155 a = []; | |
156 for (var i = 0; i < issueArray.length; i++) { | |
157 a.push({points: issueArray[i].points, date : dateArray[i].date}); | |
158 } | |
159 | |
160 return a; | |
161 } | |
162 | |
163 function limitDatesOnXAxis(limit){ | |
164 if (timestamp.length < limit){ | |
165 return timestamp.length; | |
166 } else { | |
167 return limit; | |
168 } | |
169 } | |
170 | |
171 function maxInObject( array ){ | |
172 var maxVal = 0; | |
173 for (var i = 0; i < array.length; i++) { | |
174 if (maxVal < array[i].points){ | |
175 maxVal = array[i].points; | |
176 } | |
177 } | |
178 return maxVal; | |
179 } | |
180 | |
181 | |
182 function getMaxIssues(){ | |
183 maxIssuesOfAllArrays = []; | |
184 maxIssuesOfAllArrays.push(maxInObject(critical)); | |
185 maxIssuesOfAllArrays.push(maxInObject(urgent)); | |
186 maxIssuesOfAllArrays.push(maxInObject(bug)); | |
187 maxIssuesOfAllArrays.push(maxInObject(feature)); | |
188 maxIssuesOfAllArrays.push(maxInObject(wish)); | |
189 | |
190 return Math.max.apply(Math, maxIssuesOfAllArrays)+1; | |
191 } | |
192 | |
193 | |
194 function dayDifference(first, second) { | |
195 "use strict"; | |
196 var difference = (second - first) / (1000 * 60 * 60 * 24); | |
197 | |
198 // just to avoid the get thousands of lines... would look ugly. | |
199 if (difference > 60){ | |
200 difference = 60; | |
201 } | |
202 | |
203 return difference; | |
204 } | |
205 | |
206 | |
207 // function for the grid lines | |
208 function makeGrid(direction, orientation, ticknumber) { | |
209 return d3.svg.axis() | |
210 .scale(direction) | |
211 .orient(orientation) | |
212 .ticks( ticknumber ); | |
213 } | |
214 | |
215 | |
216 //append a svg_path. pretty generic | |
217 function draw_line(svg, data_array, css_class, line_object, lineShape){ | |
218 svg.append("path") | |
219 .datum(assignIssueToDate(data_array, timestamp)) | |
220 .attr("class", css_class) | |
221 .style("stroke-dasharray", (lineShape)) | |
222 .attr("d", line_object); | |
223 } | |
224 | |
225 | |
226 function makeLegend(svg, width){ | |
227 | |
228 var legend_distance = width+40; | |
229 var top_distance = 20; | |
230 var distance_steps = 50; | |
231 | |
232 | |
233 function set_propper_distance(steps){ | |
234 top_distance += steps; | |
235 return top_distance; | |
236 } | |
237 | |
238 function draw_legend_line(svg, width, Ypos, text, issues){ | |
239 svg.append("svg:text") | |
240 .attr("class", "legend") | |
241 .attr("x", width-30 ) | |
242 .attr("y", Ypos) | |
243 .text(text + ":"); | |
244 | |
245 svg.append("svg:text") | |
246 .attr("class", "legend") | |
247 .attr("x", width+35 ) | |
248 .attr("y", Ypos) | |
249 .text(issues); | |
250 | |
251 svg.append("rect") | |
252 .attr("class", "line " + text.toLowerCase() + " legend") | |
253 .attr("x", width-30) | |
254 .attr("y", Ypos-20) | |
255 .attr("width", 100) | |
256 .attr("height", 2); | |
257 } | |
258 | |
259 draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Critical", critical[critical.length-1].points); | |
260 draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Urgent", urgent[urgent.length-1].points); | |
261 draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Bug", bug[bug.length-1].points); | |
262 draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Feature", feature[feature.length-1].points); | |
263 draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Wish", wish[wish.length-1].points); | |
264 } | |
265 | |
266 | |
267 | |
268 //draw the chart | |
13
63b9f41c3008
made the charts a bit more modular - can now define the div_name and the script name in the .conf data
sean
parents:
12
diff
changeset
|
269 function makeChart(div_name){ |
11 | 270 |
271 //declaration | |
272 var sizeOfSystemBorders = 20; | |
273 // var margin = {top: 20, right: 100, bottom: 90, left: 60}; | |
274 // var margin = {top: 0, right: 0, bottom: 0, left: 0} | |
275 | |
276 var width = document.getElementsByClassName("chart")[0].clientWidth; | |
277 var height = document.getElementsByClassName("chart")[0].clientHeight; | |
278 // var width = (document.documentElement.clientWidth-sizeOfSystemBorders) - margin.left - margin.right; | |
279 // var height = (document.documentElement.clientHeight-sizeOfSystemBorders) - margin.top - margin.bottom; | |
280 | |
281 var x = d3.time.scale() | |
282 .range([0, width]); | |
283 | |
284 var y = d3.scale.linear() | |
285 .range([height, 0]); | |
286 | |
287 var base_line = d3.svg.line() | |
288 .x(function(d) { return x(d.date); }) | |
289 .y(function(d) { return y(d.points); }); | |
290 | |
291 //lines | |
292 var criticalLine = base_line; | |
293 var urgentLine = base_line; | |
294 var bugLine = base_line; | |
295 var featureLine = base_line; | |
296 var wishLine = base_line; | |
297 var timestampLine = base_line; | |
298 | |
299 | |
300 //set domain of y axis | |
301 var yDomain = [ ]; | |
302 yDomain[0] = 0; | |
303 yDomain[1] = getMaxIssues(); | |
304 y.domain(d3.extent(yDomain, function(d){return d; })); | |
305 | |
306 //set domain of y axis | |
307 x.domain(d3.extent(timestamp, function(d){return d.date; })); | |
308 | |
309 | |
310 var xAxis = d3.svg.axis() | |
311 .scale(x) | |
312 .orient("bottom") | |
313 .ticks(limitDatesOnXAxis(10)) | |
314 .tickFormat(d3.time.format("%d.%m")); | |
315 // .tickFormat(d3.time.format("%d.%m:%H:%M")); | |
316 // .tickFormat(d3.time.format("%X")); | |
317 // .tickFormat(d3.time.format.iso); | |
318 | |
319 | |
320 var yAxis = d3.svg.axis() | |
321 .scale(y) | |
322 .orient("left"); | |
323 | |
324 | |
13
63b9f41c3008
made the charts a bit more modular - can now define the div_name and the script name in the .conf data
sean
parents:
12
diff
changeset
|
325 var svg = d3.select("." + d3jsInjectionTarget) |
11 | 326 .append("svg") |
327 .attr("class", "svg") | |
328 // .attr("width", width) | |
329 // .attr("height", height) | |
330 .attr("width", width-20) | |
331 .attr("height", height-10) | |
332 .append("g") | |
333 // .attr("transform", "translate( +50,+0,+0,+0)"); | |
334 .attr("transform", "translate(40 , 0)"); | |
335 | |
336 | |
337 // creation | |
338 | |
339 | |
340 // Draw the x Grid lines | |
341 // svg.append("g") | |
342 // .attr("class", "grid") | |
343 // .attr("transform", "translate(0," + height + ")") | |
344 // .call(makeGrid(x, "bottom", timestamp.length) | |
345 // .tickSize(-height, 0, 0) | |
346 // .tickFormat("") | |
347 // ); | |
348 | |
349 | |
350 // Draw the y Grid lines | |
351 svg.append("g") | |
352 .attr("class", "grid") | |
353 .call(makeGrid(y, "left", function(){return Math.min(getMaxIssues(), 10);}()) | |
354 .tickSize(-width, 0, 0) | |
355 .tickFormat("") | |
356 ); | |
357 | |
358 | |
359 // Draw the x-axis | |
360 svg.append("g") | |
361 .attr("class", "x axis") | |
362 // .attr("transform", "translate(0, " + 20-height + ")") | |
363 .call(xAxis) | |
364 .selectAll("text") | |
365 .style("text-anchor", "end") | |
366 // .attr("dx", "-.5em") | |
367 // .attr("dy", ".1em") | |
368 // .attr("transform", function() { | |
369 // return "rotate(-30)"; | |
370 // }); | |
371 | |
372 | |
373 // Draw the y-axis | |
374 svg.append("g") | |
375 .attr("class", "y axis") | |
376 .call(yAxis) | |
377 .append("text") | |
378 .attr("transform", "rotate(-90)") | |
379 .attr("y", 6) | |
380 .attr("dy", ".71em") | |
381 .style("text-anchor", "end"); | |
382 | |
383 | |
384 // Text for y-axis | |
385 // svg.append("text") | |
386 // .attr("transform", "rotate(-90)") | |
387 // .attr("y", 10 - margin.left) | |
388 // .attr("x", 0 - (height / 2)) | |
389 // .attr("dy", "1em") | |
390 // .style("text-anchor", "middle") | |
391 // .text("Issues"); | |
392 | |
393 | |
394 //Titel und Legende | |
395 // svg.append("svg:text") | |
396 // .attr("class", "text") | |
397 // .attr("x", 10) | |
398 // .attr("y", -5) | |
399 // .text("Issues Nach Zeit"); | |
400 | |
401 draw_line(svg, wish, "line wish", wishLine, "0, 0"); | |
402 draw_line(svg, feature, "line feature", featureLine, "3, 3"); | |
403 draw_line(svg, bug, "line bug", bugLine, "7, 7"); | |
404 draw_line(svg, urgent, "line urgent", urgentLine, "13, 13"); | |
405 draw_line(svg, critical, "line critical", criticalLine, "17, 17"); | |
406 | |
407 | |
408 // makeLegend(svg, width); | |
409 } | |
410 | |
411 | |
412 </script> |