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 |