| 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 |