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;