]>
git.proxmox.com Git - extjs.git/blob - extjs/packages/charts/src/chart/series/sprite/PieSlice.js
2 * @class Ext.chart.series.sprite.PieSlice
6 Ext
.define('Ext.chart.series.sprite.PieSlice', {
7 extend
: 'Ext.draw.sprite.Sector',
9 markerHolder
: 'Ext.chart.MarkerHolder'
11 alias
: 'sprite.pieslice',
17 * @cfg {Boolean} [doCallout=true]
18 * 'true' if the pie series uses label callouts.
23 * @cfg {String} [label='']
24 * Label associated with the Pie sprite.
28 // @deprecated Use series.label.orientation config instead.
33 * @cfg {Number} [labelOverflowPadding=10]
34 * Padding around labels to determine overlap.
35 * Any negative number allows the labels to overlap.
37 labelOverflowPadding
: 'number',
45 labelOverflowPadding
: 10,
54 * @cfg {Object} rendererData The object that is passed to the renderer.
56 * For instance when the PieSlice sprite is used in a Gauge chart, the object
57 * contains the 'store' and 'angleField' properties, and the 'value' as well
58 * for that one PieSlice that is used to draw the needle of the Gauge.
65 setGradientBBox: function (ctx
, rect
) {
68 hasGradients
= (attr
.fillStyle
&& attr
.fillStyle
.isGradient
) ||
69 (attr
.strokeStyle
&& attr
.strokeStyle
.isGradient
);
71 if (hasGradients
&& !attr
.constrainGradients
) {
72 var midAngle
= me
.getMidAngle(),
78 scaleX
= matrix
.getScaleX(),
79 scaleY
= matrix
.getScaleY(),
87 cx
+= margin
* Math
.cos(midAngle
);
88 cy
+= margin
* Math
.sin(midAngle
);
90 bbox
.x
= matrix
.x(cx
, cy
) - w
;
91 bbox
.y
= matrix
.y(cx
, cy
) - h
;
92 ctx
.setGradientBBox(bbox
);
94 me
.callParent([ctx
, rect
]);
98 render: function (surface
, ctx
, clip
, rect
) {
108 centerX
: attr
.centerX
,
109 centerY
: attr
.centerY
,
111 startAngle
: Math
.min(attr
.startAngle
, attr
.endAngle
),
112 endAngle
: Math
.max(attr
.startAngle
, attr
.endAngle
),
113 startRho
: Math
.min(attr
.startRho
, attr
.endRho
),
114 endRho
: Math
.max(attr
.startRho
, attr
.endRho
)
116 changes
= Ext
.callback(attr
.renderer
, null,
117 [me
, itemCfg
, me
.rendererData
, me
.rendererIndex
], 0, me
.getSeries());
118 me
.setAttributes(changes
);
119 me
.useAttributes(ctx
, clip
);
123 me
.callParent([surface
, ctx
, clip
, rect
]);
126 if (attr
.label
&& me
.getMarker('labels')) {
131 placeLabel: function () {
134 attributeId
= attr
.attributeId
,
135 startAngle
= Math
.min(attr
.startAngle
, attr
.endAngle
),
136 endAngle
= Math
.max(attr
.startAngle
, attr
.endAngle
),
137 midAngle
= (startAngle
+ endAngle
) * 0.5,
138 margin
= attr
.margin
,
139 centerX
= attr
.centerX
,
140 centerY
= attr
.centerY
,
141 sinMidAngle
= Math
.sin(midAngle
),
142 cosMidAngle
= Math
.cos(midAngle
),
143 startRho
= Math
.min(attr
.startRho
, attr
.endRho
) + margin
,
144 endRho
= Math
.max(attr
.startRho
, attr
.endRho
) + margin
,
145 midRho
= (startRho
+ endRho
) * 0.5,
146 surfaceMatrix
= me
.surfaceMatrix
,
147 labelCfg
= me
.labelCfg
|| (me
.labelCfg
= {}),
148 label
= me
.getMarker('labels'),
149 labelTpl
= label
.getTemplate(),
150 calloutLine
= labelTpl
.getCalloutLine(),
151 calloutLineLength
= calloutLine
&& calloutLine
.length
|| 40,
152 labelBox
, x
, y
, changes
, params
;
154 surfaceMatrix
.appendMatrix(attr
.matrix
);
156 labelCfg
.text
= attr
.label
;
158 x
= centerX
+ cosMidAngle
* midRho
;
159 y
= centerY
+ sinMidAngle
* midRho
;
160 labelCfg
.x
= surfaceMatrix
.x(x
, y
);
161 labelCfg
.y
= surfaceMatrix
.y(x
, y
);
163 x
= centerX
+ cosMidAngle
* endRho
;
164 y
= centerY
+ sinMidAngle
* endRho
;
165 labelCfg
.calloutStartX
= surfaceMatrix
.x(x
, y
);
166 labelCfg
.calloutStartY
= surfaceMatrix
.y(x
, y
);
168 x
= centerX
+ cosMidAngle
* (endRho
+ calloutLineLength
);
169 y
= centerY
+ sinMidAngle
* (endRho
+ calloutLineLength
);
170 labelCfg
.calloutPlaceX
= surfaceMatrix
.x(x
, y
);
171 labelCfg
.calloutPlaceY
= surfaceMatrix
.y(x
, y
);
173 if (!attr
.rotateLabels
) {
174 labelCfg
.rotationRads
= 0;
176 Ext
.log
.warn("'series.style.rotateLabels' config is deprecated. " +
177 "Use 'series.label.orientation' config instead.");
180 switch (labelTpl
.attr
.orientation
) {
182 labelCfg
.rotationRads
= midAngle
+ Math
.atan2(
183 surfaceMatrix
.y(1, 0) - surfaceMatrix
.y(0, 0),
184 surfaceMatrix
.x(1, 0) - surfaceMatrix
.x(0, 0)
188 labelCfg
.rotationRads
= midAngle
+ Math
.atan2(
189 surfaceMatrix
.y(1, 0) - surfaceMatrix
.y(0, 0),
190 surfaceMatrix
.x(1, 0) - surfaceMatrix
.x(0, 0)
195 labelCfg
.calloutColor
= (calloutLine
&& calloutLine
.color
) || me
.attr
.fillStyle
;
197 if (calloutLine
.width
) {
198 labelCfg
.calloutWidth
= calloutLine
.width
;
201 labelCfg
.calloutHasLine
= false;
203 labelCfg
.globalAlpha
= attr
.globalAlpha
* attr
.fillOpacity
;
205 // If a slice is empty, don't display the label.
206 // This behavior can be overridden by a renderer.
207 labelCfg
.hidden
= (attr
.startAngle
== attr
.endAngle
);
209 if (labelTpl
.attr
.renderer
) {
210 params
= [me
.attr
.label
, label
, labelCfg
, me
.rendererData
, me
.rendererIndex
];
211 changes
= Ext
.callback(labelTpl
.attr
.renderer
, null, params
, 0, me
.getSeries());
212 if (typeof changes
=== 'string') {
213 labelCfg
.text
= changes
;
215 Ext
.apply(labelCfg
, changes
);
218 me
.putMarker('labels', labelCfg
, attributeId
);
220 labelBox
= me
.getMarkerBBox('labels', attributeId
, true);
222 if (attr
.doCallout
) {
223 if (labelTpl
.attr
.display
=== 'outside') {
224 me
.putMarker('labels', {
227 } else if (labelTpl
.attr
.display
=== 'inside') {
228 me
.putMarker('labels', {
232 me
.putMarker('labels', {
233 callout
: 1 - me
.sliceContainsLabel(attr
, labelBox
)
237 me
.putMarker('labels', {
238 globalAlpha
: me
.sliceContainsLabel(attr
, labelBox
)
244 sliceContainsLabel: function (attr
, bbox
) {
245 var padding
= attr
.labelOverflowPadding
,
246 middle
= (attr
.endRho
+ attr
.startRho
) / 2,
247 outer
= middle
+ (bbox
.width
+ padding
) / 2,
248 inner
= middle
- (bbox
.width
+ padding
) / 2,
249 sliceAngle
, l1
, l2
, l3
;
254 if (bbox
.width
+ padding
* 2 > (attr
.endRho
- attr
.startRho
)) {
257 l1
= Math
.sqrt(attr
.endRho
* attr
.endRho
- outer
* outer
);
258 l2
= Math
.sqrt(attr
.endRho
* attr
.endRho
- inner
* inner
);
259 sliceAngle
= Math
.abs(attr
.endAngle
- attr
.startAngle
);
260 l3
= (sliceAngle
> Math
.PI
/2 ? inner : Math.abs(Math.tan(sliceAngle / 2)) * inner
);
261 if (bbox
.height
+ padding
* 2 > Math
.min(l1
, l2
, l3
) * 2) {