| CODENOTIFIER | HelpYou are not signed inSign in |
Project: dojo
Revision: 15168
Author: elazutkin
Date: 08 Sep 2008 02:00:27
Diff at Trac: http://trac.dojotoolkit.org/changeset/15168
Changes:gfx: fixing degenerated pies (no series, empty series, all non-positive,
only one value, only one positive value), a test case was added as well.
Fixes #7234. Fixes #6982. !strict
| ... | ...@@ -56,7 +56,7 @@ | |
| 56 | 56 | getRequiredColors: function(){ |
| 57 | 57 | return this.run ? this.run.data.length : 0; |
| 58 | 58 | }, |
| 59 | ||
| 59 | ||
| 60 | 60 | // events |
| 61 | 61 | plotEvent: function(o){ |
| 62 | 62 | // intentionally empty --- used for events |
| ... | ...@@ -92,13 +92,17 @@ | |
| 92 | 92 | this.plotEvent(o); |
| 93 | 93 | }); |
| 94 | 94 | }, |
| 95 | ||
| 95 | ||
| 96 | 96 | render: function(dim, offsets){ |
| 97 | 97 | if(!this.dirty){ return this; } |
| 98 | 98 | this.dirty = false; |
| 99 | 99 | this.cleanGroup(); |
| 100 | 100 | var s = this.group, color, t = this.chart.theme; |
| 101 | 101 | |
| 102 | if(!this.run || !this.run.data.length){ | |
| 103 | return this; | |
| 104 | } | |
| 105 | ||
| 102 | 106 | // calculate the geometry |
| 103 | 107 | var rx = (dim.width - offsets.l - offsets.r) / 2, |
| 104 | 108 | ry = (dim.height - offsets.t - offsets.b) / 2, |
| ... | ...@@ -106,22 +110,29 @@ | |
| 106 | 110 | taFont = "font" in this.opt ? this.opt.font : t.axis.font, |
| 107 | 111 | size = taFont ? g.normalizedLength(g.splitFontString(taFont).size) : 0, |
| 108 | 112 | taFontColor = "fontColor" in this.opt ? this.opt.fontColor : t.axis.fontColor, |
| 109 | start = 0, step, sum, slices, labels, shift, labelR, | |
| 113 | start = 0, step, filteredRun, slices, labels, shift, labelR, | |
| 110 | 114 | run = this.run.data, |
| 111 | 115 | events = this.events(); |
| 112 | 116 | if(typeof run[0] == "number"){ |
| 113 | sum = df.foldl1(run, "+"); | |
| 114 | slices = dojo.map(run, function(x){ return x / sum; }); | |
| 117 | filteredRun = df.map(run, "Math.max(x, 0)"); | |
| 118 | if(df.every(filteredRun, "<= 0")){ | |
| 119 | return this; | |
| 120 | } | |
| 121 | slices = df.map(filteredRun, "/this", df.foldl(filteredRun, "+", 0)); | |
| 115 | 122 | if(this.opt.labels){ |
| 116 | 123 | labels = dojo.map(slices, function(x){ |
| 117 | return this._getLabel(x * 100) + "%"; | |
| 124 | return x > 0 ? this._getLabel(x * 100) + "%" : ""; | |
| 118 | 125 | }, this); |
| 119 | 126 | } |
| 120 | 127 | }else{ |
| 121 | sum = df.foldl1(run, function(a, b){ return {y: a.y + b.y}; }).y; | |
| 122 | slices = df.map(run, function(x){ return x.y / sum; }); | |
| 128 | filteredRun = df.map(run, "Math.max(x.y, 0)"); | |
| 129 | if(df.every(filteredRun, "<= 0")){ | |
| 130 | return this; | |
| 131 | } | |
| 132 | slices = df.map(filteredRun, "/this", df.foldl(filteredRun, "+", 0)); | |
| 123 | 133 | if(this.opt.labels){ |
| 124 | 134 | labels = dojo.map(slices, function(x, i){ |
| 135 | if(x <= 0){ return ""; } | |
| 125 | 136 | var v = run[i]; |
| 126 | 137 | return "text" in v ? v.text : this._getLabel(x * 100) + "%"; |
| 127 | 138 | }, this); |
| ... | ...@@ -146,30 +157,49 @@ | |
| 146 | 157 | r: r |
| 147 | 158 | }; |
| 148 | 159 | |
| 149 | this.dyn = []; | |
| 150 | if(!this.run || !run.length){ | |
| 151 | return this; | |
| 152 | } | |
| 153 | if(run.length == 1){ | |
| 154 | // need autogenerated color | |
| 155 | color = new dojo.Color(t.next("color")); | |
| 156 | var shape = s.createCircle(circle). | |
| 157 | setFill(dc.augmentFill(t.run.fill, color)). | |
| 158 | setStroke(dc.augmentStroke(t.series.stroke, color)); | |
| 159 | this.dyn.push({color: color, fill: shape.getFill(), stroke: shape.getStroke()}); | |
| 160 | if(this.opt.labels){ | |
| 161 | // draw the label | |
| 162 | var elem = da.createText[this.opt.htmlLabels && dojox.gfx.renderer != "vml" ? "html" : "gfx"] | |
| 163 | (this.chart, s, circle.cx, circle.cy + size / 2, "middle", | |
| 164 | "100%", taFont, taFontColor); | |
| 165 | if(this.opt.htmlLabels){ this.htmlElements.push(elem); } | |
| 166 | } | |
| 167 | return this; | |
| 168 | } | |
| 160 | this.dyn = []; | |
| 169 | 161 | // draw slices |
| 170 | dojo.forEach(slices, function(x, i){ | |
| 162 | dojo.some(slices, function(slice, i){ | |
| 163 | if(slice <= 0){ | |
| 164 | // degenerated slice | |
| 165 | return false; // continue | |
| 166 | } | |
| 167 | var v = run[i]; | |
| 168 | if(slice >= 1){ | |
| 169 | // whole pie | |
| 170 | var color, fill, stroke; | |
| 171 | if(typeof v == "object"){ | |
| 172 | color = "color" in v ? v.color : new dojo.Color(t.next("color")); | |
| 173 | fill = "fill" in v ? v.fill : dc.augmentFill(t.series.fill, color); | |
| 174 | stroke = "stroke" in v ? v.stroke : dc.augmentStroke(t.series.stroke, color); | |
| 175 | }else{ | |
| 176 | color = new dojo.Color(t.next("color")); | |
| 177 | fill = dc.augmentFill(t.series.fill, color); | |
| 178 | stroke = dc.augmentStroke(t.series.stroke, color); | |
| 179 | } | |
| 180 | var shape = s.createCircle(circle).setFill(fill).setStroke(stroke); | |
| 181 | this.dyn.push({color: color, fill: fill, stroke: stroke}); | |
| 182 | ||
| 183 | if(events){ | |
| 184 | var o = { | |
| 185 | element: "slice", | |
| 186 | index: i, | |
| 187 | run: this.run, | |
| 188 | plot: this, | |
| 189 | shape: shape, | |
| 190 | x: i, | |
| 191 | y: typeof v == "number" ? v : v.y, | |
| 192 | cx: circle.cx, | |
| 193 | cy: circle.cy, | |
| 194 | cr: r | |
| 195 | }; | |
| 196 | this._connectEvents(shape, o); | |
| 197 | } | |
| 198 | ||
| 199 | return true; // stop iteration | |
| 200 | } | |
| 171 | 201 | // calculate the geometry of the slice |
| 172 | var end = start + x * 2 * Math.PI, v = run[i]; | |
| 202 | var end = start + slice * 2 * Math.PI; | |
| 173 | 203 | if(i + 1 == slices.length){ |
| 174 | 204 | end = 2 * Math.PI; |
| 175 | 205 | } |
| ... | ...@@ -198,7 +228,7 @@ | |
| 198 | 228 | setFill(fill). |
| 199 | 229 | setStroke(stroke); |
| 200 | 230 | this.dyn.push({color: color, fill: fill, stroke: stroke}); |
| 201 | ||
| 231 | ||
| 202 | 232 | if(events){ |
| 203 | 233 | var o = { |
| 204 | 234 | element: "slice", |
| ... | ...@@ -214,13 +244,27 @@ | |
| 214 | 244 | }; |
| 215 | 245 | this._connectEvents(shape, o); |
| 216 | 246 | } |
| 217 | ||
| 247 | ||
| 218 | 248 | start = end; |
| 249 | ||
| 250 | return false; // continue | |
| 219 | 251 | }, this); |
| 220 | 252 | // draw labels |
| 221 | 253 | if(this.opt.labels){ |
| 222 | 254 | start = 0; |
| 223 | dojo.forEach(slices, function(slice, i){ | |
| 255 | dojo.some(slices, function(slice, i){ | |
| 256 | if(slice <= 0){ | |
| 257 | // degenerated slice | |
| 258 | return false; // continue | |
| 259 | } | |
| 260 | if(slice >= 1){ | |
| 261 | // whole pie | |
| 262 | var v = run[i], elem = da.createText[this.opt.htmlLabels && dojox.gfx.renderer != "vml" ? "html" : "gfx"] | |
| 263 | (this.chart, s, circle.cx, circle.cy + size / 2, "middle", | |
| 264 | labels[i], taFont, (typeof v == "object" && "fontColor" in v) ? v.fontColor : taFontColor); | |
| 265 | if(this.opt.htmlLabels){ this.htmlElements.push(elem); } | |
| 266 | return true; // stop iteration | |
| 267 | } | |
| 224 | 268 | // calculate the geometry of the slice |
| 225 | 269 | var end = start + slice * 2 * Math.PI, v = run[i]; |
| 226 | 270 | if(i + 1 == slices.length){ |
| ... | ...@@ -232,16 +276,17 @@ | |
| 232 | 276 | // draw the label |
| 233 | 277 | var elem = da.createText[this.opt.htmlLabels && dojox.gfx.renderer != "vml" ? "html" : "gfx"] |
| 234 | 278 | (this.chart, s, x, y, "middle", |
| 235 | labels[i], taFont, | |
| 236 | (typeof v == "object" && "fontColor" in v) | |
| 279 | labels[i], taFont, | |
| 280 | (typeof v == "object" && "fontColor" in v) | |
| 237 | 281 | ? v.fontColor : taFontColor); |
| 238 | 282 | if(this.opt.htmlLabels){ this.htmlElements.push(elem); } |
| 239 | 283 | start = end; |
| 284 | return false; // continue | |
| 240 | 285 | }, this); |
| 241 | 286 | } |
| 242 | 287 | return this; |
| 243 | 288 | }, |
| 244 | ||
| 289 | ||
| 245 | 290 | // utilities |
| 246 | 291 | _getLabel: function(number){ |
| 247 | 292 | return this.opt.fixed ? number.toFixed(this.opt.precision) : number.toString(); |
| ... | ...@@ -25,14 +25,16 @@ | |
| 25 | 25 | dojo.require("dojox.charting.themes.PlotKit.blue"); |
| 26 | 26 | dojo.require("dojox.charting.themes.PlotKit.green"); |
| 27 | 27 | dojo.require("dojox.charting.themes.PlotKit.red"); |
| 28 | dojo.require("dojox.charting.themes.Adobebricks"); | |
| 29 | dojo.require("dojox.charting.themes.Algae"); | |
| 28 | 30 | |
| 29 | 31 | makeObjects = function(){ |
| 30 | 32 | var chart1 = new dojox.charting.Chart2D("test1"); |
| 31 | 33 | chart1.setTheme(dojox.charting.themes.PlotKit.blue); |
| 32 | 34 | chart1.addPlot("default", { |
| 33 | type: "Pie", | |
| 34 | font: "normal normal bold 12pt Tahoma", | |
| 35 | fontColor: "white", | |
| 35 | type: "Pie", | |
| 36 | font: "normal normal bold 12pt Tahoma", | |
| 37 | fontColor: "white", | |
| 36 | 38 | labelOffset: 40 |
| 37 | 39 | }); |
| 38 | 40 | chart1.addSeries("Series A", [4, 2, 1, 1]); |
| ... | ...@@ -41,9 +43,9 @@ | |
| 41 | 43 | var chart2 = new dojox.charting.Chart2D("test2"); |
| 42 | 44 | chart2.setTheme(dojox.charting.themes.PlotKit.blue); |
| 43 | 45 | chart2.addPlot("default", { |
| 44 | type: "Pie", | |
| 45 | font: "normal normal bold 12pt Tahoma", | |
| 46 | fontColor: "black", | |
| 46 | type: "Pie", | |
| 47 | font: "normal normal bold 12pt Tahoma", | |
| 48 | fontColor: "black", | |
| 47 | 49 | labelOffset: -25, |
| 48 | 50 | precision: 0 |
| 49 | 51 | }); |
| ... | ...@@ -53,10 +55,10 @@ | |
| 53 | 55 | var chart3 = new dojox.charting.Chart2D("test3"); |
| 54 | 56 | chart3.setTheme(dojox.charting.themes.PlotKit.green); |
| 55 | 57 | chart3.addPlot("default", { |
| 56 | type: "Pie", | |
| 57 | font: "normal normal bold 10pt Tahoma", | |
| 58 | fontColor: "white", | |
| 59 | labelOffset: 25, | |
| 58 | type: "Pie", | |
| 59 | font: "normal normal bold 10pt Tahoma", | |
| 60 | fontColor: "white", | |
| 61 | labelOffset: 25, | |
| 60 | 62 | radius: 90 |
| 61 | 63 | }); |
| 62 | 64 | chart3.addSeries("Series A", [4, 2, 1, 1]); |
| ... | ...@@ -65,10 +67,10 @@ | |
| 65 | 67 | var chart4 = new dojox.charting.Chart2D("test4"); |
| 66 | 68 | chart4.setTheme(dojox.charting.themes.PlotKit.green); |
| 67 | 69 | chart4.addPlot("default", { |
| 68 | type: "Pie", | |
| 69 | font: "normal normal bold 10pt Tahoma", | |
| 70 | fontColor: "black", | |
| 71 | labelOffset: -25, | |
| 70 | type: "Pie", | |
| 71 | font: "normal normal bold 10pt Tahoma", | |
| 72 | fontColor: "black", | |
| 73 | labelOffset: -25, | |
| 72 | 74 | radius: 90 |
| 73 | 75 | }); |
| 74 | 76 | chart4.addSeries("Series A", [4, 2, 1, 1]); |
| ... | ...@@ -77,9 +79,9 @@ | |
| 77 | 79 | var chart5 = new dojox.charting.Chart2D("test5"); |
| 78 | 80 | chart5.setTheme(dojox.charting.themes.PlotKit.red); |
| 79 | 81 | chart5.addPlot("default", { |
| 80 | type: "Pie", | |
| 81 | font: "normal normal bold 14pt Tahoma", | |
| 82 | fontColor: "white", | |
| 82 | type: "Pie", | |
| 83 | font: "normal normal bold 14pt Tahoma", | |
| 84 | fontColor: "white", | |
| 83 | 85 | labelOffset: 40 |
| 84 | 86 | }); |
| 85 | 87 | chart5.addSeries("Series A", [{y: 4, text: "Red"}, {y: 2, text: "Green"}, {y: 1, text: "Blue"}, {y: 1, text: "Other"}]); |
| ... | ...@@ -88,9 +90,9 @@ | |
| 88 | 90 | var chart6 = new dojox.charting.Chart2D("test6"); |
| 89 | 91 | chart6.setTheme(dojox.charting.themes.PlotKit.red); |
| 90 | 92 | chart6.addPlot("default", { |
| 91 | type: "Pie", | |
| 92 | font: "normal normal bold 14pt Tahoma", | |
| 93 | fontColor: "white", | |
| 93 | type: "Pie", | |
| 94 | font: "normal normal bold 14pt Tahoma", | |
| 95 | fontColor: "white", | |
| 94 | 96 | labelOffset: 40 |
| 95 | 97 | }); |
| 96 | 98 | chart6.addSeries("Series A", [ |
| ... | ...@@ -100,6 +102,33 @@ | |
| 100 | 102 | {y: 1, text: "Other", color: "white", fontColor: "black"} |
| 101 | 103 | ]); |
| 102 | 104 | chart6.render(); |
| 105 | ||
| 106 | var chart7 = new dojox.charting.Chart2D("test7"); | |
| 107 | chart7.setTheme(dojox.charting.themes.Adobebricks); | |
| 108 | chart7.addPlot("default", { | |
| 109 | type: "Pie", | |
| 110 | font: "normal normal bold 12pt Tahoma", | |
| 111 | fontColor: "white", | |
| 112 | radius: 80 | |
| 113 | }); | |
| 114 | chart7.addSeries("Series A", [4]); | |
| 115 | chart7.render(); | |
| 116 | ||
| 117 | var chart8 = new dojox.charting.Chart2D("test8"); | |
| 118 | chart8.setTheme(dojox.charting.themes.Algae); | |
| 119 | chart8.addPlot("default", { | |
| 120 | type: "Pie", | |
| 121 | font: "normal normal bold 12pt Tahoma", | |
| 122 | fontColor: "white", | |
| 123 | radius: 80 | |
| 124 | }); | |
| 125 | chart8.addSeries("Series A", [ | |
| 126 | {y: -1, text: "Red", color: "red"}, | |
| 127 | {y: 5, text: "Green", color: "green"}, | |
| 128 | {y: 0, text: "Blue", color: "blue"}, | |
| 129 | {y: 0, text: "Other", color: "white", fontColor: "black"} | |
| 130 | ]); | |
| 131 | chart8.render(); | |
| 103 | 132 | }; |
| 104 | 133 | |
| 105 | 134 | dojo.addOnLoad(makeObjects); |
| ... | ...@@ -123,6 +152,10 @@ | |
| 123 | 152 | <td><div id="test5" style="width: 300px; height: 300px;"></div></td> |
| 124 | 153 | <td><div id="test6" style="width: 300px; height: 300px;"></div></td> |
| 125 | 154 | </tr></table> |
| 155 | <p>7: Degenerated pie with 1 element.</p> | |
| 156 | <div id="test7" style="width: 200px; height: 200px;"></div> | |
| 157 | <p>8: Degenerated pie with 1 positive elements (out of 5).</p> | |
| 158 | <div id="test8" style="width: 200px; height: 200px;"></div> | |
| 126 | 159 | <p>That's all Folks!</p> |
| 127 | 160 | </body> |
| 128 | 161 | </html> |