| 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 draws marking lines on the chart. | |
| 12 class LineMarker implements ChartBehavior { | |
| 13 /// Position of the line markers. | |
| 14 final Map<int,dynamic> positions; | |
| 15 | |
| 16 /// If true, the markers are drawn above the series | |
| 17 final bool drawAboveSeries; | |
| 18 | |
| 19 /// If true, animates (grows from the axis into the chart) | |
| 20 final bool animate; | |
| 21 | |
| 22 CartesianArea _area; | |
| 23 bool _isLeftAxisPrimary = false; | |
| 24 Rect _rect; | |
| 25 | |
| 26 bool _showing; | |
| 27 Selection _parent; | |
| 28 DataSelection _markers; | |
| 29 | |
| 30 StreamSubscription _axesChangeSubscription; | |
| 31 | |
| 32 LineMarker(this.positions, | |
| 33 {this.drawAboveSeries: false, this.animate: false}); | |
| 34 | |
| 35 void init(ChartArea area, Selection upper, Selection lower) { | |
| 36 if (area is! CartesianArea) return; | |
| 37 _area = area; | |
| 38 _parent = drawAboveSeries ? upper : lower; | |
| 39 _isLeftAxisPrimary = _area.config.isLeftAxisPrimary; | |
| 40 _axesChangeSubscription = | |
| 41 _area.onChartAxesUpdated.listen((_) => _update()); | |
| 42 _update(); | |
| 43 } | |
| 44 | |
| 45 void dispose() { | |
| 46 if (_axesChangeSubscription != null) _axesChangeSubscription.cancel(); | |
| 47 if (_markers != null) _markers.remove(); | |
| 48 } | |
| 49 | |
| 50 bool _isDimension(int column) => _area.config.dimensions.contains(column); | |
| 51 | |
| 52 String _pathForDimension(int column, bool initial) { | |
| 53 assert(_isDimension(column)); | |
| 54 | |
| 55 int index; | |
| 56 for(index = 0; | |
| 57 _area.config.dimensions.elementAt(index) != column; ++index); | |
| 58 | |
| 59 assert(index == 0 || index == 1 && _area.useTwoDimensionAxes); | |
| 60 | |
| 61 var dimensionAtBottom = | |
| 62 index == 1 && _isLeftAxisPrimary || | |
| 63 index == 0 && !_isLeftAxisPrimary, | |
| 64 scale = _area.dimensionScales.elementAt(index), | |
| 65 scaled = scale.scale(positions[column]), | |
| 66 theme = _area.theme.getDimensionAxisTheme(), | |
| 67 renderAreaRect = _area.layout.renderArea, | |
| 68 left = renderAreaRect.x, | |
| 69 right = initial ? left : (left + renderAreaRect.width), | |
| 70 bottom = renderAreaRect.y + renderAreaRect.height, | |
| 71 top = initial ? bottom : renderAreaRect.y; | |
| 72 | |
| 73 if (scale is OrdinalScale) { | |
| 74 var band = scale.rangeBand, | |
| 75 bandPadding = theme.axisBandInnerPadding; | |
| 76 scaled = scaled - band * bandPadding + _area.theme.defaultStrokeWidth; | |
| 77 band = band + 2 * (band * bandPadding - _area.theme.defaultStrokeWidth); | |
| 78 return dimensionAtBottom | |
| 79 ? 'M ${left + scaled} ${bottom} V ${top} H ${left + scaled + band} V $
{bottom} Z' | |
| 80 : 'M ${left} ${scaled + band} H ${right} V ${scaled - band} H ${left}
Z'; | |
| 81 } else { | |
| 82 return dimensionAtBottom | |
| 83 ? 'M ${left + scaled} ${bottom} V ${top}' | |
| 84 : 'M ${left} ${scaled} H ${right}'; | |
| 85 } | |
| 86 } | |
| 87 | |
| 88 String _pathForMeasure(int column, bool initial) { | |
| 89 throw new UnimplementedError('Measure axis markers'); | |
| 90 } | |
| 91 | |
| 92 String _getMarkerPath(int column, bool initial) => | |
| 93 _isDimension(column) | |
| 94 ? _pathForDimension(column, initial) | |
| 95 : _pathForMeasure(column, initial); | |
| 96 | |
| 97 void _update() { | |
| 98 if (!_area.isReady) return; | |
| 99 _markers = _parent.selectAll('.line-marker').data(positions.keys); | |
| 100 | |
| 101 _markers.enter.append('path').each((d, i, e) { | |
| 102 e.classes.add('line-marker'); | |
| 103 e.attributes['d'] = _getMarkerPath(d, animate); | |
| 104 }); | |
| 105 | |
| 106 if (animate) { | |
| 107 _markers.transition() | |
| 108 .attrWithCallback('d', (d, i, e) => _getMarkerPath(d, false)); | |
| 109 } | |
| 110 | |
| 111 _markers.exit.remove(); | |
| 112 } | |
| 113 } | |
| 114 | |
| OLD | NEW |