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