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

Side by Side Diff: charted/lib/charts/behaviors/chart_tooltip.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 /// Displays tooltip for the values as user moves the mouse pointer over
12 /// values in the chart. It displays all the active values in the data row
13 /// and use the value in the dimension as the title.
14 @Deprecated('Use Hovercard')
15 class ChartTooltip implements ChartBehavior {
16 static const _TOOLTIP_OFFSET = 10;
17 final String orientation;
18 final bool showDimensionValue;
19 final bool showMeasureTotal;
20 final bool showSelectedMeasure;
21
22 ChartArea _area;
23 ChartState _state;
24 Selection _tooltipRoot;
25 SubscriptionsDisposer _disposer = new SubscriptionsDisposer();
26
27 /// Constructs the tooltip.
28 /// If [showDimensionValue] is set, displays the dimension value as title.
29 /// If [showMeasureTotal] is set, displays the total value.
30 ChartTooltip({
31 this.showSelectedMeasure: false,
32 this.showDimensionValue: false,
33 this.showMeasureTotal: false,
34 this.orientation: ORIENTATION_RIGHT});
35
36 /// Sets up listeners for triggering tooltip.
37 void init(ChartArea area, Selection _, Selection __) {
38 _area = area;
39 _state = area.state;
40 _disposer.addAll([
41 area.onValueMouseOver.listen(show),
42 area.onValueMouseOut.listen(hide)
43 ]);
44
45 // Tooltip requires host to be position: relative.
46 area.host.style.position = 'relative';
47
48 var _scope = new SelectionScope.element(_area.host);
49 _scope.append('div')..classed('tooltip');
50 _tooltipRoot = _scope.select('.tooltip');
51 }
52
53 void dispose() {
54 _disposer.dispose();
55 if (_tooltipRoot != null) _tooltipRoot.remove();
56 }
57
58 /// Displays tooltip upon receiving a hover event on an element in chart.
59 show(ChartEvent e) {
60 _tooltipRoot.first
61 ..children.clear()
62 ..attributes['dir'] = _area.config.isRTL ? 'rtl' : '';
63 _tooltipRoot.classed('rtl', _area.config.isRTL);
64
65 // Display dimension value if set in config.
66 if (showDimensionValue) {
67 var column = _area.config.dimensions.elementAt(0),
68 value = _area.data.rows.elementAt(e.row).elementAt(column),
69 formatter = _getFormatterForColumn(column);
70
71 _tooltipRoot.append('div')
72 ..classed('tooltip-title')
73 ..text((formatter != null) ? formatter(value) : value.toString());
74 }
75
76 // Display sum of the values in active row if set in config.
77 if (showMeasureTotal) {
78 var measures = e.series.measures,
79 formatter = _getFormatterForColumn(measures.elementAt(0)),
80 row = _area.data.rows.elementAt(e.row),
81 total = 0;
82 for (int i = 0, len = measures.length; i < len; i++) {
83 total += row.elementAt(measures.elementAt(i));
84 }
85 _tooltipRoot.append('div')
86 ..classed('tooltip-total')
87 ..text((formatter != null) ? formatter(total) : total.toString());
88 }
89
90 // Find the currently selectedMeasures and hoveredMeasures and show
91 // tooltip for them, if none is selected/hovered, show all.
92 var activeMeasures = [];
93 if (showSelectedMeasure) {
94 activeMeasures.addAll(_state.selection);
95 activeMeasures.add(_state.preview != null ? _state.preview :
96 _state.hovered.first);
97 if (activeMeasures.isEmpty) {
98 for (var series in _area.config.series) {
99 activeMeasures.addAll(series.measures);
100 }
101 }
102 activeMeasures.sort();
103 }
104
105 var data = (showSelectedMeasure) ? activeMeasures : e.series.measures;
106
107 // Create the tooltip items base on the number of measures in the series.
108 var items = _tooltipRoot.selectAll('.tooltip-item').
109 data(data);
110 items.enter.append('div')
111 ..classed('tooltip-item')
112 ..classedWithCallback('active', (d, i, c) =>
113 !showSelectedMeasure && (d == e.column));
114
115 // Display the label for the currently active series.
116 var tooltipItems = _tooltipRoot.selectAll('.tooltip-item');
117 tooltipItems.append('div')
118 ..classed('tooltip-item-label')
119 ..textWithCallback((d, i, c) => _area.data.columns.
120 elementAt((showSelectedMeasure) ? d :
121 e.series.measures.elementAt(i)).label);
122
123 // Display the value of the currently active series
124 tooltipItems.append('div')
125 ..classed('tooltip-item-value')
126 ..styleWithCallback('color', (d, i, c) =>
127 _area.theme.getColorForKey(d))
128 ..textWithCallback((d, i, c) {
129 var formatter = _getFormatterForColumn(d),
130 value = _area.data.rows.elementAt(e.row).elementAt(d);
131 return (formatter != null) ? formatter(value) : value.toString();
132 });
133
134 math.Point position = computeTooltipPosition(
135 new math.Point(e.chartX, e.chartY),
136 _tooltipRoot.first.getBoundingClientRect());
137
138 // Set position of the tooltip and display it.
139 _tooltipRoot
140 ..style('left', '${position.x}px')
141 ..style('top', '${position.y}px')
142 ..style('opacity', '1');
143 }
144
145 static String switchPositionDirection(String direction) =>
146 direction == ORIENTATION_LEFT
147 ? ORIENTATION_RIGHT
148 : ORIENTATION_LEFT;
149
150 /// Computes the ideal tooltip position based on orientation.
151 math.Point computeTooltipPosition(
152 math.Point coord, math.Rectangle rect) {
153 var x, y, direction;
154 direction = _area.config.isRTL && _area.config.switchAxesForRTL
155 ? switchPositionDirection(orientation)
156 : orientation;
157
158 if (direction == ORIENTATION_LEFT) {
159 x = coord.x - rect.width - _TOOLTIP_OFFSET;
160 y = coord.y + _TOOLTIP_OFFSET;
161 } else {
162 x = coord.x + _TOOLTIP_OFFSET;
163 y = coord.y + _TOOLTIP_OFFSET;
164 }
165 return boundTooltipPosition(
166 new math.Rectangle(x, y, rect.width, rect.height));
167 }
168
169 /// Positions the tooltip to be inside of the chart boundary.
170 math.Point boundTooltipPosition(math.Rectangle rect) {
171 var hostRect = _area.host.getBoundingClientRect();
172
173 var top = rect.top;
174 var left = rect.left;
175
176 // Checks top and bottom.
177 if (rect.top < 0) {
178 top += (2 * _TOOLTIP_OFFSET);
179 } else if (rect.top + rect.height > hostRect.height) {
180 top -= (rect.height + 2 * _TOOLTIP_OFFSET);
181 }
182
183 // Checks left and right.
184 if (rect.left < 0) {
185 left += (rect.width + 2 * _TOOLTIP_OFFSET);
186 } else if (rect.left + rect.width > hostRect.width) {
187 left -= (rect.width + 2 * _TOOLTIP_OFFSET);
188 }
189
190 return new math.Point(left, top);
191 }
192
193 FormatFunction _getFormatterForColumn(int column) =>
194 _area.data.columns.elementAt(column).formatter;
195
196 hide(ChartEvent e) {
197 if (_tooltipRoot == null) return;
198 _tooltipRoot.style('opacity', '0');
199 }
200 }
201
OLDNEW
« no previous file with comments | « charted/lib/charts/behaviors/axis_label_tooltip.dart ('k') | charted/lib/charts/behaviors/hovercard.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698