/**
* @module echarts/chart/helper/Symbol
*/
define(function (require) {
var zrUtil = require('zrender/core/util');
var graphic = require('../../util/graphic');
var Path = require('zrender/graphic/Path');
var WhiskerPath = Path.extend({
type: 'whiskerInBox',
shape: {},
buildPath: function (ctx, shape) {
for (var i in shape) {
if (i.indexOf('ends') === 0) {
var pts = shape[i];
ctx.moveTo(pts[0][0], pts[0][1]);
ctx.lineTo(pts[1][0], pts[1][1]);
}
}
}
});
/**
* @constructor
* @alias {module:echarts/chart/helper/WhiskerBox}
* @param {module:echarts/data/List} data
* @param {number} idx
* @param {Function} styleUpdater
* @param {boolean} isInit
* @extends {module:zrender/graphic/Group}
*/
function WhiskerBox(data, idx, styleUpdater, isInit) {
graphic.Group.call(this);
/**
* @type {number}
* @readOnly
*/
this.bodyIndex;
/**
* @type {number}
* @readOnly
*/
this.whiskerIndex;
/**
* @type {Function}
*/
this.styleUpdater = styleUpdater;
this._createContent(data, idx, isInit);
this.updateData(data, idx, isInit);
/**
* Last series model.
* @type {module:echarts/model/Series}
*/
this._seriesModel;
}
var whiskerBoxProto = WhiskerBox.prototype;
whiskerBoxProto._createContent = function (data, idx, isInit) {
var itemLayout = data.getItemLayout(idx);
var constDim = itemLayout.chartLayout === 'horizontal' ? 1 : 0;
var count = 0;
// Whisker element.
this.add(new graphic.Polygon({
shape: {
points: isInit
? transInit(itemLayout.bodyEnds, constDim, itemLayout)
: itemLayout.bodyEnds
},
style: {strokeNoScale: true},
z2: 100
}));
this.bodyIndex = count++;
// Box element.
var whiskerEnds = zrUtil.map(itemLayout.whiskerEnds, function (ends) {
return isInit ? transInit(ends, constDim, itemLayout) : ends;
});
this.add(new WhiskerPath({
shape: makeWhiskerEndsShape(whiskerEnds),
style: {strokeNoScale: true},
z2: 100
}));
this.whiskerIndex = count++;
};
function transInit(points, dim, itemLayout) {
return zrUtil.map(points, function (point) {
point = point.slice();
point[dim] = itemLayout.initBaseline;
return point;
});
}
function makeWhiskerEndsShape(whiskerEnds) {
// zr animation only support 2-dim array.
var shape = {};
zrUtil.each(whiskerEnds, function (ends, i) {
shape['ends' + i] = ends;
});
return shape;
}
/**
* Update symbol properties
* @param {module:echarts/data/List} data
* @param {number} idx
*/
whiskerBoxProto.updateData = function (data, idx, isInit) {
var seriesModel = this._seriesModel = data.hostModel;
var itemLayout = data.getItemLayout(idx);
var updateMethod = graphic[isInit ? 'initProps' : 'updateProps'];
// this.childAt(this.bodyIndex).stopAnimation(true);
// this.childAt(this.whiskerIndex).stopAnimation(true);
updateMethod(
this.childAt(this.bodyIndex),
{shape: {points: itemLayout.bodyEnds}},
seriesModel, idx
);
updateMethod(
this.childAt(this.whiskerIndex),
{shape: makeWhiskerEndsShape(itemLayout.whiskerEnds)},
seriesModel, idx
);
this.styleUpdater.call(null, this, data, idx);
};
zrUtil.inherits(WhiskerBox, graphic.Group);
/**
* @constructor
* @alias module:echarts/chart/helper/WhiskerBoxDraw
*/
function WhiskerBoxDraw(styleUpdater) {
this.group = new graphic.Group();
this.styleUpdater = styleUpdater;
}
var whiskerBoxDrawProto = WhiskerBoxDraw.prototype;
/**
* Update symbols draw by new data
* @param {module:echarts/data/List} data
*/
whiskerBoxDrawProto.updateData = function (data) {
var group = this.group;
var oldData = this._data;
var styleUpdater = this.styleUpdater;
data.diff(oldData)
.add(function (newIdx) {
if (data.hasValue(newIdx)) {
var symbolEl = new WhiskerBox(data, newIdx, styleUpdater, true);
data.setItemGraphicEl(newIdx, symbolEl);
group.add(symbolEl);
}
})
.update(function (newIdx, oldIdx) {
var symbolEl = oldData.getItemGraphicEl(oldIdx);
// Empty data
if (!data.hasValue(newIdx)) {
group.remove(symbolEl);
return;
}
if (!symbolEl) {
symbolEl = new WhiskerBox(data, newIdx, styleUpdater);
}
else {
symbolEl.updateData(data, newIdx);
}
// Add back
group.add(symbolEl);
data.setItemGraphicEl(newIdx, symbolEl);
})
.remove(function (oldIdx) {
var el = oldData.getItemGraphicEl(oldIdx);
el && group.remove(el);
})
.execute();
this._data = data;
};
/**
* Remove symbols.
* @param {module:echarts/data/List} data
*/
whiskerBoxDrawProto.remove = function () {
var group = this.group;
var data = this._data;
this._data = null;
data && data.eachItemGraphicEl(function (el) {
el && group.remove(el);
});
};
return WhiskerBoxDraw;
});
|