Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(227)

Side by Side Diff: charted/lib/charts/src/chart_legend_impl.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 class DefaultChartLegendImpl implements ChartLegend {
12 static const CLASS_PREFIX = 'chart-legend';
13
14 final Element host;
15 final int visibleItemsCount;
16 final bool showValues;
17 final SubscriptionsDisposer _disposer = new SubscriptionsDisposer();
18
19 String _title;
20 SelectionScope _scope;
21 Selection _root;
22 ChartArea _area;
23
24 Iterable<ChartLegendItem> _items;
25
26 DefaultChartLegendImpl(
27 this.host, this.visibleItemsCount, this.showValues, String title)
28 : _title = title {
29 assert(host != null);
30 }
31
32 void dispose() {
33 _disposer.dispose();
34 }
35
36 /**
37 * Sets the title of the legend, if the legend is already drawn, updates the
38 * title on the legend as well.
39 */
40 void set title(String title) {
41 _title = title;
42 if (_scope == null) return;
43 _updateTitle();
44 }
45
46 String get title => _title;
47
48 /** Updates the title of the legend. */
49 void _updateTitle() {
50 if (_title.isNotEmpty) {
51 if (_root.select('.chart-legend-heading').length == 0) {
52 _root.select('.chart-legend-heading');
53 _root.append('div')
54 ..classed('chart-legend-heading')
55 ..text(_title);
56 } else {
57 _root.select('.chart-legend-heading').text(_title);
58 }
59 }
60 }
61
62 /** Updates the legend base on a new list of ChartLegendItems. */
63 update(Iterable<ChartLegendItem> items, ChartArea area) {
64 assert(items != null);
65 assert(area == _area || _area == null);
66
67 _area = area;
68 if (_area.state != null) {
69 _disposer.add(_area.state.changes.listen(_handleStateChanges));
70 }
71 if (_scope == null) {
72 _scope = new SelectionScope.element(host);
73 _root = _scope.selectElements([host]);
74 }
75
76 _updateTitle();
77 _items = items;
78 _createLegendItems();
79
80 // Add more item label if there's more items than the max display items.
81 if ((visibleItemsCount > 0) && (visibleItemsCount < items.length)) {
82 _root.select('.chart-legend-more').remove();
83 _root.append('div')
84 ..on('mouseover',
85 (d, i, e) => _displayMoreItem(items.skip(visibleItemsCount)))
86 ..on('mouseleave', (d, i, e) => _hideMoreItem())
87 ..text('${items.length - visibleItemsCount} more...')
88 ..classed('chart-legend-more');
89 }
90 }
91
92 /** Hides extra legend items. */
93 void _hideMoreItem() {
94 var tooltip = _root.select('.chart-legend-more-tooltip');
95 tooltip.style('opacity', '0');
96 }
97
98 // Displays remaining legend items as a tooltip
99 void _displayMoreItem(Iterable<ChartLegendItem> items) {
100 var tooltip = _root.select('.chart-legend-more-tooltip');
101 if (tooltip.isEmpty) {
102 tooltip = _root.select('.chart-legend-more').append('div')
103 ..classed('chart-legend-more-tooltip');
104 }
105 tooltip.style('opacity', '1');
106
107 // _createLegendItems(tooltip, 'chart-legend-more', items);
108 }
109
110 /// Creates legend items starting at the given index.
111 void _createLegendItems() {
112 var state = _area.state,
113 rows = _root.selectAll(
114 '.chart-legend-row').data(_items, (x) => x.hashCode),
115 isFirstRender = rows.length == 0;
116
117 var enter = rows.enter.appendWithCallback((d, i, e) {
118 var row = Namespace.createChildElement('div', e),
119 color = Namespace.createChildElement('div', e)
120 ..className = 'chart-legend-color',
121 label = Namespace.createChildElement('div', e)
122 ..className = 'chart-legend-label',
123 value = showValues ? (Namespace.createChildElement('div', e)
124 ..className = 'chart-legend-value') : null;
125
126 var rowStyles = ['chart-legend-row'].toList();
127
128 // If this is the first time we are adding rows,
129 // Update elements before adding them to the DOM.
130 if (isFirstRender) {
131 if (state != null) {
132 if (d.index == state.preview) {
133 rowStyles.add('chart-legend-hover');
134 }
135 if (state.isSelected(d.index)) {
136 rowStyles.add('chart-legend-selected');
137 }
138 }
139 rowStyles.addAll(
140 d.series.map((ChartSeries x) => 'type-${x.renderer.name}'));
141
142 color.style.setProperty('background-color', d.color);
143 row.append(color);
144 label.text = d.label;
145 row.append(label);
146
147 if (showValues) {
148 value.text = d.value;
149 value.style.setProperty('color', d.color);
150 row.append(value);
151 }
152 }
153 row.classes.addAll(rowStyles);
154 return row;
155 });
156
157 // We have elements in the DOM that need updating.
158 if (!isFirstRender) {
159 rows.each((ChartLegendItem d, i, Element e) {
160 var classes = e.classes;
161 if (state != null) {
162 if (d.index == state.preview) {
163 classes.add('chart-legend-hover');
164 } else {
165 classes.remove('chart-legend-hover');
166 }
167 if (state.isSelected(d.index)) {
168 classes.add('chart-legend-selected');
169 } else {
170 classes.remove('chart-legend-selected');
171 }
172 }
173 classes.addAll(d.series.map((x) => 'type-${x.renderer.name}'));
174
175 (e.children[0]).style.setProperty('background-color', d.color);
176 (e.children[1]).text = d.label;
177 if (showValues) {
178 (e.lastChild as Element)
179 ..text = d.value
180 ..style.setProperty('color', d.color);
181 }
182 });
183 }
184
185 if (state != null) {
186 enter
187 ..on('mouseover', (d, i, e) => state.preview = d.index)
188 ..on('mouseout', (d, i, e) {
189 if (state.preview == d.index) {
190 state.preview = null;
191 }
192 })
193 ..on('click', (d, i, e) {
194 if (state.isSelected(d.index)) {
195 state.unselect(d.index);
196 } else {
197 state.select(d.index);
198 }
199 });
200 }
201
202 rows.exit.remove();
203 }
204
205 /// Update legend to show chart's selection and visibility.
206 void _handleStateChanges(_) => _createLegendItems();
207 }
OLDNEW
« no previous file with comments | « charted/lib/charts/src/chart_events_impl.dart ('k') | charted/lib/charts/src/chart_series_impl.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698