]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | /**\r |
2 | * @class Ext.sparkline.Pie\r | |
3 | *\r | |
4 | * Plots a pie chart based upon the input {#values} array.\r | |
5 | *\r | |
6 | * See {@link Ext.sparkline.Base the base class} for a simple example.\r | |
7 | */\r | |
8 | Ext.define('Ext.sparkline.Pie', {\r | |
9 | extend: 'Ext.sparkline.Base',\r | |
10 | \r | |
11 | alias: 'widget.sparklinepie',\r | |
12 | \r | |
13 | config: {\r | |
14 | \r | |
15 | /**\r | |
16 | * @cfg {Number} [offset] Angle in degrees to offset the first slice.\r | |
17 | */\r | |
18 | offset: 0,\r | |
19 | \r | |
20 | /**\r | |
21 | * @cfg {String[]} [sliceColors] An array of CSS colro values to apply to the chart slices.\r | |
22 | */\r | |
23 | sliceColors: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00', '#dd4477', '#0099c6', '#990099'],\r | |
24 | \r | |
25 | /**\r | |
26 | * @cfg {Number} [borderWidth=0] Border width in pixels of line round slices.\r | |
27 | */\r | |
28 | borderWidth: 0,\r | |
29 | \r | |
30 | /**\r | |
31 | * @cfg {String} [borderColor=#000] Border color of line round slices.\r | |
32 | */\r | |
33 | borderColor: '#000',\r | |
34 | \r | |
35 | tipTpl: new Ext.XTemplate('● {value} ({percent:number("0.0")}%)')\r | |
36 | },\r | |
37 | \r | |
38 | // Ensure values is an array of numbers\r | |
39 | applyValues: function(newValues) {\r | |
40 | newValues = Ext.Array.map(Ext.Array.from(newValues), Number);\r | |
41 | this.disabled = !(newValues && newValues.length);\r | |
42 | return newValues;\r | |
43 | },\r | |
44 | \r | |
45 | onUpdate: function () {\r | |
46 | var me = this,\r | |
47 | values = me.values,\r | |
48 | total = 0, i;\r | |
49 | \r | |
50 | me.callParent(arguments);\r | |
51 | \r | |
52 | me.shapes = {}; // map shape ids to value offsets\r | |
53 | me.valueShapes = {}; // maps value offsets to shape ids\r | |
54 | \r | |
55 | if (values.length > 0) {\r | |
56 | for (i = values.length; i--;) {\r | |
57 | total += values[i];\r | |
58 | }\r | |
59 | }\r | |
60 | me.total = total;\r | |
61 | me.radius = Math.floor(Math.min(me.getWidth(), me.getHeight()) / 2);\r | |
62 | },\r | |
63 | \r | |
64 | getRegion: function(x, y) {\r | |
65 | var ratio = window.devicePixelRatio || 1,\r | |
66 | shapeid = this.canvas.getShapeAt(x * ratio, y * ratio);\r | |
67 | return (shapeid != null && this.shapes[shapeid] != null) ? this.shapes[shapeid] : null;\r | |
68 | },\r | |
69 | \r | |
70 | getRegionFields: function(region) {\r | |
71 | var sliceColors = this.getSliceColors();\r | |
72 | \r | |
73 | return {\r | |
74 | isNull: this.values[region] == null,\r | |
75 | value: this.values[region],\r | |
76 | percent: this.values[region] / this.total * 100,\r | |
77 | color: sliceColors[region % sliceColors.length],\r | |
78 | offset: region\r | |
79 | };\r | |
80 | },\r | |
81 | \r | |
82 | renderHighlight: function(region) {\r | |
83 | this.renderSlice(region, true).append();\r | |
84 | },\r | |
85 | \r | |
86 | renderSlice: function(valuenum, highlight) {\r | |
87 | var me = this,\r | |
88 | canvas = me.canvas,\r | |
89 | radius = me.radius,\r | |
90 | borderWidth = me.getBorderWidth(),\r | |
91 | offset = me.getOffset(),\r | |
92 | circle = 2 * Math.PI,\r | |
93 | values = me.values,\r | |
94 | total = me.total,\r | |
95 | next = offset ? (2*Math.PI)*(offset/360) : 0,\r | |
96 | start, end, i, vlen, color,\r | |
97 | sliceColors = this.getSliceColors();\r | |
98 | \r | |
99 | vlen = values.length;\r | |
100 | for (i = 0; i < vlen; i++) {\r | |
101 | start = next;\r | |
102 | end = next;\r | |
103 | if (total > 0) { // avoid divide by zero\r | |
104 | end = next + (circle * (values[i] / total));\r | |
105 | }\r | |
106 | if (valuenum === i) {\r | |
107 | color = sliceColors[i % sliceColors.length];\r | |
108 | if (highlight) {\r | |
109 | color = me.calcHighlightColor(color);\r | |
110 | }\r | |
111 | \r | |
112 | return canvas.drawPieSlice(radius, radius, radius - borderWidth, start, end, null, color);\r | |
113 | }\r | |
114 | next = end;\r | |
115 | }\r | |
116 | },\r | |
117 | \r | |
118 | renderGraph: function () {\r | |
119 | var me = this,\r | |
120 | canvas = me.canvas,\r | |
121 | values = me.values,\r | |
122 | radius = me.radius,\r | |
123 | borderWidth = me.getBorderWidth(),\r | |
124 | shape, i,\r | |
125 | shapes = me.shapes || (me.shapes = {}),\r | |
126 | valueShapes = me.valueShapes || (me.valueShapes = {});\r | |
127 | \r | |
128 | if (!me.callParent()) {\r | |
129 | return;\r | |
130 | }\r | |
131 | if (borderWidth) {\r | |
132 | canvas.drawCircle(radius, radius, Math.floor(radius - (borderWidth / 2)),\r | |
133 | me.getBorderColor(), null, borderWidth).append();\r | |
134 | }\r | |
135 | for (i = values.length; i--;) {\r | |
136 | if (values[i]) { // don't render zero values\r | |
137 | shape = me.renderSlice(i).append();\r | |
138 | valueShapes[i] = shape.id; // store just the shapeid\r | |
139 | shapes[shape.id] = i;\r | |
140 | }\r | |
141 | }\r | |
142 | \r | |
143 | // If mouse is over, re-apply the highlight\r | |
144 | if (me.currentPageXY && me.el.getRegion().contains(me.currentPageXY)) {\r | |
145 | me.currentRegion = null;\r | |
146 | me.updateDisplay();\r | |
147 | }\r | |
148 | canvas.render();\r | |
149 | }\r | |
150 | }); |