VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/testmanager/webui/wuihlpgraphgooglechart.py@ 78138

Last change on this file since 78138 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.6 KB
Line 
1# -*- coding: utf-8 -*-
2# $Id: wuihlpgraphgooglechart.py 76553 2019-01-01 01:45:53Z vboxsync $
3
4"""
5Test Manager Web-UI - Graph Helpers - Implemented using Google Charts.
6"""
7
8__copyright__ = \
9"""
10Copyright (C) 2012-2019 Oracle Corporation
11
12This file is part of VirtualBox Open Source Edition (OSE), as
13available from http://www.virtualbox.org. This file is free software;
14you can redistribute it and/or modify it under the terms of the GNU
15General Public License (GPL) as published by the Free Software
16Foundation, in version 2 as it comes in the "COPYING" file of the
17VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19
20The contents of this file may alternatively be used under the terms
21of the Common Development and Distribution License Version 1.0
22(CDDL) only, as it comes in the "COPYING.CDDL" file of the
23VirtualBox OSE distribution, in which case the provisions of the
24CDDL are applicable instead of those of the GPL.
25
26You may elect to license modified versions of this file under the
27terms and conditions of either the GPL or the CDDL or both.
28"""
29__version__ = "$Revision: 76553 $"
30
31# Validation Kit imports.
32from common import webutils;
33from testmanager.webui.wuihlpgraphbase import WuiHlpGraphBase;
34from testmanager.webui import wuihlpgraphsimple;
35
36
37#*******************************************************************************
38#* Global Variables *
39#*******************************************************************************
40g_cGraphs = 0;
41
42class WuiHlpGraphGoogleChartsBase(WuiHlpGraphBase):
43 """ Base class for the Google Charts graphs. """
44 pass;
45
46
47## @todo bar graphs later.
48WuiHlpBarGraph = wuihlpgraphsimple.WuiHlpBarGraph;
49
50
51class WuiHlpLineGraph(WuiHlpGraphGoogleChartsBase):
52 """
53 Line graph.
54 """
55
56 ## @todo implement error bars.
57 kfNoErrorBarsSupport = True;
58
59 def __init__(self, sId, oData, oDisp = None, fErrorBarY = False):
60 # oData must be a WuiHlpGraphDataTableEx like object.
61 WuiHlpGraphGoogleChartsBase.__init__(self, sId, oData, oDisp);
62 self._cMaxErrorBars = 12;
63 self._fErrorBarY = fErrorBarY;
64
65 def setErrorBarY(self, fEnable):
66 """ Enables or Disables error bars, making this work like a line graph. """
67 self._fErrorBarY = fEnable;
68 return True;
69
70 def renderGraph(self): # pylint: disable=R0914
71 fSlideFilter = True;
72
73 # Tooltips?
74 cTooltips = 0;
75 for oSeries in self._oData.aoSeries:
76 cTooltips += oSeries.asHtmlTooltips is not None;
77
78 # Unique on load function.
79 global g_cGraphs;
80 iGraph = g_cGraphs;
81 g_cGraphs += 1;
82
83 sHtml = '<div id="%s">\n' % ( self._sId, );
84 if fSlideFilter:
85 sHtml += ' <table><tr><td><div id="%s_graph"/></td></tr><tr><td><div id="%s_filter"/></td></tr></table>\n' \
86 % ( self._sId, self._sId, );
87
88 sHtml += '<script type="text/javascript" src="https://www.google.com/jsapi"></script>\n' \
89 '<script type="text/javascript">\n' \
90 'google.load("visualization", "1.0", { packages: ["corechart"%s] });\n' \
91 'google.setOnLoadCallback(tmDrawLineGraph%u);\n' \
92 'function tmDrawLineGraph%u()\n' \
93 '{\n' \
94 ' var fnResize;\n' \
95 ' var fnRedraw;\n' \
96 ' var idRedrawTimer = null;\n' \
97 ' var cxCur = getElementWidthById("%s") - 20;\n' \
98 ' var oGraph;\n' \
99 ' var oData = new google.visualization.DataTable();\n' \
100 ' var fpXYRatio = %u / %u;\n' \
101 ' var dGraphOptions = \n' \
102 ' {\n' \
103 ' "title": "%s",\n' \
104 ' "width": cxCur,\n' \
105 ' "height": Math.round(cxCur / fpXYRatio),\n' \
106 ' "pointSize": 2,\n' \
107 ' "fontSize": %u,\n' \
108 ' "hAxis": { "title": "%s", "minorGridlines": { count: 5 }},\n' \
109 ' "vAxis": { "title": "%s", "minorGridlines": { count: 5 }},\n' \
110 ' "theme": "maximized",\n' \
111 ' "tooltip": { "isHtml": %s }\n' \
112 ' };\n' \
113 % ( ', "controls"' if fSlideFilter else '',
114 iGraph,
115 iGraph,
116 self._sId,
117 self._cxGraph, self._cyGraph,
118 self._sTitle if self._sTitle is not None else '',
119 self._cPtFont * self._cDpiGraph / 72, # fudge
120 self._oData.sXUnit if self._oData.sXUnit else '',
121 self._oData.sYUnit if self._oData.sYUnit else '',
122 'true' if cTooltips > 0 else 'false',
123 );
124 if fSlideFilter:
125 sHtml += ' var oDashboard = new google.visualization.Dashboard(document.getElementById("%s"));\n' \
126 ' var oSlide = new google.visualization.ControlWrapper({\n' \
127 ' "controlType": "NumberRangeFilter",\n' \
128 ' "containerId": "%s_filter",\n' \
129 ' "options": {\n' \
130 ' "filterColumnIndex": 0,\n' \
131 ' "ui": { "width": getElementWidthById("%s") / 2 }, \n' \
132 ' }\n' \
133 ' });\n' \
134 % ( self._sId,
135 self._sId,
136 self._sId,);
137
138 # Data variables.
139 for iSeries, oSeries in enumerate(self._oData.aoSeries):
140 sHtml += ' var aSeries%u = [\n' % (iSeries,);
141 if oSeries.asHtmlTooltips is None:
142 sHtml += '[%s,%s]' % ( oSeries.aoXValues[0], oSeries.aoYValues[0],);
143 for i in range(1, len(oSeries.aoXValues)):
144 if (i & 16) == 0: sHtml += '\n';
145 sHtml += ',[%s,%s]' % ( oSeries.aoXValues[i], oSeries.aoYValues[i], );
146 else:
147 sHtml += '[%s,%s,"%s"]' \
148 % ( oSeries.aoXValues[0], oSeries.aoYValues[0],
149 webutils.escapeAttrJavaScriptStringDQ(oSeries.asHtmlTooltips[0]),);
150 for i in range(1, len(oSeries.aoXValues)):
151 if (i & 16) == 0: sHtml += '\n';
152 sHtml += ',[%s,%s,"%s"]' \
153 % ( oSeries.aoXValues[i], oSeries.aoYValues[i],
154 webutils.escapeAttrJavaScriptStringDQ(oSeries.asHtmlTooltips[i]),);
155
156 sHtml += '];\n'
157
158 sHtml += ' oData.addColumn("number", "%s");\n' % (self._oData.sXUnit if self._oData.sXUnit else '',);
159 cVColumns = 0;
160 for oSeries in self._oData.aoSeries:
161 sHtml += ' oData.addColumn("number", "%s");\n' % (oSeries.sName,);
162 if oSeries.asHtmlTooltips:
163 sHtml += ' oData.addColumn({"type": "string", "role": "tooltip", "p": {"html": true}});\n';
164 cVColumns += 1;
165 cVColumns += 1;
166 sHtml += 'var i;\n'
167
168 cVColumsDone = 0;
169 for iSeries, oSeries in enumerate(self._oData.aoSeries):
170 sVar = 'aSeries%u' % (iSeries,);
171 sHtml += ' for (i = 0; i < %s.length; i++)\n' \
172 ' {\n' \
173 ' oData.addRow([%s[i][0]%s,%s[i][1]%s%s]);\n' \
174 % ( sVar,
175 sVar,
176 ',null' * cVColumsDone,
177 sVar,
178 '' if oSeries.asHtmlTooltips is None else ',%s[i][2]' % (sVar,),
179 ',null' * (cVColumns - cVColumsDone - 1 - (oSeries.asHtmlTooltips is not None)),
180 );
181 sHtml += ' }\n' \
182 ' %s = null\n' \
183 % (sVar,);
184 cVColumsDone += 1 + (oSeries.asHtmlTooltips is not None);
185
186 # Create and draw.
187 if fSlideFilter:
188 sHtml += ' oGraph = new google.visualization.ChartWrapper({\n' \
189 ' "chartType": "LineChart",\n' \
190 ' "containerId": "%s_graph",\n' \
191 ' "options": dGraphOptions\n' \
192 ' });\n' \
193 ' oDashboard.bind(oSlide, oGraph);\n' \
194 ' oDashboard.draw(oData);\n' \
195 % ( self._sId, );
196 else:
197 sHtml += ' oGraph = new google.visualization.LineChart(document.getElementById("%s"));\n' \
198 ' oGraph.draw(oData, dGraphOptions);\n' \
199 % ( self._sId, );
200
201 # Register a resize handler for redrawing the graph, using a timer to delay it.
202 sHtml += ' fnRedraw = function() {\n' \
203 ' var cxNew = getElementWidthById("%s") - 6;\n' \
204 ' if (Math.abs(cxNew - cxCur) > 8)\n' \
205 ' {\n' \
206 ' cxCur = cxNew;\n' \
207 ' dGraphOptions["width"] = cxNew;\n' \
208 ' dGraphOptions["height"] = Math.round(cxNew / fpXYRatio);\n' \
209 ' oGraph.draw(oData, dGraphOptions);\n' \
210 ' }\n' \
211 ' clearTimeout(idRedrawTimer);\n' \
212 ' idRedrawTimer = null;\n' \
213 ' return true;\n' \
214 ' };\n' \
215 ' fnResize = function() {\n' \
216 ' if (idRedrawTimer != null) { clearTimeout(idRedrawTimer); } \n' \
217 ' idRedrawTimer = setTimeout(fnRedraw, 512);\n' \
218 ' return true;\n' \
219 ' };\n' \
220 ' if (window.attachEvent)\n' \
221 ' { window.attachEvent("onresize", fnResize); }\n' \
222 ' else if (window.addEventListener)\n' \
223 ' { window.addEventListener("resize", fnResize, true); }\n' \
224 % ( self._sId, );
225
226 # clean up what the callbacks don't need.
227 sHtml += ' oData = null;\n' \
228 ' aaaSeries = null;\n';
229
230 # done;
231 sHtml += ' return true;\n' \
232 '};\n';
233
234 sHtml += '</script>\n' \
235 '</div>\n';
236 return sHtml;
237
238
239class WuiHlpLineGraphErrorbarY(WuiHlpLineGraph):
240 """
241 Line graph with an errorbar for the Y axis.
242 """
243
244 def __init__(self, sId, oData, oDisp = None):
245 WuiHlpLineGraph.__init__(self, sId, oData, fErrorBarY = True);
246
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette