init repo
This commit is contained in:
315
OfficeWeb/3rdparty/touch/src/chart/series/Pie.js
vendored
Normal file
315
OfficeWeb/3rdparty/touch/src/chart/series/Pie.js
vendored
Normal file
@@ -0,0 +1,315 @@
|
||||
/**
|
||||
* @class Ext.chart.series.Pie
|
||||
* @extends Ext.chart.series.Polar
|
||||
*
|
||||
* Creates a Pie Chart. A Pie Chart is a useful visualization technique to display quantitative information for different
|
||||
* categories that also have a meaning as a whole.
|
||||
* As with all other series, the Pie Series must be appended in the *series* Chart array configuration. See the Chart
|
||||
* documentation for more information. A typical configuration object for the pie series could be:
|
||||
*
|
||||
* @example preview
|
||||
* var chart = new Ext.chart.PolarChart({
|
||||
* animate: true,
|
||||
* interactions: ['rotate'],
|
||||
* colors: ["#115fa6", "#94ae0a", "#a61120", "#ff8809", "#ffd13e"],
|
||||
* store: {
|
||||
* fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
|
||||
* data: [
|
||||
* {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
|
||||
* {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
|
||||
* {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
|
||||
* {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
|
||||
* {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
|
||||
* ]
|
||||
* },
|
||||
* series: [{
|
||||
* type: 'pie',
|
||||
* labelField: 'name',
|
||||
* xField: 'data3',
|
||||
* donut: 30
|
||||
* }]
|
||||
* });
|
||||
* Ext.Viewport.setLayout('fit');
|
||||
* Ext.Viewport.add(chart);
|
||||
*
|
||||
* In this configuration we set `pie` as the type for the series, set an object with specific style properties for highlighting options
|
||||
* (triggered when hovering elements). We also set true to `showInLegend` so all the pie slices can be represented by a legend item.
|
||||
* We set `data1` as the value of the field to determine the angle span for each pie slice. We also set a label configuration object
|
||||
* where we set the field name of the store field to be renderer as text for the label. The labels will also be displayed rotated.
|
||||
* We set `contrast` to `true` to flip the color of the label if it is to similar to the background color. Finally, we set the font family
|
||||
* and size through the `font` parameter.
|
||||
*
|
||||
*/
|
||||
Ext.define('Ext.chart.series.Pie', {
|
||||
extend: 'Ext.chart.series.Polar',
|
||||
requires: [
|
||||
"Ext.chart.series.sprite.PieSlice"
|
||||
],
|
||||
type: 'pie',
|
||||
alias: 'series.pie',
|
||||
seriesType: 'pieslice',
|
||||
|
||||
config: {
|
||||
/**
|
||||
* @cfg {String} labelField
|
||||
* The store record field name to be used for the pie slice labels.
|
||||
*/
|
||||
labelField: false,
|
||||
|
||||
/**
|
||||
* @cfg {Boolean/Number} donut Whether to set the pie chart as donut chart.
|
||||
* Can be set to a particular percentage to set the radius of the donut chart.
|
||||
*/
|
||||
donut: false,
|
||||
|
||||
/**
|
||||
* @cfg {String} field
|
||||
* @deprecated Use xField directly
|
||||
*/
|
||||
field: null,
|
||||
|
||||
/**
|
||||
* @cfg {Number} rotation The starting angle of the pie slices.
|
||||
*/
|
||||
rotation: 0,
|
||||
|
||||
/**
|
||||
* @cfg {Number} [totalAngle=2*PI] The total angle of the pie series.
|
||||
*/
|
||||
totalAngle: Math.PI * 2,
|
||||
|
||||
/**
|
||||
* @cfg {Array} hidden Determines which pie slices are hidden.
|
||||
*/
|
||||
hidden: [],
|
||||
|
||||
style: {
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
directions: ['X'],
|
||||
|
||||
setField: function (f) {
|
||||
return this.setXField(f);
|
||||
},
|
||||
|
||||
getField: function () {
|
||||
return this.getXField();
|
||||
},
|
||||
|
||||
updateLabelData: function () {
|
||||
var me = this,
|
||||
store = me.getStore(),
|
||||
items = store.getData().items,
|
||||
sprites = me.getSprites(),
|
||||
labelField = me.getLabelField(),
|
||||
i, ln, labels;
|
||||
if (sprites.length > 0 && labelField) {
|
||||
labels = [];
|
||||
for (i = 0, ln = items.length; i < ln; i++) {
|
||||
labels.push(items[i].get(labelField));
|
||||
}
|
||||
for (i = 0, ln = sprites.length; i < ln; i++) {
|
||||
sprites[i].setAttributes({label: labels[i]});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
coordinateX: function () {
|
||||
var me = this,
|
||||
store = me.getStore(),
|
||||
items = store.getData().items,
|
||||
length = items.length,
|
||||
field = me.getXField(),
|
||||
value, sum = 0,
|
||||
hidden = me.getHidden(),
|
||||
summation = [], i,
|
||||
lastAngle = 0,
|
||||
totalAngle = me.getTotalAngle(),
|
||||
sprites = me.getSprites();
|
||||
|
||||
if (!sprites) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
value = items[i].get(field);
|
||||
if (!hidden[i]) {
|
||||
sum += value;
|
||||
}
|
||||
summation[i] = sum;
|
||||
if (i >= hidden.length) {
|
||||
hidden[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (sum === 0) {
|
||||
return;
|
||||
}
|
||||
sum = totalAngle / sum;
|
||||
for (i = 0; i < length; i++) {
|
||||
sprites[i].setAttributes({
|
||||
startAngle: lastAngle,
|
||||
endAngle: lastAngle = summation[i] * sum,
|
||||
globalAlpha: 1
|
||||
});
|
||||
}
|
||||
for (; i < me.sprites.length; i++) {
|
||||
sprites[i].setAttributes({
|
||||
startAngle: totalAngle,
|
||||
endAngle: totalAngle,
|
||||
globalAlpha: 0
|
||||
});
|
||||
}
|
||||
me.getChart().refreshLegendStore();
|
||||
},
|
||||
|
||||
updateCenter: function (center) {
|
||||
this.setStyle({
|
||||
translationX: center[0] + this.getOffsetX(),
|
||||
translationY: center[1] + this.getOffsetY()
|
||||
});
|
||||
this.doUpdateStyles();
|
||||
},
|
||||
|
||||
updateRadius: function (radius) {
|
||||
this.setStyle({
|
||||
startRho: radius * this.getDonut() * 0.01, // Percentage
|
||||
endRho: radius
|
||||
});
|
||||
this.doUpdateStyles();
|
||||
},
|
||||
|
||||
updateDonut: function (donut) {
|
||||
var radius = this.getRadius();
|
||||
this.setStyle({
|
||||
startRho: radius * donut * 0.01, // Percentage
|
||||
endRho: radius
|
||||
});
|
||||
this.doUpdateStyles();
|
||||
},
|
||||
|
||||
updateRotation: function (rotation) {
|
||||
this.setStyle({
|
||||
rotationRads: rotation
|
||||
});
|
||||
this.doUpdateStyles();
|
||||
},
|
||||
|
||||
updateTotalAngle: function (totalAngle) {
|
||||
this.processData();
|
||||
},
|
||||
|
||||
getSprites: function () {
|
||||
var me = this,
|
||||
chart = this.getChart(),
|
||||
store = me.getStore();
|
||||
if (!chart || !store) {
|
||||
return[];
|
||||
}
|
||||
me.getColors();
|
||||
me.getSubStyle();
|
||||
var items = store.getData().items,
|
||||
length = items.length,
|
||||
animation = chart && chart.getAnimate(),
|
||||
center = me.getCenter(),
|
||||
offsetX = me.getOffsetX(),
|
||||
offsetY = me.getOffsetY(),
|
||||
sprites = me.sprites, sprite,
|
||||
i, spriteCreated = false;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
sprite = sprites[i];
|
||||
if (!sprite) {
|
||||
sprite = me.createSprite();
|
||||
if (me.getHighlightCfg()) {
|
||||
sprite.config.highlightCfg = me.getHighlightCfg();
|
||||
sprite.addModifier('highlight', true);
|
||||
}
|
||||
if (me.getLabelField()) {
|
||||
me.getLabel().getTemplate().setAttributes({
|
||||
labelOverflowPadding: this.getLabelOverflowPadding()
|
||||
});
|
||||
me.getLabel().getTemplate().fx.setCustomDuration({'callout': 200});
|
||||
sprite.bindMarker('labels', me.getLabel());
|
||||
}
|
||||
sprite.setAttributes(this.getStyleByIndex(i));
|
||||
spriteCreated = true;
|
||||
}
|
||||
sprite.fx.setConfig(animation);
|
||||
}
|
||||
if (spriteCreated) {
|
||||
me.doUpdateStyles();
|
||||
}
|
||||
return me.sprites;
|
||||
},
|
||||
|
||||
betweenAngle: function (x, a, b) {
|
||||
b -= a;
|
||||
x -= a;
|
||||
x %= Math.PI * 2;
|
||||
b %= Math.PI * 2;
|
||||
x += Math.PI * 2;
|
||||
b += Math.PI * 2;
|
||||
x %= Math.PI * 2;
|
||||
b %= Math.PI * 2;
|
||||
return x < b;
|
||||
},
|
||||
|
||||
getItemForPoint: function (x, y) {
|
||||
var me = this,
|
||||
sprites = me.getSprites();
|
||||
if (sprites) {
|
||||
var center = me.getCenter(),
|
||||
offsetX = me.getOffsetX(),
|
||||
offsetY = me.getOffsetY(),
|
||||
originalX = x - center[0] + offsetX,
|
||||
originalY = y - center[1] + offsetY,
|
||||
store = me.getStore(),
|
||||
donut = me.getDonut(),
|
||||
items = store.getData().items,
|
||||
direction = Math.atan2(originalY, originalX) - me.getRotation(),
|
||||
donutLimit = Math.sqrt(originalX * originalX + originalY * originalY),
|
||||
endRadius = me.getRadius(),
|
||||
startRadius = donut / 100 * endRadius,
|
||||
i, ln, attr;
|
||||
|
||||
for (i = 0, ln = items.length; i < ln; i++) {
|
||||
// Fortunately, the id of items equals the index of it in instances list.
|
||||
attr = sprites[i].attr;
|
||||
if (startRadius + attr.margin <= donutLimit && donutLimit + attr.margin <= endRadius) {
|
||||
if (this.betweenAngle(direction, attr.startAngle, attr.endAngle)) {
|
||||
return {
|
||||
series: this,
|
||||
sprite: sprites[i],
|
||||
index: i,
|
||||
record: items[i],
|
||||
field: this.getXField()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
provideLegendInfo: function (target) {
|
||||
var store = this.getStore();
|
||||
if (store) {
|
||||
var items = store.getData().items,
|
||||
labelField = this.getLabelField(),
|
||||
field = this.getField(),
|
||||
hidden = this.getHidden();
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
target.push({
|
||||
name: labelField ? String(items[i].get(labelField)) : (field && field[i]) || this.getId(),
|
||||
mark: this.getStyleByIndex(i).fillStyle || this.getStyleByIndex(i).strokeStyle || 'black',
|
||||
disabled: hidden[i],
|
||||
series: this.getId(),
|
||||
index: i
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user