2 * Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
10 * Main results viewer component.
12 var Viewer
= ui
.define('div');
14 //"Private" functions for Viewer
16 * Determines the appropriate parser for a given column, using it's first
18 * @param {String} firstElement The first (non-header) element of a given
20 * @return {String} The YUI parser needed for the column.
22 function getColumnParser(firstElement
) {
23 if (isNumeric(firstElement
)) {
25 } else if (isDate(firstElement
)) {
33 * Determines whether or not the given element is a date.
34 * @param {String} str The string representation of a potential date.
35 * @return {boolean} true/false whether or not str can be parsed to
38 function isDate(str
) {
39 var timestamp
= Date
.parse(str
);
40 return !isNaN(timestamp
);
44 * Generates the YUI column definition for the given dataset.
45 * @param {String[][]} dataSet the dataset that will be displayed.
46 * @return {JSON[]} The array containing the column definitions.
48 function createYUIColumnDefinitions(dataSet
) {
49 var header
= dataSet
[0];
50 var firstRow
= dataSet
[1];
51 var columnDefinitions
= [];
52 header
.forEach(function (element
, index
, array
) {
53 columnDefinitions
.push({
54 'key' : index
.toString(),
55 'label':element
.toString(),
58 'parser':getColumnParser(firstRow
[index
])});
60 return columnDefinitions
;
64 * Generates the YUI data source for the given dataset.
65 * @param {String[][]} dataSet the dataset that will be displayed.
66 * @return {YAHOO.util.FunctionDataSource} The YUI data source
67 * derived from the dataset.
69 function createYUIDataSource(dataSet
) {
71 //Starts from the first non-header line.
72 for (var i
= 1; i
< dataSet
.length
; i
++) {
73 var dataSourceLine
= {};
74 dataSet
[i
].forEach(function (element
, index
, array
) {
75 if (isNumeric(element
)) {
76 dataSourceLine
[index
.toString()] = parseFloat(element
);
78 dataSourceLine
[index
.toString()] = element
81 dataSource
.push(dataSourceLine
);
83 return new YAHOO
.util
.FunctionDataSource(function() {
88 * Un-selects all the columns from the given data table.
89 * @param {YAHOO.widget.DataTable} dataTable The data table that
90 * contains the results.
92 function unselectAllColumns(dataTable
) {
93 var selectedColumns
= dataTable
.getSelectedColumns();
94 for (var i
= 0; i
< selectedColumns
.length
; i
++) {
95 dataTable
.unselectColumn(selectedColumns
[i
]);
100 * Generates an array that contains the indices of the selected
101 * columns in the data table.
102 * @param {YAHOO.widget.DataTable} dataTable
103 * @return {int[]} An array with the indices of the selected columns.
105 function getSelectedColumnIndices(dataTable
) {
106 var selectedColumnIndices
= [];
107 var selectedColumns
= dataTable
.getSelectedColumns();
108 for (var i
= 0; i
< selectedColumns
.length
; i
++) {
109 selectedColumnIndices
.push(selectedColumns
[i
].key
);
111 return selectedColumnIndices
;
115 __proto__
: HTMLDivElement
.prototype,
116 decorate:function() {
118 * The id for the element that contains the barchart (Optional).
121 this.barChartElementId_
= undefined;
123 * The rectangular array that contains the contents of the cvs file.
126 this.dataSet_
= undefined;
128 set barChartElementId(e
) {
129 this.barChartElementId_
= e
;
131 get barChartElementId() {
132 return this.barChartElementId_
;
138 return this.dataSet_
;
141 * Renders the Viewer component.
145 document
.body
.appendChild(this);
146 var previousBarChart
= this.barChartElementId_
!= null ?
147 $(this.barChartElementId_
) : null;
148 if (previousBarChart
!= null) {
149 document
.body
.removeChild(previousBarChart
);
150 window
.location
.hash
= this.id
;
153 var columnDefinitions
= createYUIColumnDefinitions(this.dataSet_
);
154 var dataSource
= createYUIDataSource(this.dataSet_
);
155 var dataTable
= new YAHOO
.widget
.DataTable(this.id
, columnDefinitions
,
156 dataSource
, {caption
:'Results'});
157 var firstRow
= this.dataSet_
[1];
158 var currentViewer
= this;
160 dataTable
.subscribe('cellClickEvent', function (oArgs
) {
161 var selectedColumn
= dataTable
.getColumn(oArgs
.target
);
162 var selectedColumnIndex
= parseInt(selectedColumn
.key
);
164 if (selectedColumnIndex
== 0) {
165 unselectAllColumns(dataTable
);
169 if (isNumeric(firstRow
[selectedColumnIndex
])) {
170 dataTable
.selectColumn(selectedColumn
);
171 if (currentViewer
.barChartElementId_
!= null) {
172 var viewerBarChart_
=
173 new ViewerBarChart({ownerDocument
:window
.document
});
174 viewerBarChart_
.id
= currentViewer
.barChartElementId_
;
175 viewerBarChart_
.dataSet
= currentViewer
.dataSet_
;
176 viewerBarChart_
.selectedColumnIndices
177 = getSelectedColumnIndices(dataTable
);
178 viewerBarChart_
.render();
187 * BarChart component for the results viewer.
189 var ViewerBarChart
= ui
.define('div');
191 //"Private" functions for ViewerBarChart
193 * Generates a new array that contains only the first column, and all
194 * other selected columns.
195 * @param {(string|number)[][]} dataset Array with the csv contents.
196 * @param {int[]} selectedColumnIndices Indices for all the selected
198 * @return {String[][]} A new array containing the first column
199 * and all selected columns.
201 function extractColumnsToPlot(dataset
, selectedColumnIndices
) {
204 for (var i
= 0; i
< dataset
.length
; ++i
) {
205 line
.push(dataset
[i
][0]);
206 for (var j
= 0; j
< selectedColumnIndices
.length
; j
++) {
207 var elementValue
= dataset
[i
][selectedColumnIndices
[j
]];
208 line
.push(isNumeric(elementValue
) ? parseFloat(elementValue
) :
217 ViewerBarChart
.prototype = {
218 __proto__
:HTMLDivElement
.prototype,
219 decorate: function() {
221 * Percetage of the window width that will be used for the chart
225 ViewerBarChart
.PERCENTAGE_OF_WINDOW_WIDTH_FOR_CHART
= 0.75;
227 * Approximate number of pixels that will be used per line
231 ViewerBarChart
.HEIGHT_PER_LINE_IN_PIXELS
= 28;
234 * Raw dataset, which contains the csv file contents.
235 * @type {(String|number)[][]}
237 this.dataSet_
= undefined;
239 * Array that contains the selected indices from the table view.
242 this.selectedColumnIndices_
= undefined;
245 * Renders the ViewerBarChart component.
248 render : function() {
249 var existingBarChart
= $(this.id
);
250 if (existingBarChart
!= null) {
251 //Remove the previous bar chart
252 document
.body
.removeChild(existingBarChart
);
254 //Attach this component to the document
255 document
.body
.appendChild(this);
256 var lines
= extractColumnsToPlot(this.dataSet_
,
257 this.selectedColumnIndices_
);
258 var data
= google
.visualization
.arrayToDataTable(lines
);
260 var barCharWidth
= window
.width
*
261 ViewerBarChart
.PERCENTAGE_OF_WINDOW_WIDTH_FOR_CHART
;
262 var barCharHeight
= this.dataSet_
.length
*
263 ViewerBarChart
.HEIGHT_PER_LINE_IN_PIXELS
;
265 'width': barCharWidth
,
266 'height':barCharHeight
,
269 new google
.visualization
.BarChart(this).draw(data
, options
);
270 window
.location
.hash
= this.id
;
275 set selectedColumnIndices(sci
) {
276 this.selectedColumnIndices_
= sci
;
282 * Determines whether or not a string can be parsed to a number.
283 * @param {String} element String representation of the potential number.
284 * @return {boolean} True or false depending on whether the element is
287 function isNumeric(element
) {
288 return !isNaN(parseFloat(element
)) && isFinite(element
);
291 window
.Viewer
= Viewer
;
292 window
.ViewerBarChart
= ViewerBarChart
;