| <!DOCTYPE html> |
| <!-- |
| Copyright (c) 2014 The Chromium Authors. All rights reserved. |
| Use of this source code is governed by a BSD-style license that can be |
| found in the LICENSE file. |
| --> |
| |
| <link rel="import" href="/tracing/base/math/range.html"> |
| <link rel="import" href="/tracing/ui/base/chart_base_2d.html"> |
| |
| <script> |
| 'use strict'; |
| |
| tr.exportTo('tr.ui.b', function() { |
| var ScatterChart = tr.ui.b.define('scatter-chart', tr.ui.b.ChartBase2D); |
| |
| // @constructor |
| ScatterChart.Dot = function(x, y, radius, color, breadcrumb) { |
| this.x = x; |
| this.y = y; |
| this.radius = radius; |
| this.color = color; |
| this.breadcrumb = breadcrumb; |
| }; |
| |
| ScatterChart.prototype = { |
| __proto__: tr.ui.b.ChartBase2D.prototype, |
| |
| decorate() { |
| super.decorate(); |
| this.brushedXRange_ = new tr.b.math.Range(); |
| this.brushedYRange_ = new tr.b.math.Range(); |
| }, |
| |
| get hideLegend() { |
| return true; |
| }, |
| |
| get defaultGraphHeight() { |
| return 100; |
| }, |
| |
| get defaultGraphWidth() { |
| return 100; |
| }, |
| |
| updateMargins_() { |
| super.updateMargins_(); |
| if (this.data.length === 0) return; |
| |
| var rightOverhangPx = tr.b.math.Statistics.max( |
| this.data, d => this.xScale_(d.x) + d.radius - this.graphWidth); |
| this.margin.right = Math.max(this.margin.right, rightOverhangPx); |
| |
| var topOverhangPx = tr.b.math.Statistics.max( |
| this.data, d => (this.graphHeight - this.yScale_(d.y)) + d.radius) - |
| this.graphHeight; |
| this.margin.top = Math.max(this.margin.top, topOverhangPx); |
| }, |
| |
| setBrushedRanges(xRange, yRange) { |
| this.brushedXRange_.reset(); |
| this.brushedYRange_.reset(); |
| this.brushedXRange_.addRange(xRange); |
| this.brushedYRange_.addRange(yRange); |
| this.updateContents_(); |
| }, |
| |
| updateBrushContents_(brushSel) { |
| brushSel.selectAll('*').remove(); |
| if (this.brushedXRange_.isEmpty || this.brushedYRange_.isEmpty) return; |
| |
| var brushRectsSel = brushSel.selectAll('rect').data([undefined]); |
| brushRectsSel.enter().append('rect') |
| .attr('x', () => this.xScale_(this.brushedXRange_.min)) |
| .attr('y', () => this.yScale_(this.brushedYRange_.max)) |
| .attr('width', () => this.xScale_(this.brushedXRange_.max) - |
| this.xScale_(this.brushedXRange_.min)) |
| .attr('height', () => this.yScale_(this.brushedYRange_.min) - |
| this.yScale_(this.brushedYRange_.max)); |
| brushRectsSel.exit().remove(); |
| }, |
| |
| setDataFromCallbacks(data, getX, getY, getRadius, getColor) { |
| this.data = data.map(d => new ScatterChart.Dot( |
| getX(d), getY(d), getRadius(d), getColor(d), d)); |
| }, |
| |
| isDatumFieldSeries_(fieldName) { |
| return fieldName === 'y'; |
| }, |
| |
| updateDataContents_(dataSel) { |
| dataSel.selectAll('*').remove(); |
| dataSel.selectAll('circle') |
| .data(this.data_) |
| .enter() |
| .append('circle') |
| .attr('cx', d => this.xScale_(d.x)) |
| .attr('cy', d => this.yScale_(d.y)) |
| .attr('r', d => d.radius) |
| .attr('fill', d => d.color); |
| } |
| }; |
| |
| return { |
| ScatterChart, |
| }; |
| }); |
| </script> |