提交 0e5bb432 编写于 作者: L lang

Pie label

上级 d678bc85
......@@ -9,7 +9,7 @@ define(function (require) {
echarts.registerVisualCoding('chart', require('./pie/pieVisual'));
echarts.registerLayout(zrUtil.curry(
require('../layout/pie'), 'pie'
require('./pie/pieLayout'), 'pie'
));
echarts.registerProcessor(require('./pie/dataItemFilter'));
......
......@@ -89,6 +89,7 @@ define(function(require) {
minAngle: 0,
// 选中是扇区偏移量
selectedOffset: 10,
avoidLabelOverlap: true,
// 选择模式,默认关闭,可选single,multiple
// selectedMode: false,
// 南丁格尔玫瑰图模式,'radius'(半径) | 'area'(面积)
......@@ -107,7 +108,10 @@ define(function(require) {
},
labelLine: {
show: true,
// 引导线两段中的第一段长度
length: 20,
// 引导线两段中的第二段长度
length2: 5,
lineStyle: {
// color: 各异,
width: 1,
......
......@@ -8,17 +8,20 @@ define(function (require) {
var dataIndex = this.dataIndex;
var name = data.getName(dataIndex);
updateSelected(this, seriesModel.toggleSelected(name));
updateSelected(this,
seriesModel.toggleSelected(name),
seriesModel.get('selectedOffset')
);
}
function updateSelected(el, isSelected) {
function updateSelected(el, isSelected, selectedOffset) {
var shape = el.shape;
var midAngle = (shape.startAngle + shape.endAngle) / 2;
var dx = Math.cos(midAngle);
var dy = (shape.clockwise ? 1 : -1) * Math.sin(midAngle);
var offset = isSelected ? shape.r * 0.1 : 0;
var offset = isSelected ? selectedOffset : 0;
// animateTo will stop revious animation like update transition
el.animate()
......@@ -28,13 +31,60 @@ define(function (require) {
.start('bounceOut');
}
function createSectorAndLabel(layout, text, hasAnimation) {
var shape = zrUtil.extend({}, layout);
delete shape.label;
var sector = new graphic.Sector({
shape: shape
});
var labelLayout = layout.label;
var labelLine = new graphic.Polyline({
shape: {
points: labelLayout.linePoints
}
});
var labelText = new graphic.Text({
style: {
x: labelLayout.x,
y: labelLayout.y,
text: text,
textAlign: labelLayout.textAlign,
textBaseline: labelLayout.textBaseline,
font: labelLayout.font
}
});
sector.__labelLine = labelLine;
sector.__labelText = labelText;
if (hasAnimation) {
sector.shape.endAngle = layout.startAngle;
sector.animateTo({
shape: {
endAngle: layout.endAngle
}
}, 300, 'cubicOut');
}
return sector;
}
var Pie = require('../../view/Chart').extend({
type: 'pie',
init: function () {
var sectorGroup = new graphic.Group();
this._sectorGroup = sectorGroup;
},
render: function (seriesModel, ecModel, api) {
var data = seriesModel.getData();
var oldData = this._data;
var sectorGroup = this._sectorGroup;
var group = this.group;
var hasAnimation = ecModel.get('animation');
......@@ -46,38 +96,67 @@ define(function (require) {
data.diff(oldData)
.add(function (idx) {
var layout = data.getItemLayout(idx);
var sector = new graphic.Sector({
shape: zrUtil.extend({}, layout)
});
if (hasAnimation && !isFirstRender) {
sector.shape.endAngle = layout.startAngle;
sector.animateTo({
shape: {
endAngle: layout.endAngle
}
}, 300, 'cubicOut');
}
var sector = createSectorAndLabel(
layout, data.getName(idx),
hasAnimation && !isFirstRender
);
sector.on('click', onSectorClick);
data.setItemGraphicEl(idx, sector);
group.add(sector);
sectorGroup.add(sector);
group.add(sector.__labelLine);
group.add(sector.__labelText);
firstSector = firstSector || sector;
})
.update(function (newIdx, oldIdx) {
var sector = oldData.getItemGraphicEl(oldIdx);
var layout = data.getItemLayout(newIdx);
var labelLayout = layout.label;
sector.animateTo({
shape: data.getItemLayout(newIdx)
shape: layout
}, 300, 'cubicOut');
group.add(sector);
var labelLine = sector.__labelLine;
var labelText = sector.__labelText;
labelLine.animateTo({
shape: {
points: labelLayout.linePoints
}
}, 300, 'cubicOut');
labelText.animateTo({
style: {
x: labelLayout.x,
y: labelLayout.y
}
}, 300, 'cubicOut');
labelText.setStyle({
text: data.getName(newIdx),
textAlign: labelLayout.textAlign,
textBaseline: labelLayout.textBaseline,
font: labelLayout.font
});
sectorGroup.add(sector);
data.setItemGraphicEl(newIdx, sector);
group.add(labelLine);
group.add(labelText);
})
.remove(function (idx) {
var sector = oldData.getItemGraphicEl(idx);
group.remove(sector);
sectorGroup.remove(sector);
group.remove(sector.__labelLine);
group.remove(sector.__labelText);
})
.execute();
......@@ -85,18 +164,23 @@ define(function (require) {
var shape = firstSector.shape;
var r = Math.max(api.getWidth(), api.getHeight()) / 2;
var removeClipPath = zrUtil.bind(group.removeClipPath, group);
group.setClipPath(this._createClipPath(
var removeClipPath = zrUtil.bind(sectorGroup.removeClipPath, sectorGroup);
sectorGroup.setClipPath(this._createClipPath(
shape.cx, shape.cy, r, shape.startAngle, shape.clockwise, removeClipPath
));
}
// Make sure sectors is on top of labels
group.remove(sectorGroup);
group.add(sectorGroup);
this._updateAll(data, seriesModel);
this._data = data;
},
_updateAll: function (data, seriesModel) {
var selectedOffset = seriesModel.get('selectedOffset');
data.eachItemGraphicEl(function (sector, idx) {
var itemModel = data.getItemModel(idx);
......@@ -113,7 +197,7 @@ define(function (require) {
itemModel.getModel('itemStyle.emphasis').getItemStyle()
);
updateSelected(sector, itemModel.get('selected'));
updateSelected(sector, itemModel.get('selected'), selectedOffset);
});
},
......
define(function (require) {
'use strict';
var textContain = require('zrender/contain/text');
return function (seriesModel) {
var data = seriesModel.getData();
var itemStyleModel = seriesModel.getModel('itemStyle.normal');
var labelLineModel = itemStyleModel.getModel('labelLine');
var labelModel = itemStyleModel.getModel('label')
var labelLineLen = labelLineModel.get('length');
var labelLineLen2 = labelLineModel.get('length2');
var isLabelInside = labelModel.get('position') === 'inside';
var avoidLabelOverlap = seriesModel.get('avoidLabelOverlap');
data.each(function (idx) {
var layout = data.getItemLayout(idx);
var itemModel = data.getItemModel(idx);
var font = itemModel.getModel('itemStyle.normal.label.textStyle').getFont();
var midAngle = (layout.startAngle + layout.endAngle) / 2;
var dx = Math.cos(midAngle);
var dy = Math.sin(midAngle);
var r = layout.r;
var x1 = (isLabelInside ? r / 2 * dx : r * dx) + layout.cx;
var y1 = (isLabelInside ? r / 2 * dy : r * dy) + layout.cy;
var textX = x1 + dx * 3;
var textY = y1 + dy * 3;
var linePoints;
if (!isLabelInside) {
var x2 = x1 + dx * labelLineLen;
var y2 = y1 + dy * labelLineLen;
var x3 = x2 + ((dx < 0 ? -1 : 1) * labelLineLen2);
var y3 = y2;
textX = x3 + (dx < 0 ? -5 : 5);
textY = y3;
linePoints = [[x1, y1], [x2, y2], [x3, y3]];
}
var textAlign = isLabelInside ? 'center' : (dx > 0 ? 'left' : 'right');
var textBaseline = 'middle';
layout.label = {
x: textX,
y: textY,
linePoints: linePoints,
textAlign: textAlign,
textBaseline: textBaseline,
font: font
};
});
}
});
\ No newline at end of file
// TODO minAngle
define(function (require) {
var numberUtil = require('../../util/number');
var parsePercent = numberUtil.parsePercent;
var labelLayout = require('./labelLayout');
return function (seriesType, ecModel, api) {
ecModel.eachSeriesByType(seriesType, function (seriesModel) {
var center = seriesModel.get('center');
var radius = seriesModel.get('radius');
var width = api.getWidth();
var height = api.getHeight();
var size = Math.min(width, height);
var cx = parsePercent(center[0], width);
var cy = parsePercent(center[1], height);
var r0 = parsePercent(radius[0], size) / 2;
var r = parsePercent(radius[1], size) / 2;
var data = seriesModel.getData();
var startAngle = -seriesModel.get('startAngle') * Math.PI / 180;
var sum = data.getSum('x');
if (sum === 0) {
sum = data.count();
}
var radianPerVal = Math.PI / sum * 2;
var clockWise = seriesModel.get('clockWise');
data.each('x', function (value, idx) {
var angle = sum === 0 ? radianPerVal : (value * radianPerVal);
var endAngle = startAngle + angle;
data.setItemLayout(idx, {
startAngle: startAngle,
endAngle: endAngle,
clockwise: clockWise,
cx: cx,
cy: cy,
r0: r0,
r: r
});
startAngle = endAngle;
}, true);
labelLayout(seriesModel);
});
}
});
\ No newline at end of file
define(function (require) {
var zrUtil = require('zrender/core/util');
var numberUtil = require('../../util/number');
var symbolCreator = require('../../util/symbol');
var graphic = require('../../util/graphic');
......
// TODO minAngle
define(function (require) {
var numberUtil = require('../util/number');
var parsePercent = numberUtil.parsePercent;
return function (seriesType, ecModel, api) {
ecModel.eachSeriesByType(seriesType, function (seriesModel) {
var center = seriesModel.get('center');
var radius = seriesModel.get('radius');
var width = api.getWidth();
var height = api.getHeight();
var size = Math.min(width, height);
var cx = parsePercent(center[0], width);
var cy = parsePercent(center[1], height);
var r0 = parsePercent(radius[0], size) / 2;
var r = parsePercent(radius[1], size) / 2;
var data = seriesModel.getData();
var startAngle = -seriesModel.get('startAngle') * Math.PI / 180;
var sum = data.getSum('x');
if (sum === 0) {
sum = data.count();
}
var radianPerVal = Math.PI / sum * 2;
var clockWise = seriesModel.get('clockWise');
data.each('x', function (value, idx) {
var angle = sum === 0 ? radianPerVal : (value * radianPerVal);
var endAngle = startAngle + angle;
data.setItemLayout(idx, {
startAngle: startAngle,
endAngle: endAngle,
clockwise: clockWise,
cx: cx,
cy: cy,
r0: r0,
r: r
});
startAngle = endAngle;
}, true);
});
}
});
\ No newline at end of file
<html>
<head>
<meta charset="utf-8">
<script src="esl.js"></script>
<script src="config.js"></script>
</head>
<body>
<style>
html, body, #main {
width: 100%;
height: 100%;
}
</style>
<div id="main"></div>
<button id="random"></button>
<script>
require([
'echarts',
'echarts/chart/pie',
'echarts/component/legend',
'echarts/component/grid',
'echarts/component/tooltip'
], function (echarts) {
var chart = echarts.init(document.getElementById('main'), null, {
renderer: 'canvas'
});
var randomData = function () {
return [
{value:Math.random().toFixed(3), name:'a'},
{value:Math.random().toFixed(3), name:'b'},
{value:Math.random().toFixed(3), name:'c'},
{value:Math.random().toFixed(3), name:'d'},
{value:Math.random().toFixed(3), name:'e'}
];
}
var itemStyle = {
normal: {
// shadowBlur: 10,
// shadowOffsetX: 0,
// shadowOffsetY: 5,
// shadowColor: 'rgba(0, 0, 0, 0.4)'
}
};
chart.setOption({
legend: {
data:['a','b','c','d','e']
},
tooltip: {
},
series: [{
name: 'pie',
type: 'pie',
stack: 'all',
symbol: 'circle',
symbolSize: 10,
data: randomData(),
itemStyle: itemStyle
}]
});
setInterval(function () {
chart.setOption({
series: [{
name: 'pie',
data: randomData()
}]
})
}, 1000)
})
</script>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册