Commit 59c6b07c authored by sebastien letort's avatar sebastien letort

I moved method code in the class, seem more clean to me. Also big update in...

I moved method code in the class, seem more clean to me. Also big update in Chartjs options, to make it manage data on a time scale. This allows to fix the X axis on the range dates, so on the 3 displays.
parent 3c0ca813
Pipeline #64673 failed with stage
......@@ -18,10 +18,16 @@ function get_random_color()
const BLACK = '#000000';
function fmt_date(d)
{ return d.substring(0,10); }
{ return new Date(d).toISOString().substring(0,10); }
function build_list( l_data, key, fn_map )
{
/* build a set of keys from l_data records,
* then return a sorted list of those keys,
* where fn_map is applied on each key.
* It is used to reformat dates.
*/
let d_keys = {};
for( let i=0; i<l_data.length; ++i )
{
......@@ -38,6 +44,11 @@ class Metrics
{
constructor( app_name, d_app )
{
// attribute to alter scale of chart. reformat date
this.from = fmt_date(d_app['from']);
this.to = fmt_date(d_app['to']);
this.step = d_app['step'];
this.app_name = app_name;
this.chartjs_data = null;
......@@ -50,41 +61,62 @@ class Metrics
this._setChartjsData( d_app['data'] );
//~ console.log( this.constructor.name + ": chartjs_data = " + JSON.stringify(this.chartjs_data) );
}
}
Metrics.prototype.build_chart = function( id )
{
let ctx = $(id)[0].getContext('2d');
let local_options = {
legend: this.d_legend,
title :
{
display: true,
text: this.title
},
scales:
{
yAxes:
[{
build_chart( id )
{
let ctx = $(id)[0].getContext('2d');
let local_options = {
legend: this.d_legend,
title :
{
display: true,
ticks:
{
beginAtZero: true // minimum value will be 0.
}
}]
}
};
const options = Object.assign( {}, local_options, this.options ); // merge of 2 javascript objects.
text: this.title
},
scales:
{
xAxes:
[{
type: 'time',
time:
{
min : this.from,
max : this.to,
unit: this.step,
displayFormats:
{
//~ [this.step]: 'DD-MM-YYYY' //same display whatever the scale
'year' : 'YYYY',
'month': 'MM-YYYY',
'day' : 'DD-MM-YYYY'
}
},
ticks:
{
autoSkip: true
}
}],
yAxes:
[{
display: true,
ticks:
{
beginAtZero: true // minimum value will be 0.
}
}]
}
};
const options = jQuery.extend( true, {}, local_options, this.options );
this.chartjs = new Chart( ctx,
{
type: this.type,
data: this.chartjs_data,
options: options
});
this.chartjs = new Chart( ctx,
{
type: this.type,
data: this.chartjs_data,
options: options
});
}
}
class PerUserPlot extends Metrics
{
constructor( app_name, d_app )
......@@ -104,59 +136,61 @@ class PerUserPlot extends Metrics
}
};
}
}
PerUserPlot.prototype._setChartjsData = function( l_data )
{
function __dictionnarize2( l_data, key, l_periods )
{
// turn [ {'time_period':x, key:y, 'n':z }, ...]
// to { y: [{ x: z },{ x: z },...], ... }
// d_default is the default dictionnary {any_key: default_val}
let d_defaults = {};
for( let i=0; i<l_periods.length; ++i )
{ let tp = l_periods[i]; d_defaults[tp] = 0; }
let d_data = {};
for( let i=0; i<l_data.length; ++i )
_setChartjsData( l_data )
{
function __dictionnarize2( l_data, key, l_periods )
{
let tp = fmt_date(l_data[i]["time_period"]);
let val = l_data[i][key];
let n = l_data[i]["n"];
// turn [ {'time_period':x, key:y, 'n':z }, ...]
// to { y: [{ x: z },{ x: z },...], ... }
// d_default is the default dictionnary {any_key: default_val}
let d_defaults = {};
for( let i=0; i<l_periods.length; ++i )
{ let tp = l_periods[i]; d_defaults[tp] = 0; }
let d_data = {};
for( let i=0; i<l_data.length; ++i )
{
let tp = fmt_date(l_data[i]["time_period"]);
let val = l_data[i][key];
let n = l_data[i]["n"];
if( !d_data[val] )
d_data[val] = JSON.parse(JSON.stringify(d_defaults)); // new object.
if( !d_data[val] )
d_data[val] = JSON.parse(JSON.stringify(d_defaults)); // new object.
d_data[val][tp] = n;
}
d_data[val][tp] = n;
}
return d_data;
}
return d_data;
}
let l_periods = build_list( l_data, 'time_period', fmt_date );
let l_periods = build_list( l_data, 'time_period', fmt_date );
// turn [ {'time_period':tp,'uname':u,'n':n }, ...]
// to { u: [{tp: n},{tp: n},, ...], ... }
let d_data = __dictionnarize2( l_data, 'uname', l_periods );
// turn [ {'time_period':tp,'uname':u,'n':n }, ...]
// to { u: [{tp: n},{tp: n},, ...], ... }
let d_data = __dictionnarize2( l_data, 'uname', l_periods );
let chartjs_data = {
// keys are dates, and they are strings, in Y-m-d format, so should work.
labels : l_periods,
datasets: []
};
let chartjs_data = {
// keys are dates, and they are strings, in Y-m-d format, so should work.
labels : l_periods,
datasets: []
};
for( let user in d_data )
{
let d_dataset = {
label: user,
data : l_periods.map( x => d_data[user][x] ),
for( let user in d_data )
{
let d_dataset = {
label: user,
data : l_periods.map( x => d_data[user][x] ),
backgroundColor: get_random_color(),
borderColor : BLACK,
};
chartjs_data.datasets.push( d_dataset );
}
backgroundColor: get_random_color(),
borderColor : BLACK,
};
chartjs_data.datasets.push( d_dataset );
this.chartjs_data = chartjs_data;
}
this.chartjs_data = chartjs_data;
}
......@@ -171,85 +205,86 @@ class PerStatePlot extends Metrics
];
this.type = 'line';
}
}
PerStatePlot.prototype._setChartjsData = function( l_data )
{
function __dictionnarize( l_data, key, d_defaults )
{
// turn [ {'time_period':x, key:y, 'n':z }, ...]
// to { x: { y: z }, ... }
// d_defaults is the default dictionnary {any_key: default_val}
//~ let ld_new = []
let d_keys = {};
let d_data = {};
for( let i=0; i<l_data.length; ++i )
_setChartjsData( l_data )
{
function __dictionnarize( l_data, key, d_defaults )
{
let tp = fmt_date( l_data[i]["time_period"] );
let val = l_data[i][key];
let n = l_data[i]["n"];
if( !d_data[tp] )
if( d_defaults )
d_data[tp] = JSON.parse(JSON.stringify(d_defaults)); // new object.
else
// the [val] notation as key means 'val' will be evaluated.
d_data[tp] = { [val]: null };
d_data[tp][val] = n;
d_keys[val] = 1;
// turn [ {'time_period':x, key:y, 'n':z }, ...]
// to { x: { y: z }, ... }
// d_defaults is the default dictionnary {any_key: default_val}
//~ let ld_new = []
let d_keys = {};
let d_data = {};
for( let i=0; i<l_data.length; ++i )
{
let tp = fmt_date( l_data[i]["time_period"] );
let val = l_data[i][key];
let n = l_data[i]["n"];
if( !d_data[tp] )
if( d_defaults )
d_data[tp] = JSON.parse(JSON.stringify(d_defaults)); // new object.
else
// the [val] notation as key means 'val' will be evaluated.
d_data[tp] = { [val]: null };
d_data[tp][val] = n;
d_keys[val] = 1;
}
return d_data;
}
return d_data;
}
// SLETORT: Note : I really don't like the way I had to write 3 times the labels !
let d_colors = {
"NONE" : '#000000',
"SUCCESS": '#00FF00',
"ERROR" : '#FF0000',
"ABORTED": '#FF8000',
"TIMEOUT": '#DDAA22'
};
let d_defaults = {
// I did not succeed in building it looping on d_labels !
"NONE" : 0,
"SUCCESS": 0,
"ERROR" : 0,
"ABORTED": 0,
"TIMEOUT": 0
};
// SLETORT: Note : I really don't like the way I had to write 3 times the labels !
let d_colors = {
"NONE" : '#000000',
"SUCCESS": '#00FF00',
"ERROR" : '#FF0000',
"ABORTED": '#FF8000',
"TIMEOUT": '#DDAA22'
};
let d_defaults = {
// I did not succeed in building it looping on d_labels !
"NONE" : 0,
"SUCCESS": 0,
"ERROR" : 0,
"ABORTED": 0,
"TIMEOUT": 0
};
let l_periods = build_list( l_data, 'time_period', fmt_date );
let d_data = __dictionnarize( l_data, 'result', d_defaults );
// now let's turn this dict to chartjs_data
let chartjs_data = { labels: l_periods, datasets: [] };
let l_labels = [ "NONE", "SUCCESS", "ERROR", "ABORTED", "TIMEOUT" ]; // to ensure the order.
for( let i=0; i<l_labels.length; ++i )
{
let status = l_labels[i];
let l_periods = build_list( l_data, 'time_period', fmt_date );
let l_res = [];
for( let j=0; j<l_periods.length; ++j )
let d_data = __dictionnarize( l_data, 'result', d_defaults );
// now let's turn this dict to chartjs_data
let chartjs_data = { labels: l_periods, datasets: [] };
let l_labels = [ "NONE", "SUCCESS", "ERROR", "ABORTED", "TIMEOUT" ]; // to ensure the order.
for( let i=0; i<l_labels.length; ++i )
{
let tp = l_periods[j];
l_res.push( d_data[tp][status] );
}
let status = l_labels[i];
chartjs_data.datasets[i] =
let l_res = [];
for( let j=0; j<l_periods.length; ++j )
{
data : l_res,
label: status.toLowerCase(),
let tp = l_periods[j];
l_res.push( d_data[tp][status] );
}
fill : false,
backgroundColor: d_colors[status],
borderColor: d_colors[status],
borderWidth: 1,
};
}
chartjs_data.datasets[i] =
{
data : l_res,
label: status.toLowerCase(),
fill : false,
backgroundColor: d_colors[status],
borderColor: d_colors[status],
borderWidth: 1,
};
}
this.chartjs_data = chartjs_data;
this.chartjs_data = chartjs_data;
}
}
......@@ -265,28 +300,29 @@ class LaunchedPlot extends Metrics
this.type = 'line';
this.d_legend.display = false;
}
}
LaunchedPlot.prototype._setChartjsData = function( l_data )
{
let l_periods = build_list( l_data, 'time_period', fmt_date );
let d_data = {}
for( let i=0; i<l_data.length; ++i )
_setChartjsData( l_data )
{
let tp = fmt_date( l_data[i].time_period );
let val = l_data[i].n;
d_data[tp] = val; // by construction there should be no collision.
}
let l_periods = build_list( l_data, 'time_period', fmt_date );
let chartjs_data = { labels: l_periods, datasets: [ { data:[] } ] };
let d_data = {}
for( let i=0; i<l_data.length; ++i )
{
let tp = fmt_date( l_data[i].time_period );
let val = l_data[i].n;
d_data[tp] = val; // by construction there should be no collision.
}
for( let i=0; i<l_periods.length; ++i )
{
let tp = l_periods[i];
chartjs_data.datasets[0]['data'].push( d_data[tp] );
}
let chartjs_data = { labels: l_periods, datasets: [ { data:[] } ] };
for( let i=0; i<l_periods.length; ++i )
{
let tp = l_periods[i];
chartjs_data.datasets[0]['data'].push( d_data[tp] );
}
this.chartjs_data = chartjs_data;
this.chartjs_data = chartjs_data;
}
}
// ===========================================
......@@ -351,6 +387,7 @@ function draw_plots()
if( obj )
obj.destroy();
//~ console.log( id );
let o_plot = new cstr( app, json[app] );
o_plot.build_chart( id );
D_CHARTS[which_chart][2] = o_plot.chartjs;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment