1 |
|
2 | const Util = require('./util');
|
3 | const Interaction = require('./base');
|
4 |
|
5 |
|
6 | const ZOOMING_TYPES = ['X', 'Y', 'XY'];
|
7 | const DEFAULT_TYPE = 'X';
|
8 |
|
9 |
|
10 |
|
11 | class Zoom extends Interaction {
|
12 | getDefaultCfg() {
|
13 | const cfg = super.getDefaultCfg();
|
14 | return Util.mix({}, cfg, {
|
15 | processEvent: 'mousewheel',
|
16 | type: DEFAULT_TYPE,
|
17 | stepRatio: 0.05,
|
18 | stepByField: {},
|
19 | originScaleDefsByField: {}
|
20 | });
|
21 | }
|
22 |
|
23 | constructor(cfg, view) {
|
24 | super(cfg, view);
|
25 | const me = this;
|
26 | me.chart = view;
|
27 | me.type = me.type.toUpperCase();
|
28 |
|
29 | const scales = view.getYScales();
|
30 | const xScale = view.getXScale();
|
31 | scales.push(xScale);
|
32 | const scaleController = view.get('scaleController');
|
33 | scales.forEach(scale => {
|
34 | const field = scale.field;
|
35 | const def = scaleController.defs[field] || {};
|
36 | me.originScaleDefsByField[field] = Util.mix(def, {
|
37 | nice: !!def.nice
|
38 | });
|
39 | if (scale.isLinear) {
|
40 | me.stepByField[field] = (scale.max - scale.min) * me.stepRatio;
|
41 | }
|
42 | });
|
43 |
|
44 | if (ZOOMING_TYPES.indexOf(me.type) === -1) {
|
45 | me.type = DEFAULT_TYPE;
|
46 | }
|
47 | }
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 | _applyScale(scale, delta, minOffset = 0) {
|
54 | const me = this;
|
55 | const { chart, stepByField } = me;
|
56 | if (scale.isLinear) {
|
57 | const { min, max, field } = scale;
|
58 | const maxOffset = 1 - minOffset;
|
59 | const step = stepByField[field] * delta;
|
60 | const newMin = min + step * minOffset;
|
61 | const newMax = max - step * maxOffset;
|
62 | if (newMax > newMin) {
|
63 | chart.scale(field, {
|
64 | nice: false,
|
65 | min: newMin,
|
66 | max: newMax
|
67 | });
|
68 | }
|
69 | }
|
70 | }
|
71 |
|
72 | process(ev) {
|
73 | const me = this;
|
74 | const { chart, type } = me;
|
75 | const coord = chart.get('coord');
|
76 | const deltaY = ev.deltaY;
|
77 | const offsetPoint = coord.invertPoint(ev);
|
78 | if (deltaY) {
|
79 | me.onZoom && me.onZoom(deltaY, offsetPoint, me);
|
80 | if (deltaY > 0) {
|
81 | me.onZoomin && me.onZoomin(deltaY, offsetPoint, me);
|
82 | } else {
|
83 | me.onZoomout && me.onZoomout(deltaY, offsetPoint, me);
|
84 | }
|
85 | const delta = deltaY / Math.abs(deltaY);
|
86 | if (type.indexOf('X') > -1) {
|
87 | me._applyScale(chart.getXScale(), delta, offsetPoint.x);
|
88 | }
|
89 | if (type.indexOf('Y') > -1) {
|
90 | const yScales = chart.getYScales();
|
91 | yScales.forEach(yScale => {
|
92 | me._applyScale(yScale, delta, offsetPoint.y);
|
93 | });
|
94 | }
|
95 | }
|
96 | chart.repaint();
|
97 | }
|
98 |
|
99 | reset() {
|
100 | const me = this;
|
101 | const { view, originScaleDefsByField } = me;
|
102 | const scales = view.getYScales();
|
103 | const xScale = view.getXScale();
|
104 | scales.push(xScale);
|
105 | scales.forEach(scale => {
|
106 | if (scale.isLinear) {
|
107 | const field = scale.field;
|
108 | view.scale(field, originScaleDefsByField[field]);
|
109 | }
|
110 | });
|
111 | view.repaint();
|
112 | }
|
113 | }
|
114 |
|
115 |
|
116 |
|
117 |
|
118 | module.exports = Zoom; |
\ | No newline at end of file |