echarts
Version:
A powerful charting and visualization library for browser
279 lines (234 loc) • 9.57 kB
JavaScript
define(function (require) {
'use strict';
var zrUtil = require('zrender/core/util');
var graphic = require('../../util/graphic');
var helper = require('./helper');
var BAR_BORDER_WIDTH_QUERY = ['itemStyle', 'normal', 'barBorderWidth'];
// FIXME
// Just for compatible with ec2.
zrUtil.extend(require('../../model/Model').prototype, require('./barItemStyle'));
var BarView = require('../../echarts').extendChartView({
type: 'bar',
render: function (seriesModel, ecModel, api) {
var coordinateSystemType = seriesModel.get('coordinateSystem');
if (coordinateSystemType === 'cartesian2d'
|| coordinateSystemType === 'polar'
) {
this._render(seriesModel, ecModel, api);
}
else if (__DEV__) {
console.warn('Only cartesian2d and polar supported for bar.');
}
return this.group;
},
dispose: zrUtil.noop,
_render: function (seriesModel, ecModel, api) {
var group = this.group;
var data = seriesModel.getData();
var oldData = this._data;
var coord = seriesModel.coordinateSystem;
var baseAxis = coord.getBaseAxis();
var isHorizontalOrRadial;
if (coord.type === 'cartesian2d') {
isHorizontalOrRadial = baseAxis.isHorizontal();
}
else if (coord.type === 'polar') {
isHorizontalOrRadial = baseAxis.dim === 'angle';
}
var animationModel = seriesModel.isAnimationEnabled() ? seriesModel : null;
data.diff(oldData)
.add(function (dataIndex) {
if (!data.hasValue(dataIndex)) {
return;
}
var itemModel = data.getItemModel(dataIndex);
var layout = getLayout[coord.type](data, dataIndex, itemModel);
var el = elementCreator[coord.type](
data, dataIndex, itemModel, layout, isHorizontalOrRadial, animationModel
);
data.setItemGraphicEl(dataIndex, el);
group.add(el);
updateStyle(
el, data, dataIndex, itemModel, layout,
seriesModel, isHorizontalOrRadial, coord.type === 'polar'
);
})
.update(function (newIndex, oldIndex) {
var el = oldData.getItemGraphicEl(oldIndex);
if (!data.hasValue(newIndex)) {
group.remove(el);
return;
}
var itemModel = data.getItemModel(newIndex);
var layout = getLayout[coord.type](data, newIndex, itemModel);
if (el) {
graphic.updateProps(el, {shape: layout}, animationModel, newIndex);
}
else {
el = elementCreator[coord.type](
data, newIndex, itemModel, layout, isHorizontalOrRadial, animationModel, true
);
}
data.setItemGraphicEl(newIndex, el);
// Add back
group.add(el);
updateStyle(
el, data, newIndex, itemModel, layout,
seriesModel, isHorizontalOrRadial, coord.type === 'polar'
);
})
.remove(function (dataIndex) {
var el = oldData.getItemGraphicEl(dataIndex);
if (coord.type === 'cartesian2d') {
el && removeRect(dataIndex, animationModel, el);
}
else {
el && removeSector(dataIndex, animationModel, el);
}
})
.execute();
this._data = data;
},
remove: function (ecModel, api) {
var group = this.group;
var data = this._data;
if (ecModel.get('animation')) {
if (data) {
data.eachItemGraphicEl(function (el) {
if (el.type === 'sector') {
removeSector(el.dataIndex, ecModel, el);
}
else {
removeRect(el.dataIndex, ecModel, el);
}
});
}
}
else {
group.removeAll();
}
}
});
var elementCreator = {
cartesian2d: function (
data, dataIndex, itemModel, layout, isHorizontal,
animationModel, isUpdate
) {
var rect = new graphic.Rect({shape: zrUtil.extend({}, layout)});
// Animation
if (animationModel) {
var rectShape = rect.shape;
var animateProperty = isHorizontal ? 'height' : 'width';
var animateTarget = {};
rectShape[animateProperty] = 0;
animateTarget[animateProperty] = layout[animateProperty];
graphic[isUpdate ? 'updateProps' : 'initProps'](rect, {
shape: animateTarget
}, animationModel, dataIndex);
}
return rect;
},
polar: function (
data, dataIndex, itemModel, layout, isRadial,
animationModel, isUpdate
) {
var sector = new graphic.Sector({shape: zrUtil.extend({}, layout)});
// Animation
if (animationModel) {
var sectorShape = sector.shape;
var animateProperty = isRadial ? 'r' : 'endAngle';
var animateTarget = {};
sectorShape[animateProperty] = isRadial ? 0 : layout.startAngle;
animateTarget[animateProperty] = layout[animateProperty];
graphic[isUpdate ? 'updateProps' : 'initProps'](sector, {
shape: animateTarget
}, animationModel, dataIndex);
}
return sector;
}
};
function removeRect(dataIndex, animationModel, el) {
// Not show text when animating
el.style.text = '';
graphic.updateProps(el, {
shape: {
width: 0
}
}, animationModel, dataIndex, function () {
el.parent && el.parent.remove(el);
});
}
function removeSector(dataIndex, animationModel, el) {
// Not show text when animating
el.style.text = '';
graphic.updateProps(el, {
shape: {
r: el.shape.r0
}
}, animationModel, dataIndex, function () {
el.parent && el.parent.remove(el);
});
}
var getLayout = {
cartesian2d: function (data, dataIndex, itemModel) {
var layout = data.getItemLayout(dataIndex);
var fixedLineWidth = getLineWidth(itemModel, layout);
// fix layout with lineWidth
var signX = layout.width > 0 ? 1 : -1;
var signY = layout.height > 0 ? 1 : -1;
return {
x: layout.x + signX * fixedLineWidth / 2,
y: layout.y + signY * fixedLineWidth / 2,
width: layout.width - signX * fixedLineWidth,
height: layout.height - signY * fixedLineWidth
};
},
polar: function (data, dataIndex, itemModel) {
var layout = data.getItemLayout(dataIndex);
return {
cx: layout.cx,
cy: layout.cy,
r0: layout.r0,
r: layout.r,
startAngle: layout.startAngle,
endAngle: layout.endAngle
};
}
};
function updateStyle(
el, data, dataIndex, itemModel, layout, seriesModel, isHorizontal, isPolar
) {
var color = data.getItemVisual(dataIndex, 'color');
var opacity = data.getItemVisual(dataIndex, 'opacity');
var itemStyleModel = itemModel.getModel('itemStyle.normal');
var hoverStyle = itemModel.getModel('itemStyle.emphasis').getBarItemStyle();
if (!isPolar) {
el.setShape('r', itemStyleModel.get('barBorderRadius') || 0);
}
el.useStyle(zrUtil.defaults(
{
fill: color,
opacity: opacity
},
itemStyleModel.getBarItemStyle()
));
var cursorStyle = itemModel.getShallow('cursor');
cursorStyle && el.attr('cursor', cursorStyle);
var labelPositionOutside = isHorizontal
? (layout.height > 0 ? 'bottom' : 'top')
: (layout.width > 0 ? 'left' : 'right');
if (!isPolar) {
helper.setLabel(
el.style, hoverStyle, itemModel, color,
seriesModel, dataIndex, labelPositionOutside
);
}
graphic.setHoverStyle(el, hoverStyle);
}
// In case width or height are too small.
function getLineWidth(itemModel, rawLayout) {
var lineWidth = itemModel.get(BAR_BORDER_WIDTH_QUERY) || 0;
return Math.min(lineWidth, Math.abs(rawLayout.width), Math.abs(rawLayout.height));
}
return BarView;
});