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 library charted.demo.interactive; |
| 10 |
| 11 import 'dart:html'; |
| 12 import 'package:observe/observe.dart'; |
| 13 import 'package:charted/charts/charts.dart'; |
| 14 |
| 15 import 'demo_charts.dart'; |
| 16 |
| 17 const List DIMENSION_COLUMNS = const[0, 4]; |
| 18 |
| 19 int customSeriesCounter = 0; |
| 20 |
| 21 Map RENDERERS = { |
| 22 'bar-chart': 'Bar chart', |
| 23 'line-chart': 'Line chart', |
| 24 'stacked-bar-chart': 'Stacked bar chart', |
| 25 'waterfall-chart': 'Waterfall chart', |
| 26 }; |
| 27 |
| 28 CartesianRenderer getRendererForType(String name) { |
| 29 if (name == 'bar-chart') return new BarChartRenderer(); |
| 30 if (name == 'line-chart') return new LineChartRenderer(); |
| 31 if (name == 'stacked-bar-chart') return new StackedBarChartRenderer(); |
| 32 return new BarChartRenderer(); |
| 33 } |
| 34 |
| 35 String getTypeForRenderer(CartesianRenderer renderer) { |
| 36 if (renderer is BarChartRenderer) return 'bar-chart'; |
| 37 if (renderer is LineChartRenderer) return 'line-chart'; |
| 38 if (renderer is StackedBarChartRenderer) return 'stacked-bar-chart'; |
| 39 return 'bar-chart'; |
| 40 } |
| 41 |
| 42 main() { |
| 43 List DATA_SOURCE = ORDINAL_DATA; |
| 44 ChartSeries activeSeries, |
| 45 defaultSeries = new ChartSeries("Default series", |
| 46 new ObservableList.from([ 2, 3 ]), new BarChartRenderer()); |
| 47 |
| 48 ObservableList rows = new ObservableList.from(DATA_SOURCE.sublist(0, 10)), |
| 49 columns = new ObservableList.from(ORDINAL_DATA_COLUMNS), |
| 50 seriesList = new ObservableList.from([ defaultSeries ]); |
| 51 |
| 52 ChartData data = new ChartData(columns, rows); |
| 53 ChartConfig config = new ChartConfig(seriesList, DIMENSION_COLUMNS); |
| 54 |
| 55 CartesianArea area = |
| 56 new CartesianArea(querySelector('.chart-host'), |
| 57 data, config, autoUpdate: true, useTwoDimensionAxes: false); |
| 58 |
| 59 area.addChartBehavior(new ChartTooltip()); |
| 60 config.legend = new ChartLegend(querySelector('.chart-legend-host')); |
| 61 |
| 62 area.draw(); |
| 63 |
| 64 /* |
| 65 * Create and hook up the control panel |
| 66 */ |
| 67 |
| 68 ButtonElement addRowButton = querySelector('#add-row'), |
| 69 removeRowButton = querySelector('#remove-row'), |
| 70 addSeriesButton = querySelector('#add-series'), |
| 71 removeSeriesButton = querySelector('#remove-series'); |
| 72 |
| 73 InputElement useRTLScriptCheckBox = querySelector('#rtl-use-script'), |
| 74 switchAxesForRTLCheckBox = querySelector('#rtl-switch-axes'), |
| 75 useRTLLayoutCheckBox = querySelector('#rtl-use-layout'); |
| 76 |
| 77 SelectElement seriesSelect = querySelector('#select-series'), |
| 78 rendererSelect = querySelector('#select-renderer'); |
| 79 |
| 80 Element columnButtons = querySelector('#column-buttons'), |
| 81 chartsContainer = querySelector('.chart-wrapper'); |
| 82 |
| 83 /* |
| 84 * RTL handling |
| 85 */ |
| 86 |
| 87 useRTLLayoutCheckBox.onChange.listen((_) { |
| 88 bool isRTL = useRTLLayoutCheckBox.checked; |
| 89 config.isRTL = isRTL; |
| 90 chartsContainer.attributes['dir'] = isRTL ? 'rtl' : 'ltr'; |
| 91 }); |
| 92 |
| 93 useRTLScriptCheckBox.onChange.listen((_) { |
| 94 bool isRTL = useRTLScriptCheckBox.checked; |
| 95 rows.clear(); |
| 96 DATA_SOURCE = isRTL ? ORDINAL_DATA_RTL : ORDINAL_DATA; |
| 97 rows.addAll(DATA_SOURCE.sublist(0, 10)); |
| 98 }); |
| 99 |
| 100 /* |
| 101 * Updating rows |
| 102 */ |
| 103 |
| 104 updateRowButtonStates() { |
| 105 addRowButton.disabled = rows.length >= DATA_SOURCE.length; |
| 106 removeRowButton.disabled = rows.length <= 1; |
| 107 } |
| 108 |
| 109 addRowButton.onClick.listen((_) { |
| 110 if (rows.length < DATA_SOURCE.length) { |
| 111 rows.add(DATA_SOURCE.elementAt(rows.length)); |
| 112 } |
| 113 updateRowButtonStates(); |
| 114 }); |
| 115 |
| 116 removeRowButton.onClick.listen((_) { |
| 117 if (rows.length > 0) rows.removeLast(); |
| 118 updateRowButtonStates(); |
| 119 }); |
| 120 |
| 121 |
| 122 /* |
| 123 * Series selection |
| 124 */ |
| 125 |
| 126 selectSeries(ChartSeries series) { |
| 127 activeSeries = series; |
| 128 |
| 129 List<Element> options = rendererSelect.children.toList(); |
| 130 String rendererType = getTypeForRenderer(series.renderer); |
| 131 for (int i = 0; i < options.length; i++) { |
| 132 if ((options[i] as OptionElement).value == rendererType) |
| 133 rendererSelect.selectedIndex = i; |
| 134 } |
| 135 |
| 136 List buttons = querySelectorAll('.column-button'); |
| 137 Iterable measures = series.measures; |
| 138 for (int i = 0; i < buttons.length; i++) { |
| 139 buttons[i].checked = measures.contains(i + 1); |
| 140 } |
| 141 } |
| 142 |
| 143 updateSeriesSelector([ChartSeries selected]) { |
| 144 seriesSelect.children.clear(); |
| 145 seriesList.forEach((ChartSeries item) { |
| 146 var option = new OptionElement() |
| 147 ..value = item.name |
| 148 ..text = item.name; |
| 149 seriesSelect.append(option); |
| 150 }); |
| 151 selectSeries(selected == null ? seriesList.first : selected); |
| 152 } |
| 153 |
| 154 seriesSelect.onChange.listen( |
| 155 (_) => selectSeries(seriesList.firstWhere( |
| 156 (ChartSeries x) => x.name == seriesSelect.value))); |
| 157 |
| 158 |
| 159 /* |
| 160 * Renderer selection for active series |
| 161 */ |
| 162 |
| 163 updateRendererSelector() { |
| 164 rendererSelect.children.clear(); |
| 165 RENDERERS.forEach((name, label) { |
| 166 var option = new OptionElement() |
| 167 ..value = name |
| 168 ..text = label; |
| 169 rendererSelect.append(option); |
| 170 }); |
| 171 } |
| 172 |
| 173 rendererSelect.onChange.listen((_) { |
| 174 activeSeries.renderer = getRendererForType(rendererSelect.value); |
| 175 }); |
| 176 |
| 177 |
| 178 /* |
| 179 * Column selection on active series |
| 180 */ |
| 181 |
| 182 updateColumns([Event e]) { |
| 183 if (activeSeries == null) return; |
| 184 |
| 185 List<Element> buttons = querySelectorAll('.column-button'); |
| 186 InputElement firstChecked; |
| 187 for (int i = 0; i < buttons.length && firstChecked == null; i++) { |
| 188 if ((buttons[i] as InputElement).checked) firstChecked = buttons[i]; |
| 189 } |
| 190 |
| 191 List measures = activeSeries.measures as List; |
| 192 int index = buttons.indexOf(e.target) + 1; |
| 193 if ((e.target as InputElement).checked) { |
| 194 measures.add(index); |
| 195 buttons.forEach((InputElement b) => b.disabled = false); |
| 196 } else { |
| 197 measures.remove(index); |
| 198 if (measures.length <= 1) firstChecked.disabled = true; |
| 199 } |
| 200 } |
| 201 |
| 202 updateColumnsList() { |
| 203 columnButtons.children.clear(); |
| 204 for (int i = 0; i < ORDINAL_DATA_COLUMNS.length; ++i) { |
| 205 if (i == 0) continue; |
| 206 var row = new DivElement(), |
| 207 spec = ORDINAL_DATA_COLUMNS.elementAt(i), |
| 208 button = new InputElement() |
| 209 ..className = 'column-button' |
| 210 ..type = 'checkbox' |
| 211 ..value = spec.label |
| 212 ..id = 'column-$i' |
| 213 ..onChange.listen((e) => updateColumns(e)), |
| 214 label = new LabelElement() |
| 215 ..text = spec.label |
| 216 ..htmlFor = 'column-$i'; |
| 217 row.children.addAll([button,label]); |
| 218 columnButtons.append(row); |
| 219 }; |
| 220 } |
| 221 |
| 222 |
| 223 /* |
| 224 * Updates to series |
| 225 */ |
| 226 |
| 227 updateSeriesButtonStates() { |
| 228 removeSeriesButton.disabled = seriesList.length <= 1; |
| 229 } |
| 230 |
| 231 addSeriesButton.onClick.listen((_) { |
| 232 var name = 'New Series ${customSeriesCounter}', |
| 233 series = new ChartSeries(name, new ObservableList.from([1, 2, 3]), |
| 234 new BarChartRenderer()); |
| 235 seriesList.add(series); |
| 236 updateSeriesSelector(series); |
| 237 seriesSelect.selectedIndex = seriesList.length - 1; |
| 238 updateSeriesButtonStates(); |
| 239 customSeriesCounter++; |
| 240 }); |
| 241 |
| 242 removeSeriesButton.onClick.listen((_) { |
| 243 if (seriesList.length > 0) seriesList.removeLast(); |
| 244 updateSeriesSelector(); |
| 245 updateSeriesButtonStates(); |
| 246 }); |
| 247 |
| 248 |
| 249 /* |
| 250 * Update UI |
| 251 */ |
| 252 |
| 253 updateColumnsList(); |
| 254 updateRendererSelector(); |
| 255 updateSeriesSelector(); |
| 256 } |
OLD | NEW |