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