| OLD | NEW |
| 1 // | 1 // |
| 2 // Copyright 2014 Google Inc. All rights reserved. | 2 // Copyright 2014 Google Inc. All rights reserved. |
| 3 // | 3 // |
| 4 // Use of this source code is governed by a BSD-style | 4 // Use of this source code is governed by a BSD-style |
| 5 // license that can be found in the LICENSE file or at | 5 // license that can be found in the LICENSE file or at |
| 6 // https://developers.google.com/open-source/licenses/bsd | 6 // https://developers.google.com/open-source/licenses/bsd |
| 7 // | 7 // |
| 8 | 8 |
| 9 part of charted.svg.shapes; | 9 part of charted.svg.shapes; |
| 10 | 10 |
| 11 /// Function to convert a list of points to path. | 11 /// Function to convert a list of points to path. |
| 12 typedef String LineInterpolator(Iterable<math.Point> points, int tension); | 12 typedef String LineInterpolator(Iterable<math.Point> points, int tension); |
| 13 | 13 |
| 14 /// | 14 /// |
| 15 /// [SvgLine] provides a data-driven way to create path descriptions | 15 /// [SvgLine] provides a data-driven way to create path descriptions |
| 16 /// that can be used to draw lines. | 16 /// that can be used to draw lines. |
| 17 /// | 17 /// |
| 18 class SvgLine implements SvgShape { | 18 class SvgLine implements SvgShape { |
| 19 static const LINE_INTERPOLATOR_LINEAR = 'linear'; | 19 static const LINE_INTERPOLATOR_LINEAR = 'linear'; |
| 20 | 20 |
| 21 static final LINE_INTERPOLATORS = {LINE_INTERPOLATOR_LINEAR: _linear}; | 21 static final LINE_INTERPOLATORS = <String, LineInterpolator>{ |
| 22 LINE_INTERPOLATOR_LINEAR: _linear |
| 23 }; |
| 22 | 24 |
| 23 /// Callback to access/convert datum to x coordinate value. | 25 /// Callback to access/convert datum to x coordinate value. |
| 24 final SelectionValueAccessor<num> xValueAccessor; | 26 final SelectionValueAccessor<num> xValueAccessor; |
| 25 | 27 |
| 26 /// Callback to access/convert datum to y coordinate value. | 28 /// Callback to access/convert datum to y coordinate value. |
| 27 final SelectionValueAccessor<num> yValueAccessor; | 29 final SelectionValueAccessor<num> yValueAccessor; |
| 28 | 30 |
| 29 /// Callback that is used to determine if a value is considered valid. | 31 /// Callback that is used to determine if a value is considered valid. |
| 30 /// If [isDefined] returns false at any time, the value isn't part | 32 /// If [isDefined] returns false at any time, the value isn't part |
| 31 /// of the line - the line would be split. | 33 /// of the line - the line would be split. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 44 this.tension: 0, | 46 this.tension: 0, |
| 45 String interpolate: LINE_INTERPOLATOR_LINEAR}) | 47 String interpolate: LINE_INTERPOLATOR_LINEAR}) |
| 46 : interpolator = LINE_INTERPOLATORS[interpolate] { | 48 : interpolator = LINE_INTERPOLATORS[interpolate] { |
| 47 assert(interpolator != null); | 49 assert(interpolator != null); |
| 48 } | 50 } |
| 49 | 51 |
| 50 /// Generates path for drawing a line based in the selected [interpolator] | 52 /// Generates path for drawing a line based in the selected [interpolator] |
| 51 @override | 53 @override |
| 52 String path(data, int index, Element e) { | 54 String path(data, int index, Element e) { |
| 53 assert(data is Iterable); | 55 assert(data is Iterable); |
| 54 var segments = new StringBuffer(), points = []; | 56 var segments = new StringBuffer(), points = <math.Point<num>>[]; |
| 55 for (int i = 0, len = data.length; i < len; ++i) { | 57 for (int i = 0, len = data.length; i < len; ++i) { |
| 56 final d = data.elementAt(i); | 58 final d = data.elementAt(i); |
| 57 if (isDefined(d, i, e)) { | 59 if (isDefined(d, i, e)) { |
| 58 points.add(new math.Point(xValueAccessor(d, i), yValueAccessor(d, i))); | 60 points.add(new math.Point(xValueAccessor(d, i), yValueAccessor(d, i))); |
| 59 } else if (points.isNotEmpty) { | 61 } else if (points.isNotEmpty) { |
| 60 segments.write('M${interpolator(points, tension)}'); | 62 segments.write('M${interpolator(points, tension)}'); |
| 61 points.clear(); | 63 points.clear(); |
| 62 } | 64 } |
| 63 } | 65 } |
| 64 if (points.isNotEmpty) { | 66 if (points.isNotEmpty) { |
| 65 segments.write('M${interpolator(points, tension)}'); | 67 segments.write('M${interpolator(points, tension)}'); |
| 66 } | 68 } |
| 67 return segments.toString(); | 69 return segments.toString(); |
| 68 } | 70 } |
| 69 | 71 |
| 70 /// Default implementation of [xValueAccessor]. | 72 /// Default implementation of [xValueAccessor]. |
| 71 /// Returns the first element if [d] is an iterable, otherwise returns [d]. | 73 /// Returns the first element if [d] is an iterable, otherwise returns [d]. |
| 72 static num defaultDataToX(d, i) => d is Iterable ? d.first : d; | 74 static num defaultDataToX(d, i) => d is Iterable ? d.first : d; |
| 73 | 75 |
| 74 /// Default implementation of [yValueAccessor]. | 76 /// Default implementation of [yValueAccessor]. |
| 75 /// Returns the second element if [d] is an iterable, otherwise returns [d]. | 77 /// Returns the second element if [d] is an iterable, otherwise returns [d]. |
| 76 static num defaultDataToY(d, i) => d is Iterable ? d.elementAt(1) : d; | 78 static num defaultDataToY(d, i) => d is Iterable ? d.elementAt(1) : d; |
| 77 | 79 |
| 78 /// Default implementation of [isDefined]. | 80 /// Default implementation of [isDefined]. |
| 79 /// Returns true for all non-null values of [d]. | 81 /// Returns true for all non-null values of [d]. |
| 80 static bool defaultIsDefined(d, i, e) => d != null; | 82 static bool defaultIsDefined(d, i, e) => d != null; |
| 81 | 83 |
| 82 /// Linear interpolator. | 84 /// Linear interpolator. |
| 83 static String _linear(Iterable points, _) => | 85 static String _linear(Iterable points, int _) => |
| 84 points.map((pt) => '${pt.x},${pt.y}').join('L'); | 86 points.map((pt) => '${pt.x},${pt.y}').join('L'); |
| 85 } | 87 } |
| OLD | NEW |