Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Dmytro Bogatov
status-site
Commits
f830489b
Commit
f830489b
authored
Aug 08, 2017
by
Dmytro Bogatov
💕
Browse files
Rerender data tables on plot zoom.
parent
0aa0d49c
Changes
9
Hide whitespace changes
Inline
Side-by-side
client/ts/metric.ts
View file @
f830489b
...
...
@@ -13,6 +13,7 @@ import "bootstrap"
declare
var
source
:
string
;
declare
var
type
:
number
;
declare
var
min
:
number
;
declare
var
max
:
number
;
...
...
client/ts/modules/constants.ts
View file @
f830489b
...
...
@@ -55,4 +55,10 @@ export class Constants {
* of 5 minutes and sums of user actions will be displayed per interval.
*/
static
USER_ACTIONS_AGGREGATION_INTERVAL
:
number
=
30
;
/**
* The interval in milliseconds that defines a default time frame of data
* on metric pages.
*/
static
METRIC_PAGE_DATA_PREVIEW
:
number
=
2
*
60
*
60
*
1000
;
}
client/ts/modules/metric-page/abstract.ts
View file @
f830489b
...
...
@@ -10,8 +10,12 @@ import "../../vendor/jquery.flot.time.js";
import
"
../../vendor/jquery.flot.selection.js
"
;
import
"
../../vendor/jquery.flot.threshold.js
"
;
import
"
../../vendor/jquery.flot.tooltip.js
"
;
import
{
Constants
}
from
"
../constants
"
;
declare
var
start
:
number
;
declare
var
end
:
number
;
/**
* Represents set of procedures for rendering metric page.
*
...
...
@@ -23,6 +27,7 @@ export abstract class MetricPage<T extends Metric<DataPoint>> {
protected
metric
:
T
;
protected
dataTablesRendered
:
boolean
=
false
;
protected
dataTable
:
DataTables
.
DataTable
;
/**
* Minimal theoretical value for data series.
...
...
@@ -50,10 +55,21 @@ export abstract class MetricPage<T extends Metric<DataPoint>> {
protected
minData
:
number
;
protected
maxData
:
number
;
protected
start
:
Date
=
null
;
protected
end
:
Date
=
null
;
constructor
(
min
:
number
,
max
:
number
)
{
this
.
max
=
max
;
this
.
min
=
min
;
if
(
start
>
0
)
{
this
.
start
=
new
Date
(
start
);
}
if
(
end
>
0
)
{
this
.
end
=
new
Date
(
end
);
}
window
.
setTimeout
(
async
()
=>
{
await
this
.
metric
.
loadData
(
60
*
60
*
24
*
3
);
// 3 days
...
...
@@ -84,7 +100,7 @@ export abstract class MetricPage<T extends Metric<DataPoint>> {
* @memberOf MetricPage
*/
private
renderPlot
():
void
{
var
plot
:
any
=
$
.
plot
(
$
(
"
#metric-detailed-plot
"
),
this
.
formattedData
,
...
...
@@ -113,17 +129,46 @@ export abstract class MetricPage<T extends Metric<DataPoint>> {
// don't fire event on the overview to prevent eternal loop
overview
.
setSelection
(
ranges
,
true
);
this
.
renderTable
(
true
,
new
Date
(
ranges
.
xaxis
.
from
),
new
Date
(
ranges
.
xaxis
.
to
));
}));
$
(
"
#metric-overview-plot
"
).
bind
(
"
plotselected
"
,
<
any
>
((
event
,
ranges
)
=>
{
plot
.
setSelection
(
ranges
);
}));
// if latest data point is more than 2 hours ago
// select recent 2 hours in plot
if
(
new
Date
().
getTime
()
-
this
.
minData
>
2
*
60
*
60
*
1000
)
{
let
from
=
new
Date
().
getTime
()
-
2
*
60
*
60
*
1000
;
plot
.
setSelection
({
xaxis
:
{
from
:
from
,
to
:
this
.
maxData
},
yaxis
:
{
from
:
0
,
to
:
0
}
});
if
(
this
.
start
!=
null
)
{
let
from
=
Math
.
min
(
Math
.
max
(
this
.
start
.
getTime
(),
this
.
minData
),
this
.
maxData
)
;
let
to
=
this
.
end
==
null
?
Math
.
min
(
this
.
maxData
,
this
.
start
.
getTime
()
+
Constants
.
METRIC_PAGE_DATA_PREVIEW
)
:
Math
.
max
(
Math
.
min
(
this
.
end
.
getTime
(),
this
.
maxData
),
this
.
minData
)
;
plot
.
setSelection
({
xaxis
:
{
from
:
from
,
to
:
to
},
yaxis
:
{
from
:
0
,
to
:
0
}
});
}
else
{
// if latest data point is more than 2 hours ago
// select recent 2 hours in plot
if
(
new
Date
().
getTime
()
-
this
.
minData
>
Constants
.
METRIC_PAGE_DATA_PREVIEW
)
{
let
from
=
new
Date
().
getTime
()
-
Constants
.
METRIC_PAGE_DATA_PREVIEW
;
plot
.
setSelection
({
xaxis
:
{
from
:
from
,
to
:
this
.
maxData
},
yaxis
:
{
from
:
0
,
to
:
0
}
});
}
}
}
...
...
@@ -135,7 +180,19 @@ export abstract class MetricPage<T extends Metric<DataPoint>> {
*
* @memberOf MetricPage
*/
protected
abstract
renderTable
():
void
;
/**
* Renders data tables in the UI.
* Does not load the data.
*
* @protected
* @abstract
* @param {boolean} redraw if data table has to be force-redrawn; implies non-null values of start and end;
* @param {Date} start start date for filter
* @param {Date} end end date for filter
* @memberof MetricPage
*/
protected
abstract
renderTable
(
redraw
:
boolean
,
start
:
Date
,
end
:
Date
):
void
;
/**
* Renders numeric values in the UI.
...
...
@@ -160,10 +217,10 @@ export abstract class MetricPage<T extends Metric<DataPoint>> {
*/
public
render
():
void
{
this
.
configurePlot
()
this
.
configurePlot
()
this
.
renderPlot
();
this
.
renderValues
();
this
.
renderTable
();
this
.
renderTable
(
false
,
null
,
null
);
}
}
client/ts/modules/metric-page/cpu-load.ts
View file @
f830489b
...
...
@@ -106,9 +106,13 @@ export class CpuLoadMetricPage extends MetricPage<Metric<CpuLoadDataPoint>> {
};
};
protected
renderTable
():
void
{
protected
renderTable
(
redraw
:
boolean
,
start
:
Date
,
end
:
Date
):
void
{
if
(
!
this
.
dataTablesRendered
)
{
if
(
!
this
.
dataTablesRendered
||
redraw
)
{
if
(
this
.
dataTablesRendered
)
{
this
.
dataTable
.
destroy
();
}
let
header
=
`
<tr>
...
...
@@ -124,6 +128,17 @@ export class CpuLoadMetricPage extends MetricPage<Metric<CpuLoadDataPoint>> {
this
.
metric
.
data
.
map
(
dp
=>
<
CpuLoadDataPoint
>
dp
)
.
filter
((
value
,
index
,
array
)
=>
{
if
(
start
!=
null
&&
value
.
timestamp
<
start
)
{
return
false
;
}
if
(
end
!=
null
&&
value
.
timestamp
>
end
)
{
return
false
;
}
return
true
;
})
.
map
(
dp
=>
`
<tr>
...
...
@@ -135,7 +150,7 @@ export class CpuLoadMetricPage extends MetricPage<Metric<CpuLoadDataPoint>> {
.
join
()
);
$
(
'
#metric-data
'
).
DataTable
({
this
.
dataTable
=
$
(
'
#metric-data
'
).
DataTable
({
"
order
"
:
[[
0
,
"
desc
"
]],
lengthChange
:
false
,
searching
:
false
,
...
...
client/ts/modules/metric-page/health.ts
View file @
f830489b
...
...
@@ -111,9 +111,13 @@ export class HealthMetricPage extends MetricPage<Metric<HealthDataPoint>> {
};
};
protected
renderTable
():
void
{
protected
renderTable
(
redraw
:
boolean
,
start
:
Date
,
end
:
Date
):
void
{
if
(
!
this
.
dataTablesRendered
)
{
if
(
!
this
.
dataTablesRendered
||
redraw
)
{
if
(
this
.
dataTablesRendered
)
{
this
.
dataTable
.
destroy
();
}
let
header
=
`
<tr>
...
...
@@ -130,6 +134,17 @@ export class HealthMetricPage extends MetricPage<Metric<HealthDataPoint>> {
this
.
metric
.
data
.
map
(
dp
=>
<
HealthDataPoint
>
dp
)
.
filter
((
value
,
index
,
array
)
=>
{
if
(
start
!=
null
&&
value
.
timestamp
<
start
)
{
return
false
;
}
if
(
end
!=
null
&&
value
.
timestamp
>
end
)
{
return
false
;
}
return
true
;
})
.
map
(
dp
=>
`
<tr>
...
...
@@ -160,7 +175,7 @@ export class HealthMetricPage extends MetricPage<Metric<HealthDataPoint>> {
.
join
()
);
$
(
'
#metric-data
'
).
DataTable
({
this
.
dataTable
=
$
(
'
#metric-data
'
).
DataTable
({
"
order
"
:
[[
0
,
"
desc
"
]],
lengthChange
:
false
,
searching
:
false
,
...
...
@@ -173,8 +188,8 @@ export class HealthMetricPage extends MetricPage<Metric<HealthDataPoint>> {
'
showDetails
'
,
(
e
:
CustomEvent
)
=>
{
let
data
:
any
[]
=
e
.
detail
.
data
;
let
timestamp
:
Date
=
e
.
detail
.
timestamp
;
let
data
:
any
[]
=
e
.
detail
.
data
;
let
timestamp
:
Date
=
e
.
detail
.
timestamp
;
let
code
=
`
<div
...
...
@@ -211,17 +226,17 @@ export class HealthMetricPage extends MetricPage<Metric<HealthDataPoint>> {
</thead>
<tbody>
${
data
.
sortByProperty
(
el
=>
el
.
Source
)
.
map
(
el
=>
`
data
.
sortByProperty
(
el
=>
el
.
Source
)
.
map
(
el
=>
`
<tr>
<th>
${
el
.
Type
}
</th>
<th>
${
el
.
Source
}
</th>
<th>
${
el
.
Label
}
</th>
</tr>
`
)
.
join
(
""
)
}
.
join
(
""
)
}
</tbody>
</table>
</div>
...
...
client/ts/modules/metric-page/ping.ts
View file @
f830489b
...
...
@@ -149,9 +149,13 @@ export class PingMetricPage extends MetricPage<Metric<PingDataPoint>> {
};
};
protected
renderTable
():
void
{
protected
renderTable
(
redraw
:
boolean
,
start
:
Date
,
end
:
Date
):
void
{
if
(
!
this
.
dataTablesRendered
)
{
if
(
!
this
.
dataTablesRendered
||
redraw
)
{
if
(
this
.
dataTablesRendered
)
{
this
.
dataTable
.
destroy
();
}
let
header
=
`
<tr>
...
...
@@ -168,6 +172,17 @@ export class PingMetricPage extends MetricPage<Metric<PingDataPoint>> {
this
.
metric
.
data
.
map
(
dp
=>
<
PingDataPoint
>
dp
)
.
filter
((
value
,
index
,
array
)
=>
{
if
(
start
!=
null
&&
value
.
timestamp
<
start
)
{
return
false
;
}
if
(
end
!=
null
&&
value
.
timestamp
>
end
)
{
return
false
;
}
return
true
;
})
.
map
(
dp
=>
`
<tr>
...
...
@@ -180,7 +195,7 @@ export class PingMetricPage extends MetricPage<Metric<PingDataPoint>> {
.
join
()
);
$
(
'
#metric-data
'
).
DataTable
({
this
.
dataTable
=
$
(
'
#metric-data
'
).
DataTable
({
"
order
"
:
[[
0
,
"
desc
"
]],
lengthChange
:
false
,
searching
:
false
,
...
...
client/ts/modules/metric-page/user-action.ts
View file @
f830489b
...
...
@@ -154,9 +154,13 @@ export class UserActionMetricPage extends MetricPage<Metric<UserActionDataPoint>
};
};
protected
renderTable
():
void
{
protected
renderTable
(
redraw
:
boolean
,
start
:
Date
,
end
:
Date
):
void
{
if
(
!
this
.
dataTablesRendered
)
{
if
(
!
this
.
dataTablesRendered
||
redraw
)
{
if
(
this
.
dataTablesRendered
)
{
this
.
dataTable
.
destroy
();
}
let
header
=
`
<tr>
...
...
@@ -173,6 +177,17 @@ export class UserActionMetricPage extends MetricPage<Metric<UserActionDataPoint>
this
.
metric
.
data
.
map
(
dp
=>
<
UserActionDataPoint
>
dp
)
.
filter
((
value
,
index
,
array
)
=>
{
if
(
start
!=
null
&&
value
.
timestamp
<
start
)
{
return
false
;
}
if
(
end
!=
null
&&
value
.
timestamp
>
end
)
{
return
false
;
}
return
true
;
})
.
map
(
dp
=>
`
<tr>
...
...
@@ -185,7 +200,7 @@ export class UserActionMetricPage extends MetricPage<Metric<UserActionDataPoint>
.
join
()
);
$
(
'
#metric-data
'
).
DataTable
({
this
.
dataTable
=
$
(
'
#metric-data
'
).
DataTable
({
"
order
"
:
[[
0
,
"
desc
"
]],
lengthChange
:
false
,
searching
:
false
,
...
...
src/web/Controllers/View/HomeController.cs
View file @
f830489b
...
...
@@ -65,8 +65,8 @@ namespace StatusMonitor.Web.Controllers.View
return
View
(
model
);
}
[
Route
(
"Home/Metric/{type}/{source}"
)]
public
async
Task
<
IActionResult
>
Metric
(
string
type
,
string
source
)
[
Route
(
"Home/Metric/{type}/{source}
/{start?}/{end?}
"
)]
public
async
Task
<
IActionResult
>
Metric
(
string
type
,
string
source
,
string
start
=
null
,
string
end
=
null
)
{
Metrics
metricType
;
...
...
@@ -79,6 +79,41 @@ namespace StatusMonitor.Web.Controllers.View
return
BadRequest
(
"Bad type. Needs to be one of Metrics type."
);
}
if
(
start
!=
null
)
{
try
{
DateTime
.
SpecifyKind
(
new
DateTime
(
1970
,
1
,
1
),
DateTimeKind
.
Utc
).
AddMilliseconds
(
Convert
.
ToInt64
(
start
));
}
catch
(
System
.
Exception
)
{
return
BadRequest
(
"Bad start date. Needs to be the number of milliseconds since Epoch."
);
}
}
if
(
end
!=
null
)
{
try
{
DateTime
.
SpecifyKind
(
new
DateTime
(
1970
,
1
,
1
),
DateTimeKind
.
Utc
).
AddMilliseconds
(
Convert
.
ToInt64
(
end
));
}
catch
(
System
.
Exception
)
{
return
BadRequest
(
"Bad end date. Needs to be the number of milliseconds since Epoch."
);
}
}
if
(
start
!=
null
&&
end
!=
null
)
{
if
(
DateTime
.
SpecifyKind
(
new
DateTime
(
1970
,
1
,
1
),
DateTimeKind
.
Utc
).
AddMilliseconds
(
Convert
.
ToInt64
(
start
))
>=
DateTime
.
SpecifyKind
(
new
DateTime
(
1970
,
1
,
1
),
DateTimeKind
.
Utc
).
AddMilliseconds
(
Convert
.
ToInt64
(
end
))
)
{
return
BadRequest
(
"Bad dates. End date needs to be greater than the start date."
);
}
}
var
model
=
await
_metricService
.
GetMetricsAsync
(
metricType
,
source
);
if
(
model
.
Count
()
==
0
)
...
...
@@ -107,6 +142,9 @@ namespace StatusMonitor.Web.Controllers.View
ViewBag
.
Uptime
=
await
_uptime
.
ComputeUptimeAsync
(
source
);
}
ViewBag
.
Start
=
start
??
0.
ToString
();
ViewBag
.
End
=
end
??
0.
ToString
();
return
View
(
model
.
First
());
}
...
...
src/web/Views/Home/Metric.cshtml
View file @
f830489b
...
...
@@ -186,8 +186,12 @@
<script>
var
source
=
"
@Model.Source
"
;
var
type
=
@
Model
.
Type
;
var
min
=
@
ViewData
[
"
Min
"
];
var
max
=
@
ViewData
[
"
Max
"
];
var
start
=
@
ViewData
[
"
Start
"
];
var
end
=
@
ViewData
[
"
End
"
];
</script>
<environment
names=
"Development"
>
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment