bar_chart.html revision cef7893435aa41160dd1255c43cb8498279738cc
1<!DOCTYPE html> 2<!-- 3Copyright (c) 2014 The Chromium Authors. All rights reserved. 4Use of this source code is governed by a BSD-style license that can be 5found in the LICENSE file. 6--> 7 8<link rel="import" href="/tracing/ui/base/chart_base_2d_brushable_x.html"> 9 10<script> 11'use strict'; 12 13tr.exportTo('tr.ui.b', function() { 14 var ColorScheme = tr.b.ColorScheme; 15 var ChartBase2DBrushX = tr.ui.b.ChartBase2DBrushX; 16 var getColorOfKey = tr.ui.b.getColorOfKey; 17 18 // @constructor 19 var BarChart = tr.ui.b.define('bar-chart', ChartBase2DBrushX); 20 21 BarChart.prototype = { 22 __proto__: ChartBase2DBrushX.prototype, 23 24 decorate: function() { 25 ChartBase2DBrushX.prototype.decorate.call(this); 26 this.classList.add('bar-chart'); 27 this.xCushion_ = 0; 28 }, 29 30 isDatumFieldSeries_: function(fieldName) { 31 return fieldName != 'x'; 32 }, 33 34 getXForDatum_: function(datum, index) { 35 return datum.x; 36 }, 37 38 updateScales_: function() { 39 if (this.data_.length === 0) 40 return; 41 42 var xDifferences = 0; 43 var currentX = undefined; 44 var previousX = undefined; 45 var yRange = new tr.b.Range(); 46 this.data_.forEach(function(datum, index) { 47 previousX = currentX; 48 currentX = this.getXForDatum_(datum, index); 49 if (previousX !== undefined) { 50 xDifferences += currentX - previousX; 51 } 52 53 this.seriesKeys_.forEach(function(key) { 54 // Allow for sparse data 55 if (datum[key] !== undefined) 56 yRange.addValue(datum[key]); 57 }); 58 }, this); 59 60 // X. 61 // Leave a cushion on the right so that the last rect doesn't 62 // exceed the chart boundaries. The last rect's width is set to the 63 // average width of the rects, which is chart.width / data.length. 64 var width = this.chartAreaSize.width; 65 this.xScale_.range([0, width]); 66 var domain = d3.extent(this.data_, this.getXForDatum_.bind(this)); 67 this.xCushion_ = xDifferences / (this.data_.length - 1); 68 this.xScale_.domain([domain[0], domain[1] + this.xCushion_]); 69 70 // Y. 71 this.yScale_.range([this.chartAreaSize.height, 0]); 72 this.yScale_.domain(this.getYScaleDomain_(yRange.min, yRange.max)); 73 }, 74 75 updateDataContents_: function(dataSel) { 76 dataSel.selectAll('*').remove(); 77 var rectsSel = dataSel.selectAll('path').data(this.seriesKeys_); 78 this.data_.forEach(function(datum, index) { 79 var currentX = this.getXForDatum_(datum, index); 80 var width = undefined; 81 if (index < (this.data_.length - 1)) { 82 var nextX = this.getXForDatum_(this.data_[index + 1], index + 1); 83 width = nextX - currentX; 84 } else { 85 width = this.xCushion_; 86 } 87 88 var stacks = []; 89 this.seriesKeys_.forEach(function(key) { 90 if (datum[key] !== undefined) 91 stacks.push({y: datum[key], color: getColorOfKey(key)}); 92 }); 93 stacks.sort(function(a, b) { 94 return b.y - a.y; 95 }); 96 97 stacks.forEach(function(stack) { 98 var left = this.xScale_(currentX); 99 var right = this.xScale_(currentX + width); 100 var widthPx = right - left; 101 var top = this.yScale_(Math.max(stack.y, this.getYScaleMin_())); 102 rectsSel.enter() 103 .append('rect') 104 .attr('fill', stack.color) 105 .attr('x', left) 106 .attr('y', top) 107 .attr('width', widthPx) 108 .attr('height', this.yScale_.range()[0] - top); 109 }, this); 110 }, this); 111 rectsSel.exit().remove(); 112 } 113 }; 114 115 return { 116 BarChart: BarChart 117 }; 118}); 119</script> 120