OLD | NEW |
| (Empty) |
1 // | |
2 // Copyright 2014 Google Inc. All rights reserved. | |
3 // | |
4 // Use of this source code is governed by a BSD-style | |
5 // license that can be found in the LICENSE file or at | |
6 // https://developers.google.com/open-source/licenses/bsd | |
7 // | |
8 | |
9 part of charted.charts; | |
10 | |
11 /// A behavior that tracks mouse pointer and paints a dashed line to | |
12 /// the axes from the current pointer location. | |
13 class MouseTracker implements ChartBehavior { | |
14 ChartArea _area; | |
15 Rect _rect; | |
16 | |
17 Element _markerX; | |
18 Element _markerY; | |
19 | |
20 bool _showMarkerX = true; | |
21 bool _showMarkerY = true; | |
22 bool _showing; | |
23 | |
24 Element _lower; | |
25 | |
26 StreamSubscription _mouseMoveSubscription; | |
27 StreamSubscription _mouseInSubscription; | |
28 StreamSubscription _mouseOutSubscription; | |
29 | |
30 void init(ChartArea area, Selection upper, Selection lower) { | |
31 _area = area; | |
32 _lower = lower.first; | |
33 | |
34 if (area is CartesianArea) { | |
35 _mouseInSubscription = _area.onMouseOver.listen(_show); | |
36 _mouseOutSubscription = _area.onMouseOut.listen(_hide); | |
37 } | |
38 } | |
39 | |
40 void dispose() { | |
41 if (_mouseInSubscription != null) _mouseInSubscription.cancel(); | |
42 if (_mouseOutSubscription != null) _mouseOutSubscription.cancel(); | |
43 if (_mouseMoveSubscription != null) _mouseOutSubscription.cancel(); | |
44 if (_markerX != null) _markerX.remove(); | |
45 if (_markerY != null) _markerY.remove(); | |
46 } | |
47 | |
48 void _show(ChartEvent e) { | |
49 if (_mouseMoveSubscription != null) return; | |
50 _create(); | |
51 _visibility(true); | |
52 _mouseMoveSubscription = _area.onMouseMove.listen(_update); | |
53 } | |
54 | |
55 void _hide(ChartEvent e) { | |
56 if (_showing != true) return; | |
57 _visibility(false); | |
58 _mouseMoveSubscription.cancel(); | |
59 _mouseMoveSubscription = null; | |
60 } | |
61 | |
62 void _visibility(bool show) { | |
63 if (_showing == show) return; | |
64 var value = show ? 'visible' : 'hidden'; | |
65 if (_markerX != null) { | |
66 _markerX.style.visibility = value; | |
67 } | |
68 if (_markerY != null) { | |
69 _markerY.style.visibility = value; | |
70 } | |
71 } | |
72 | |
73 bool _isRenderArea(ChartEvent e) => | |
74 _rect != null && _rect.contains(e.chartX, e.chartY); | |
75 | |
76 void _create() { | |
77 if (_rect == null) { | |
78 var renderArea = _area.layout.renderArea; | |
79 _rect = new Rect( | |
80 renderArea.x, renderArea.y, renderArea.width, renderArea.height); | |
81 } | |
82 if (_showMarkerX && _markerX == null) { | |
83 _markerX = new LineElement(); | |
84 _markerX.attributes | |
85 ..['x1'] = '0' | |
86 ..['y1'] = _rect.y.toString() | |
87 ..['x2'] = '0' | |
88 ..['y2'] = (_rect.y + _rect.height).toString() | |
89 ..['class'] = 'axis-marker axis-marker-x'; | |
90 _lower.append(_markerX); | |
91 } | |
92 if (_showMarkerY && _markerY == null) { | |
93 _markerY = new LineElement(); | |
94 _markerY.attributes | |
95 ..['x1'] = _rect.x.toString() | |
96 ..['y1'] = '0' | |
97 ..['x2'] = (_rect.x + _rect.width).toString() | |
98 ..['y2'] = '0' | |
99 ..['class'] = 'axis-marker axis-marker-y'; | |
100 _lower.append(_markerY); | |
101 } | |
102 _visibility(false); | |
103 } | |
104 | |
105 void _update(ChartEvent e) { | |
106 if (!_isRenderArea(e)) { | |
107 _visibility(false); | |
108 } else { | |
109 _visibility(true); | |
110 window.requestAnimationFrame((_) { | |
111 if (_showMarkerX) { | |
112 _markerX.attributes['transform'] = 'translate(${e.chartX},0)'; | |
113 } | |
114 if (_showMarkerY) { | |
115 _markerY.attributes['transform'] = 'translate(0,${e.chartY})'; | |
116 } | |
117 }); | |
118 } | |
119 } | |
120 } | |
OLD | NEW |