Skip to content

Commit b84f3f4

Browse files
author
Sergey
committed
Dashboard improvement. It is responsible now.
1 parent 902c5b3 commit b84f3f4

File tree

3 files changed

+203
-96
lines changed

3 files changed

+203
-96
lines changed

Perfon.WebApi/UI/PerfCountersUI.html

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@
66
<meta charset="utf-8"/>
77
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
88

9+
<!--<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css"" rel="stylesheet" />-->
910
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css"" rel="stylesheet" />
10-
<link href="https://cdnjs.cloudflare.com/ajax/libs/dygraph/2.0.0/dygraph.css" rel="stylesheet" />
11+
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
1112

12-
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
13+
<!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
1314
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.2.0/js/tether.min.js" integrity="sha384-Plbmg8JY28KFelvJVai01l8WyZzrYWG825m+cZ0eDDS1f7d/js6ikvy1+X+guPIB" crossorigin="anonymous"></script>
1415
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
15-
<!--<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>-->
16+
-->
17+
18+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
19+
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
1620

1721
<script src="https://cdnjs.cloudflare.com/ajax/libs/dygraph/2.0.0/dygraph.js"></script>
1822

@@ -33,18 +37,18 @@
3337
<a class="navbar-brand" href="#">Perfon.Net</a>
3438
<div class="collapse navbar-collapse" id="navbarCollapse">
3539
<ul class="navbar-nav mr-auto">
36-
<li class="nav-item active">
37-
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
40+
<li class="nav-item">
41+
<a class="nav-link" href="https://github.com/magsoft2/Perfon.Net">Help <span class="sr-only">(current)</span></a>
3842
</li>
3943
<li class="nav-item">
40-
<a class="nav-link" href="#">Git</a>
44+
<a class="nav-link" href="https://github.com/magsoft2/Perfon.Net">Github</a>
4145
</li>
4246
</ul>
4347
</div>
4448
</nav>
4549

4650
<!-- Begin page content -->
47-
<div class="container" style="padding: 60px 15px 0;">
51+
<div class="container-fluid" style="padding: 0px 15px 0;">
4852
PLACEHOLDER_FOR_PANEL
4953
</div>
5054

Perfon.WebApi/UI/PerfCountersUIPanel.html

Lines changed: 191 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,120 +1,222 @@
1-
<nav class="navbar navbar-light" style="background-color: #e3f2fd; width: 300px">
2-
<form class="form-inline">
3-
<label class="col-1">Date </label>
4-
<input class="form-control" type="date" id="date1" aria-label="Selected date" onchange="refresh()">
5-
</form>
6-
</nav>
7-
<div class="card card-block">
8-
<form class="form-inline">
9-
<label class="col-2">Select perf counter</label>
10-
<select class="form-control" id="perfCounterName" onchange="perCounterNameChange(this.value)" style="width: 300px">
11-
<option value=""></option>
12-
</select>
13-
</form>
14-
<div id="chart1" style="width: 600px; height: 300px;"></div>
15-
<div id="logs">
16-
</div>
17-
1+
<nav class="navbar navbar-default">
2+
<div class="">
3+
<form class="navbar-form">
4+
<div class="form-group">
5+
<label for="selected_date">Date </label>
6+
<input class="form-control" type="date" id="date1" name="selected_date" onchange="dateChange()">
7+
</div>
8+
<div class="form-group">
9+
<div class="form-check">
10+
<label class="form-check-label">
11+
<input class="form-check-input" type="checkbox" id="checkPollId" onchange="checkPoll()" value="">
12+
Poll server
13+
</label>
14+
</div>
15+
</div>
16+
<div class="form-group">
17+
<div class="btn btn-default" onclick="addChartBlock()">Add chart</div>
18+
</div>
19+
</form>
1820
</div>
21+
</nav>
1922

23+
<div id="chartsContainer">
24+
25+
</div>
2026

27+
<style>
28+
.graph-block
29+
{
30+
border:1px solid lightgray;
31+
padding:5px;
32+
}
33+
select.form-control:not([size]):not([multiple])
34+
{
35+
padding-top: 2px;
36+
}
37+
@media (min-width: 1600px){
38+
.col-lg-xl-3
39+
{
40+
width:25%;
41+
}
42+
}
43+
</style>
2144
<script type="text/javascript">
2245

2346
var uri = 'perfcounters';
47+
var globalChartBlockId = 0;
2448

25-
var dataArr = [[0,0]];
26-
27-
var dyg = ResetGraph("chart1");
49+
var graphBlocks = [];
50+
var graphBlocksDOM = [];
2851

29-
function ResetGraph(id)
30-
{
31-
dataArr = [[0,0]];
32-
33-
return new Dygraph(
34-
document.getElementById(id),
35-
dataArr,
36-
{
37-
customBars: false,
38-
delimiter : ';',
39-
title: 'none',
40-
ylabel: '',
41-
legend: 'always',
42-
labels: [ "Time", "Val" ],
43-
showRangeSelector: true,
44-
drawPoints: true
45-
//showRoller: true
46-
}
47-
);
48-
}
4952

5053
$(document).ready(function () {
5154

5255
$("#date1").val(new Date().toISOString().split('T')[0]);
5356

54-
refresh();
57+
var num = 6;
58+
for(let i=0;i<num;i++)
59+
{
60+
addChartBlock();
61+
}
5562
});
5663

57-
function refresh() {
58-
59-
dyg = ResetGraph("chart1");
60-
61-
getPerfCountersList().then(function(data)
64+
function addChartBlock()
65+
{
66+
var idx = globalChartBlockId++;
67+
var gr = new GraphBlock(idx);
68+
graphBlocks.push(gr);
69+
graphBlocksDOM.push(gr.generateGraphBlockDOM($('#chartsContainer')));
70+
gr.refresh();
71+
}
72+
function deleteChartBlock(event)
73+
{
74+
var blockIdx = $(event.target).closest('.graph-block').attr('id');
75+
var block = graphBlocksDOM.find(function(a){return a.attr('id')== blockIdx;});
76+
var idx = graphBlocksDOM.indexOf(block);
77+
if(idx >= 0)
6278
{
63-
var ctrl = $("#perfCounterName");
64-
ctrl.find('option').remove();
65-
ctrl.append('<option value=""></option>');
66-
for(let i=0;i<data.length;i++)
67-
{
68-
ctrl.append('<option value="'+data[i]+'">'+data[i]+'</option>');
69-
}
70-
});
79+
graphBlocks.splice(idx,1);
80+
graphBlocksDOM.splice(idx,1);
81+
$(event.target).closest('.graph-block').remove();
82+
}
7183
}
72-
function perCounterNameChange(name){
73-
if(name === undefined || name ==='')
84+
85+
var pollTimer = undefined;
86+
function checkPoll()
87+
{
88+
if(pollTimer === undefined)
7489
{
75-
return;
90+
pollTimer = setInterval(pollServer, 5000);
91+
}else{
92+
clearInterval(pollTimer);
93+
pollTimer = undefined;
7694
}
77-
var date = $("#date1").val();
78-
getPerfCounterTrack(name, date).then(function(data)
95+
}
96+
97+
function refresh() {
98+
graphBlocks.forEach(function(self){
99+
self.refresh();
100+
});
101+
102+
}
103+
function dateChange()
104+
{
105+
graphBlocks.forEach(function(self){
106+
self.resetData();
107+
self.updatePerfCounterChartBlock();
108+
});
109+
}
110+
111+
function GraphBlock(idx)
112+
{
113+
var self = this;
114+
115+
this.dataArray = [];
116+
this.graphDyg = undefined;
117+
this.graphBlockDOM = undefined;
118+
this.idx = idx;
119+
120+
this.resetGraph = function(){
121+
this.dataArray = [[0,0]];
122+
var lbl = $(self.graphBlockDOM).find('.labelsDiv')[0];
123+
self.graphDyg = new Dygraph(
124+
$(self.graphBlockDOM).find('.chart')[0],
125+
self.dataArray,
126+
{
127+
customBars: false,
128+
delimiter : ';',
129+
//title: 'none',
130+
ylabel: '',
131+
legend: 'always',
132+
labels: [ "Time", "Value" ],
133+
showRangeSelector: true,
134+
drawPoints: true,
135+
labelsDiv: lbl,
136+
fillGraph : true
137+
//showRoller: true
138+
}
139+
);
140+
};
141+
142+
this.refresh = function() {
143+
self.resetGraph();
144+
145+
getPerfCountersList().then(function(data)
146+
{
147+
var ctrl = $(self.graphBlockDOM).find(".perfcounter-name").first();
148+
ctrl.find('option').remove();
149+
ctrl.append('<option value=""></option>');
150+
for(let i=0;i<data.length;i++)
151+
{
152+
ctrl.append('<option value="'+data[i]+'">'+data[i]+'</option>');
153+
}
154+
});
155+
};
156+
this.resetData = function(){
157+
this.dataArray.lentgh = 0;
158+
}
159+
this.updatePerfCounterChartBlock = function()
79160
{
80-
var text = '';
81-
if(dataArr === undefined)
161+
self.refreshPerfCounter($(self.graphBlockDOM).find(".perfcounter-name").first().val(), $("#date1").val(), self.graphDyg);
162+
}
163+
this.refreshPerfCounter = function(name, date, graph){
164+
if(name === undefined || name ==='')
82165
{
83-
dataArr = [];
166+
return;
84167
}
85-
dataArr.length = 0;
86-
var lastTime = new Date();
87-
for(let i=0;i<data.length;i++)
168+
getPerfCounterTrack(name, date).then(function(data)
88169
{
89-
lastTime = new Date(data[i].Timestamp);
90-
dataArr.push([lastTime, data[i].Value]);
91-
text += JSON.stringify(data[i]);
92-
}
93-
94-
dyg.updateOptions({
95-
title: name,
96-
dateWindow:[lastTime-1000*60*15, lastTime],
97-
'file': dataArr
170+
if(self.dataArray === undefined)
171+
{
172+
self.dataArray = [];
173+
}
174+
self.dataArray.length = 0;
175+
var lastTime = new Date();
176+
for(let i=self.dataArray.length;i<data.length;i++)
177+
{
178+
lastTime = new Date(data[i].Timestamp);
179+
self.dataArray.push([lastTime, data[i].Value]);
180+
}
181+
182+
graph.updateOptions({
183+
//title: name,
184+
dateWindow:[lastTime-1000*60*15, lastTime],
185+
'file': self.dataArray
186+
});
98187
});
188+
}
99189

100-
$("#logs").text(text);
101-
});
102-
}
190+
this.generateGraphBlockDOM = function(container){
103191

104-
//setInterval(PollServer, 1000);
192+
var block = $('<div class="col-sm-12 col-md-6 col-lg-4 col-lg-xl-3 graph-block" id="id'+idx+'"></div>').appendTo(container);
193+
194+
//var block = $(container).find('.graph-block');
195+
196+
$('<form class="form-inline"></form>').appendTo(block);
197+
$('<div class="form-group" style="width: 100%;"></div>').appendTo($(block).find('.form-inline'));
198+
//$('<div>Select perf counter</div>').appendTo($(block).find('.form-group'));
199+
$('<select class="form-control perfcounter-name" style="width: auto"></select>').appendTo(block.find('.form-group'));
200+
$('<span class="glyphicon glyphicon-trash pull-right" aria-hidden="true" data-toggle="tooltip" title="Delete chart block"></span>').appendTo(block.find('.form-group'));
201+
$('<div class="labelsDiv pull-right"></div>').appendTo(block);
202+
$('<div class="chart" style="width: 100%; height: 250px;"></div>').appendTo(block);
105203

106-
function PollServer()
107-
{
108-
perCounterNameChange($("#perfCounterName").val(), $("#date1").val());
109-
//var x = new Date(); // current time
110-
//var y = Math.random();
111-
//dataArr.push([x, y]);
112-
//dyg.updateOptions( {
113-
// 'file': dataArr,
114-
// dateWindow:[dyg.dateWindow_[0],x]
115-
//} );
204+
$(block).find('select').on('change', self.updatePerfCounterChartBlock);
205+
$(block).find('.glyphicon-trash').on('click', deleteChartBlock);
206+
207+
this.graphBlockDOM = block;
208+
209+
return block;
210+
};
116211
}
117-
212+
213+
function pollServer()
214+
{
215+
graphBlocks.forEach(function(self){
216+
self.updatePerfCounterChartBlock();
217+
});
218+
}
219+
118220
function getPerfCountersList(){
119221
return $.get(uri);
120222

TestServer/perf.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ time;RequestsCount, num/sec;RequestProcessTime, ms;RequestMaxProcessTime, ms;KBy
1818
05.02.2017 20:26:29;0;0;0;0,000;0,000;0;0;0;0,00;0;0;0;
1919
05.02.2017 20:26:29;0;0;0;0,000;0,000;0;0;0;0,00;0;0;0;
2020
05.02.2017 20:26:29;0;0;0;0,000;0,000;0;0;0;0,00;0;0;0;
21+
06.02.2017 0:57:15;1;106;106;0,223;0,229;0;0;16;3,90;0;0;0;

0 commit comments

Comments
 (0)