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

Side by Side Diff: packages/charted/lib/charts/behaviors/hovercard.dart

Issue 1521693002: Roll Observatory deps (charted -> ^0.3.0) (Closed) Base URL: https://chromium.googlesource.com/external/github.com/dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years 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
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
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 /// single row. Eg: Would not work with a water-fall chart. 51 /// single row. Eg: Would not work with a water-fall chart.
52 /// 52 ///
53 class Hovercard implements ChartBehavior { 53 class Hovercard implements ChartBehavior {
54 final HovercardBuilder builder; 54 final HovercardBuilder builder;
55 55
56 bool _isMouseTracking; 56 bool _isMouseTracking;
57 bool _isMultiValue; 57 bool _isMultiValue;
58 bool _showDimensionTitle; 58 bool _showDimensionTitle;
59 Iterable<int> _columnsToShow; 59 Iterable<int> _columnsToShow;
60 60
61 Iterable placementOrder = 61 Iterable placementOrder = const [
62 const['orientation', 'top', 'right', 'bottom', 'left', 'orientation']; 62 'orientation',
63 'top',
64 'right',
65 'bottom',
66 'left',
67 'orientation'
68 ];
63 int offset = 20; 69 int offset = 20;
64 70
65 ChartArea _area; 71 ChartArea _area;
66 ChartState _state; 72 ChartState _state;
67 SubscriptionsDisposer _disposer = new SubscriptionsDisposer(); 73 SubscriptionsDisposer _disposer = new SubscriptionsDisposer();
68 74
69 Element _hovercardRoot; 75 Element _hovercardRoot;
70 76
71 Hovercard({ 77 Hovercard(
72 bool isMouseTracking, 78 {bool isMouseTracking,
73 bool isMultiValue: false, 79 bool isMultiValue: false,
74 bool showDimensionTitle: false, 80 bool showDimensionTitle: false,
75 List columnsToShow: const [], 81 List columnsToShow: const [],
76 this.builder}) { 82 this.builder}) {
77 _isMouseTracking = isMouseTracking; 83 _isMouseTracking = isMouseTracking;
78 _isMultiValue = isMultiValue; 84 _isMultiValue = isMultiValue;
79 _showDimensionTitle = showDimensionTitle; 85 _showDimensionTitle = showDimensionTitle;
80 _columnsToShow = columnsToShow; 86 _columnsToShow = columnsToShow;
81 } 87 }
82 88
83 void init(ChartArea area, Selection _, Selection __) { 89 void init(ChartArea area, Selection _, Selection __) {
84 _area = area; 90 _area = area;
85 _state = area.state; 91 _state = area.state;
86 92
87 // If we don't have state, fall back to mouse events. 93 // If we don't have state, fall back to mouse events.
88 _isMouseTracking = 94 _isMouseTracking =
89 _isMouseTracking == true || _state == null || _area is LayoutArea; 95 _isMouseTracking == true || _state == null || _area is LayoutArea;
90 96
91 // Subscribe to events. 97 // Subscribe to events.
92 if (_isMouseTracking) { 98 if (_isMouseTracking) {
93 _disposer.addAll([ 99 _disposer.addAll([
94 _area.onValueMouseOver.listen(_handleMouseOver), 100 _area.onValueMouseOver.listen(_handleMouseOver),
95 _area.onValueMouseOut.listen(_handleMouseOut) 101 _area.onValueMouseOut.listen(_handleMouseOut)
96 ]); 102 ]);
97 } else { 103 } else {
98 _disposer.add(_state.changes.listen(_handleStateChange)); 104 _disposer.add(_state.changes.listen(_handleStateChange));
99 } 105 }
100 } 106 }
101 107
102 void dispose() { 108 void dispose() {
103 _disposer.dispose(); 109 _disposer.dispose();
104 if (_hovercardRoot != null) _hovercardRoot.remove(); 110 if (_hovercardRoot != null) _hovercardRoot.remove();
105 } 111 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 // update position and offset accordingly. 205 // update position and offset accordingly.
200 if (area.dimensionsUsingBands.contains(dimensionCol)) { 206 if (area.dimensionsUsingBands.contains(dimensionCol)) {
201 assert(dimensionScale is OrdinalScale); 207 assert(dimensionScale is OrdinalScale);
202 dimensionOffset = (dimensionScale as OrdinalScale).rangeBand / 2; 208 dimensionOffset = (dimensionScale as OrdinalScale).rangeBand / 2;
203 dimensionCenterOffset = dimensionOffset; 209 dimensionCenterOffset = dimensionOffset;
204 } 210 }
205 211
206 var rowData = area.data.rows.elementAt(row), 212 var rowData = area.data.rows.elementAt(row),
207 measurePosition = 0, 213 measurePosition = 0,
208 isNegative = false, 214 isNegative = false,
209 dimensionPosition = dimensionScale.scale( 215 dimensionPosition = dimensionScale
210 rowData.elementAt(dimensionCol)) + dimensionCenterOffset; 216 .scale(rowData.elementAt(dimensionCol)) +
217 dimensionCenterOffset;
211 218
212 if (_isMultiValue) { 219 if (_isMultiValue) {
213 var max = SMALL_INT_MIN, 220 var max = SMALL_INT_MIN, min = SMALL_INT_MAX;
214 min = SMALL_INT_MAX;
215 area.config.series.forEach((ChartSeries series) { 221 area.config.series.forEach((ChartSeries series) {
216 CartesianRenderer renderer = series.renderer; 222 CartesianRenderer renderer = series.renderer;
217 Extent extent = renderer.extentForRow(rowData); 223 Extent extent = renderer.extentForRow(rowData);
218 if (extent.min < min) min = extent.min; 224 if (extent.min < min) min = extent.min;
219 if (extent.max > max) max = extent.max; 225 if (extent.max > max) max = extent.max;
220 measurePosition = measureScale.scale(max); 226 measurePosition = measureScale.scale(max);
221 isNegative = max < 0; 227 isNegative = max < 0;
222 }); 228 });
223 } else { 229 } else {
224 var value = rowData.elementAt(column); 230 var value = rowData.elementAt(column);
225 isNegative = value < 0; 231 isNegative = value < 0;
226 measurePosition = measureScale.scale(rowData.elementAt(column)); 232 measurePosition = measureScale.scale(rowData.elementAt(column));
227 } 233 }
228 234
229 if (area.config.isLeftAxisPrimary) { 235 if (area.config.isLeftAxisPrimary) {
230 _positionAtPoint(measurePosition, dimensionPosition, 236 _positionAtPoint(measurePosition, dimensionPosition, 0, dimensionOffset,
231 0, dimensionOffset, isNegative, true); 237 isNegative, true);
232 } else { 238 } else {
233 _positionAtPoint(dimensionPosition, measurePosition, 239 _positionAtPoint(dimensionPosition, measurePosition, dimensionOffset, 0,
234 dimensionOffset, 0, isNegative, false); 240 isNegative, false);
235 } 241 }
236 } 242 }
237 243
238 void _positionAtPoint(num x, num y, 244 void _positionAtPoint(num x, num y, num xBand, num yBand, bool negative,
239 num xBand, num yBand, bool negative, [bool isLeftPrimary = false]) { 245 [bool isLeftPrimary = false]) {
240 var rect = _hovercardRoot.getBoundingClientRect(), 246 var rect = _hovercardRoot.getBoundingClientRect(),
241 width = rect.width, 247 width = rect.width,
242 height = rect.height, 248 height = rect.height,
243 scaleToHostY = 249 scaleToHostY = (_area.theme.padding != null
244 (_area.theme.padding != null ? _area.theme.padding.top : 0) + 250 ? _area.theme.padding.top
251 : 0) +
245 (_area.layout.renderArea.y), 252 (_area.layout.renderArea.y),
246 scaleToHostX = 253 scaleToHostX = (_area.theme.padding != null
247 (_area.theme.padding != null ? _area.theme.padding.start: 0) + 254 ? _area.theme.padding.start
255 : 0) +
248 (_area.layout.renderArea.x), 256 (_area.layout.renderArea.x),
249 renderAreaHeight = _area.layout.renderArea.height, 257 renderAreaHeight = _area.layout.renderArea.height,
250 renderAreaWidth = _area.layout.renderArea.width; 258 renderAreaWidth = _area.layout.renderArea.width;
251 259
252 if (scaleToHostY < 0) scaleToHostY = 0; 260 if (scaleToHostY < 0) scaleToHostY = 0;
253 if (scaleToHostX < 0) scaleToHostX = 0; 261 if (scaleToHostX < 0) scaleToHostX = 0;
254 262
255 num top = 0, left = 0; 263 num top = 0, left = 0;
256 for (int i = 0, len = placementOrder.length; i < len; ++i) { 264 for (int i = 0, len = placementOrder.length; i < len; ++i) {
257 String placement = placementOrder.elementAt(i); 265 String placement = placementOrder.elementAt(i);
(...skipping 15 matching lines...) Expand all
273 top = isLeftPrimary ? y - height / 2 : y; 281 top = isLeftPrimary ? y - height / 2 : y;
274 left = negative ? x + xBand : x - (width + xBand); 282 left = negative ? x + xBand : x - (width + xBand);
275 } 283 }
276 if (placement == 'bottom') { 284 if (placement == 'bottom') {
277 top = negative ? y - (height + yBand) : y + yBand; 285 top = negative ? y - (height + yBand) : y + yBand;
278 left = isLeftPrimary ? x - width : x - width / 2; 286 left = isLeftPrimary ? x - width : x - width / 2;
279 } 287 }
280 288
281 // Check if the popup is contained in the RenderArea. 289 // Check if the popup is contained in the RenderArea.
282 // If not, try other placements. 290 // If not, try other placements.
283 if (top > 0 && left > 0 && 291 if (top > 0 &&
284 top + height < renderAreaHeight && left + width < renderAreaWidth) { 292 left > 0 &&
293 top + height < renderAreaHeight &&
294 left + width < renderAreaWidth) {
285 break; 295 break;
286 } 296 }
287 } 297 }
288 298
289 _hovercardRoot.style 299 _hovercardRoot.style
290 ..top = '${top + scaleToHostY}px' 300 ..top = '${top + scaleToHostY}px'
291 ..left = '${left + scaleToHostX}px'; 301 ..left = '${left + scaleToHostX}px';
292 } 302 }
293 303
294 Element _createTooltip(int column, int row) { 304 Element _createTooltip(int column, int row) {
295 var element = new Element.div(); 305 var element = new Element.div();
296 if (_showDimensionTitle) { 306 if (_showDimensionTitle) {
297 var titleElement = new Element.div() 307 var titleElement = new Element.div()
298 ..className = 'hovercard-title' 308 ..className = 'hovercard-title'
299 ..text = _getDimensionTitle(column, row); 309 ..text = _getDimensionTitle(column, row);
300 element.append(titleElement); 310 element.append(titleElement);
301 } 311 }
302 312
303 var measureVals = _getMeasuresData(column, row); 313 var measureVals = _getMeasuresData(column, row);
304 measureVals.forEach((ChartLegendItem item) { 314 measureVals.forEach((ChartLegendItem item) {
305 var labelElement = new Element.div() 315 var labelElement = new Element.div()
306 ..className = 'hovercard-measure-label' 316 ..className = 'hovercard-measure-label'
307 ..text = item.label, 317 ..text = item.label,
308 valueElement = new Element.div() 318 valueElement = new Element.div()
309 ..style.color = item.color 319 ..style.color = item.color
310 ..className = 'hovercard-measure-value' 320 ..className = 'hovercard-measure-value'
311 ..text = item.value, 321 ..text = item.value,
312 measureElement = new Element.div() 322 measureElement = new Element.div()
313 ..append(labelElement) 323 ..append(labelElement)
(...skipping 28 matching lines...) Expand all
342 }); 352 });
343 } else { 353 } else {
344 measureVals.add(_createHovercardItem(column, row)); 354 measureVals.add(_createHovercardItem(column, row));
345 } 355 }
346 356
347 return measureVals; 357 return measureVals;
348 } 358 }
349 359
350 ChartLegendItem _createHovercardItem(int column, int row) { 360 ChartLegendItem _createHovercardItem(int column, int row) {
351 var rowData = _area.data.rows.elementAt(row), 361 var rowData = _area.data.rows.elementAt(row),
352 columns = _area.data.columns, 362 columns = _area.data.columns,
353 spec = columns.elementAt(column), 363 spec = columns.elementAt(column),
354 colorKey = _area.useRowColoring ? row : column, 364 colorKey = _area.useRowColoring ? row : column,
355 formatter = _getFormatterForColumn(column), 365 formatter = _getFormatterForColumn(column),
356 label = _area.useRowColoring 366 label = _area.useRowColoring
357 ? rowData.elementAt(_area.config.dimensions.first) 367 ? rowData.elementAt(_area.config.dimensions.first)
358 : spec.label; 368 : spec.label;
359 return new ChartLegendItem( 369 return new ChartLegendItem(
360 label: label, 370 label: label,
361 value: formatter(rowData.elementAt(column)), 371 value: formatter(rowData.elementAt(column)),
362 color: _area.theme.getColorForKey(colorKey)); 372 color: _area.theme.getColorForKey(colorKey));
363 } 373 }
364 374
365 String _getDimensionTitle(int column, int row) { 375 String _getDimensionTitle(int column, int row) {
366 var rowData = _area.data.rows.elementAt(row), 376 var rowData = _area.data.rows.elementAt(row),
367 colSpec = _area.data.columns.elementAt(column); 377 colSpec = _area.data.columns.elementAt(column);
368 if (_area.useRowColoring) { 378 if (_area.useRowColoring) {
369 return colSpec.label; 379 return colSpec.label;
370 } else { 380 } else {
371 var count = (_area as CartesianArea).useTwoDimensionAxes ? 2 : 1, 381 var count = (_area as CartesianArea).useTwoDimensionAxes ? 2 : 1,
372 dimensions = _area.config.dimensions.take(count); 382 dimensions = _area.config.dimensions.take(count);
373 return dimensions.map( 383 return dimensions
374 (int c) => 384 .map((int c) => _getFormatterForColumn(c)(rowData.elementAt(c)))
375 _getFormatterForColumn(c)(rowData.elementAt(c))).join(', '); 385 .join(', ');
376 } 386 }
377 } 387 }
378 388
379 // TODO: Move this to a common place? 389 // TODO: Move this to a common place?
380 Scale _getScaleForColumn(int column) { 390 Scale _getScaleForColumn(int column) {
381 var series = _area.config.series.firstWhere( 391 var series = _area.config.series.firstWhere(
382 (ChartSeries x) => x.measures.contains(column), orElse: () => null); 392 (ChartSeries x) => x.measures.contains(column),
393 orElse: () => null);
383 return series != null 394 return series != null
384 ? (_area as CartesianArea).measureScales(series).first 395 ? (_area as CartesianArea).measureScales(series).first
385 : null; 396 : null;
386 } 397 }
387 398
388 // TODO: Move this to a common place? 399 // TODO: Move this to a common place?
389 FormatFunction _getFormatterForColumn(int column) { 400 FormatFunction _getFormatterForColumn(int column) {
390 var formatter = _area.data.columns.elementAt(column).formatter; 401 var formatter = _area.data.columns.elementAt(column).formatter;
391 if (formatter == null && _area is CartesianArea) { 402 if (formatter == null && _area is CartesianArea) {
392 var scale = _getScaleForColumn(column); 403 var scale = _getScaleForColumn(column);
393 if (scale != null) { 404 if (scale != null) {
394 formatter = scale.createTickFormatter(); 405 formatter = scale.createTickFormatter();
395 } 406 }
396 } 407 }
397 if (formatter == null) { 408 if (formatter == null) {
398 // Formatter function must return String. Default to identity function 409 // Formatter function must return String. Default to identity function
399 // but return the toString() instead. 410 // but return the toString() instead.
400 formatter = (x) => x.toString(); 411 formatter = (x) => x.toString();
401 } 412 }
402 return formatter; 413 return formatter;
403 } 414 }
404 } 415 }
OLDNEW
« no previous file with comments | « packages/charted/lib/charts/behaviors/chart_tooltip.dart ('k') | packages/charted/lib/charts/behaviors/line_marker.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698