Skip to content
Snippets Groups Projects
Commit 17bba215 authored by Jan Mach's avatar Jan Mach
Browse files

Fixed broken charts in database status view module.

After previous commits the database status view module was broken, because it was still using old charting code. This is fixed in this commit. Additionally, this commit introduces new ability to define custom value label and formatter for dict based pie datasets. The implementation of this feature was necessary to enable displaying values in tables as size in bytes instead of simple count (which was necessary for datasets showing sizes of database tables). (Redmine issue: #4321)
parent 883adabd
No related branches found
No related tags found
No related merge requests found
......@@ -117,20 +117,6 @@ class ViewView(HTMLViewMixin, HawatSimpleView):
"""
return lazy_gettext('Database status')
@staticmethod
def calculate_secondary_stats(stats):
"""
Calculate secondary statistics.
"""
for key in ['total_bytes', 'table_bytes', 'index_bytes', 'row_estimate']:
stats['cnt_{}'.format(key)] = len(stats[key])
stats['sum_{}'.format(key)] = sum(stats[key].values())
stats['min_{}'.format(key)] = min(stats[key].values())
stats['max_{}'.format(key)] = max(stats[key].values())
stats['avg_{}'.format(key)] = stats['sum_{}'.format(key)]/stats['cnt_{}'.format(key)]
stats['list_{}'.format(key)] = list(sorted(stats[key].keys()))
return stats
def do_before_response(self, **kwargs):
"""
*Interface implementation* of :py:func:`hawat.base.HawatRenderableView.do_before_response`.
......@@ -155,7 +141,7 @@ class ViewView(HTMLViewMixin, HawatSimpleView):
}
}
self.response_context.update(
database_statistics_events = self.calculate_secondary_stats(dbstatistics_events)
database_statistics_events = dbstatistics_events
)
......
......@@ -132,16 +132,23 @@
<hr>
<br>
<!-- Search result dump - BEGIN ----------------------------------->
<script>
var database_statistics_events = {{ database_statistics_events | tojson }};
</script>
<!-- Search result dump - END ------------------------------------->
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
{%-
for chsection in [
{'ident': 'row_estimate', 'label': gettext('Row counts')},
{'ident': 'total_bytes', 'label': gettext('Total sizes')},
{'ident': 'table_bytes', 'label': gettext('Table sizes')},
{'ident': 'index_bytes', 'label': gettext('Index sizes')}
set chsections = [
{'ident': 'row_estimate', 'label': _('Row counts'), 'value_label': False, 'value_format': False},
{'ident': 'total_bytes', 'label': _('Total sizes'), 'value_label': _('Size'), 'value_format': 'byteFormatter'},
{'ident': 'table_bytes', 'label': _('Table sizes'), 'value_label': _('Size'), 'value_format': 'byteFormatter'},
{'ident': 'index_bytes', 'label': _('Index sizes'), 'value_label': _('Size'), 'value_format': 'byteFormatter'}
]
%}
{%- for chsection in chsections %}
<li role="presentation"{% if loop.first %} class="active"{% endif %}>
<a href="#tab-dbstatus-events-{{ chsection['ident'] }}" aria-controls="tab-dbstatus-events-{{ chsection['ident'] }}" role="tab" data-toggle="tab">
<strong>{{ chsection['label'] }}</strong>
......@@ -150,25 +157,20 @@
{%- endfor %}
</ul>
<div class="tab-content">
{%-
for chsection in [
{'ident': 'row_estimate', 'label': gettext('Row counts'), 'value_label': False, 'value_unit': False, 'value_format': False},
{'ident': 'total_bytes', 'label': gettext('Total sizes'), 'value_label': gettext('Size in bytes'), 'value_unit': gettext('Size'), 'value_format': babel_format_bytes},
{'ident': 'table_bytes', 'label': gettext('Table sizes'), 'value_label': gettext('Size in bytes'), 'value_unit': gettext('Size'), 'value_format': babel_format_bytes},
{'ident': 'index_bytes', 'label': gettext('Index sizes'), 'value_label': gettext('Size in bytes'), 'value_unit': gettext('Size'), 'value_format': babel_format_bytes}
]
%}
{%- for chsection in chsections %}
<div role="tabpanel" class="tab-pane fade{% if loop.first %} in active{% endif %}" id="tab-dbstatus-events-{{ chsection['ident'] }}">
<br>
<h4>{{ chsection['label'] }}</h4>
{{ macros_chart.render_chart_pie(
'database_events',
{{ macros_chart.render_dataset_pie_dict(
database_statistics_events,
'database_statistics_events',
'database_events',
chsection['ident'],
value_label = chsection['value_label'],
value_unit = chsection['value_unit'],
value_format = chsection['value_format']
{
'value_label': chsection['value_label'],
'value_format': chsection['value_format']
}
)
}}
</div>
......@@ -221,7 +223,8 @@
{%- if permission_can('developer') %}
<hr>
{{ macros_site.render_raw_var('database_status_events', database_status_events) }}
{{ macros_site.render_raw_var('database_status_events', database_status_events) }}
{{ macros_site.render_raw_var('database_statistics_events', database_statistics_events) }}
{{ macros_site.render_raw_var('sw_versions', sw_versions) }}
{%- endif %}
......
......@@ -242,7 +242,7 @@ function get_series_dict(raw_data, dict_key) {
// Render pie chart.
function render_chart_pie(chid, chart_data, params = null) {
function render_chart_pie(chid, chart_data, params = {}) {
console.log('Rendering PIE chart: ' + chid);
nv.addGraph(function() {
......@@ -255,7 +255,14 @@ function render_chart_pie(chid, chart_data, params = null) {
.labelType("key") //Configure what type of data to show in the label. Can be "key", "value" or "percent"
.donut(true) //Turn on Donut mode. Makes pie chart look tasty!
.donutRatio(0.2) //Configure how big you want the donut hole size to be.
;
;
// Parameters may override default value formatter.
if (params.value_formatter) {
chart.tooltip.valueFormatter(
params.value_formatter
);
}
// Select the appropriate SVG element and bind datum to the chart.
d3.select("#" + chid + " svg")
......@@ -317,6 +324,32 @@ function table_value_formatter(formatter) {
}
}
function byteFormatter() {
var value_formatter = GLOBALIZER.numberFormatter({
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
var units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB'];
var step_size = 1024;
return function(size) {
var unit = 'B';
console.log('ByteFormat(' + size + ', ' + unit + ')')
for (var i = 0; i < units.length-1; i++) {
console.log(' - (' + size + ', ' + unit + ')')
if (size > step_size) {
if (unit.toUpperCase() == units[i]) {
size = size / step_size;
unit = units[i+1];
}
}
else {
break;
}
}
return '' + value_formatter(size) + ' ' + unit;
}
}
// Render multi-timeline table.
function render_table_timeline_multi(tid, table_columns, table_data, data_stats) {
console.log('Rendering table: ' + tid);
......@@ -461,12 +494,18 @@ function render_action_dropdown(actions, value) {
}
// Render table for dict-based dataset.
function render_table_dict(tid, table_columns, table_data, data_stats, action_list = null) {
function render_table_dict(tid, table_columns, table_data, data_stats, action_list = null, params = {}) {
console.log('Rendering table: ' + tid);
var value_formatter = table_value_formatter(
var number_formatter = table_value_formatter(
GLOBALIZER.numberFormatter()
);
var value_formatter = number_formatter;
// Parameters may override default numeric value formatter.
if (params.value_formatter) {
value_formatter = table_value_formatter(params.value_formatter);
}
var percent_formatter = table_value_formatter(
GLOBALIZER.numberFormatter({
style: "percent",
......@@ -606,6 +645,11 @@ function render_table_dict(tid, table_columns, table_data, data_stats, action_li
if (i == 0) {
return d.value;
}
// Second column contains the value, but always use numeric formatter
// for 'cnt' aggregation.
if (i == 1 && d.func == 'cnt') {
return '<span>' + number_formatter(d.value) + '</span>';
}
// Second column contains the value.
if (i == 1) {
return '<span>' + value_formatter(d.value) + '</span>';
......
......@@ -178,7 +178,8 @@
$(document).ready(function () {
render_chart_pie(
'{{ chart_id }}_chart',
{{ chart_id }}_dataset
{{ chart_id }}_dataset{%- if cfg_params and 'value_format' in cfg_params and cfg_params['value_format'] %},
{ 'value_formatter': {{ cfg_params['value_format'] }}() }{%- endif %}
);
});
{%- endmacro %}
......@@ -222,18 +223,27 @@
-#}
{%- macro _snippet_table_dict(chart_id, cfg_params) %}
{%- set tmplabel = cfg_params['value_label'] %}
{%- if not tmplabel %}{%- set tmplabel = _('Count') %}{%- endif %}
// Render table for dataset '{{ chart_id }}'.
$(document).ready(function () {
render_table_dict(
'{{ chart_id }}_table',
[
{'ident': 'key', 'label': '{{ _("Name") }}'},
{'ident': 'value', 'label': '{{ _("Count") }}'},
{'ident': 'share', 'label': '{{ _("Share") }}'},
{'ident': 'key', 'label': '{{ _('Name') }}'},
{'ident': 'value', 'label': '{{ tmplabel }}'},
{'ident': 'share', 'label': '{{ _('Share') }}'},
],
{{ chart_id }}_dataset,
GLOBAL_TABLE_COLS_STATS{%- if 'csag_name' in cfg_params %},
Hawat.get_csag('{{ cfg_params['csag_name'] }}'){%- endif %}
GLOBAL_TABLE_COLS_STATS,
{%- if cfg_params and 'csag_name' in cfg_params and cfg_params['csag_name'] %}
Hawat.get_csag('{{ cfg_params['csag_name'] }}')
{%- else %}
null,
{%- endif %}
{%- if cfg_params and 'value_format' in cfg_params and cfg_params['value_format'] %}
{ 'value_formatter': {{ cfg_params['value_format'] }}() }
{%- endif %}
);
});
{%- endmacro %}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment