light-chart
Version:
Charts for mobile visualization.
149 lines (136 loc) • 3.98 kB
JavaScript
const Util = require('../util/common');
const Interaction = require('./base');
const Chart = require('../chart/chart');
class PieSelect extends Interaction {
getDefaultCfg() {
let defaultCfg = super.getDefaultCfg();
defaultCfg = Util.mix({}, defaultCfg, {
startEvent: 'tap',
processEvent: null,
animate: false,
offset: 1,
appendRadius: 8,
style: {
fillOpacity: 0.5
},
cancelable: true,
defaultSelected: null // set the default selected shape
});
if (Util.isWx || Util.isMy) { // 小程序
defaultCfg.startEvent = 'touchstart';
defaultCfg.endEvent = 'touchend';
}
return defaultCfg;
}
constructor(cfg, chart) {
super(cfg, chart);
const self = this;
chart.registerPlugins({
clearInner() {
self.halo && self.halo.remove(true);
self.selected = false;
self.selectedShape = null;
self.lastShape = null;
self.halo = null;
self.defaultSelected = null;
}
});
const defaultSelected = self.defaultSelected;
if (Util.isObject(defaultSelected)) {
const selectedShape = self._getSelectedShapeByData(defaultSelected);
selectedShape && self._selectedShape(selectedShape);
this.canvas.draw();
}
}
_getSelectedShapeByData(data) {
let selectedShape = null;
const chart = this.chart;
const geom = chart.get('geoms')[0];
const container = geom.get('container');
const children = container.get('children');
Util.each(children, child => {
if (child.get('isShape') && (child.get('className') === geom.get('type'))) { // get geometry's shape
const shapeData = child.get('origin')._origin;
if (Util.isObjectValueEqual(shapeData, data)) {
selectedShape = child;
return false;
}
}
});
return selectedShape;
}
_selectedShape(selectedShape) {
const { offset, style, appendRadius, chart } = this;
this.lastShape = selectedShape;
const { x, y, startAngle, endAngle, r, fill } = selectedShape._attrs.attrs;
const frontPlot = chart.get('frontPlot');
const halo = frontPlot.addShape('sector', {
attrs: Util.mix({
x,
y,
r: r + offset + appendRadius,
r0: r + offset,
fill,
startAngle,
endAngle
}, style)
});
this.halo = halo;
let animate = this.animate;
if (animate) {
if (animate === true) {
animate = {
duration: 300
};
}
halo.attr('r', r + offset);
halo.animate().to(Util.mix({
attrs: {
r: r + offset + appendRadius
}
}, animate));
}
}
start(ev) {
const chart = this.chart;
if (ev.type === 'tap') {
ev.clientX = ev.center.x;
ev.clientY = ev.center.y;
}
const { x, y } = Util.createEvent(ev, chart);
const records = chart.getSnapRecords({ x, y });
if (!records.length) {
this.selected = false;
this.selectedShape = null;
return;
}
const data = records[0]._origin;
const selectedShape = this._getSelectedShapeByData(data);
const lastShape = this.lastShape;
this.selectedShape = selectedShape;
this.selected = true;
if (selectedShape === lastShape) {
if (!this.cancelable) {
return;
}
this.halo && this.halo.remove(true);
this.lastShape = null;
this.selected = false;
} else {
this.halo && this.halo.remove(true);
this._selectedShape(selectedShape);
}
this.canvas.draw();
}
end(ev) {
const selectedShape = this.selectedShape;
if (selectedShape && !selectedShape.get('destroyed')) {
ev.data = selectedShape.get('origin')._origin;
ev.shapeInfo = selectedShape.get('origin');
ev.shape = selectedShape;
ev.selected = !!this.selected;
}
}
}
Chart.registerInteraction('pie-select', PieSelect);
module.exports = PieSelect;