| OLD | NEW |
| (Empty) |
| 1 /* | |
| 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. | |
| 5 */ | |
| 6 | |
| 7 /** | |
| 8 * @fileoverview Collection of functions which operate on graph data. | |
| 9 */ | |
| 10 | |
| 11 var graphUtils = window['graphUtils'] || {}; | |
| 12 | |
| 13 /** | |
| 14 * Interpolate given multiple lines of graphs, and returns the lines of | |
| 15 * the graphs where each line has the same number of points and x coordinates. | |
| 16 * | |
| 17 * For example, | |
| 18 * <pre> | |
| 19 * [[[0, 1], [2, 3]], // 1st line | |
| 20 * [[1, 3]]] // 2nd line | |
| 21 * </pre> | |
| 22 * will be converted to | |
| 23 * <pre> | |
| 24 * [[[0, 1], [1, 2], [2, 3]], // [1, 2] is interpolated. | |
| 25 * [[0, 0], [1, 3], [2, 0]]] // [0, 0] and [2, 0] are interpolated. | |
| 26 * </pre> | |
| 27 * where every line has points at x=0, 1 and 2. | |
| 28 * Interpolated data points are marked with a property | |
| 29 * {@code point.interpolated == true}. | |
| 30 * | |
| 31 * @param {Array.<Array.<Array.<number>>>} plotData List of arrays that | |
| 32 * represent individual lines. The line itself is an Array of points. | |
| 33 * @return {Array.<Array.<Array.<number>>>} An interpolated {@code plotData}. | |
| 34 * The original {@code plotData} is not affected. | |
| 35 */ | |
| 36 graphUtils.interpolate = function(plotData) { | |
| 37 var interpolated = []; // resulting interpolated {@code plotData} | |
| 38 var unconsumed = []; // indices to unconsumed points in {@code plotData} | |
| 39 for (var i = 0; i < plotData.length; ++i) { | |
| 40 interpolated.push([]); | |
| 41 unconsumed.push(0); | |
| 42 } | |
| 43 | |
| 44 // Returns the next x-coordinate to interpolate if any, or null. | |
| 45 function nextX() { | |
| 46 var index = null; | |
| 47 for (var i = 0; i < unconsumed.length; ++i) { | |
| 48 if (0 <= unconsumed[i] && unconsumed[i] < plotData[i].length && | |
| 49 (index == null || | |
| 50 plotData[i][unconsumed[i]][0] < | |
| 51 plotData[index][unconsumed[index]][0])) { | |
| 52 index = i; | |
| 53 } | |
| 54 } | |
| 55 return index == null ? null : plotData[index][unconsumed[index]][0]; | |
| 56 } | |
| 57 | |
| 58 for (var x = nextX(); x != null; x = nextX()) { // for all x | |
| 59 for (var i = 0; i < plotData.length; ++i) { // for all lines | |
| 60 var y = 0; | |
| 61 var hasPoint = false; | |
| 62 if (0 <= unconsumed[i] && unconsumed[i] < plotData[i].length) { | |
| 63 var p = plotData[i][unconsumed[i]]; | |
| 64 if (p[0] <= x) { | |
| 65 y = p[1]; // The original line has a point at x. | |
| 66 hasPoint = true; | |
| 67 } else if (unconsumed[i] == 0) { | |
| 68 y = 0; // y = 0 before the first point | |
| 69 } else { | |
| 70 // Interpolate a point. | |
| 71 var p0 = plotData[i][unconsumed[i] - 1]; | |
| 72 y = (x - p0[0]) / (p[0] - p0[0]) * (p[1] - p0[1]) + p0[1]; | |
| 73 } | |
| 74 } // else y = 0 because it's out of range. | |
| 75 | |
| 76 var point = [x, y]; | |
| 77 if (!hasPoint) { | |
| 78 point.interpolated = true; | |
| 79 } | |
| 80 interpolated[i].push(point); | |
| 81 } | |
| 82 | |
| 83 // Consume {@code plotData} by incrementing indices in {@code unconsumed}. | |
| 84 for (var i = 0; i < unconsumed.length; ++i) { | |
| 85 if (0 <= unconsumed[i] && unconsumed[i] < plotData[i].length && | |
| 86 plotData[i][unconsumed[i]][0] <= x) { | |
| 87 ++unconsumed[i]; | |
| 88 } | |
| 89 } | |
| 90 } | |
| 91 | |
| 92 return interpolated; | |
| 93 }; | |
| 94 | |
| 95 /** | |
| 96 * Creates and returns a set of stacked graphs, assuming the given | |
| 97 * {@code plotData} is interpolated by {@code graphUtils.interpolate}. | |
| 98 * | |
| 99 * For example, | |
| 100 * <pre> | |
| 101 * [[[0, 1], [1, 2]], // 1st line | |
| 102 * [[0, 1], [1, 3]], // 2nd line | |
| 103 * [[0, 2], [1, 1]]] // 3rd line | |
| 104 * </pre> | |
| 105 * will be converted to | |
| 106 * <pre> | |
| 107 * [[[0, 1], [1, 2]], // 1st | |
| 108 * [[0, 2], [1, 5]], // 1st + 2nd | |
| 109 * [[0, 4], [1, 6]]] // 1st + 2nd + 3rd | |
| 110 * </pre> | |
| 111 * | |
| 112 * @param {Array.<Array.<Array.<number>>>} plotData List of arrays that | |
| 113 * represent individual lines. The line itself is an Array of points. | |
| 114 * @return {Array.<Array.<Array.<number>>>} A stacked {@code plotData}. | |
| 115 * The original {@code plotData} is not affected. | |
| 116 */ | |
| 117 graphUtils.stackFrontToBack = function(plotData) { | |
| 118 if (!(plotData && plotData[0] && plotData[0].length > 0)) { | |
| 119 return []; | |
| 120 } | |
| 121 | |
| 122 var stacked = []; | |
| 123 for (var i = 0; i < plotData.length; ++i) { | |
| 124 stacked.push([]); | |
| 125 } | |
| 126 | |
| 127 for (var j = 0; j < plotData[0].length; ++j) { | |
| 128 for (var i = 0; i < plotData.length; ++i) { | |
| 129 var point = [ | |
| 130 plotData[i][j][0], | |
| 131 plotData[i][j][1] + | |
| 132 (i == 0 ? 0 : stacked[i - 1][j][1])]; | |
| 133 if (plotData[i][j].interpolated) { | |
| 134 point.interpolated = true; | |
| 135 } | |
| 136 stacked[i].push(point); | |
| 137 } | |
| 138 } | |
| 139 | |
| 140 return stacked; | |
| 141 }; | |
| OLD | NEW |