]>
git.proxmox.com Git - sencha-touch.git/blob - src/src/chart/series/sprite/PieSlice.js
2 * @class Ext.chart.series.sprite.PieSlice
6 Ext
.define('Ext.chart.series.sprite.PieSlice', {
7 alias
: 'sprite.pieslice',
9 markerHolder
: 'Ext.chart.MarkerHolder'
11 extend
: 'Ext.draw.sprite.Sector',
17 * @cfg {Boolean} [doCallout=true] 'true' if the pie series uses label callouts.
22 * @cfg {Boolean} [rotateLabels=true] 'true' if the labels are rotated for easier reading.
27 * @cfg {String} [label=''] Label associated with the Pie sprite.
32 * @cfg {Number} [labelOverflowPadding=10] Padding around labels to determine overlap.
33 * Any negative number allows the labels to overlap.
35 labelOverflowPadding
: 'number',
43 labelOverflowPadding
: 10,
52 * @cfg {Object} rendererData The object that is passed to the renderer.
54 * For instance when the PieSlice sprite is used in a Gauge chart, the object
55 * contains the 'store' and 'field' properties, and the 'value' as well
56 * for that one PieSlice that is used to draw the needle of the Gauge.
62 render: function (ctx
, surface
, clipRegion
) {
72 centerX
: attr
.centerX
,
73 centerY
: attr
.centerY
,
75 startAngle
: Math
.min(attr
.startAngle
, attr
.endAngle
),
76 endAngle
: Math
.max(attr
.startAngle
, attr
.endAngle
),
77 startRho
: Math
.min(attr
.startRho
, attr
.endRho
),
78 endRho
: Math
.max(attr
.startRho
, attr
.endRho
)
80 changes
= attr
.renderer
.call(me
, me
, itemCfg
, me
.rendererData
, me
.rendererIndex
);
81 Ext
.apply(me
.attr
, changes
);
85 me
.callSuper(arguments
);
88 if (attr
.label
&& me
.getBoundMarker('labels')) {
93 placeLabel: function () {
96 startAngle
= Math
.min(attr
.startAngle
, attr
.endAngle
),
97 endAngle
= Math
.max(attr
.startAngle
, attr
.endAngle
),
98 midAngle
= (startAngle
+ endAngle
) * 0.5,
100 centerX
= attr
.centerX
,
101 centerY
= attr
.centerY
,
102 startRho
= Math
.min(attr
.startRho
, attr
.endRho
) + margin
,
103 endRho
= Math
.max(attr
.startRho
, attr
.endRho
) + margin
,
104 midRho
= (startRho
+ endRho
) * 0.5,
105 surfaceMatrix
= me
.surfaceMatrix
,
106 labelCfg
= me
.labelCfg
|| (me
.labelCfg
= {}),
107 labelTpl
= me
.getBoundMarker('labels')[0].getTemplate(),
108 labelBox
, x
, y
, changes
;
110 surfaceMatrix
.appendMatrix(attr
.matrix
);
112 labelCfg
.text
= attr
.label
;
114 x
= centerX
+ Math
.cos(midAngle
) * midRho
;
115 y
= centerY
+ Math
.sin(midAngle
) * midRho
;
116 labelCfg
.x
= surfaceMatrix
.x(x
, y
);
117 labelCfg
.y
= surfaceMatrix
.y(x
, y
);
119 x
= centerX
+ Math
.cos(midAngle
) * endRho
;
120 y
= centerY
+ Math
.sin(midAngle
) * endRho
;
121 labelCfg
.calloutStartX
= surfaceMatrix
.x(x
, y
);
122 labelCfg
.calloutStartY
= surfaceMatrix
.y(x
, y
);
124 x
= centerX
+ Math
.cos(midAngle
) * (endRho
+ 40);
125 y
= centerY
+ Math
.sin(midAngle
) * (endRho
+ 40);
126 labelCfg
.calloutPlaceX
= surfaceMatrix
.x(x
, y
);
127 labelCfg
.calloutPlaceY
= surfaceMatrix
.y(x
, y
);
129 labelCfg
.rotationRads
= (attr
.rotateLabels
? midAngle
+ Math
.atan2(surfaceMatrix
.y(1, 0) - surfaceMatrix
.y(0, 0), surfaceMatrix
.x(1, 0) - surfaceMatrix
.x(0, 0)) : 0);
130 labelCfg
.calloutColor
= me
.attr
.fillStyle
;
131 labelCfg
.globalAlpha
= attr
.globalAlpha
* attr
.fillOpacity
;
133 // If a slice is empty, don't display the label.
134 // This behavior can be overridden by a renderer.
135 labelCfg
.hidden
= (attr
.startAngle
== attr
.endAngle
);
138 labelCfg
.type
= 'label';
139 changes
= attr
.renderer
.call(me
, me
, labelCfg
, me
.rendererData
, me
.rendererIndex
);
140 Ext
.apply(labelCfg
, changes
);
142 me
.putMarker('labels', labelCfg
, me
.attr
.attributeId
);
144 labelBox
= me
.getMarkerBBox('labels', me
.attr
.attributeId
, true);
146 if (attr
.doCallout
) {
147 if (labelTpl
.attr
.display
=== 'outside') {
148 me
.putMarker('labels', {callout
: 1}, me
.attr
.attributeId
);
150 me
.putMarker('labels', {callout
: 1 - +me
.sliceContainsLabel(attr
, labelBox
)}, me
.attr
.attributeId
);
153 me
.putMarker('labels', {globalAlpha
: +me
.sliceContainsLabel(attr
, labelBox
)}, me
.attr
.attributeId
);
158 sliceContainsLabel: function (attr
, bbox
) {
159 var padding
= attr
.labelOverflowPadding
,
160 middle
= (attr
.endRho
+ attr
.startRho
) / 2,
161 outer
= middle
+ (bbox
.width
+ padding
) / 2,
162 inner
= middle
- (bbox
.width
+ padding
) / 2,
163 sliceAngle
, l1
, l2
, l3
;
168 if (bbox
.width
+ padding
* 2 > (attr
.endRho
- attr
.startRho
)) {
171 l1
= Math
.sqrt(attr
.endRho
* attr
.endRho
- outer
* outer
);
172 l2
= Math
.sqrt(attr
.endRho
* attr
.endRho
- inner
* inner
);
173 sliceAngle
= Math
.abs(attr
.endAngle
- attr
.startAngle
);
174 l3
= (sliceAngle
> Math
.PI
/2 ? inner : Math.abs(Math.tan(sliceAngle / 2)) * inner
);
175 if (bbox
.height
+ padding
* 2 > Math
.min(l1
, l2
, l3
) * 2) {