提交 6b3d744b 编写于 作者: P pah100

Merge branch 'master' of https://github.com/pissang/echarts-next

...@@ -26,6 +26,13 @@ define(function (require) { ...@@ -26,6 +26,13 @@ define(function (require) {
var data = seriesModel.getData(); var data = seriesModel.getData();
var oldData = this._data; var oldData = this._data;
var cartesian = seriesModel.coordinateSystem;
var baseAxis = cartesian.getBaseAxis();
var isInverse = cartesian.getOtherAxis(baseAxis).inverse;
var isHorizontal = baseAxis.isHorizontal();
var enableAnimation = ecModel.get('animation');
data.diff(oldData) data.diff(oldData)
.add(function (dataIndex) { .add(function (dataIndex) {
// 空数据 // 空数据
...@@ -35,11 +42,7 @@ define(function (require) { ...@@ -35,11 +42,7 @@ define(function (require) {
var layout = data.getItemLayout(dataIndex); var layout = data.getItemLayout(dataIndex);
var rect = new graphic.Rect({ var rect = new graphic.Rect({
shape: { shape: zrUtil.extend({}, layout)
x: layout.x,
y: layout.y + layout.height,
width: layout.width
}
}); });
data.setItemGraphicEl(dataIndex, rect); data.setItemGraphicEl(dataIndex, rect);
...@@ -47,9 +50,16 @@ define(function (require) { ...@@ -47,9 +50,16 @@ define(function (require) {
group.add(rect); group.add(rect);
// Animation // Animation
if (enableAnimation) {
var rectShape = rect.shape;
var animateProperty = isHorizontal ? 'height' : 'width';
var animateTarget = {};
rectShape[animateProperty] = 0;
animateTarget[animateProperty] = layout[animateProperty];
rect.animateTo({ rect.animateTo({
shape: layout shape: animateTarget
}, 1000, 300 * dataIndex / data.count(), 'cubicOut'); }, 1000, 300 * dataIndex / data.count(), 'cubicOut');
}
}) })
.update(function (newIndex, oldIndex) { .update(function (newIndex, oldIndex) {
var rect = oldData.getItemGraphicEl(oldIndex); var rect = oldData.getItemGraphicEl(oldIndex);
...@@ -70,6 +80,7 @@ define(function (require) { ...@@ -70,6 +80,7 @@ define(function (require) {
}) })
.remove(function (idx) { .remove(function (idx) {
var el = oldData.getItemGraphicEl(idx); var el = oldData.getItemGraphicEl(idx);
el.style.text = '';
el.animateTo({ el.animateTo({
shape: { shape: {
width: 0 width: 0
...@@ -83,12 +94,30 @@ define(function (require) { ...@@ -83,12 +94,30 @@ define(function (require) {
data.eachItemGraphicEl(function (rect, idx) { data.eachItemGraphicEl(function (rect, idx) {
var itemModel = data.getItemModel(idx); var itemModel = data.getItemModel(idx);
var labelModel = itemModel.getModel('itemStyle.normal.label');
var color = data.getItemVisual(idx, 'color');
var layout = data.getItemLayout(idx);
rect.setStyle(zrUtil.defaults( rect.setStyle(zrUtil.defaults(
{ {
fill: data.getItemVisual(idx, 'color') fill: color
}, },
itemModel.getModel('itemStyle.normal').getBarItemStyle() itemModel.getModel('itemStyle.normal').getBarItemStyle()
)); ));
if (labelModel.get('show')) {
var labelPosition = labelModel.get('position') || 'inside';
// FIXME
var labelColor = labelPosition === 'inside' ? 'white' : color;
var labelPositionOutside = isHorizontal
? (layout.height > 0 ? 'bottom' : 'top')
: (layout.width > 0 ? 'left' : 'right');
rect.setStyle({
text: data.getRawValue(idx),
textFont: labelModel.getModel('textStyle').getFont(),
textPosition: labelPosition === 'outside' ? labelPositionOutside : 'inside',
textFill: labelColor
});
}
graphic.setHoverStyle( graphic.setHoverStyle(
rect, itemModel.getModel('itemStyle.emphasis').getBarItemStyle() rect, itemModel.getModel('itemStyle.emphasis').getBarItemStyle()
); );
...@@ -101,6 +130,8 @@ define(function (require) { ...@@ -101,6 +130,8 @@ define(function (require) {
if (this._data) { if (this._data) {
var group = this.group; var group = this.group;
this._data.eachItemGraphicEl(function (el) { this._data.eachItemGraphicEl(function (el) {
// Not show text when animating
el.style.text = '';
el.animateTo({ el.animateTo({
shape: { shape: {
width: 0 width: 0
......
...@@ -2,9 +2,24 @@ define(function (require) { ...@@ -2,9 +2,24 @@ define(function (require) {
var zrUtil = require('zrender/core/util'); var zrUtil = require('zrender/core/util');
var Group = require('zrender/container/Group'); var Group = require('zrender/container/Group');
var symbolCreators = require('../../util/symbol'); var symbolUtil = require('../../util/symbol');
var graphic = require('../../util/graphic'); var graphic = require('../../util/graphic');
function normalizeSymbolSize(symbolSize) {
if (!zrUtil.isArray(symbolSize)) {
symbolSize = [+symbolSize, +symbolSize];
}
return symbolSize;
}
function isAroundEqual(a, b) {
return Math.abs(a - b) < 1e-4;
}
function isSymbolSizeSame(a, b) {
return isAroundEqual(a[0], b[0]) && isAroundEqual(a[1], b[1]);
}
function createSymbol(data, idx, enableAnimation) { function createSymbol(data, idx, enableAnimation) {
var point = data.getItemLayout(idx); var point = data.getItemLayout(idx);
var color = data.getItemVisual(idx, 'color'); var color = data.getItemVisual(idx, 'color');
...@@ -16,41 +31,36 @@ define(function (require) { ...@@ -16,41 +31,36 @@ define(function (require) {
return; return;
} }
var symbolEl = symbolCreators.createSymbol( symbolSize = normalizeSymbolSize(symbolSize);
symbolType, -0.5, -0.5, 1, 1, color
var x = -symbolSize[0] / 2;
var y = -symbolSize[1] / 2;
var w = symbolSize[0];
var h = symbolSize[1];
var symbolEl = symbolUtil.createSymbol(
symbolType, x, y, w, h, color
); );
symbolEl.position = point; symbolEl.position = point;
symbolEl.z2 = 100;
if (enableAnimation) { if (enableAnimation) {
symbolEl.scale = [0.1, 0.1]; symbolEl.scale = [0, 0];
symbolEl.animateTo({ symbolEl.animateTo({
scale: [symbolSize, symbolSize] scale: [1, 1]
}, 500); }, 500);
// symbolEl
// .on('mouseover', function () {
// this.animateTo({
// scale: [symbolSize * 1.4, symbolSize * 1.4]
// }, 400, 'elasticOut');
// })
// .on('mouseout', function () {
// this.animateTo({
// scale: [symbolSize, symbolSize]
// }, 400, 'elasticOut');
// });
} }
else { else {
symbolEl.scale = [symbolSize, symbolSize]; symbolEl.scale = [1, 1];
} }
return symbolEl; return symbolEl;
} }
function DataSymbol() { function DataSymbol() {
this.group = new Group(); this.group = new Group();
} }
...@@ -85,45 +95,62 @@ define(function (require) { ...@@ -85,45 +95,62 @@ define(function (require) {
}) })
.update(function (newIdx, oldIdx) { .update(function (newIdx, oldIdx) {
var el = oldData.getItemGraphicEl(oldIdx); var el = oldData.getItemGraphicEl(oldIdx);
// Empty data // Empty data
if (!data.hasValue(newIdx)) { if (!data.hasValue(newIdx)) {
group.remove(el); group.remove(el);
return; return;
} }
var symbolSize = data.getItemVisual(newIdx, 'symbolSize'); var symbolSize = normalizeSymbolSize(
data.getItemVisual(newIdx, 'symbolSize')
);
var point = data.getItemLayout(newIdx); var point = data.getItemLayout(newIdx);
var symbolType = data.getItemVisual(newIdx, 'symbol');
// Symbol changed // Symbol changed
if (oldData.getItemVisual(newIdx, 'symbol') !== data.getItemVisual(oldIdx, 'symbol')) { if (oldData.getItemVisual(oldIdx, 'symbol') !== symbolType) {
// Remove the old one // Remove the old one
el && group.remove(el); el && group.remove(el);
el = createSymbol(data, newIdx, enableAnimation); el = createSymbol(data, newIdx, enableAnimation);
}
// Disable symbol by setting `symbol: 'none'` // Disable symbol by setting `symbol: 'none'`
if (!el) { if (!el) {
return; return;
} }
// Color changed
var newColor = data.getItemVisual(newIdx, 'color');
if (oldData.getItemVisual(newIdx, 'color') !== newColor) {
el.setStyle('fill', newColor);
} }
else {
// Update animation
if (!el) {
return;
}
var newTarget = {};
if (!isSymbolSizeSame(
symbolSize, normalizeSymbolSize(
oldData.getItemVisual(oldIdx, 'symbolSize')
)
)) {
// FIXME symbol created with pathStr has symbolSizeChanged
newTarget = symbolUtil.getSymbolShape(
symbolType,
-symbolSize[0] / 2, -symbolSize[1] / 2,
symbolSize[0], symbolSize[1]
) || {};
}
var newColor = data.getItemVisual(newIdx, 'color');
el.setColor(newColor);
// TODO Merge animateTo and attr methods into one // TODO Merge animateTo and attr methods into one
newTarget.position = point.slice();
if (!isAroundEqual(el.scale[0], 1)) { // May have scale 0
newTarget.scale = [1, 1];
}
if (enableAnimation) { if (enableAnimation) {
el.animateTo({ el.animateTo(newTarget, 300, 'cubicOut');
scale: [symbolSize, symbolSize],
position: point
}, 300, 'cubicOut');
} }
else { else {
el.attr({ // May still have animation. Must stop
scale: [symbolSize, symbolSize], el.stopAnimation();
position: point.slice() el.attr(newTarget);
}); }
} }
data.setItemGraphicEl(newIdx, el); data.setItemGraphicEl(newIdx, el);
...@@ -149,22 +176,33 @@ define(function (require) { ...@@ -149,22 +176,33 @@ define(function (require) {
// Update common properties // Update common properties
data.eachItemGraphicEl(function (el, idx) { data.eachItemGraphicEl(function (el, idx) {
var itemModel = data.getItemModel(idx); var itemModel = data.getItemModel(idx);
var labelModel = itemModel.getModel('itemStyle.normal.label');
var color = data.getItemVisual(idx, 'color');
zrUtil.extend( zrUtil.extend(
el.style, el.style,
itemModel.getModel('itemStyle.normal').getItemStyle(['color']) itemModel.getModel('itemStyle.normal').getItemStyle(['color'])
); );
if (labelModel.get('show')) {
var labelPosition = labelModel.get('position') || 'inside';
var labelColor = labelPosition === 'inside' ? 'white' : color;
// Text use the value of last dimension
var lastDim = data.dimensions[data.dimensions.length - 1];
el.setStyle({
// FIXME
text: data.get(lastDim, idx),
textFont: labelModel.getModel('textStyle').getFont(),
textPosition: labelPosition,
textFill: labelColor
});
}
graphic.setHoverStyle( graphic.setHoverStyle(
el, el,
itemModel.getModel('itemStyle.emphasis').getItemStyle() itemModel.getModel('itemStyle.emphasis').getItemStyle()
); );
var symbolSize = data.getItemVisual(idx, 'symbolSize');
// Adjust the line width
el.__lineWidth = el.__lineWidth || el.style.lineWidth;
el.style.lineWidth = el.__lineWidth / symbolSize;
}, this); }, this);
this._data = data; this._data = data;
......
...@@ -19,7 +19,7 @@ define(function(require) { ...@@ -19,7 +19,7 @@ define(function(require) {
if (xAxisModel.get('type') === 'category') { if (xAxisModel.get('type') === 'category') {
dimensions = [{ dimensions = [{
name: 'x', name: 'x',
type: 'int' type: 'ordinal'
}, { }, {
name: 'y', name: 'y',
stackable: true stackable: true
...@@ -30,7 +30,7 @@ define(function(require) { ...@@ -30,7 +30,7 @@ define(function(require) {
else if (yAxisModel.get('type') === 'category') { else if (yAxisModel.get('type') === 'category') {
dimensions = [{ dimensions = [{
name: 'y', name: 'y',
type: 'int' type: 'ordinal'
}, { }, {
name: 'x', name: 'x',
stackable: true stackable: true
...@@ -59,7 +59,7 @@ define(function(require) { ...@@ -59,7 +59,7 @@ define(function(require) {
if (angleAxisModel.get('type') === 'category') { if (angleAxisModel.get('type') === 'category') {
dimensions = [{ dimensions = [{
name: 'angle', name: 'angle',
type: 'int' type: 'ordinal'
}, { }, {
name: 'radius', name: 'radius',
stackable: true stackable: true
...@@ -70,7 +70,7 @@ define(function(require) { ...@@ -70,7 +70,7 @@ define(function(require) {
else if (radiusAxisModel.get('type') === 'category') { else if (radiusAxisModel.get('type') === 'category') {
dimensions = [{ dimensions = [{
name: 'radius', name: 'radius',
type: 'int' type: 'ordinal'
}, { }, {
name: 'angle', name: 'angle',
stackable: true stackable: true
......
define(function(require) { define(function(require) {
'use strict'; 'use strict';
var smoothBezier = require('zrender/graphic/helper/smoothBezier');
return require('zrender/graphic/Path').extend({ return require('zrender/graphic/Path').extend({
type: 'ec-area', type: 'ec-area',
...@@ -17,7 +19,7 @@ define(function(require) { ...@@ -17,7 +19,7 @@ define(function(require) {
var i = 0; var i = 0;
var len = points.length; var len = points.length;
while (i < points.length) { while (i < len) {
for (var k = i; k < len; k++) { for (var k = i; k < len; k++) {
var p = points[k]; var p = points[k];
if (p == null || isNaN(p[0]) || isNaN(p[1])) { if (p == null || isNaN(p[0]) || isNaN(p[1])) {
......
...@@ -16,8 +16,8 @@ define(function(require) { ...@@ -16,8 +16,8 @@ define(function(require) {
return; return;
} }
for (var i = 0; i < points1.length; i++) { for (var i = 0; i < points1.length; i++) {
var p1 = points1[i].point; var p1 = points1[i];
var p2 = points2[i].point; var p2 = points2[i];
if (p1[0] !== p2[0] || p1[1] !== p2[1]) { if (p1[0] !== p2[0] || p1[1] !== p2[1]) {
return; return;
} }
...@@ -37,20 +37,9 @@ define(function(require) { ...@@ -37,20 +37,9 @@ define(function(require) {
return extent; return extent;
} }
function getDataArray(coordSys, data, points) { function sign(val) {
var dimensions = coordSys.type === 'cartesian2d' ? ['x', 'y'] : ['radius', 'angle']; return val >= 0 ? 1 : -1;
return data.map(dimensions, function (x, y, idx) {
return {
x: x,
y: y,
point: points[idx],
name: data.getName(idx),
idx: idx,
rawIdx: data.getRawIndex(idx)
};
});
} }
/** /**
* @param {module:echarts/coord/cartesian/Cartesian2D|module:echarts/coord/polar/Polar} coordSys * @param {module:echarts/coord/cartesian/Cartesian2D|module:echarts/coord/polar/Polar} coordSys
* @param {module:echarts/data/List} data * @param {module:echarts/data/List} data
...@@ -58,22 +47,33 @@ define(function(require) { ...@@ -58,22 +47,33 @@ define(function(require) {
* @private * @private
*/ */
function getStackedOnPoints(coordSys, data, points) { function getStackedOnPoints(coordSys, data, points) {
var stackedOnData = data.stackedOn; var baseAxis = coordSys.getBaseAxis();
if (stackedOnData) { var valueAxis = coordSys.getOtherAxis(baseAxis);
return stackedOnData.map(stackedOnData.getItemLayout, true); var valueAxisStart = baseAxis.onZero
? valueAxis.dataToCoord(0) : valueAxis.getExtent()[0];
var valueDim = valueAxis.dim;
var baseCoordOffset = valueDim === 'x' || valueDim === 'radius' ? 1 : 0;
return data.map([valueDim], function (val, idx) {
var stackedOnSameSign;
var stackedOn = data.stackedOn;
if (val > 0) {
// Find first stacked value with same sign
while (stackedOn &&
sign(stackedOn.get(valueDim, idx)) === sign(val)
) {
stackedOnSameSign = stackedOn;
break;
}
} }
else {
var valueAxis = coordSys.getOtherAxis(coordSys.getBaseAxis());
var valueStart = valueAxis.getExtent()[0];
var dim = valueAxis.dim;
var baseCoordOffset = dim === 'x' || dim === 'radius' ? 1 : 0;
return zrUtil.map(points, function (point, idx) {
var pt = []; var pt = [];
pt[baseCoordOffset] = point[baseCoordOffset]; pt[baseCoordOffset] = points[idx][baseCoordOffset];
pt[1 - baseCoordOffset] = valueStart; pt[1 - baseCoordOffset] = stackedOnSameSign
? stackedOnSameSign.getItemLayout(idx)[1 - baseCoordOffset]
: valueAxisStart;
return pt; return pt;
}); }, true);
}
} }
return require('../../echarts').extendChartView({ return require('../../echarts').extendChartView({
...@@ -81,7 +81,9 @@ define(function(require) { ...@@ -81,7 +81,9 @@ define(function(require) {
type: 'line', type: 'line',
init: function () { init: function () {
this._dataSymbol = new DataSymbol(); var dataSymbol = new DataSymbol();
this.group.add(dataSymbol.group);
this._dataSymbol = dataSymbol;
}, },
render: function (seriesModel, ecModel) { render: function (seriesModel, ecModel) {
...@@ -92,7 +94,6 @@ define(function(require) { ...@@ -92,7 +94,6 @@ define(function(require) {
var areaStyleModel = seriesModel.getModel('itemStyle.normal.areaStyle'); var areaStyleModel = seriesModel.getModel('itemStyle.normal.areaStyle');
var points = data.map(data.getItemLayout, true); var points = data.map(data.getItemLayout, true);
var dataArray = getDataArray(coordSys, data, points);
var isCoordSysPolar = coordSys.type === 'polar'; var isCoordSysPolar = coordSys.type === 'polar';
var prevCoordSys = this._coordSys; var prevCoordSys = this._coordSys;
...@@ -108,14 +109,6 @@ define(function(require) { ...@@ -108,14 +109,6 @@ define(function(require) {
coordSys, data, points coordSys, data, points
); );
var stackedOnDataArray = data.stackedOn ? getDataArray(
coordSys, data.stackedOn, stackedOnPoints
) : zrUtil.map(stackedOnPoints, function (pt) {
return {
point: pt
};
});
// Initialization animation or coordinate system changed // Initialization animation or coordinate system changed
if ( if (
!(polyline !(polyline
...@@ -148,11 +141,11 @@ define(function(require) { ...@@ -148,11 +141,11 @@ define(function(require) {
// In the case data zoom triggerred refreshing frequently // In the case data zoom triggerred refreshing frequently
// Data may not change if line has a category axis. So it should animate nothing // Data may not change if line has a category axis. So it should animate nothing
if (!isPointsSame(this._dataArray, dataArray)) { // if (!isDataSame(this._data, data)) {
this._updateAnimation( this._updateAnimation(
data, dataArray, stackedOnDataArray, coordSys data, stackedOnPoints, coordSys
); );
} // }
// Add back // Add back
group.add(polyline); group.add(polyline);
group.add(polygon); group.add(polygon);
...@@ -167,7 +160,7 @@ define(function(require) { ...@@ -167,7 +160,7 @@ define(function(require) {
)); ));
if (polygon) { if (polygon) {
polygon.style.opacity = 0.7; polygon.style.opacity = 0.7;
polygon.setStyle(zrUtil.extend( polygon.setStyle(zrUtil.defaults(
areaStyleModel.getAreaStyle(), areaStyleModel.getAreaStyle(),
{ {
fill: data.getVisual('color'), fill: data.getVisual('color'),
...@@ -176,16 +169,11 @@ define(function(require) { ...@@ -176,16 +169,11 @@ define(function(require) {
)); ));
} }
// Make sure symbols is on top of line
group.remove(dataSymbol.group);
group.add(dataSymbol.group);
this._data = data; this._data = data;
// Save the coordinate system and data for transition animation when data changed // Save the coordinate system for transition animation when data changed
this._dataArray = dataArray;
this._stackedOnDataArray = stackedOnDataArray;
this._coordSys = coordSys; this._coordSys = coordSys;
this._stackedOnPoints = stackedOnPoints;
!isCoordSysPolar && !seriesModel.get('showAllSymbol') !isCoordSysPolar && !seriesModel.get('showAllSymbol')
&& this._updateSymbolDisplay(data, coordSys); && this._updateSymbolDisplay(data, coordSys);
...@@ -209,7 +197,8 @@ define(function(require) { ...@@ -209,7 +197,8 @@ define(function(require) {
shape: { shape: {
points: points points: points
}, },
silent: true silent: true,
z2: 10
}); });
var clipPath = this._createClipShape(coordSys, hasAnimation); var clipPath = this._createClipShape(coordSys, hasAnimation);
...@@ -272,13 +261,13 @@ define(function(require) { ...@@ -272,13 +261,13 @@ define(function(require) {
/** /**
* @private * @private
*/ */
_updateAnimation: function (data, dataArray, stackedOnDataArray, coordSys) { _updateAnimation: function (data, stackedOnPoints, coordSys) {
var polyline = this._polyline; var polyline = this._polyline;
var polygon = this._polygon; var polygon = this._polygon;
var diff = lineAnimationDiff( var diff = lineAnimationDiff(
this._dataArray, dataArray, this._data, data,
this._stackedOnDataArray, stackedOnDataArray, this._stackedOnPoints, stackedOnPoints,
this._coordSys, coordSys this._coordSys, coordSys
); );
polyline.shape.points = diff.current; polyline.shape.points = diff.current;
...@@ -325,10 +314,9 @@ define(function(require) { ...@@ -325,10 +314,9 @@ define(function(require) {
for (var i = 0; i < addedDataIndices.length; i++) { for (var i = 0; i < addedDataIndices.length; i++) {
var el = data.getItemGraphicEl(addedDataIndices[i]); var el = data.getItemGraphicEl(addedDataIndices[i]);
if (el) { if (el) {
var oldScale = el.scale; el.scale = [0, 0];
el.scale = [1, 1];
el.animateTo({ el.animateTo({
scale: oldScale scale: [1, 1]
}, 300, 300, 'cubicOut'); }, 300, 300, 'cubicOut');
} }
} }
...@@ -372,7 +360,7 @@ define(function(require) { ...@@ -372,7 +360,7 @@ define(function(require) {
width: xExtent[1] - xExtent[0], width: xExtent[1] - xExtent[0],
height: yExtent[1] - yExtent[0] height: yExtent[1] - yExtent[0]
} }
}, 1500, animation); }, 1500);
} }
return clipPath; return clipPath;
......
...@@ -6,39 +6,60 @@ define(function (require) { ...@@ -6,39 +6,60 @@ define(function (require) {
return a.name === b.name; return a.name === b.name;
} }
function getStackedOnPoint(coordSys, stackedItem, item) { function sign(val) {
if ('x' in stackedItem) { return val >= 0 ? 1 : -1;
return coordSys.dataToPoint([stackedItem.x, stackedItem.y]);
} }
else {
function getStackedOnPoint(coordSys, data, idx) {
var baseAxis = coordSys.getBaseAxis(); var baseAxis = coordSys.getBaseAxis();
var valueAxis = coordSys.getOtherAxis(baseAxis); var valueAxis = coordSys.getOtherAxis(baseAxis);
var valueStart = valueAxis.getExtent()[0]; var valueAxisStart = baseAxis.onZero
var dim = valueAxis.dim; ? valueAxis.dataToCoord(0) : valueAxis.getExtent()[0];
dim === 'radius' && (dim = 'x');
dim === 'angle' && (dim = 'y'); var valueDim = valueAxis.dim;
var baseCoordOffset = dim === 'x' ? 1 : 0; var baseCoordOffset = valueDim === 'x' || valueDim === 'radius' ? 1 : 0;
var stackedOnSameSign;
var stackedOn = data.stackedOn;
var val = data.get(valueDim, idx);
if (val > 0) {
// Find first stacked value with same sign
while (stackedOn &&
sign(stackedOn.get(valueDim, idx)) === sign(val)
) {
stackedOnSameSign = stackedOn;
break;
}
}
var pt = []; var pt = [];
pt[baseCoordOffset] = baseAxis.dataToCoord(item[dim === 'y' ? 'x' : 'y']); pt[baseCoordOffset] = data.getItemLayout(idx)[baseCoordOffset];
pt[1 - baseCoordOffset] = valueStart; pt[1 - baseCoordOffset] = stackedOnSameSign
? stackedOnSameSign.getItemLayout(idx)[1 - baseCoordOffset]
: valueAxisStart;
return pt; return pt;
} }
}
return function (oldData, newData, oldStackedData, newStackedData, oldCoordSys, newCoordSys) { return function (
oldData, newData,
oldStackedOnPoints, newStackedOnPoints,
oldCoordSys, newCoordSys
) {
var newNameList = newData.map(newData.getName);
var oldNameList = oldData.map(oldData.getName);
var oldPoints = []; var currPoints = [];
var newPoints = []; var nextPoints = [];
// Points for stacking base line // Points for stacking base line
var oldStackedPoints = []; var currStackedPoints = [];
var newStackedPoints = []; var nextStackedPoints = [];
var status = []; var status = [];
var sortedIndices = []; var sortedIndices = [];
var rawIndices = []; var rawIndices = [];
// FIXME One data ? // FIXME One data ?
var diff = arrayDiff(oldData, newData, nameCompare); var diff = arrayDiff(oldNameList, newNameList);
for (var i = 0; i < diff.length; i++) { for (var i = 0; i < diff.length; i++) {
var diffItem = diff[i]; var diffItem = diff[i];
...@@ -48,46 +69,49 @@ define(function (require) { ...@@ -48,46 +69,49 @@ define(function (require) {
// Which is in case remvoing or add more than one data in the tail or head // Which is in case remvoing or add more than one data in the tail or head
switch (diffItem.cmd) { switch (diffItem.cmd) {
case '=': case '=':
oldPoints.push(oldData[diffItem.idx].point); currPoints.push(oldData.getItemLayout(diffItem.idx));
newPoints.push(newData[diffItem.idx1].point); nextPoints.push(newData.getItemLayout(diffItem.idx1));
oldStackedPoints.push(oldStackedData[diffItem.idx].point); currStackedPoints.push(oldStackedOnPoints[diffItem.idx]);
newStackedPoints.push(newStackedData[diffItem.idx1].point); nextStackedPoints.push(newStackedOnPoints[diffItem.idx1]);
rawIndices.push(newData[diffItem.idx1].rawIdx); rawIndices.push(newData.getRawIndex(diffItem.idx));
break; break;
case '+': case '+':
var newDataItem = newData[diffItem.idx]; var idx = diffItem.idx;
var newStackedDataItem = newStackedData[diffItem.idx]; currPoints.push(
oldCoordSys.dataToPoint([
oldPoints.push( newData.get('x', idx), newData.get('y', idx)
oldCoordSys.dataToPoint([newDataItem.x, newDataItem.y]) ])
); );
newPoints.push(newDataItem.point); nextPoints.push(newData.getItemLayout(idx));
oldStackedPoints.push( currStackedPoints.push(
getStackedOnPoint(oldCoordSys, newStackedDataItem, newDataItem) getStackedOnPoint(oldCoordSys, newData, idx)
); );
newStackedPoints.push(newStackedDataItem.point); nextStackedPoints.push(newStackedOnPoints[idx]);
rawIndices.push(newDataItem.rawIdx); rawIndices.push(newData.getRawIndex(idx));
break; break;
case '-': case '-':
var oldDataItem = oldData[diffItem.idx]; var idx = diffItem.idx;
var oldStackedDataItem = oldStackedData[diffItem.idx]; var rawIndex = oldData.getRawIndex(idx);
// Data is replaced. In the case of dynamic data queue // Data is replaced. In the case of dynamic data queue
// FIXME FIXME FIXME // FIXME FIXME FIXME
if (oldDataItem.rawIdx !== diffItem.idx) { if (rawIndex !== idx) {
oldPoints.push(oldDataItem.point); currPoints.push(oldData.getItemLayout(idx));
newPoints.push(newCoordSys.dataToPoint([oldDataItem.x, oldDataItem.y])); nextPoints.push(newCoordSys.dataToPoint([
oldData.get('x', idx), oldData.get('y', idx)
oldStackedPoints.push(oldStackedDataItem.point); ]));
newStackedPoints.push(
getStackedOnPoint(newCoordSys, oldStackedDataItem, oldDataItem) currStackedPoints.push(oldStackedOnPoints[idx]);
nextStackedPoints.push(
getStackedOnPoint(
newCoordSys, newData, idx
)
); );
rawIndices.push(oldDataItem.rawIdx); rawIndices.push(rawIndex);
} }
else { else {
pointAdded = false; pointAdded = false;
...@@ -107,30 +131,30 @@ define(function (require) { ...@@ -107,30 +131,30 @@ define(function (require) {
return rawIndices[a] - rawIndices[b]; return rawIndices[a] - rawIndices[b];
}); });
var sortedOldPoints = []; var sortedCurrPoints = [];
var sortedNewPoints = []; var sortedNextPoints = [];
var sortedOldStackedPoints = []; var sortedCurrStackedPoints = [];
var sortedNewStackedPoints = []; var sortedNextStackedPoints = [];
var sortedStatus = []; var sortedStatus = [];
for (var i = 0; i < sortedIndices.length; i++) { for (var i = 0; i < sortedIndices.length; i++) {
var idx = sortedIndices[i]; var idx = sortedIndices[i];
sortedOldPoints[i] = oldPoints[idx]; sortedCurrPoints[i] = currPoints[idx];
sortedNewPoints[i] = newPoints[idx]; sortedNextPoints[i] = nextPoints[idx];
sortedOldStackedPoints[i] = oldStackedPoints[idx]; sortedCurrStackedPoints[i] = currStackedPoints[idx];
sortedNewStackedPoints[i] = newStackedPoints[idx]; sortedNextStackedPoints[i] = nextStackedPoints[idx];
sortedStatus[i] = status[idx]; sortedStatus[i] = status[idx];
} }
return { return {
current: sortedOldPoints, current: sortedCurrPoints,
next: sortedNewPoints, next: sortedNextPoints,
stackedOnCurrent: sortedOldStackedPoints, stackedOnCurrent: sortedCurrStackedPoints,
stackedOnNext: sortedNewStackedPoints, stackedOnNext: sortedNextStackedPoints,
status: sortedStatus status: sortedStatus
}; };
......
...@@ -9,7 +9,7 @@ define(function (require) { ...@@ -9,7 +9,7 @@ define(function (require) {
echarts.registerVisualCoding('chart', require('./pie/pieVisual')); echarts.registerVisualCoding('chart', require('./pie/pieVisual'));
echarts.registerLayout(zrUtil.curry( echarts.registerLayout(zrUtil.curry(
require('../layout/pie'), 'pie' require('./pie/pieLayout'), 'pie'
)); ));
echarts.registerProcessor(require('./pie/dataItemFilter')); echarts.registerProcessor(require('./pie/dataItemFilter'));
......
...@@ -89,6 +89,7 @@ define(function(require) { ...@@ -89,6 +89,7 @@ define(function(require) {
minAngle: 0, minAngle: 0,
// 选中是扇区偏移量 // 选中是扇区偏移量
selectedOffset: 10, selectedOffset: 10,
avoidLabelOverlap: true,
// 选择模式,默认关闭,可选single,multiple // 选择模式,默认关闭,可选single,multiple
// selectedMode: false, // selectedMode: false,
// 南丁格尔玫瑰图模式,'radius'(半径) | 'area'(面积) // 南丁格尔玫瑰图模式,'radius'(半径) | 'area'(面积)
...@@ -107,7 +108,10 @@ define(function(require) { ...@@ -107,7 +108,10 @@ define(function(require) {
}, },
labelLine: { labelLine: {
show: true, show: true,
// 引导线两段中的第一段长度
length: 20, length: 20,
// 引导线两段中的第二段长度
length2: 5,
lineStyle: { lineStyle: {
// color: 各异, // color: 各异,
width: 1, width: 1,
......
...@@ -8,17 +8,20 @@ define(function (require) { ...@@ -8,17 +8,20 @@ define(function (require) {
var dataIndex = this.dataIndex; var dataIndex = this.dataIndex;
var name = data.getName(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 shape = el.shape;
var midAngle = (shape.startAngle + shape.endAngle) / 2; var midAngle = (shape.startAngle + shape.endAngle) / 2;
var dx = Math.cos(midAngle); var dx = Math.cos(midAngle);
var dy = (shape.clockwise ? 1 : -1) * Math.sin(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 // animateTo will stop revious animation like update transition
el.animate() el.animate()
...@@ -28,13 +31,60 @@ define(function (require) { ...@@ -28,13 +31,60 @@ define(function (require) {
.start('bounceOut'); .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({ var Pie = require('../../view/Chart').extend({
type: 'pie', type: 'pie',
init: function () {
var sectorGroup = new graphic.Group();
this._sectorGroup = sectorGroup;
},
render: function (seriesModel, ecModel, api) { render: function (seriesModel, ecModel, api) {
var data = seriesModel.getData(); var data = seriesModel.getData();
var oldData = this._data; var oldData = this._data;
var sectorGroup = this._sectorGroup;
var group = this.group; var group = this.group;
var hasAnimation = ecModel.get('animation'); var hasAnimation = ecModel.get('animation');
...@@ -46,38 +96,67 @@ define(function (require) { ...@@ -46,38 +96,67 @@ define(function (require) {
data.diff(oldData) data.diff(oldData)
.add(function (idx) { .add(function (idx) {
var layout = data.getItemLayout(idx); var layout = data.getItemLayout(idx);
var sector = new graphic.Sector({
shape: zrUtil.extend({}, layout)
});
if (hasAnimation && !isFirstRender) { var sector = createSectorAndLabel(
sector.shape.endAngle = layout.startAngle; layout, data.getName(idx),
sector.animateTo({ hasAnimation && !isFirstRender
shape: { );
endAngle: layout.endAngle
}
}, 300, 'cubicOut');
}
sector.on('click', onSectorClick); sector.on('click', onSectorClick);
data.setItemGraphicEl(idx, sector); data.setItemGraphicEl(idx, sector);
group.add(sector);
sectorGroup.add(sector);
group.add(sector.__labelLine);
group.add(sector.__labelText);
firstSector = firstSector || sector; firstSector = firstSector || sector;
}) })
.update(function (newIdx, oldIdx) { .update(function (newIdx, oldIdx) {
var sector = oldData.getItemGraphicEl(oldIdx); var sector = oldData.getItemGraphicEl(oldIdx);
var layout = data.getItemLayout(newIdx);
var labelLayout = layout.label;
sector.animateTo({ sector.animateTo({
shape: data.getItemLayout(newIdx) shape: layout
}, 300, 'cubicOut'); }, 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); data.setItemGraphicEl(newIdx, sector);
group.add(labelLine);
group.add(labelText);
}) })
.remove(function (idx) { .remove(function (idx) {
var sector = oldData.getItemGraphicEl(idx); var sector = oldData.getItemGraphicEl(idx);
group.remove(sector); sectorGroup.remove(sector);
group.remove(sector.__labelLine);
group.remove(sector.__labelText);
}) })
.execute(); .execute();
...@@ -85,18 +164,23 @@ define(function (require) { ...@@ -85,18 +164,23 @@ define(function (require) {
var shape = firstSector.shape; var shape = firstSector.shape;
var r = Math.max(api.getWidth(), api.getHeight()) / 2; var r = Math.max(api.getWidth(), api.getHeight()) / 2;
var removeClipPath = zrUtil.bind(group.removeClipPath, group); var removeClipPath = zrUtil.bind(sectorGroup.removeClipPath, sectorGroup);
group.setClipPath(this._createClipPath( sectorGroup.setClipPath(this._createClipPath(
shape.cx, shape.cy, r, shape.startAngle, shape.clockwise, removeClipPath 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._updateAll(data, seriesModel);
this._data = data; this._data = data;
}, },
_updateAll: function (data, seriesModel) { _updateAll: function (data, seriesModel) {
var selectedOffset = seriesModel.get('selectedOffset');
data.eachItemGraphicEl(function (sector, idx) { data.eachItemGraphicEl(function (sector, idx) {
var itemModel = data.getItemModel(idx); var itemModel = data.getItemModel(idx);
...@@ -113,7 +197,7 @@ define(function (require) { ...@@ -113,7 +197,7 @@ define(function (require) {
itemModel.getModel('itemStyle.emphasis').getItemStyle() 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) { 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
...@@ -6,8 +6,10 @@ define(function (require) { ...@@ -6,8 +6,10 @@ define(function (require) {
var data = seriesModel.getData(); var data = seriesModel.getData();
var dataAll = seriesModel.getDataAll(); var dataAll = seriesModel.getDataAll();
data.each(function (idx) { data.each(function (idx) {
var itemModel = data.getItemModel(idx);
var rawIdx = data.getRawIndex(idx); var rawIdx = data.getRawIndex(idx);
var color = colorList[rawIdx % colorList.length]; var color = itemModel.get('itemStyle.normal.color')
|| colorList[rawIdx % colorList.length];
// Legend use the visual info in data before processed // Legend use the visual info in data before processed
dataAll.setItemVisual(rawIdx, 'color', color); dataAll.setItemVisual(rawIdx, 'color', color);
data.setItemVisual(idx, 'color', color); data.setItemVisual(idx, 'color', color);
......
...@@ -18,7 +18,6 @@ define(function(require) { ...@@ -18,7 +18,6 @@ define(function(require) {
}; };
} }
require('../coord/polar/polarCreator'); require('../coord/polar/polarCreator');
require('../echarts').extendComponentView({ require('../echarts').extendComponentView({
......
...@@ -35,10 +35,10 @@ define(function(require) { ...@@ -35,10 +35,10 @@ define(function(require) {
var otherAxis = grid.getAxis(axis.dim === 'x' ? 'y' : 'x'); var otherAxis = grid.getAxis(axis.dim === 'x' ? 'y' : 'x');
var position = 0; var position = 0;
if (axisModel.get('axisLine.onZero')) { if (axis.onZero) {
position = otherAxis.dataToCoord(0); position = otherAxis.dataToCoord(0);
} }
else {
switch (axis.position) { switch (axis.position) {
case 'left': case 'left':
position = rect.x; position = rect.x;
...@@ -52,6 +52,7 @@ define(function(require) { ...@@ -52,6 +52,7 @@ define(function(require) {
case 'bottom': case 'bottom':
position = rect.y + rect.height; position = rect.y + rect.height;
} }
}
return position; return position;
} }
......
define(function (require) { define(function (require) {
var zrUtil = require('zrender/core/util'); var zrUtil = require('zrender/core/util');
var numberUtil = require('../../util/number');
var symbolCreator = require('../../util/symbol'); var symbolCreator = require('../../util/symbol');
var graphic = require('../../util/graphic'); var graphic = require('../../util/graphic');
......
// HINT Markpoint can't be used too much
define(function (require) {
var DataSymbol = require('../chart/helper/DataSymbol');
var zrUtil = require('zrender/core/util');
var List = require('../data/List');
require('./marker/MarkPointModel');
require('../echarts').extendComponentView({
type: 'markPoint',
init: function () {
this._dataSymbolMap = {};
},
render: function (markPointModel, ecModel) {
var dataSymbolMap = this._dataSymbolMap;
for (var name in dataSymbolMap) {
dataSymbolMap[name].__keep = false;
}
ecModel.eachSeries(function (seriesModel) {
var mpModel = seriesModel.markPointModel;
mpModel && this._renderSeriesMP(seriesModel, mpModel);
}, this);
for (var name in dataSymbolMap) {
if (!dataSymbolMap[name].__keep) {
dataSymbolMap[name].remove();
this.group.remove(dataSymbolMap[name].group);
}
}
},
_renderSeriesMP: function (seriesModel, mpModel) {
var coordSys = seriesModel.coordinateSystem;
var seriesName = seriesModel.name;
var seriesData = seriesModel.getData();
var dataSymbolMap = this._dataSymbolMap;
var dataSymbol = dataSymbolMap[seriesName];
if (!dataSymbol) {
dataSymbol = dataSymbolMap[seriesName] = new DataSymbol();
}
var mpData = createList(coordSys, seriesData, mpModel);
mpData.each(['x', 'y'], function (x, y, idx) {
var itemModel = mpData.getItemModel(idx);
var xPx = itemModel.getShallow('x');
var yPx = itemModel.getShallow('y');
var point = (xPx != null && yPx != null) ? [xPx, yPx] : coordSys.dataToPoint([x, y]);
mpData.setItemLayout(idx, point);
mpData.setItemVisual(idx, {
symbolSize: itemModel.getShallow('symbolSize'),
color: itemModel.get('itemStyle.normal.color')
|| seriesData.getVisual('color'),
symbol: itemModel.getShallow('symbol')
});
});
// TODO Text are wrong
dataSymbol.updateData(mpData, true);
this.group.add(dataSymbol.group);
dataSymbol.__keep = true;
}
});
var markPointTypeCalculatorWithExtent = function (percent, data, baseAxisDim, valueAxisDim) {
var extent = data.getDataExtent(valueAxisDim);
var valueIndex = (valueAxisDim === 'radius' || valueAxisDim === 'x') ? 0 : 1;
var valueArr = [];
var min = extent[0];
var max = extent[1];
var val = (max - min) * percent + min;
var dataIndex = data.indexOfNearest(valueAxisDim, val);
valueArr[1 - valueIndex] = data.get(baseAxisDim, dataIndex);
valueArr[valueIndex] = data.get(valueAxisDim, dataIndex, true);
return valueArr;
};
var markPointTypeCalculator = {
/**
* @method
* @param {module:echarts/data/List} data
* @param {string} baseAxisDim
* @param {string} valueAxisDim
*/
min: zrUtil.curry(markPointTypeCalculatorWithExtent, 0),
/**
* @method
* @param {module:echarts/data/List} data
* @param {string} baseAxisDim
* @param {string} valueAxisDim
*/
max: zrUtil.curry(markPointTypeCalculatorWithExtent, 1),
/**
* @method
* @param {module:echarts/data/List} data
* @param {string} baseAxisDim
* @param {string} valueAxisDim
*/
average: zrUtil.curry(markPointTypeCalculatorWithExtent, 0.5)
};
var dataTransform = function (data, baseAxis, valueAxis, item) {
// If not specify the position with pixel directly
if (isNaN(item.x) || isNaN(item.y) && !zrUtil.isArray(item.value)) {
// Clone the option
// Transform the properties xAxis, yAxis, radiusAxis, angleAxis, geoCoord to value
// Competitable with 2.x
item = zrUtil.extend({}, item);
// Special types, Compatible with 2.0
if (item.type && markPointTypeCalculator[item.type]
&& baseAxis && valueAxis) {
var value = markPointTypeCalculator[item.type](
data, baseAxis.dim, valueAxis.dim
);
value.push(+item.value);
item.value = value;
}
else if (!isNaN(item.value)) {
// FIXME Only has one of xAxis and yAxis.
item.value = [
item.xAxis || item.radiusAxis,
item.yAxis || item.angleAxis,
+item.value
];
}
}
return item;
};
// Filter data which is out of coordinateSystem range
var dataFilter = function (coordSys, dimensionInverse, item) {
var value = [item.value[0], item.value[1]];
dimensionInverse && value.inverse();
return coordSys.containData(value);
}
/**
* @inner
* @param {module:echarts/coord/*} coordSys
* @param {module:echarts/data/List} seriesData
* @param {module:echarts/model/Model} mpModel
*/
var createList = function (coordSys, seriesData, mpModel) {
var baseAxis = coordSys && coordSys.getBaseAxis();
var valueAxis = coordSys && coordSys.getOtherAxis(baseAxis);
var dimensions = seriesData.dimensions.slice();
// Polar and cartesian with category axis may have dimensions inversed
var dimensionInverse = dimensions[0] === 'y' || dimensions[0] === 'angle';
if (dimensionInverse) {
dimensions.inverse();
}
var mpData = new List(zrUtil.map(
dimensions, seriesData.getDimensionInfo, seriesData
), mpModel);
mpData.initData(
zrUtil.filter(
zrUtil.map(mpModel.get('data'), zrUtil.curry(
dataTransform, seriesData, baseAxis, valueAxis
)),
zrUtil.curry(dataFilter, coordSys, dimensionInverse)
)
);
return mpData;
};
});
\ No newline at end of file
define(function (require) {
var zrUtil = require('zrender/core/util');
var Model = require('../../model/Model');
// Default enable markpoint
var globalDefault = require('../../model/globalDefault');
globalDefault.markPoint = {};
var MarkPointModel = require('../../echarts').extendComponentModel({
type: 'markPoint',
dependencies: ['series', 'grid', 'polar'],
/**
* @overrite
*/
init: function (option, parentModel, ecModel, dependentModels, idx, createdBySelf) {
this.mergeDefaultAndTheme(option, ecModel);
this.mergeOption(option, createdBySelf);
},
mergeOption: function (newOpt, createdBySelf) {
// If not created by self for each series
if (!createdBySelf) {
var ecModel = this.ecModel;
ecModel.eachSeries(function (seriesModel) {
var markPointOpt = seriesModel.get('markPoint');
if (markPointOpt && markPointOpt.data) {
var mpModel = seriesModel.markPointModel;
if (!mpModel) {
mpModel = new MarkPointModel(
markPointOpt, this, ecModel, [], 0, true
);
}
else {
mpModel.mergeOption(markPointOpt, true);
}
// Use the same series index
mpModel.seriesIndex = seriesModel.seriesIndex;
seriesModel.markPointModel = mpModel;
}
else {
seriesModel.markPointModel = null;
}
}, this);
}
},
defaultOption: {
zlevel: 0,
z: 5,
clickable: true,
symbol: 'pin', // 标注类型
symbolSize: [30, 50], // 标注大小
// symbolRotate: null, // 标注旋转控制
large: false,
effect: {
show: false,
loop: true,
// 运动周期,无单位,值越大越慢
period: 15,
// 可用为 scale | bounce
type: 'scale',
// 放大倍数,以markPoint点size为基准
scaleSize: 2,
// 跳动距离,单位px
bounceDistance: 10
// color: 'gold',
// shadowColor: 'rgba(255,215,0,0.8)',
// 炫光模糊
// shadowBlur: 0
},
itemStyle: {
normal: {
// color: 各异,
// 标注边线颜色,优先于color
// borderColor: 各异,
// 标注边线线宽,单位px,默认为1
borderWidth: 2,
label: {
show: true,
// 标签文本格式器,同Tooltip.formatter,不支持回调
// formatter: null,
// 可选为'left'|'right'|'top'|'bottom'
position: 'inside'
// 默认使用全局文本样式,详见TEXTSTYLE
// textStyle: null
}
},
emphasis: {
// color: 各异
label: {
show: true
// 标签文本格式器,同Tooltip.formatter,不支持回调
// formatter: null,
// position: 'inside' // 'left'|'right'|'top'|'bottom'
// textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE
}
}
}
}
});
return MarkPointModel;
});
\ No newline at end of file
...@@ -51,8 +51,9 @@ define(function (require) { ...@@ -51,8 +51,9 @@ define(function (require) {
constructor: Axis, constructor: Axis,
/** /**
* If axis extent contain give coord * If axis extent contain given coord
* @param {number} * @param {number} coord
* @return {boolean}
*/ */
contain: function (coord) { contain: function (coord) {
var extent = this._extent; var extent = this._extent;
...@@ -61,6 +62,15 @@ define(function (require) { ...@@ -61,6 +62,15 @@ define(function (require) {
return coord >= min && coord <= max; return coord >= min && coord <= max;
}, },
/**
* If axis extent contain given data
* @param {number} data
* @return {boolean}
*/
containData: function (data) {
return this.contain(this.dataToCoord(data))
},
/** /**
* Get coord extent. * Get coord extent.
* @return {Array.<number>} * @return {Array.<number>}
......
...@@ -39,6 +39,12 @@ define(function (require) { ...@@ -39,6 +39,12 @@ define(function (require) {
constructor: Axis2D, constructor: Axis2D,
/**
* If axis is on the zero position of the other axis
* @type {boolean}
*/
onZero: false,
/** /**
* Axis model * Axis model
* @param {module:echarts/coord/cartesian/AxisModel} * @param {module:echarts/coord/cartesian/AxisModel}
......
...@@ -33,15 +33,18 @@ define(function(require) { ...@@ -33,15 +33,18 @@ define(function(require) {
type: 'xAxis', type: 'xAxis',
init: function (axisOption, parentModel, ecModel) { init: function (axisOption, parentModel, ecModel) {
AxisModel.prototype.init.call(this);
axisOption.type = axisOption.type || 'category'; zrUtil.merge(axisOption, this.getDefaultOption(), false);
axisOption.position = axisOption.position || 'bottom'; mergeDefault(axisOption, ecModel);
},
axisOption.gridIndex = axisOption.gridIndex || 0; defaultOption: {
type: 'category',
mergeDefault(axisOption, ecModel); gridIndex: 0,
position: 'bottom'
} }
}); });
...@@ -51,15 +54,18 @@ define(function(require) { ...@@ -51,15 +54,18 @@ define(function(require) {
type: 'yAxis', type: 'yAxis',
init: function (axisOption, parentModel, ecModel) { init: function (axisOption, parentModel, ecModel) {
AxisModel.prototype.init.call(this);
axisOption.type = axisOption.type || 'value'; zrUtil.merge(axisOption, this.getDefaultOption(), false);
axisOption.position = axisOption.position || 'left'; mergeDefault(axisOption, ecModel);
},
axisOption.gridIndex = axisOption.gridIndex || 0; defaultOption: {
type: 'value',
mergeDefault(axisOption, ecModel); gridIndex: 0,
position: 'left'
} }
}); });
......
...@@ -38,6 +38,16 @@ define(function(require) { ...@@ -38,6 +38,16 @@ define(function(require) {
&& this.getAxis('y').contain(point[1]); && this.getAxis('y').contain(point[1]);
}, },
/**
* If contain data
* @param {Array.<number>} data
* @return {boolean}
*/
containData: function (data) {
return this.getAxis('x').containData(data[0])
&& this.getAxis('y').containData(data[1]);
},
/** /**
* Convert series data to a list of points * Convert series data to a list of points
* @param {module:echarts/data/List} data * @param {module:echarts/data/List} data
......
...@@ -12,6 +12,8 @@ define(function(require, factory) { ...@@ -12,6 +12,8 @@ define(function(require, factory) {
var IntervalScale = require('../../scale/Interval'); var IntervalScale = require('../../scale/Interval');
var numberUtil = require('../../util/number'); var numberUtil = require('../../util/number');
var CATEGORY_AXIS_TYPE = 'category';
// 依赖 GridModel, AxisModel 做预处理 // 依赖 GridModel, AxisModel 做预处理
require('./GridModel'); require('./GridModel');
...@@ -23,7 +25,7 @@ define(function(require, factory) { ...@@ -23,7 +25,7 @@ define(function(require, factory) {
function createScaleByModel(axisModel) { function createScaleByModel(axisModel) {
var axisType = axisModel.get('type'); var axisType = axisModel.get('type');
if (axisType) { if (axisType) {
return axisType === 'category' return axisType === CATEGORY_AXIS_TYPE
// Give [Infinity, -Infinity] extent to make the unionExtent is right // Give [Infinity, -Infinity] extent to make the unionExtent is right
? new OrdinalScale(axisModel.get('data'), [Infinity, -Infinity]) ? new OrdinalScale(axisModel.get('data'), [Infinity, -Infinity])
: new IntervalScale(); : new IntervalScale();
...@@ -205,6 +207,14 @@ define(function(require, factory) { ...@@ -205,6 +207,14 @@ define(function(require, factory) {
this._coordsMap[key] = cartesian; this._coordsMap[key] = cartesian;
this._coordsList.push(cartesian); this._coordsList.push(cartesian);
// On zero can not be used when other axis is a category axis
if (xAxis.type === CATEGORY_AXIS_TYPE) {
yAxis.onZero = false;
}
if (yAxis.type === CATEGORY_AXIS_TYPE) {
xAxis.onZero = false;
}
cartesian.addAxis(xAxis); cartesian.addAxis(xAxis);
cartesian.addAxis(yAxis); cartesian.addAxis(yAxis);
}, this); }, this);
...@@ -230,9 +240,12 @@ define(function(require, factory) { ...@@ -230,9 +240,12 @@ define(function(require, factory) {
axisPosition axisPosition
); );
axis.onBand = axisModel.get('boundaryGap') && axis.type === 'category'; var isCategory = axis.type === CATEGORY_AXIS_TYPE;
axis.onBand = isCategory && axisModel.get('boundaryGap');
axis.inverse = axisModel.get('inverse'); axis.inverse = axisModel.get('inverse');
axis.onZero = axisModel.get('axisLine.onZero');
// Inject axis into axisModel // Inject axis into axisModel
axisModel.axis = axis; axisModel.axis = axis;
......
...@@ -53,6 +53,8 @@ define(function(require) { ...@@ -53,6 +53,8 @@ define(function(require) {
/** /**
* If contain coord * If contain coord
* @param {Array.<number>} point
* @return {boolean}
*/ */
containPoint: function (point) { containPoint: function (point) {
var coord = this.pointToCoord(point); var coord = this.pointToCoord(point);
...@@ -61,6 +63,17 @@ define(function(require) { ...@@ -61,6 +63,17 @@ define(function(require) {
}, },
/** /**
* If contain data
* @param {Array.<number>} data
* @return {boolean}
*/
containData: function (data) {
return this._radiusAxis.containData(data[0])
&& this._angleAxis.containData(data[1]);
},
/**
* @param {string} axisType
* @return {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis} * @return {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis}
*/ */
getAxis: function (axisType) { getAxis: function (axisType) {
...@@ -69,6 +82,8 @@ define(function(require) { ...@@ -69,6 +82,8 @@ define(function(require) {
/** /**
* Get axes by type of scale * Get axes by type of scale
* @param {string} scaleType
* @return {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis}
*/ */
getAxesByScale: function (scaleType) { getAxesByScale: function (scaleType) {
var axes = []; var axes = [];
......
...@@ -15,6 +15,23 @@ define(function (require) { ...@@ -15,6 +15,23 @@ define(function (require) {
*/ */
coordinateSystem: null, coordinateSystem: null,
/**
* @param {string} axisType
* @return {module:echarts/coord/polar/AxisModel}
*/
findAxisModel: function (axisType) {
var angleAxisModel;
var ecModel = this.ecModel;
ecModel.eachComponent(axisType, function (axisModel) {
if (ecModel.getComponent(
'polar', axisModel.getShallow('polarIndex')
) === this) {
angleAxisModel = axisModel;
}
}, this);
return angleAxisModel;
},
defaultOption: { defaultOption: {
zlevel: 0, zlevel: 0,
......
...@@ -10,29 +10,6 @@ define(function (require) { ...@@ -10,29 +10,6 @@ define(function (require) {
// 依赖 PolarModel 做预处理 // 依赖 PolarModel 做预处理
require('./PolarModel'); require('./PolarModel');
/**
* Retrieve angle axis or radius axis belongs to the given polar
* @param {string} axisType
* @param {number} polarIndex
* @param {module:echarts/model/Global} ecModel
* @param {module:echarts/ExtensionAPI} api
* @return {module:echarts/coord/polar/AxisModel}
* @inner
*/
function retrieveAxisModelForPolar(axisType, polarIndex, ecModel, api) {
var axisModel;
ecModel.eachComponent(axisType, function (model) {
if (model.get('polarIndex') === polarIndex) {
if (axisModel) {
// api.log('Polar ' + polarIndex + ' has more than one ' + axisType);
return;
}
axisModel = model;
}
});
return axisModel;
}
/** /**
* Resize methods bound to the polar * Resize methods bound to the polar
* @param {module:echarts/coord/polar/PolarModel} polarModel * @param {module:echarts/coord/polar/PolarModel} polarModel
...@@ -134,8 +111,8 @@ define(function (require) { ...@@ -134,8 +111,8 @@ define(function (require) {
var radiusAxis = polar.getRadiusAxis(); var radiusAxis = polar.getRadiusAxis();
var angleAxis = polar.getAngleAxis(); var angleAxis = polar.getAngleAxis();
var radiusAxisModel = retrieveAxisModelForPolar('radiusAxis', idx, ecModel, api); var radiusAxisModel = polarModel.findAxisModel('radiusAxis');
var angleAxisModel = retrieveAxisModelForPolar('angleAxis', idx, ecModel, api); var angleAxisModel = polarModel.findAxisModel('angleAxis');
setAxis(radiusAxis, radiusAxisModel); setAxis(radiusAxis, radiusAxisModel);
setAxis(angleAxis, angleAxisModel); setAxis(angleAxis, angleAxisModel);
......
...@@ -14,6 +14,8 @@ define(function (require) { ...@@ -14,6 +14,8 @@ define(function (require) {
var dataCtors = { var dataCtors = {
float: Float32Array, float: Float32Array,
int: Int32Array, int: Int32Array,
// Ordinal data type can be string or int
ordinal: Array,
'number': Array 'number': Array
}; };
...@@ -28,9 +30,9 @@ define(function (require) { ...@@ -28,9 +30,9 @@ define(function (require) {
* @alias module:echarts/data/List * @alias module:echarts/data/List
* *
* @param {Array.<string>} dimensions * @param {Array.<string>} dimensions
* @param {module:echarts/model/Model} seriesModel * @param {module:echarts/model/Model} hostModel
*/ */
var List = function (dimensions, seriesModel) { var List = function (dimensions, hostModel) {
dimensions = dimensions || ['x', 'y']; dimensions = dimensions || ['x', 'y'];
...@@ -52,7 +54,7 @@ define(function (require) { ...@@ -52,7 +54,7 @@ define(function (require) {
else { else {
dimensionInfo = dimensions[i]; dimensionInfo = dimensions[i];
dimensionName = dimensionInfo.name; dimensionName = dimensionInfo.name;
dimensionInfo.type = dimensionInfo.type || 'float' dimensionInfo.type = dimensionInfo.type || 'number'
} }
dimensionNames.push(dimensionName); dimensionNames.push(dimensionName);
dimensionInfos[dimensionName] = dimensionInfo; dimensionInfos[dimensionName] = dimensionInfo;
...@@ -72,7 +74,7 @@ define(function (require) { ...@@ -72,7 +74,7 @@ define(function (require) {
/** /**
* @type {module:echarts/model/Model} * @type {module:echarts/model/Model}
*/ */
this.seriesModel = seriesModel; this.hostModel = hostModel;
/** /**
* Indices stores the indices of data subset after filtered. * Indices stores the indices of data subset after filtered.
...@@ -144,6 +146,13 @@ define(function (require) { ...@@ -144,6 +146,13 @@ define(function (require) {
listProto.type = 'list'; listProto.type = 'list';
/**
* Get type and stackable info of particular dimension
*/
listProto.getDimensionInfo = function (dim) {
return this._dimensionInfos[dim];
};
/** /**
* Initialize from data * Initialize from data
* @param {Array.<Object|number|Array>} data * @param {Array.<Object|number|Array>} data
...@@ -180,7 +189,7 @@ define(function (require) { ...@@ -180,7 +189,7 @@ define(function (require) {
// Each data item contains value and option // Each data item contains value and option
if (data[idx] != null && data[idx].hasOwnProperty('value')) { if (data[idx] != null && data[idx].hasOwnProperty('value')) {
value = data[idx].value; value = data[idx].value;
var model = new Model(data[idx], this.seriesModel); var model = new Model(data[idx], this.hostModel);
var modelIdx = optionModels.length; var modelIdx = optionModels.length;
optionModelIndices[idx] = modelIdx; optionModelIndices[idx] = modelIdx;
optionModels.push(model); optionModels.push(model);
...@@ -263,6 +272,7 @@ define(function (require) { ...@@ -263,6 +272,7 @@ define(function (require) {
var dataIndex = this.indices[idx]; var dataIndex = this.indices[idx];
var value = storage[dim] && storage[dim][dataIndex]; var value = storage[dim] && storage[dim][dataIndex];
// FIXME ordinal data type is not stackable
if (stack && this.stackedOn) { if (stack && this.stackedOn) {
var stackedValue = this.stackedOn.get(dim, idx, stack); var stackedValue = this.stackedOn.get(dim, idx, stack);
// Considering positive stack, negative stack and empty data // Considering positive stack, negative stack and empty data
...@@ -283,8 +293,13 @@ define(function (require) { ...@@ -283,8 +293,13 @@ define(function (require) {
*/ */
listProto.hasValue = function (idx) { listProto.hasValue = function (idx) {
var dimensions = this.dimensions; var dimensions = this.dimensions;
var dimensionInfos = this._dimensionInfos;
for (var i = 0, len = dimensions.length; i < len; i++) { for (var i = 0, len = dimensions.length; i < len; i++) {
if (isNaN(this.get(dimensions[i], idx))) { if (
// Ordinal type can be string or number
dimensionInfos[dimensions[i]].type !== 'ordinal'
&& isNaN(this.get(dimensions[i], idx))
) {
return false; return false;
} }
} }
...@@ -360,10 +375,12 @@ define(function (require) { ...@@ -360,10 +375,12 @@ define(function (require) {
listProto.indexOf = function (dim, value) { listProto.indexOf = function (dim, value) {
var storage = this._storage; var storage = this._storage;
var dimData = storage[dim]; var dimData = storage[dim];
var indices = this.indices;
if (dimData) { if (dimData) {
for (var i = 0, len = dimData.length; i < len; i++) { for (var i = 0, len = indices.length; i < len; i++) {
if (dimData[i] === value) { var rawIndex = indices[i];
if (dimData[rawIndex] === value) {
return i; return i;
} }
} }
...@@ -371,6 +388,32 @@ define(function (require) { ...@@ -371,6 +388,32 @@ define(function (require) {
return -1; return -1;
}; };
/**
* Retreive the index of nearest value
* @param {number} idx
* @param {number} value
* @param {boolean} stack If given value is after stacked
* @return {number}
*/
listProto.indexOfNearest = function (dim, value, stack) {
var storage = this._storage;
var dimData = storage[dim];
if (dimData) {
var minDist = Number.MAX_VALUE;
var nearestIdx = -1;
for (var i = 0, len = this.count(); i < len; i++) {
var dist = Math.abs(this.get(dim, i, stack) - value);
if (dist <= minDist) {
minDist = dist;
nearestIdx = i;
}
}
return nearestIdx;
}
return -1;
}
/** /**
* Get raw data index * Get raw data index
* @param {number} idx * @param {number} idx
...@@ -558,7 +601,7 @@ define(function (require) { ...@@ -558,7 +601,7 @@ define(function (require) {
// Use a temporary model proxy if value on idx is not an option. // Use a temporary model proxy if value on idx is not an option.
// FIXME Create a new one may cause memory leak // FIXME Create a new one may cause memory leak
model = temporaryModel; model = temporaryModel;
model.parentModel = this.seriesModel; model.parentModel = this.hostModel;
} }
return model; return model;
}; };
...@@ -670,15 +713,23 @@ define(function (require) { ...@@ -670,15 +713,23 @@ define(function (require) {
itemVisual[key] = value; itemVisual[key] = value;
}; };
var setItemDataAndSeriesIndex = function (child) {
child.seriesIndex = this.seriesIndex;
child.dataIndex = this.dataIndex;
}
/** /**
* @param {number} idx * @param {number} idx
* @param {module:zrender/Element} el * @param {module:zrender/Element} el
*/ */
listProto.setItemGraphicEl = function (idx, el) { listProto.setItemGraphicEl = function (idx, el) {
var hostModel = this.hostModel;
// Add data index and series index for indexing the data by element // Add data index and series index for indexing the data by element
// Useful in tooltip // Useful in tooltip
el.dataIndex = idx; el.dataIndex = idx;
el.seriesIndex = this.seriesModel.seriesIndex; el.seriesIndex = hostModel && hostModel.seriesIndex;;
if (el.type === 'group') {
el.traverse(setItemDataAndSeriesIndex, this)
}
this._graphicEls[idx] = el; this._graphicEls[idx] = el;
}; };
...@@ -711,7 +762,7 @@ define(function (require) { ...@@ -711,7 +762,7 @@ define(function (require) {
var dimensionInfoList = zrUtil.map(this.dimensions, function (dim) { var dimensionInfoList = zrUtil.map(this.dimensions, function (dim) {
return this._dimensionInfos[dim]; return this._dimensionInfos[dim];
}, this); }, this);
var list = new List(dimensionInfoList, this.seriesModel); var list = new List(dimensionInfoList, this.hostModel);
list.stackedOn = this.stackedOn; list.stackedOn = this.stackedOn;
// FIXME // FIXME
......
...@@ -144,10 +144,12 @@ define(function(require) { ...@@ -144,10 +144,12 @@ define(function(require) {
var columnLayoutInfo = barWidthAndOffset[cartesian.name][stackId]; var columnLayoutInfo = barWidthAndOffset[cartesian.name][stackId];
var columnOffset = columnLayoutInfo.offset; var columnOffset = columnLayoutInfo.offset;
var columnWidth = columnLayoutInfo.width; var columnWidth = columnLayoutInfo.width;
var valueAxis = cartesian.getOtherAxis(columnLayoutInfo.axis); var baseAxis = columnLayoutInfo.axis;
var valueAxis = cartesian.getOtherAxis(baseAxis);
if (data.type === 'list') { if (data.type === 'list') {
var valueAxisStart = valueAxis.getExtent()[0]; var valueAxisStart = baseAxis.onZero
? valueAxis.dataToCoord(0) : valueAxis.getExtent()[0];
var coords = cartesian.dataToPoints(data, true); var coords = cartesian.dataToPoints(data, true);
lastStackCoords[stackId] = lastStackCoords[stackId] || []; lastStackCoords[stackId] = lastStackCoords[stackId] || [];
...@@ -156,25 +158,31 @@ define(function(require) { ...@@ -156,25 +158,31 @@ define(function(require) {
if (isNaN(value)) { if (isNaN(value)) {
return; return;
} }
if (!lastStackCoords[stackId][idx]) {
lastStackCoords[stackId][idx] = {
// Positive stack
p: valueAxisStart,
// Negative stack
n: valueAxisStart
}
}
var sign = value >= 0 ? 'p' : 'n';
var coord = coords[idx]; var coord = coords[idx];
var lastCoord = lastStackCoords[stackId][idx] || valueAxisStart; var lastCoord = lastStackCoords[stackId][idx][sign];
var x, y, width, height; var x, y, width, height;
if (valueAxis.isHorizontal()) { if (valueAxis.isHorizontal()) {
x = Math.min(lastCoord, coord[0]); x = lastCoord;
y = coord[1] + columnOffset; y = coord[1] + columnOffset;
width = Math.abs(coord[0] - lastCoord); width = coord[0] - lastCoord;
height = columnWidth; height = columnWidth;
lastCoord += coord[0] - lastCoord;
} }
else { else {
x = coord[0] + columnOffset; x = coord[0] + columnOffset;
y = Math.min(lastCoord, coord[1]); y = lastCoord;
width = columnWidth; width = columnWidth;
height = Math.abs(coord[1] - lastCoord); height = coord[1] - lastCoord;
lastCoord += coord[1] - lastCoord;
} }
lastStackCoords[stackId][idx] = lastCoord; lastStackCoords[stackId][idx][sign] += height;
data.setItemLayout(idx, { data.setItemLayout(idx, {
x: x, x: x,
......
// 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
...@@ -9,6 +9,8 @@ define(function (require) { ...@@ -9,6 +9,8 @@ define(function (require) {
/** /**
* @alias module:echarts/model/Model * @alias module:echarts/model/Model
* @constructor * @constructor
* @param {Object} option
* @param {module:echarts/model/Model} parentModel
*/ */
function Model(option, parentModel) { function Model(option, parentModel) {
...@@ -89,12 +91,15 @@ define(function (require) { ...@@ -89,12 +91,15 @@ define(function (require) {
/** /**
* @param {string} path * @param {string} path
* @param {module:echarts/model/Model} [parentModel]
* @return {module:echarts/model/Model} * @return {module:echarts/model/Model}
*/ */
getModel: function (path) { getModel: function (path, parentModel) {
var obj = this.get(path); var obj = this.get(path);
var parentModel = this.parentModel; var thisParentModel = this.parentModel;
return new Model(obj, parentModel && parentModel.getModel(path)); return new Model(
obj, parentModel || (thisParentModel && thisParentModel.getModel(path))
);
}, },
/** /**
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
// FIXME only one data // FIXME only one data
define(function (require) { define(function (require) {
var zrUtil = require('zrender/core/util');
/** /**
* @alias module:echarts/coord/scale/Ordinal * @alias module:echarts/coord/scale/Ordinal
* @param {Array} data * @param {Array} data
...@@ -39,10 +41,14 @@ define(function (require) { ...@@ -39,10 +41,14 @@ define(function (require) {
}, },
/** /**
* Normalize given rank to linear [0, 1] * Normalize given rank or name to linear [0, 1]
* @return {number} [val] * @param {number|string} [val]
* @return {number}
*/ */
normalize: function (val) { normalize: function (val) {
if (isNaN(val)) { // Is string
val = zrUtil.indexOf(this._data, val);
}
var extent = this._extent; var extent = this._extent;
// Only one data // Only one data
if (extent[1] === extent[0]) { if (extent[1] === extent[0]) {
......
...@@ -24,7 +24,7 @@ define(function(require) { ...@@ -24,7 +24,7 @@ define(function(require) {
graphic.Polyline = require('zrender/graphic/shape/Polyline'); graphic.Polyline = require('zrender/graphic/shape/Polyline');
graphic.Rect = require('zrender/graphic/shape/Rectangle'); graphic.Rect = require('zrender/graphic/shape/Rect');
graphic.Line = require('zrender/graphic/shape/Line'); graphic.Line = require('zrender/graphic/shape/Line');
......
...@@ -101,10 +101,10 @@ define(function(require) { ...@@ -101,10 +101,10 @@ define(function(require) {
} }
switch (positionInfo.y || positionInfo.y2) { switch (positionInfo.y || positionInfo.y2) {
case 'middle': case 'middle':
y -= containerHeight / 2 - height / 2; y = containerHeight / 2 - height / 2;
break; break;
case 'bottom': case 'bottom':
y -= containerHeight - height; y = containerHeight - height;
break; break;
} }
......
...@@ -5,6 +5,7 @@ define(function(require) { ...@@ -5,6 +5,7 @@ define(function(require) {
var graphic = require('./graphic'); var graphic = require('./graphic');
var BoundingRect = require('zrender/core/BoundingRect'); var BoundingRect = require('zrender/core/BoundingRect');
var zrUtil = require('zrender/core/util');
/** /**
* Diamond shape * Diamond shape
...@@ -29,140 +30,243 @@ define(function(require) { ...@@ -29,140 +30,243 @@ define(function(require) {
} }
}); });
var symbolCreators = { /**
line: function (x, y, w, h) { * Pin shape
return new graphic.Line({ */
var Pin = graphic.extendShape({
type: 'pin',
shape: { shape: {
// x, y on the cusp
x: 0,
y: 0,
width: 0,
height: 0
},
buildPath: function (path, shape) {
var x = shape.x;
var y = shape.y;
var w = shape.width;
// Height must be larger than width
var h = Math.max(w, shape.height);
var r = w / 2;
// Dist on y with tangent point and circle center
var dy = r * r / (h - r);
var cy = y - h + r + dy;
var angle = Math.asin(dy / r);
// Dist on x with tangent point and circle center
var dx = Math.cos(angle) * r;
var tanX = Math.sin(angle);
var tanY = Math.cos(angle);
path.arc(
x,
cy,
r,
Math.PI - angle,
Math.PI * 2 + angle
);
var cpLen = r * 0.6;
var cpLen2 = r * 0.7;
path.bezierCurveTo(
x + dx - tanX * cpLen, cy + dy + tanY * cpLen,
x, y - cpLen2,
x, y
);
path.bezierCurveTo(
x, y - cpLen2,
x - dx + tanX * cpLen, cy + dy + tanY * cpLen,
x - dx, cy + dy
);
}
});
var symbolCtors = {
line: graphic.Line,
rect: graphic.Rect,
roundRect: graphic.Rect,
square: graphic.Rect,
circle: graphic.Circle,
diamond: Diamond,
pin: Pin
};
var symbolShapeMakers = {
line: function (x, y, w, h) {
return {
x1: x, x1: x,
y1: y + h / 2, y1: y + h / 2,
x2: x + w, x2: x + w,
y2: y + h / 2 y2: y + h / 2
} };
});
}, },
rect: function (x, y, w, h) { rect: function (x, y, w, h) {
return new graphic.Rect({ return {
shape: {
x: x, x: x,
y: y, y: y,
width: w, width: w,
height: h height: h
} }
})
}, },
roundRect: function (x, y, w, h, r) { roundRect: function (x, y, w, h, r) {
return new graphic.Rect({ return {
shape: {
x: x, x: x,
y: y, y: y,
width: w, width: w,
height: h, height: h,
r: r || Math.min(w, h) / 4 r: r || Math.min(w, h) / 4
} };
});
}, },
square: function (x, y, size) { square: function (x, y, size) {
return new graphic.Rect({ return {
shape: {
x: x, x: x,
y: y, y: y,
width: size / 2, width: size / 2,
height: size / 2 height: size / 2
} };
});
}, },
circle: function (x, y, w, h) { circle: function (x, y, w, h) {
// Put circle in the center of square // Put circle in the center of square
var size = Math.min(w, h); var size = Math.min(w, h);
return new graphic.Circle({ return {
shape: {
cx: x + w / 2, cx: x + w / 2,
cy: y + h / 2, cy: y + h / 2,
r: size / 2 r: size / 2
} }
});
}, },
diamond: function (x, y, w, h) { diamond: function (x, y, w, h) {
return new Diamond({ return {
shape: {
cx: x + w / 2, cx: x + w / 2,
cy: y + h / 2, cy: y + h / 2,
width: w, width: w,
height: h height: h
} };
})
}, },
image: function (img, x, y, w, h) { pin: function (x, y, w, h) {
return new graphic.Image({ return {
style: { x: x + w / 2,
image: img, // FIXME Why not y + h ?
x: x, y: y + h / 2,
y: y,
width: w, width: w,
height: h height: h
};
} }
})
},
path: function (pathStr, x, y, w, h) { };
return graphic.makePath(pathStr, null, new BoundingRect(x, y, w, h));
}
// Provide setColor helper method to avoid determine if set the fill or stroke outside
var symbolPathSetColor = function (color) {
var symbolStyle = this.style;
if (this.__isEmptyBrush) {
symbolStyle.stroke = color;
}
else {
// FIXME 判断图形默认是填充还是描边,使用 onlyStroke ?
symbolStyle.fill && (symbolStyle.fill = color);
symbolStyle.stroke && (symbolStyle.stroke = color);
}
this.dirty();
}; };
return { var symbolUtil = {
/** /**
* Create a symbol element with given symbol configuration: shape, x, y, width, height, color * Create a symbol element with given symbol configuration: shape, x, y, width, height, color
* @param {string} symbolConfig * @param {string} symbolType
* @param {number} x * @param {number} x
* @param {number} y * @param {number} y
* @param {number} w * @param {number} w
* @param {number} h * @param {number} h
* @param {string} color * @param {string} color
*/ */
createSymbol: function (symbolConfig, x, y, w, h, color) { createSymbol: function (symbolType, x, y, w, h, color) {
var isEmpty = symbolConfig.indexOf('empty') === 0; var isEmpty = symbolType.indexOf('empty') === 0;
if (isEmpty) { if (isEmpty) {
symbolConfig = symbolConfig.substr(5, 1).toLowerCase() + symbolConfig.substr(6); symbolType = symbolType.substr(5, 1).toLowerCase() + symbolType.substr(6);
} }
var symbolPath; var symbolPath;
if (symbolConfig.indexOf('image://') === 0) { if (symbolType.indexOf('image://') === 0) {
symbolPath = symbolCreators.image(symbolConfig.slice(8), x, y, w, h); symbolPath = new graphic.Image({
style: {
image: symbolType.slice(8),
x: x,
y: y,
width: w,
height: h
} }
else if (symbolConfig.indexOf('path://') === 0) { });
symbolPath = symbolCreators.image(symbolConfig.slice(7), x, y, w, h);
} }
else { else if (symbolType.indexOf('path://') === 0) {
if (symbolCreators[symbolConfig]) { symbolPath = graphic.makePath(symbolType.slice(7), new BoundingRect(x, y, w, h));
symbolPath = symbolCreators[symbolConfig](x, y, w, h);
} }
else { else {
symbolPath = symbolCreators.rect(x, y, w, h); if (!symbolShapeMakers[symbolType]) {
symbolType = 'rect';
} }
symbolPath = new symbolCtors[symbolType]({
shape: symbolShapeMakers[symbolType](x, y, w, h)
});
} }
var symbolStyle = symbolPath.style; var symbolStyle = symbolPath.style;
if (isEmpty) { if (isEmpty) {
symbolStyle.set({ symbolStyle.set({
stroke: color,
fill: '#fff', fill: '#fff',
lineWidth: 2 lineWidth: 2
}); });
} }
else {
// FIXME 判断图形默认是填充还是描边,使用 onlyStroke ? symbolPath.__isEmptyBrush = isEmpty;
symbolStyle.fill && (symbolStyle.fill = color);
symbolStyle.stroke && (symbolStyle.stroke = color); symbolPath.setColor = symbolPathSetColor;
}
symbolPath.setColor(color);
return symbolPath; return symbolPath;
},
/**
* Get symbol shape object by given x, y, w, h
* @param {string} symbolType
* @param {number} x
* @param {number} y
* @param {number} w
* @param {number} h
* @return {Object}
*/
getSymbolShape: function (symbolType, x, y, w, h) {
if (symbolType.indexOf('empty') === 0) {
symbolType = symbolType.substr(5, 1).toLowerCase() + symbolType.substr(6);
}
if (symbolType.indexOf('image://') === 0) {
return {
style: {
x: x,
y: y,
width: w,
height: h
} }
}; };
}
else if (!(symbolType.indexOf('path://') === 0)) {
if (!symbolShapeMakers[symbolType]) {
symbolType = 'rect';
}
return {
shape: symbolShapeMakers[symbolType](x, y, w, h)
};
}
}
};
return symbolUtil;
}); });
\ No newline at end of file
...@@ -4,7 +4,9 @@ define(function (require) { ...@@ -4,7 +4,9 @@ define(function (require) {
ecModel.eachSeries(function (seriesModel) { ecModel.eachSeries(function (seriesModel) {
var colorList = ecModel.get('color'); var colorList = ecModel.get('color');
var data = seriesModel.getData(); var data = seriesModel.getData();
data.setVisual('color', colorList[seriesModel.seriesIndex]); var color = seriesModel.get('itemStyle.normal.color') // Set in itemStyle
|| colorList[seriesModel.seriesIndex]; // Default color
data.setVisual('color', color);
}); });
} }
}); });
\ No newline at end of file
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
} }
#main { #main {
width: 1000px; width: 1000px;
background: #999; background: #fff;
} }
</style> </style>
<div id="main"></div> <div id="main"></div>
...@@ -38,17 +38,23 @@ ...@@ -38,17 +38,23 @@
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
xAxisData.push('类目' + i); xAxisData.push('类目' + i);
data1.push(Math.random() * 5); data1.push((Math.random() * 5).toFixed(2));
data2.push(Math.random()); data2.push((Math.random() + 0.2).toFixed(2));
data3.push(Math.random()); data3.push((Math.random() + 0.5).toFixed(2));
} }
var itemStyle = { var itemStyle = {
normal: { normal: {
label: {
show: true,
position: 'outside'
}
}, },
emphasis: { emphasis: {
barBorderColor: 'red', shadowBlur: 10,
barBorderWidth: 1 shadowOffsetX: 0,
shadowOffsetY: 0,
shadowColor: 'rgba(0,0,0,0.5)'
} }
}; };
...@@ -63,13 +69,17 @@ ...@@ -63,13 +69,17 @@
}, },
orient: 'vertical', orient: 'vertical',
x: 'right', x: 'right',
y: 'bottom',
align: 'right' align: 'right'
}, },
tooltip: {}, tooltip: {},
xAxis: { xAxis: {
data: xAxisData, data: xAxisData,
splitLine: {
show: false
},
splitArea: { splitArea: {
show: true show: false
} }
}, },
yAxis: { yAxis: {
......
...@@ -21,7 +21,8 @@ ...@@ -21,7 +21,8 @@
'echarts/component/grid', 'echarts/component/grid',
'echarts/component/axis', 'echarts/component/axis',
'echarts/component/dataZoom', 'echarts/component/dataZoom',
'echarts/component/tooltip' 'echarts/component/tooltip',
'echarts/component/markPoint'
], function (echarts) { ], function (echarts) {
var chart = echarts.init(document.getElementById('main'), null, { var chart = echarts.init(document.getElementById('main'), null, {
...@@ -35,7 +36,7 @@ ...@@ -35,7 +36,7 @@
for (var i = 0; i < 200; i++) { for (var i = 0; i < 200; i++) {
xAxisData.push('类目' + i); xAxisData.push('类目' + i);
data1.push(Math.random() * 4); data1.push((Math.random() * 4).toFixed(2));
data2.push(Math.random()); data2.push(Math.random());
data3.push(Math.random()); data3.push(Math.random());
} }
...@@ -64,6 +65,11 @@ ...@@ -64,6 +65,11 @@
normal: { normal: {
areaStyle: {} areaStyle: {}
} }
},
markPoint: {
data: [{
type: 'max'
}]
} }
}, },
{ {
......
...@@ -21,16 +21,22 @@ ...@@ -21,16 +21,22 @@
'echarts/component/grid' 'echarts/component/grid'
], function (echarts) { ], function (echarts) {
function randomData() {
return (Math.random() + 3).toFixed(3);
}
var chart = echarts.init(document.getElementById('main'), null, { var chart = echarts.init(document.getElementById('main'), null, {
renderer: 'canvas' renderer: 'canvas'
}); });
var xAxisData = []; var xAxisData = [];
var data1 = []; var data1 = [];
var data2 = [];
var count = 0; var count = 0;
for (; count < 500; count++) { for (; count < 500; count++) {
xAxisData.push('类目' + count); xAxisData.push('类目' + count);
data1.push(+Math.random().toFixed(3)); data1.push(randomData());
data2.push(-randomData());
} }
var itemStyle = { var itemStyle = {
...@@ -56,7 +62,7 @@ ...@@ -56,7 +62,7 @@
chart.setOption({ chart.setOption({
legend: { legend: {
data: ['line'] data: ['line', 'line2']
}, },
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',
...@@ -73,6 +79,7 @@ ...@@ -73,6 +79,7 @@
boundaryGap: false boundaryGap: false
}, },
yAxis: { yAxis: {
scale: true,
splitLine: { splitLine: {
// show: false // show: false
} }
...@@ -85,6 +92,20 @@ ...@@ -85,6 +92,20 @@
symbolSize: 10, symbolSize: 10,
data: data1, data: data1,
itemStyle: itemStyle itemStyle: itemStyle
}, {
name: 'line2',
type: 'line',
stack: 'all',
symbol: 'none',
symbolSize: 10,
data: data2,
itemStyle: {
normal: {
areaStyle: {
color: 'black'
}
}
}
}] }]
}); });
...@@ -93,7 +114,11 @@ ...@@ -93,7 +114,11 @@
xAxisData.shift(); xAxisData.shift();
xAxisData.push('类目' + count); xAxisData.push('类目' + count);
data1.shift(); data1.shift();
data1.push(+Math.random().toFixed(3)); data1.push(randomData());
data2.shift();
data2.push(-randomData());
count++; count++;
} }
chart.setOption({ chart.setOption({
...@@ -103,6 +128,9 @@ ...@@ -103,6 +128,9 @@
series: [{ series: [{
name: 'line', name: 'line',
data: data1 data: data1
}, {
name: 'line2',
data: data2
}] }]
}); });
}, 500); }, 500);
......
...@@ -72,12 +72,15 @@ ...@@ -72,12 +72,15 @@
boundaryGap: false, boundaryGap: false,
// inverse: true, // inverse: true,
splitArea: { splitArea: {
show: true show: false
},
splitLine: {
show: false
} }
}, },
yAxis: { yAxis: {
splitLine: { splitArea: {
// show: false show: true
} }
}, },
series: [{ series: [{
...@@ -106,18 +109,6 @@ ...@@ -106,18 +109,6 @@
itemStyle: itemStyle itemStyle: itemStyle
}] }]
}); });
chart.setOption({
series: [{
name: 'line',
type: 'line',
stack: 'all',
symbol: 'circle',
symbolSize: 10,
data: data1,
itemStyle: itemStyle
}]
});
}) })
</script> </script>
......
<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>
<script>
require([
'echarts',
'echarts/chart/line',
'echarts/component/legend',
'echarts/component/grid',
'echarts/component/tooltip',
'echarts/component/markPoint'
], function (echarts) {
var chart = echarts.init(document.getElementById('main'), null, {
renderer: 'canvas'
});
var xAxisData = [];
var data1 = [];
var data2 = [];
var data3 = [];
for (var i = 0; i < 10; i++) {
xAxisData.push('类目' + i);
data1.push(+Math.random().toFixed(2));
data2.push(+Math.random().toFixed(2));
}
chart.setOption({
legend: {
data: ['line', 'line2', 'line3']
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'line'
}
},
xAxis: {
// data: ['类目1', '类目2', '类目3', '类目4', '类目5',]
data: xAxisData,
boundaryGap: false,
// inverse: true,
splitArea: {
show: true
}
},
yAxis: {
splitLine: {
// show: false
}
},
series: [{
name: 'line',
type: 'line',
stack: 'all',
symbolSize: 6,
data: data1,
markPoint: {
data: [{
name: '最大值',
type: 'max',
value: 1
}, {
xAxis: '类目3',
yAxis: 0.5,
value: 2
}]
}
}, {
name: 'line2',
type: 'line',
stack: 'all',
symbolSize: 6,
data: data2,
markPoint: {
data: [{
name: '最大值',
type: 'max',
value: 1
}]
}
}]
});
})
</script>
</body>
</html>
\ 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
...@@ -31,9 +31,9 @@ ...@@ -31,9 +31,9 @@
var data3 = []; var data3 = [];
for (var i = 0; i < 100; i++) { for (var i = 0; i < 100; i++) {
data1.push([Math.random() * 5, Math.random() * 4, Math.random()]); data1.push([Math.random() * 5, Math.random() * 4, Math.random().toFixed(2)]);
data2.push([Math.random() * 10, Math.random() * 5, Math.random()]); data2.push([Math.random() * 10, Math.random() * 5, (Math.random() + 0.3).toFixed(2)]);
data3.push([Math.random() * 15, Math.random() * 10, Math.random()]); data3.push([Math.random() * 15, Math.random() * 10, Math.random().toFixed(2)]);
} }
chart.setOption({ chart.setOption({
...@@ -75,6 +75,13 @@ ...@@ -75,6 +75,13 @@
symbolSize: function (val) { symbolSize: function (val) {
return val[2] * 40; return val[2] * 40;
}, },
itemStyle: {
normal: {
label: {
show: true
}
}
},
data: data2 data: data2
}, { }, {
name: 'scatter3', name: 'scatter3',
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册