ILinePlot.js revision 535b3bd3ff699415798dbf1e9cf9e3bc3f56c3b2
1/*
2 *    Copyright 2015-2016 ARM Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17var ILinePlot = ( function() {
18
19   var graphs = new Array();
20   var syncObjs = new Array();
21
22   var convertToDataTable = function (d, index_col) {
23
24        var columns = _.keys(d);
25        var out = [];
26        var index_col_default = false;
27        var index;
28
29        if (index_col == undefined) {
30
31            var index = [];
32
33            columns.forEach(function(col) {
34                index = index.concat(Object.keys(d[col]));
35            });
36
37            index = $.unique(index);
38            index_col_default = true;
39            index = index.sort(function(a, b) {
40                return (parseFloat(a) - parseFloat(b));
41            });
42        } else {
43            index = d[index_col];
44            columns.splice(columns.indexOf(index_col), 1);
45        }
46
47        for (var ix in index) {
48
49            var ix_val = ix;
50
51            if (index_col_default)
52                ix_val = index[ix];
53
54            var row = [parseFloat(ix_val)];
55            columns.forEach(function(col) {
56
57                var val = d[col][ix_val];
58                if (val == undefined)
59                    val = null;
60
61                row.push(val);
62            });
63            out.push(row);
64        }
65
66        var labels = ["index"].concat(columns);
67        return {
68            data: out,
69            labels: labels
70        }
71    };
72
73    var purge = function() {
74        for (var div_name in graphs) {
75            if (document.getElementById(div_name) == null) {
76                delete graphs[div_name];
77            }
78        }
79    };
80
81    var sync = function(group) {
82
83        var syncGraphs = Array();
84        var xRange;
85        var yRange;
86        var syncZoom = true;
87
88        for (var div_name in graphs) {
89
90            if (graphs[div_name].group == group) {
91                syncGraphs.push(graphs[div_name].graph);
92                syncZoom = syncZoom & graphs[div_name].syncZoom;
93
94                var xR = graphs[div_name].graph.xAxisRange();
95                var yR = graphs[div_name].graph.yAxisRange();
96
97                if (xRange != undefined) {
98                    if (xR[0] < xRange[0])
99                        xRange[0] = xR[0];
100                    if (xR[1] > xRange[1])
101                        xRange[1] = xR[1];
102                } else
103                    xRange = xR;
104
105                if (yRange != undefined) {
106                    if (yR[0] < yRange[0])
107                        yRange[0] = yR[0];
108                    if (yR[1] > yRange[1])
109                        yRange[1] = yR[1];
110                } else
111                    yRange = yR;
112            }
113        }
114
115        if (syncGraphs.length >= 2) {
116            if (syncZoom) {
117                if (syncObjs[group] != undefined)
118                    syncObjs[group].detach();
119
120                syncObjs[group] = Dygraph.synchronize(syncGraphs, {
121                    zoom: true,
122                    selection: false,
123                    range: true
124                });
125            }
126
127            $.each(syncGraphs, function(g) {
128                var graph = syncGraphs[g];
129
130                graph.updateOptions({
131                    valueRange: yRange,
132                    dateWindow: xRange
133                });
134
135                if (graph.padFront_ == undefined) {
136                    graph.padFront_ = true;
137                    var _decoy_elem = new Array(graph.rawData_[0].length);
138                    graph.rawData_.unshift(_decoy_elem);
139                }
140                graph.rawData_[0][0] = xRange[0];
141
142                if (graph.padBack_ == undefined) {
143                    graph.padBack_ = true;
144                    var _decoy_elem = new Array(graph.rawData_[0].length);
145                    graph.rawData_.push(_decoy_elem);
146                }
147                graph.rawData_[graph.rawData_.length - 1][0] = xRange[1];
148            });
149        }
150    };
151
152    var generate = function(data) {
153        create_graph(data);
154        purge();
155        if (data.syncGroup != undefined)
156            sync(data.syncGroup);
157    };
158
159    var create_graph = function(t_info) {
160        var tabular = convertToDataTable(t_info.data, t_info.index_col);
161
162        var graph = new Dygraph(document.getElementById(t_info.name), tabular.data, {
163            legend: 'always',
164            title: t_info.title,
165            labels: tabular.labels,
166            labelsDivStyles: {
167                'textAlign': 'right'
168            },
169            rollPeriod: 1,
170            animatedZooms: true,
171            connectSeparatedPoints: true,
172            showRangeSelector: t_info.rangesel,
173            rangeSelectorHeight: 50,
174            stepPlot: t_info.step_plot,
175            logscale: t_info.logscale,
176            fillGraph: t_info.fill_graph,
177            labelsDiv: t_info.name + "_legend",
178            errorBars: false,
179            labelsSeparateLines: true,
180            valueRange: t_info.valueRange,
181            drawPoints: t_info.drawPoints,
182            strokeWidth: t_info.strokeWidth,
183            pointSize: t_info.pointSize,
184            dateWindow: t_info.dateWindow
185        });
186
187        var width = $("#" + t_info.name)
188            .closest(".output_subarea").width() / t_info.per_line
189
190        /*
191         * Remove 3 pixels from width to avoid unnecessary horizontal scrollbar
192         */
193        graph.resize(width - 3, t_info.height);
194
195        $(window).on("resize." + t_info.name, function() {
196
197            var width = $("#" + t_info.name)
198                .closest(".output_subarea").width() / t_info.per_line
199
200            graph.resize(width, t_info.height);
201        });
202
203        graphs[t_info.name] =
204            {
205                graph: graph,
206                group: t_info.syncGroup,
207                syncZoom: t_info.syncZoom
208            };
209
210    };
211
212    return {
213        generate: generate
214    };
215
216}());
217