提交 01f33e47 编写于 作者: L lang

Pin symbol shape, markPoint

上级 a712df0f
......@@ -5,6 +5,13 @@ define(function (require) {
var symbolCreators = require('../../util/symbol');
var graphic = require('../../util/graphic');
function normalizeSymbolSize(symbolSize) {
if (!zrUtil.isArray(symbolSize)) {
symbolSize = [+symbolSize, +symbolSize];
}
return symbolSize;
}
function createSymbol(data, idx, enableAnimation) {
var point = data.getItemLayout(idx);
var color = data.getItemVisual(idx, 'color');
......@@ -16,8 +23,19 @@ define(function (require) {
return;
}
symbolSize = normalizeSymbolSize(symbolSize);
// FIXME
var x = -0.5;
var y = -0.5;
var w = 1;
var h = 1;
if (symbolType.match(/(pin|Pin)$/)) {
y = -1;
h = 2;
}
var symbolEl = symbolCreators.createSymbol(
symbolType, -0.5, -0.5, 1, 1, color
symbolType, x, y, w, h, color
);
symbolEl.position = point;
......@@ -29,7 +47,7 @@ define(function (require) {
symbolEl.scale = [0.1, 0.1];
symbolEl.animateTo({
scale: [symbolSize, symbolSize]
scale: symbolSize
}, 500);
// symbolEl
......@@ -94,7 +112,9 @@ define(function (require) {
return;
}
var symbolSize = data.getItemVisual(newIdx, 'symbolSize');
var symbolSize = normalizeSymbolSize(
data.getItemVisual(newIdx, 'symbolSize')
);
var point = data.getItemLayout(newIdx);
// Symbol changed
......@@ -108,22 +128,21 @@ define(function (require) {
return;
}
// Color changed
// Update color
// FIXME emptyXXX ?
var newColor = data.getItemVisual(newIdx, 'color');
if (oldData.getItemVisual(newIdx, 'color') !== newColor) {
el.setStyle('fill', newColor);
}
el.setStyle('fill', newColor);
// TODO Merge animateTo and attr methods into one
if (enableAnimation) {
el.animateTo({
scale: [symbolSize, symbolSize],
scale: symbolSize,
position: point
}, 300, 'cubicOut');
}
else {
el.attr({
scale: [symbolSize, symbolSize],
scale: symbolSize,
position: point.slice()
});
}
......@@ -166,7 +185,7 @@ define(function (require) {
var symbolSize = data.getItemVisual(idx, 'symbolSize');
// Adjust the line width
el.__lineWidth = el.__lineWidth || el.style.lineWidth;
el.style.lineWidth = el.__lineWidth / symbolSize;
el.style.lineWidth = el.__lineWidth / (symbolSize[0] || symbolSize);
}, this);
this._data = data;
......
// 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');
......@@ -32,37 +37,129 @@ define(function (require) {
},
_renderSeriesMP: function (seriesModel, mpModel) {
var dataSymbolMap = this._dataSymbolMap;
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();
this.group.add(dataSymbol.group);
}
var seriesData = seriesModel.getData();
var data = mpModel.getData();
var mpData = createList(coordSys, seriesData, mpModel);
var coordSys = seriesModel.coordinateSystem;
mpData.each(['x', 'y'], function (x, y, idx) {
var itemModel = mpData.getItemModel(idx);
// FIXME Put visual out
data.each(['x', 'y'], function (x, y, idx) {
var itemModel = data.getItemModel(idx);
var xPx = itemModel.getShallow('x');
var yPx = itemModel.getShallow('y');
var point = (xPx != null && yPx != null) ? [xPx, yPx] : coordSys.dataToPoint([x, y]);
data.setItemLayout(idx, point);
data.setItemVisual(idx, {
mpData.setItemLayout(idx, point);
mpData.setItemVisual(idx, {
symbolSize: itemModel.getShallow('symbolSize'),
color: itemModel.get('itemStyle.normal.color')
|| seriesData.getVisual('color')
|| seriesData.getVisual('color'),
symbol: itemModel.getShallow('symbol')
});
});
dataSymbol.updateData(data, true);
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;
valueArr[valueIndex] = val;
var dataIndex = data.indexOfNearest(valueAxisDim, val);
valueArr[1 - valueIndex] = data.get(baseAxisDim, dataIndex);
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, baseAxisDim, valueAxisDim, 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]
&& baseAxisDim && valueAxisDim) {
var value = markPointTypeCalculator[item.type](
data, baseAxisDim, valueAxisDim
);
value.push(+item.value);
item.value = value;
}
else if (!isNaN(item.value)) {
item.value = [
item.xAxis || item.radiusAxis,
item.yAxis || item.angleAxis,
+item.value
];
}
}
return item;
};
/**
* @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
if (dimensions[0] === 'y' || dimensions[0] === 'angle') {
dimensions.inverse();
}
var mpData = new List(dimensions, mpModel);
mpData.initData(zrUtil.map(mpModel.get('data'), zrUtil.curry(
dataTransform, seriesData, baseAxis && baseAxis.dim, valueAxis && valueAxis.dim
)));
return mpData;
};
});
\ No newline at end of file
define(function (require) {
var List = require('../../data/List');
var zrUtil = require('zrender/core/util');
var Model = require('../../model/Model');
// Default enable markpoint
var globalDefault = require('../../model/globalDefault');
globalDefault.markPoint = {};
var geoCoordDataTransform = function (item) {
}
var specialTypeCalculatorWithExtent = function (percent, data, mainAxisDim, 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;
valueArr[valueIndex] = val;
var dataIndex = data.indexOfNearest(valueAxisDim, val);
valueArr[1 - valueIndex] = data.get(mainAxisDim, dataIndex);
return valueArr;
};
var specialTypeCalculator = {
/**
* @method
* @param {module:echarts/data/List} data
* @param {string} mainAxisDim
* @param {string} valueAxisDim
*/
min: zrUtil.curry(specialTypeCalculatorWithExtent, 0),
/**
* @method
* @param {module:echarts/data/List} data
* @param {string} mainAxisDim
* @param {string} valueAxisDim
*/
max: zrUtil.curry(specialTypeCalculatorWithExtent, 1),
/**
* @method
* @param {module:echarts/data/List} data
* @param {string} mainAxisDim
* @param {string} valueAxisDim
*/
average: zrUtil.curry(specialTypeCalculatorWithExtent, 0.5)
}
var dataTransform = function (data, mainAxisDim, valueAxisDim, item) {
// If not specify the position with pixel directly
if (isNaN(item.x) || isNaN(item.y)) {
// Special types, Compatible with 2.0
if (item.type && specialTypeCalculator[item.type]
&& mainAxisDim && valueAxisDim) {
var value = specialTypeCalculator[item.type](
data, mainAxisDim, valueAxisDim
);
value.push(+item.value);
item.value = value;
}
else if (!isNaN(item.value)) {
item.value = [
item.xAxis || item.radiusAxis,
item.yAxis || item.angleAxis,
item.value
];
}
}
return item;
};
// FIXME 公用?
var getAxesDimMap = function (ecModel, seriesModel) {
var coordSysType = seriesModel.get('coordinateSystem');
var mainAxisDim;
var valueAxisDim;
if (coordSysType === 'cartesian2d') {
var xAxisModel = ecModel.getComponent('xAxis', seriesModel.get('xAxisIndex'));
if (xAxisModel.type === 'category') {
mainAxisDim = 'y';
valueAxisDim = 'x';
}
else {
mainAxisDim = 'x';
valueAxisDim = 'y';
}
}
else if (coordSysType === 'polar') {
var polarModel = ecModel.getComponent(seriesModel.get('polarIndex'));
var radiusAxisModel = polarModel.findAxisModel('radiusAxis');
if (radiusAxisModel.type === 'category') {
mainAxisDim = 'radius';
valueAxisDim = 'angle';
}
else {
mainAxisDim = 'angle';
valueAxisDim = 'radius';
}
}
return {
main: mainAxisDim,
value: valueAxisDim
};
}
var MarkPointModel = require('../../echarts').extendSeriesModel({
var MarkPointModel = require('../../echarts').extendComponentModel({
type: 'markPoint',
......@@ -133,29 +35,10 @@ define(function (require) {
);
}
else {
// FIXME 后面 data transform 是否会对新的 merge 有影响
mpModel.mergeOption(markPointOpt, true);
}
var seriesData = seriesModel.getData();
var dimensions = seriesData.dimensions.slice();
// Polar and cartesian with category axis may have dimensions inversed
if (dimensions[0] === 'y' || dimensions[0] === 'angle') {
dimensions.inverse();
}
var mpData = new List(dimensions, mpModel);
// Dim of axis of calculating min, max
var axesDims = getAxesDimMap(ecModel, seriesModel);
mpData.initData(
zrUtil.map(markPointOpt.data, zrUtil.curry(
dataTransform, seriesData,
axesDims.main, axesDims.value
))
);
mpModel.getData = function () {
return mpData;
}
// Use the same series index
mpModel.seriesIndex = seriesModel.seriesIndex;
seriesModel.markPointModel = mpModel;
}
else {
......@@ -165,10 +48,6 @@ define(function (require) {
}
},
restoreData: function () {
// FIXME dataZoom needs to know markPoint model
},
defaultOption: {
zlevel: 0,
z: 5,
......
......@@ -704,10 +704,11 @@ define(function (require) {
* @param {module:zrender/Element} el
*/
listProto.setItemGraphicEl = function (idx, el) {
var hostModel = this.hostModel;
// Add data index and series index for indexing the data by element
// Useful in tooltip
el.dataIndex = idx;
el.seriesIndex = this.hostModel.seriesIndex;
el.seriesIndex = hostModel && hostModel.seriesIndex;
this._graphicEls[idx] = el;
};
......
......@@ -9,6 +9,8 @@ define(function (require) {
/**
* @alias module:echarts/model/Model
* @constructor
* @param {Object} option
* @param {module:echarts/model/Model} parentModel
*/
function Model(option, parentModel) {
......
......@@ -29,7 +29,56 @@ define(function(require) {
}
});
/**
* Pin shape
*/
var Pin = graphic.extendShape({
type: 'diamond',
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;
path.arc(
x,
cy,
r,
Math.PI - angle,
Math.PI * 2 + angle
);
path.bezierCurveTo(
x + dx, cy + dy,
x, y - r * 0.6,
x, y
);
path.bezierCurveTo(
x, y - r * 0.6,
x - dx, cy + dy,
x - dx, cy + dy
);
}
});
var symbolCreators = {
line: function (x, y, w, h) {
return new graphic.Line({
shape: {
......@@ -110,6 +159,17 @@ define(function(require) {
})
},
pin: function (x, y, w, h) {
return new Pin({
shape: {
x: x + w / 2,
y: y + h / 2,
width: w,
height: h
}
});
},
path: function (pathStr, x, y, w, h) {
return graphic.makePath(pathStr, null, new BoundingRect(x, y, w, h));
}
......
<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 < 100; i++) {
xAxisData.push('类目' + i);
data1.push(+Math.random().toFixed(3));
data2.push(+Math.random().toFixed(3));
data3.push(+Math.random().toFixed(3));
}
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',
symbol: 'none',
symbolSize: 10,
data: data1,
markPoint: {
data: [{
type: 'max',
value: 1
}]
}
}]
});
})
</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.
先完成此消息的编辑!
想要评论请 注册