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.charts; | 9 part of charted.charts; |
10 | 10 |
11 typedef bool FilterFunction(dynamic value); | 11 typedef bool FilterFunction(dynamic value); |
12 | 12 |
13 /** | 13 /// Transforms the ChartData base on the specified FilterDefinitions. Each row |
14 * Transforms the ChartData base on the specified FilterDefinitions. Each row | 14 /// of data will be tested by passing the value at target column to the filter |
15 * of data will be tested by passing the value at target column to the filter | 15 /// function. If filter function returns false, the row will be filtered out. |
16 * function. If filter function returns false, the row will be filtered out. | 16 /// This transformer does not modify the column part of the input ChartData. |
17 * This transformer does not modify the column part of the input ChartData. | |
18 */ | |
19 class FilterTransformer extends ChangeNotifier | 17 class FilterTransformer extends ChangeNotifier |
20 implements ChartDataTransform, ChartData { | 18 implements ChartDataTransform, ChartData { |
21 final SubscriptionsDisposer _dataSubscriptions = new SubscriptionsDisposer(); | 19 final SubscriptionsDisposer _dataSubscriptions = new SubscriptionsDisposer(); |
22 Iterable<ChartColumnSpec> columns; | 20 Iterable<ChartColumnSpec> columns; |
23 ObservableList<Iterable> rows = new ObservableList(); | 21 ObservableList<Iterable> rows = new ObservableList(); |
24 List<FilterDefinition> filterFunctions; | 22 List<FilterDefinition> filterFunctions; |
25 ChartData _data; | 23 ChartData _data; |
26 | 24 |
27 FilterTransformer(this.filterFunctions); | 25 FilterTransformer(this.filterFunctions); |
28 | 26 |
29 /** | 27 /// Transforms the input data with the list of [FilterDefinition] specified in |
30 * Transforms the input data with the list of [FilterDefinition] specified in | 28 /// the constructor. If the rows and columns are ObservableList in the data, |
31 * the constructor. If the rows and columns are ObservableList in the data, | 29 /// changes in rows and columns in input data will trigger transform to be |
32 * changes in rows and columns in input data will trigger transform to be | 30 /// performed again to update the output rows and columns. |
33 * performed again to update the output rows and columns. | |
34 */ | |
35 ChartData transform(ChartData data) { | 31 ChartData transform(ChartData data) { |
36 _data = data; | 32 _data = data; |
37 _registerListeners(); | 33 _registerListeners(); |
38 _transform(); | 34 _transform(); |
39 return this; | 35 return this; |
40 } | 36 } |
41 | 37 |
42 /** Registers listeners if data.rows or data.columns are Observable. */ | 38 /// Registers listeners if data.rows or data.columns are Observable. |
43 _registerListeners() { | 39 _registerListeners() { |
44 _dataSubscriptions.dispose(); | 40 _dataSubscriptions.dispose(); |
45 | 41 |
46 if(_data is Observable) { | 42 if (_data is Observable) { |
47 var observable = (_data as Observable); | 43 var observable = (_data as Observable); |
48 _dataSubscriptions.add(observable.changes.listen((records) { | 44 _dataSubscriptions.add(observable.changes.listen((records) { |
49 _transform(); | 45 _transform(); |
50 | 46 |
51 // NOTE: Currently we're only passing the first change because the chart | 47 // NOTE: Currently we're only passing the first change because the chart |
52 // area just draw with the updated data. When we add partial update | 48 // area just draw with the updated data. When we add partial update |
53 // to chart area, we'll need to handle this better. | 49 // to chart area, we'll need to handle this better. |
54 notifyChange(records.first); | 50 notifyChange(records.first); |
55 })); | 51 })); |
56 } | 52 } |
57 } | 53 } |
58 | 54 |
59 /** | 55 /// Performs the filter transform with _data. This is called on transform and |
60 * Performs the filter transform with _data. This is called on transform and | 56 /// onChange if the input ChartData is Observable. |
61 * onChange if the input ChartData is Observable. | |
62 */ | |
63 _transform() { | 57 _transform() { |
64 columns = _data.columns; | 58 columns = _data.columns; |
65 rows.clear(); | 59 rows.clear(); |
66 | 60 |
67 for (var row in _data.rows) { | 61 for (var row in _data.rows) { |
68 // Add the row if each value in target column passes the filter function. | 62 // Add the row if each value in target column passes the filter function. |
69 if (filterFunctions.every((e) => | 63 if (filterFunctions |
70 e.filterFunc(row.elementAt(e.targetColumn)))) { | 64 .every((e) => e.filterFunc(row.elementAt(e.targetColumn)))) { |
71 rows.add(row); | 65 rows.add(row); |
72 } | 66 } |
73 } | 67 } |
74 } | 68 } |
75 } | 69 } |
76 | 70 |
77 class FilterDefinition { | 71 class FilterDefinition { |
78 final FilterFunction filterFunc; | 72 final FilterFunction filterFunc; |
79 final int targetColumn; | 73 final int targetColumn; |
80 FilterDefinition(this.targetColumn, this.filterFunc); | 74 FilterDefinition(this.targetColumn, this.filterFunc); |
81 } | 75 } |
OLD | NEW |