Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / web_components / ui / line_chart.js
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 'use strict';
6
7 tvcm.require('tvcm.range');
8 tvcm.require('tracing.color_scheme');
9 tvcm.require('telemetry.web_components.ui.d3');
10 tvcm.require('telemetry.web_components.ui.chart_base');
11
12 tvcm.requireStylesheet('telemetry.web_components.ui.line_chart');
13
14 tvcm.exportTo('telemetry.web_components.ui', function() {
15   var ChartBase = telemetry.web_components.ui.ChartBase;
16   var getColorOfKey = telemetry.web_components.ui.getColorOfKey;
17
18   /**
19    * @constructor
20    */
21   var LineChart = tvcm.ui.define('line-chart', ChartBase);
22
23   LineChart.prototype = {
24     __proto__: ChartBase.prototype,
25
26     decorate: function() {
27       ChartBase.prototype.decorate.call(this);
28       this.classList.add('line-chart');
29
30       this.xScale_ = d3.scale.linear();
31       this.yScale_ = d3.scale.linear();
32       d3.select(this.chartAreaElement)
33           .append('g')
34           .attr('id', 'series');
35     },
36
37     /**
38      * Sets the data array for the object
39      *
40      * @param {Array} data The data. Each element must be an object, with at
41      * least an x property. All other properties become series names in the
42      * chart.
43      */
44     set data(data) {
45       if (data.length == 0)
46         throw new Error('Data must be nonzero. Pass undefined.');
47
48       var keys;
49       if (data !== undefined) {
50         var d = data[0];
51         if (d.x === undefined)
52           throw new Error('Elements must have "x" fields');
53         keys = d3.keys(data[0]);
54         keys.splice(keys.indexOf('x'), 1);
55         if (keys.length == 0)
56           throw new Error('Elements must have at least one other field than X');
57       } else {
58         keys = undefined;
59       }
60       this.data_ = data;
61       this.seriesKeys_ = keys;
62
63       this.updateContents_();
64     },
65
66     getLegendKeys_: function() {
67       if (this.seriesKeys_ &&
68           this.seriesKeys_.length > 1)
69         return this.seriesKeys_.slice();
70       return [];
71     },
72
73     updateScales_: function(width, height) {
74       if (this.data_ === undefined)
75         return;
76
77       // X.
78       this.xScale_.range([0, width]);
79       this.xScale_.domain(d3.extent(this.data_, function(d) { return d.x; }));
80
81       // Y.
82       var yRange = new tvcm.Range();
83       this.data_.forEach(function(d) {
84         this.seriesKeys_.forEach(function(k) {
85           yRange.addValue(d[k]);
86         });
87       }, this);
88
89       this.yScale_.range([height, 0]);
90       this.yScale_.domain([yRange.min, yRange.max]);
91     },
92
93     updateContents_: function() {
94       ChartBase.prototype.updateContents_.call(this);
95       if (!this.data_)
96         return;
97
98       var chartAreaSel = d3.select(this.chartAreaElement);
99       var seriesSel = chartAreaSel.select('#series');
100       var pathsSel = seriesSel.selectAll('path').data(this.seriesKeys_);
101       pathsSel.enter()
102           .append('path')
103           .attr('class', 'line')
104           .style('stroke', function(key) {
105             return getColorOfKey(key);
106           })
107           .attr('d', function(key) {
108             var line = d3.svg.line()
109               .x(function(d) { return this.xScale_(d.x); }.bind(this))
110               .y(function(d) { return this.yScale_(d[key]); }.bind(this));
111             return line(this.data_);
112           }.bind(this));
113       pathsSel.exit().remove();
114     }
115   };
116
117   return {
118     LineChart: LineChart
119   };
120 });