提交 845594c2 编写于 作者: L lang

Add markLine

上级 f1b50ccc
......@@ -39,6 +39,7 @@ define(function (require) {
// symbolRotate: null, // 图形旋转控制
itemStyle: {
normal: {
opacity: 0.8,
// color: 各异,
label: {
show: false
......
define(function (require) {
require('./marker/MarkLineModel');
require('./marker/MarkLineView');
});
\ No newline at end of file
......@@ -2,113 +2,7 @@
define(function (require) {
var DataSymbol = require('../chart/helper/DataSymbol');
var zrUtil = require('zrender/core/util');
var List = require('../data/List');
var markerHelper = require('./marker/markerHelper');
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;
}
});
/**
* @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(
markerHelper.dataTransform, seriesData, baseAxis, valueAxis
)),
zrUtil.curry(
markerHelper.dataFilter, coordSys, dimensionInverse
)
)
);
return mpData;
};
require('./marker/MarkPointView');
});
\ No newline at end of file
define(function (require) {
// Default enable markLine
var globalDefault = require('../../model/globalDefault');
globalDefault.markLine = {};
var MarkLineModel = require('../../echarts').extendComponentModel({
type: 'markLine',
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 (!createdBySelf) {
var ecModel = this.ecModel;
ecModel.eachSeries(function (seriesModel) {
var markLineOpt = seriesModel.get('markLine');
if (markLineOpt && markLineOpt.data) {
var mlModel = seriesModel.markLineModel;
if (!mlModel) {
mlModel = new MarkLineModel(
markLineOpt, this, ecModel, [], 0, true
);
}
else {
mlModel.mergeOption(markLineOpt, true);
}
// Use the same series index
mlModel.seriesIndex = seriesModel.seriesIndex;
seriesModel.markLineModel = mlModel;
}
else {
seriesModel.markLineModel = null;
}
}, this);
}
},
defaultOption: {
zlevel: 0,
z: 5,
clickable: true,
// 标线起始和结束的symbol介绍类型,如果都一样,可以直接传string
symbol: ['circle', 'arrow'],
// 标线起始和结束的symbol大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize * 2
symbolSize: [2, 4],
// 标线起始和结束的symbol旋转控制
//symbolRotate: null,
//smooth: false,
smoothness: 0.2, // 平滑度
precision: 2,
effect: {
show: false,
loop: true,
period: 15, // 运动周期,无单位,值越大越慢
scaleSize: 2 // 放大倍数,以markLine线lineWidth为基准
// color: 'gold',
// shadowColor: 'rgba(255,215,0,0.8)',
// shadowBlur: lineWidth * 2 // 炫光模糊,默认等于scaleSize计算所得
},
// 边捆绑
bundling: {
enable: false,
// [0, 90]
maxTurningAngle: 45
},
itemStyle: {
normal: {
// color: 各异, // 标线主色,线色,symbol主色
// borderColor: 随color, // 标线symbol边框颜色,优先于color
borderWidth: 1.5, // 标线symbol边框线宽,单位px,默认为2
label: {
show: true,
// 标签文本格式器,同Tooltip.formatter,不支持回调
// formatter: null,
// 可选为 'start'|'end'|'left'|'right'|'top'|'bottom'
position: 'end'
// textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE
},
lineStyle: {
// color: 随borderColor, // 主色,线色,优先级高于borderColor和color
// width: 随borderWidth, // 优先于borderWidth
type: 'dashed'
// shadowColor: 'rgba(0,0,0,0)', //默认透明
// shadowBlur: 0,
// shadowOffsetX: 0,
// shadowOffsetY: 0
}
},
emphasis: {
// color: 各异
label: {
show: false
// 标签文本格式器,同Tooltip.formatter,不支持回调
// formatter: null,
// position: 'inside' // 'left'|'right'|'top'|'bottom'
// textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE
},
lineStyle: {}
}
}
}
});
return MarkLineModel;
});
\ No newline at end of file
define(function (require) {
var zrUtil = require('zrender/core/util');
var List = require('../../data/List');
var markerHelper = require('./markerHelper');
var SeriesMarkLine = require('./SeriesMarkLine');
var markLineTransform = function (data, baseAxis, valueAxis, item) {
// Special type markLine like 'min', 'max', 'average'
var mlType = item.type;
if (!zrUtil.isArray(item)
&& mlType === 'min' || mlType === 'max' || mlType === 'average'
) {
var baseAxisKey = baseAxis.dim + 'Axis';
var valueAxisKey = valueAxis.dim + 'Axis';
var baseScaleExtent = baseAxis.scale.getExtent();
var mlFrom = zrUtil.extend({}, item);
var mlTo = {};
var extent = data.getDataExtent(valueAxis.dim, true);
delete mlFrom.type; // Remove type
mlFrom[baseAxisKey] = baseScaleExtent[0];
mlTo[baseAxisKey] = baseScaleExtent[1];
var percent = mlType === 'average' ?
0.5 : (mlType === 'max' ? 1 : 0);
var value = (extent[1] - extent[0]) * percent + extent[0];
mlFrom[valueAxisKey] = mlTo[valueAxisKey] = value;
item = [
mlFrom,
mlTo
];
};
return [
markerHelper.dataTransform(data, baseAxis, valueAxis, item[0]),
markerHelper.dataTransform(data, baseAxis, valueAxis, item[1])
];
};
function markLineFilter(coordSys, dimensionInverse, item) {
return markerHelper.dataFilter(coordSys, dimensionInverse, item[0])
&& markerHelper.dataFilter(coordSys, dimensionInverse, item[1]);
}
require('../../echarts').extendComponentView({
type: 'markLine',
init: function () {
/**
* Markline grouped by series
* @private
* @type {Object}
*/
this._markLineMap = {};
},
render: function (markLineModel, ecModel) {
var seriesMarkLineMap = this._markLineMap;
for (var name in seriesMarkLineMap) {
seriesMarkLineMap[name].__keep = false;
}
ecModel.eachSeries(function (seriesModel) {
var mlModel = seriesModel.markLineModel;
mlModel && this._renderSeriesML(seriesModel, mlModel);
}, this);
for (var name in seriesMarkLineMap) {
if (!seriesMarkLineMap[name].__keep) {
this.group.remove(seriesMarkLineMap[name].group);
}
}
},
_renderSeriesML: function (seriesModel, mlModel) {
var coordSys = seriesModel.coordinateSystem;
var seriesName = seriesModel.name;
var seriesData = seriesModel.getData();
var seriesMarkLineMap = this._markLineMap;
var seriesMarkLine = seriesMarkLineMap[seriesName];
if (!seriesMarkLine) {
seriesMarkLine = seriesMarkLineMap[seriesName] = new SeriesMarkLine();
}
this.group.add(seriesMarkLine.group);
var mlData = createList(coordSys, seriesData, mlModel)
var dims = mlData.from.dimensions.slice(0, 2);
mlData.from.each(function (idx) {
updateDataVisualAndLayout(mlData.from, idx);
updateDataVisualAndLayout(mlData.to, idx);
});
seriesMarkLine.update(mlData.from, mlData.to);
function updateDataVisualAndLayout(data, idx) {
var itemModel = data.getItemModel(idx);
var point;
var xPx = itemModel.getShallow('x');
var yPx = itemModel.getShallow('y');
if (xPx != null && yPx != null) {
point = [xPx, yPx];
}
else {
var x = data.get(dims[0], idx);
var y = data.get(dims[1], idx);
point = coordSys.dataToPoint([x, y]);
}
data.setItemLayout(idx, point);
data.setItemVisual(idx, {
// symbolSize: itemModel.getShallow('symbolSize'),
// symbol: itemModel.getShallow('symbol'),
color: itemModel.get('itemStyle.normal.color')
|| seriesData.getVisual('color')
});
}
seriesMarkLine.__keep = true;
}
});
/**
* @inner
* @param {module:echarts/coord/*} coordSys
* @param {module:echarts/data/List} seriesData
* @param {module:echarts/model/Model} mpModel
*/
function createList (coordSys, seriesData, mlModel) {
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 dimensionInfosMap = zrUtil.map(
dimensions, seriesData.getDimensionInfo, seriesData
);
var fromData = new List(dimensionInfosMap, mlModel);
var toData = new List(dimensionInfosMap, mlModel);
var optData = zrUtil.filter(
zrUtil.map(mlModel.get('data'), zrUtil.curry(
markLineTransform, seriesData, baseAxis, valueAxis
)),
zrUtil.curry(
markLineFilter, coordSys, dimensionInverse
)
);
fromData.initData(
zrUtil.map(optData, function (item) { return item[0]; })
);
toData.initData(
zrUtil.map(optData, function (item) { return item[1]; })
);
return {
from: fromData,
to: toData
};
};
});
\ No newline at end of file
define(function (require) {
var DataSymbol = require('../../chart/helper/DataSymbol');
var zrUtil = require('zrender/core/util');
var List = require('../../data/List');
var markerHelper = require('./markerHelper');
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);
var dims = mpData.dimensions.slice(0, 2);
mpData.each(function (idx) {
var itemModel = mpData.getItemModel(idx);
var point;
var xPx = itemModel.getShallow('x');
var yPx = itemModel.getShallow('y');
if (xPx != null && yPx != null) {
point = [xPx, yPx];
}
else {
var x = mpData.get(dims[0], idx);
var y = mpData.get(dims[1], idx);
point = 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;
}
});
/**
* @inner
* @param {module:echarts/coord/*} coordSys
* @param {module:echarts/data/List} seriesData
* @param {module:echarts/model/Model} mpModel
*/
function createList (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(
markerHelper.dataTransform, seriesData, baseAxis, valueAxis
)),
zrUtil.curry(
markerHelper.dataFilter, coordSys, dimensionInverse
)
)
);
return mpData;
};
});
\ No newline at end of file
define(function (require) {
var graphic = require('../../util/graphic');
var zrUtil = require('zrender/core/util');
function SeriesMarkLine() {
this.group = new graphic.Group();
}
var seriesMarkLineProto = SeriesMarkLine.prototype;
seriesMarkLineProto.update = function (fromData, toData) {
var oldFromData = this._fromData;
var group = this.group;
fromData.diff(oldFromData)
.add(function (idx) {
var p1 = fromData.getItemLayout(idx);
var p2 = toData.getItemLayout(idx);
var line = new graphic.Line({
shape: {
x1: p1[0],
y1: p1[1],
x2: p1[0],
y2: p1[1]
}
});
line.animateTo({
shape: {
x2: p2[0],
y2: p2[1]
}
}, 1000);
group.add(line);
fromData.setItemGraphicEl(idx, line);
})
.update(function (newIdx, oldIdx) {
var line = oldFromData.getItemGraphicEl(oldIdx);
var p1 = fromData.getItemLayout(newIdx);
var p2 = toData.getItemLayout(newIdx);
line.animateTo({
shape: {
x1: p1[0],
y1: p1[1],
x2: p2[0],
y2: p2[1]
}
}, 300, 'cubicOut');
fromData.setItemGraphicEl(newIdx, line);
group.add(line);
})
.remove(function (idx) {
var line = oldFromData.getItemGraphicEl(idx);
group.remove(line);
})
.execute();
fromData.eachItemGraphicEl(function (line, idx) {
var itemModel = fromData.getItemModel(idx);
line.setStyle(zrUtil.defaults(
{
stroke: fromData.getItemVisual(idx, 'color')
},
itemModel.getModel('itemStyle.normal.lineStyle').getLineStyle()
));
graphic.setHoverStyle(
line,
itemModel.getModel('itemStyle.emphasis.lineStyle').getLineStyle()
);
});
this._fromData = fromData;
// this._toData = toData;
}
return SeriesMarkLine;
});
\ No newline at end of file
......@@ -15,6 +15,7 @@ define(function (require) {
return valueArr;
};
// TODO Specified percent
var markerTypeCalculator = {
/**
* @method
......@@ -40,7 +41,8 @@ define(function (require) {
};
var dataTransform = function (data, baseAxis, valueAxis, item) {
// If not specify the position with pixel directly
// 1. If not specify the position with pixel directly
// 2. If value is not a data array. Which uses xAxis, yAxis to specify the value on each dimension
if (isNaN(item.x) || isNaN(item.y) && !zrUtil.isArray(item.value)) {
// Clone the option
// Transform the properties xAxis, yAxis, radiusAxis, angleAxis, geoCoord to value
......@@ -56,11 +58,11 @@ define(function (require) {
value.push(+item.value);
item.value = value;
}
else if (!isNaN(item.value)) {
else {
// FIXME Only has one of xAxis and yAxis.
item.value = [
item.xAxis || item.radiusAxis,
item.yAxis || item.angleAxis,
item.xAxis != null ? item.xAxis : item.radiusAxis,
item.yAxis != null ? item.yAxis : item.angleAxis,
+item.value
];
}
......
......@@ -388,8 +388,8 @@ define(function (require) {
var zlevel = componentModel.get('zlevel');
// Set z and zlevel
component.group.traverse(function (el) {
el.z = z;
el.zlevel = zlevel;
z != null && (el.z = z);
zlevel != null && (el.zlevel = zlevel);
});
}, this);
......@@ -408,8 +408,8 @@ define(function (require) {
var zlevel = seriesModel.get('zlevel');
// Set z and zlevel
chart.group.traverse(function (el) {
el.z = z;
el.zlevel = zlevel;
z != null && (el.z = z);
zlevel != null && (el.zlevel = zlevel);
});
}, this);
......
......@@ -10,8 +10,8 @@ define({
// https://dribbble.com/shots/1065960-Infographic-Pie-chart-visualization
color: ['#5793f3', '#5578c2', '#d4df5a', '#fd9c35', '#fec42c',
'#dd4444', '#bd3b47', '#bd3b47', '#cd4870'],
color: ['#5793f3', '#d14a61', '#fd9c35', '#675bba', '#fec42c',
'#dd4444', '#d4df5a', '#cd4870'],
// 默认需要 Grid 配置项
grid: {},
......
......@@ -33,21 +33,21 @@
for (var i = 0; i < 10; i++) {
xAxisData.push('类目' + i);
data1.push(+Math.random().toFixed(3));
data2.push(+Math.random().toFixed(3));
data3.push(+Math.random().toFixed(3));
data1.push((-Math.random() - 0.2).toFixed(3));
data2.push((Math.random() + 0.3).toFixed(3));
data3.push((Math.random() + 0.2).toFixed(3));
}
var itemStyle = {
normal: {
borderColor: 'white',
borderWidth: 3,
// borderColor: 'white',
// borderWidth: 3,
// shadowBlur: 10,
// shadowOffsetX: 0,
// shadowOffsetY: 5,
// shadowColor: 'rgba(0, 0, 0, 0.4)',
lineStyle: {
width: 3,
width: 2,
// shadowBlur: 10,
// shadowOffsetX: 0,
// shadowOffsetY: 5,
......@@ -86,7 +86,6 @@
name: 'line',
type: 'line',
stack: 'all',
symbol: 'circle',
symbolSize: 10,
data: data1,
itemStyle: itemStyle
......@@ -94,7 +93,6 @@
name: 'line2',
type: 'line',
stack: 'all',
symbol: 'circle',
symbolSize: 10,
data: data2,
itemStyle: itemStyle
......@@ -102,7 +100,6 @@
name: 'line3',
type: 'line',
stack: 'all',
symbol: 'circle',
symbolSize: 10,
data: data3,
itemStyle: itemStyle
......
......@@ -22,7 +22,8 @@
'echarts/component/axis',
'echarts/component/dataZoom',
'echarts/component/tooltip',
'echarts/component/markPoint'
'echarts/component/markPoint',
'echarts/component/markLine'
], function (echarts) {
var chart = echarts.init(document.getElementById('main'), null, {
......@@ -36,9 +37,9 @@
for (var i = 0; i < 200; i++) {
xAxisData.push('类目' + i);
data1.push((Math.random() * 4).toFixed(2));
data2.push(Math.random());
data3.push(Math.random());
data1.push((Math.random() + 0.5).toFixed(2));
data2.push(Math.random().toFixed(2));
data3.push(Math.random().toFixed(2));
}
chart.setOption({
......@@ -57,10 +58,23 @@
// scale: true
},
series: [
{
name: 'line2',
type: 'line',
stack: 'all',
data: data2
},
{
name: 'line3',
type: 'line',
stack: 'all',
data: data3
},
{
name: 'line',
type: 'line',
data: data1,
stack: 'all',
itemStyle: {
normal: {
areaStyle: {}
......@@ -70,17 +84,12 @@
data: [{
type: 'max'
}]
},
markLine: {
data: [{
type: 'average'
}]
}
},
{
name: 'line2',
type: 'line',
data: data2
},
{
name: 'line3',
type: 'line',
data: data3
}
],
dataZoom: {
......
......@@ -99,13 +99,14 @@
symbol: 'none',
symbolSize: 10,
data: data2,
itemStyle: {
normal: {
areaStyle: {
color: 'black'
}
}
}
// itemStyle: {
// normal: {
// areaStyle: {
// color: 'black'
// }
// }
// }
itemStyle: itemStyle
}]
});
......@@ -117,7 +118,7 @@
data1.push(randomData());
data2.shift();
data2.push(-randomData());
data2.push(randomData());
count++;
}
......
<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/markLine'
], function (echarts) {
var chart = echarts.init(document.getElementById('main'), null, {
renderer: 'canvas'
});
var xAxisData = [];
var data1 = [];
var data2 = [];
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']
},
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,
markLine: {
data: [{
name: '平均值',
type: 'average',
value: 1
}]
}
}, {
name: 'line2',
type: 'line',
stack: 'all',
symbolSize: 6,
data: data2,
markLine: {
data: [{
name: '平均值',
type: 'average',
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.
先完成此消息的编辑!
想要评论请 注册