Author: croberts
Date: 2012-11-01 14:05:53 +0000 (Thu, 01 Nov 2012)
New Revision: 5531
Modified:
branches/croberts/cumin/python/cumin/grid/dashboard.py
branches/croberts/cumin/python/cumin/stat.py
branches/croberts/cumin/python/cumin/stat.strings
branches/croberts/cumin/resources/app.js
branches/croberts/wooly/python/wooly/pages.strings
Log:
Testing out new chart type code.
Modified: branches/croberts/cumin/python/cumin/grid/dashboard.py
===================================================================
--- branches/croberts/cumin/python/cumin/grid/dashboard.py 2012-11-01 13:47:29 UTC (rev
5530)
+++ branches/croberts/cumin/python/cumin/grid/dashboard.py 2012-11-01 14:05:53 UTC (rev
5531)
@@ -49,34 +49,41 @@
charts = WidgetSet(app, "charts")
self.add_child(charts)
- chart = self.PoolEfficiencyChart(app, "eff",
app.model.com_redhat_grid_plumage.OSUtil)
- chart.stats = ["efficiency"]
- chart.max_samples = 250
- chart.duration.param.default = "86400"
- charts.add_child(chart)
-
- chart = self.PoolMemoryChart(app, "fmem",
app.model.com_redhat_grid_plumage.OSUtil)
- chart.stats = ["usedmem", "freemem"]
- chart.max_samples = 250
- chart.duration.param.default = "86400"
- chart.chart_type = "stacked"
- charts.add_child(chart)
+# chart = self.PoolEfficiencyChart(app, "eff",
app.model.com_redhat_grid_plumage.OSUtil)
+# chart.stats = ["efficiency"]
+# chart.max_samples = 250
+# chart.duration.param.default = "86400"
+# charts.add_child(chart)
+#
+# chart = self.PoolMemoryChart(app, "fmem",
app.model.com_redhat_grid_plumage.OSUtil)
+# chart.stats = ["usedmem", "freemem"]
+# chart.max_samples = 250
+# chart.duration.param.default = "86400"
+# chart.chart_type = "stacked"
+# charts.add_child(chart)
+#
+# chart = self.PoolCpuChart(app, "fcpu",
app.model.com_redhat_grid_plumage.OSUtil)
+# chart.stats = [ "usedcpu", "freecpu"]
+# chart.max_samples = 250
+# chart.duration.param.default = "86400"
+# chart.chart_type = "stacked"
+# charts.add_child(chart)
- chart = self.PoolCpuChart(app, "fcpu",
app.model.com_redhat_grid_plumage.OSUtil)
- chart.stats = [ "usedcpu", "freecpu"]
+# chart = self.UserUsageChart(app, "useruse",
app.model.com_redhat_grid_plumage.Accountant)
+# chart.stats = ["resused"]
+# chart.max_samples = 250
+# filter = ReportingChart.FilterInput(app, "namefilter",
app.model.com_redhat_grid_plumage.Accountant,
app.model.com_redhat_grid_plumage.Accountant.user.name, "userc", "Filter
user")
+# chart.filters.append(filter)
+# chart.add_child(filter)
+# chart.duration.param.default= "86400"
+# charts.add_child(chart)
+
+ chart = self.AccountingChart(app, "accuse",
app.model.com_redhat_grid_plumage.Accountant)
chart.max_samples = 250
+ chart.chart_type = "genusechart"
chart.duration.param.default = "86400"
- chart.chart_type = "stacked"
+ chart.leftlegend = False
charts.add_child(chart)
-
- chart = self.UserUsageChart(app, "useruse",
app.model.com_redhat_grid_plumage.Accountant)
- chart.stats = ["resused"]
- chart.max_samples = 250
- filter = ReportingChart.FilterInput(app, "namefilter",
app.model.com_redhat_grid_plumage.Accountant,
app.model.com_redhat_grid_plumage.Accountant.user.name, "userc", "Filter
user")
- chart.filters.append(filter)
- chart.add_child(filter)
- chart.duration.param.default= "86400"
- charts.add_child(chart)
def render_title(self, session):
return "History"
Modified: branches/croberts/cumin/python/cumin/stat.py
===================================================================
--- branches/croberts/cumin/python/cumin/stat.py 2012-11-01 13:47:29 UTC (rev 5530)
+++ branches/croberts/cumin/python/cumin/stat.py 2012-11-01 14:05:53 UTC (rev 5531)
@@ -9,6 +9,7 @@
from wooly.pages import HtmlPage
from wooly.parameters import IntegerParameter, ListParameter, StringParameter,\
BooleanParameter
+from wooly.sql import SqlOperation
from cumin.formats import fmt_bytes, fmt_duration_brief
from cumin.model import CuminStatistic, SamplesSqlAdapter
@@ -278,6 +279,10 @@
return self.render_id(session).replace(".", "_")
class ReportingChart(ReportingStatValueChart):
+ def __init__(self, app, name, cls):
+ super(ReportingChart, self).__init__(app, name, cls)
+ self.leftlegend = True #hack to force "leftlegend" class on containing
div
+
def get_flash_name(self, session):
return "chart.json"
@@ -307,6 +312,11 @@
def render_id_nodots(self, session):
return self.render_id(session).replace(".", "_")
+ def render_leftlegend(self, session):
+ if self.leftlegend:
+ return "leftlegend"
+ return ""
+
def render_filters(self, session):
filtertext = ""
for f in self.filters:
@@ -794,7 +804,8 @@
return chart.create()
class FlashLineChart(Widget):
- colors = ('#FF0000', '#0000FF', '#00FF00', '#FF00FF',
'#FFFF00', '#00FFFF', '#000000')
+ colors =
('#009926','#992600','#0036d6','#ffc414','730099','#ff00cc',
'#ff0000', '#0000ff', '#00ff00', '#00ffff',
'#ff00ff', '#000000', '#666600')
+ legendCols = 6
one_day = 24 * 60 * 60
def __init__(self, app, name, page):
super(FlashLineChart, self).__init__(app, name)
@@ -923,6 +934,9 @@
#print "**********\n"+chart.create()
chart.graph_div = "%s_chart" % chart.id.replace(".",
"_")
chart.stackSeries = self.stackSeries
+ chart.legendLocation = self.legendLocation
+ chart.colors = self.colors
+ chart.legendCols = self.legendCols
return chart.create()
def get_y_labels(self, absy, intervals, step):
@@ -994,6 +1008,7 @@
self.alpha = 3
self.stackSeries = False
+ self.legendLocation = "n"
def getStatSamples(self, adapter, samples, stat, dur, interval, method,
end_seconds_ago, delta):
# get more samples than needed to allow chart to clip correctly (explains the +
600)
@@ -1144,6 +1159,115 @@
class ReportAreaChart(AreaChart):
pass
+class GeneralUseChart(AreaChart):
+ colors =
('#009926','#992600','#0036d6','#ffc414','730099','#ff00cc',
'#ff0000', '#0000ff', '#00ff00', '#00ffff',
'#ff00ff', '#000000', '#666600')
+ def __init__(self, app, name, page):
+ super(GeneralUseChart, self).__init__(app, name, page)
+ self.stackSeries = True
+ self.legendLocation = "e"
+ self.legendCols = 1
+ self.accGroups = self.AccGroupSqlOperation(app)
+ self.accUse = self.AccGroupUseSqlOperation(app, self)
+
+ def fetch_samples(self, adapter, dur, interval, method, mode, delta, stats,
end_seconds_ago=0):
+ samples = dict()
+
+ groups = self.accGroups.execute(self.app.session).fetchall()
+ for group in groups:
+ group_name = group[0]
+ result = self.accUse.execute(self.app.session, group_name, dur,
interval).fetchall()
+ if len(result) > 0:
+ samples[group_name] = result
+
+ return samples
+
+ def get_line_title(self, stat):
+ return stat.replace("<", "").replace(">",
"")
+
+ def fix_samples(self, samples):
+ # each set of samples needs to be the same length and contain the same x-values
+ x_vals = list()
+ for sample in samples:
+ for point in samples[sample]:
+ if point[0] not in x_vals:
+ x_vals.append(point[0])
+ for sample in samples:
+ for x in x_vals:
+ try:
+ if len(samples[sample]) == 0 or [item[0] for item in
samples[sample]].index(x) < 0:
+ samples[sample].append((x, 0, None))
+ except ValueError, e:
+ samples[sample].append((x, 0, None))
+
+
+ def make_chart_lines(self, session, chart, line_type, stats, dot_size, halo_size,
line_width, samples, duration, end_secs, mode):
+ chart.elements = list()
+ self.fix_samples(samples)
+
+ for stat, color in reversed(zip(samples, self.colors)):
+ line = Element()
+ line.type = line_type
+ line.fill = color
+ line.fill_alpha = self.alpha
+
+ line.colour = color
+ line.width = line_width
+ tip_title = stat
+ line.text = mode == "rate" and "%s / sec" % tip_title or
self.get_line_title(stat)
+
+ vals = self.get_vals(session, samples, stat, line.text, duration, end_secs)
+ line.values = vals
+ chart.elements.append(line)
+
+ def get_vals(self, session, samples, stat, text, duration, end_secs):
+ tnow = time()
+ vals = list()
+
+ min_dt = tnow - duration - end_secs
+ for dt, value, dev in samples[stat]:
+ if value is not None:
+ vals.append({"dt": secs(dt), "y": value})
+ if secs(dt) < min_dt:
+ break
+
+ vals.sort(key=lambda stat: stat["dt"], reverse=False) #here, we sort by
dt to be sure that our graphs are valid
+ return vals
+
+ class AccGroupUseSqlOperation(SqlOperation):
+ def __init__(self, app, chart):
+ super(GeneralUseChart.AccGroupUseSqlOperation, self).__init__(app)
+ self.chart = chart
+
+ def get_connection(self, session):
+ return self.app.database.get_read_connection()
+
+ def execute(self, session, group, duration, interval):
+ sql = self.render_sql(session, [group, duration, interval])
+
+ return self.do_execute(session, sql)
+
+
+ def render_sql(self, session, args):
+ writer = Writer()
+ self.sql_tmpl.render(writer, session, args)
+ return writer.to_string()
+
+ def render_accgroup(self, session, args):
+ return args[0]
+
+ def render_duration(self, session, args):
+ return args[1]
+
+ def render_interval(self, session, args):
+ return args[2]
+
+ class AccGroupSqlOperation(SqlOperation):
+ def __init__(self, app):
+ super(GeneralUseChart.AccGroupSqlOperation, self).__init__(app)
+
+ def get_connection(self, session):
+ return self.app.database.get_read_connection()
+
class StackedAreaChart(AreaChart):
colors = ('#FFABAB', '#ABABFF', '#ABFFAB', '#FFABFF',
'#FFFFAB', '#ABFFFF', '#ABABAB')
def __init__(self, app, name, page):
@@ -1285,7 +1409,9 @@
elif chart_type == "pie":
chart_obj = FlashPieChart(self.app, chart_type, self)
elif chart_type == "reportarea":
- chart_obj = ReportAreaChart(self.app, chart_type, self)
+ chart_obj = ReportAreaChart(self.app, chart_type, self)
+ elif chart_type == "genusechart":
+ chart_obj = GeneralUseChart(self.app, chart_type, self)
return chart_obj
Modified: branches/croberts/cumin/python/cumin/stat.strings
===================================================================
--- branches/croberts/cumin/python/cumin/stat.strings 2012-11-01 13:47:29 UTC (rev 5530)
+++ branches/croberts/cumin/python/cumin/stat.strings 2012-11-01 14:05:53 UTC (rev 5531)
@@ -349,7 +349,7 @@
<div>
<!-- don't put this data url inside the holder div, jqplot will kill it
on a zoom -->
<a rel="api" type="application/json"
href="{href}" style="display:none">Data</a>
- <div id="{id_nodots}_chart" class="jqplotgraph leftlegend"
style="height:150px;width:400px;">
+ <div id="{id_nodots}_chart" class="jqplotgraph
{leftlegend}" style="height:150px;width:400px;">
<div class="loading"
style="display:none;"><span>Loading...</span></div>
</div>
</div>
@@ -359,6 +359,10 @@
</div>
</div>
+[ReportingChart.css]
+div.ReportingStatValueChart div.jqplotgraph table.jqplot-table-legend {
+ margin-left: 30px;
+}
[ReportingChart.javascript]
function updateFilter(filter, a, id, param, attempt) {
@@ -446,3 +450,16 @@
<div id="{id}_chart">
</div>
</div>
+
+
+[AccGroupSqlOperation.sql]
+select distinct(agroup) from
"com.redhat.grid.plumage"."Accountant_samples"
+ order by agroup asc;
+
+[AccGroupUseSqlOperation.sql]
+select max("Accountant_samples"."ts") as interval_end,
+cast(avg("Accountant_samples"."resused") as integer) as value,
+stddev("Accountant_samples"."resused") as dev from
"com.redhat.grid.plumage"."Accountant_samples"
+where ("Accountant_samples"."user" like '{accgroup}') and
"Accountant_samples"."ts" >= now() - interval '{duration}
seconds'
+group by floor(extract(epoch from "Accountant_samples"."ts") /
{interval}) order by interval_end desc limit all offset 0;
+
\ No newline at end of file
Modified: branches/croberts/cumin/resources/app.js
===================================================================
--- branches/croberts/cumin/resources/app.js 2012-11-01 13:47:29 UTC (rev 5530)
+++ branches/croberts/cumin/resources/app.js 2012-11-01 14:05:53 UTC (rev 5531)
@@ -588,6 +588,9 @@
.append([ json.x_axis.labels.labels[i].text ]);
}
dataContainer['stackSeries'] = json.stackSeries;
+ dataContainer['legendLocation'] = json.legendLocation;
+ dataContainer['legendCols'] = json.legendCols;
+ dataContainer['colors'] = json.colors
return dataContainer;
}
@@ -622,13 +625,13 @@
grid: { background: '#FFFFFF' },
legend: {
show:true,
- location: 'n',
+ location: dataContainer['legendLocation'],
renderer: $j.jqplot.EnhancedLegendRenderer,
yoffset: 0,
xoffset: 0,
placement: "outside",
rendererOptions:{
- numberColumns:6,
+ numberColumns:dataContainer['legendCols'],
seriesToggle:"fast",
disableIEFading:true
}
@@ -651,7 +654,8 @@
},
series: getSeries(dataContainer),
stackSeries: dataContainer['stackSeries'],
- seriesColors:
['#009926','#992600','#0036d6','#ffc414','730099','#ff00cc'],
+
+ seriesColors: dataContainer['colors'],
seriesDefaults: {
lineWidth:1,
fill:true,
Modified: branches/croberts/wooly/python/wooly/pages.strings
===================================================================
--- branches/croberts/wooly/python/wooly/pages.strings 2012-11-01 13:47:29 UTC (rev 5530)
+++ branches/croberts/wooly/python/wooly/pages.strings 2012-11-01 14:05:53 UTC (rev 5531)
@@ -7,12 +7,13 @@
<link rel="shortcut icon" href="resource?name=favicon.ico"
type="image/x-icon"/>
+ <link rel="stylesheet" type="text/css"
href="resource?name=jquery.jqplot.css" />
<link rel="stylesheet" type="text/css"
href="resource?name=wooly.css"/>
<link rel="stylesheet" type="text/css"
href="resource?name=app.css"/>
<link rel="stylesheet" type="text/css"
href="{base_name}.css"/>
<!--[if IE]><link rel="stylesheet" type="text/css"
href="resource?name=ie.css"/><![endif]-->
<!--[if lte IE 7]><link rel="stylesheet" type="text/css"
href="resource?name=ielte7.css"/><![endif]-->
- <link rel="stylesheet" type="text/css"
href="resource?name=jquery.jqplot.css" />
+
<script type="text/javascript"
src="resource?name=mootools.js"> </script>
<script type="text/javascript"
src="resource?name=wooly.js"> </script>
@@ -21,11 +22,11 @@
<!--[if lt IE 9]><script language="javascript"
type="text/javascript"
src="resource?name=excanvas.js"></script><![endif]-->
<script type="text/javascript"
src="resource?name=jquery.js"></script>
<script type="text/javascript"
src="resource?name=jquery.jqplot.js"></script>
- <script type="text/javascript"
src="resource?name=jqplot.pieRenderer.min.js"></script>
+ <script type="text/javascript"
src="resource?name=jqplot.pieRenderer.js"></script>
<script type="text/javascript"
src="resource?name=jqplot.donutRenderer.min.js"></script>
<script type="text/javascript"
src="resource?name=jqplot.categoryAxisRenderer.js"></script>
<script type="text/javascript"
src="resource?name=jqplot.enhancedLegendRenderer.js"></script>
- <script type="text/javascript"
src="resource?name=jqplot.highlighter.min.js"></script>
+ <script type="text/javascript"
src="resource?name=jqplot.highlighter.js"></script>
<script type="text/javascript"
src="resource?name=jqplot.cursor.js"></script>
<script type="text/javascript"
src="resource?name=jqplot.dateAxisRenderer.js"></script>