4 Commits

Author SHA1 Message Date
9af0ba1bb8 Best optimization so far 2020-11-21 19:42:14 +01:00
04c27560ea Added timeout processing 2020-11-21 19:18:29 +01:00
73157520ab Optimized chart update (did not achieve much) 2020-11-21 18:32:12 +01:00
f862e4b8da Added all charts (pre optimization) 2020-11-21 18:10:36 +01:00
7 changed files with 168 additions and 198 deletions

View File

@ -42,10 +42,23 @@ class Dashboard extends Component {
this.updateSeries = this.updateSeries.bind(this);
this.updateDynamic = this.updateDynamic.bind(this);
this.performTask = this.performTask.bind(this);
}
static contextType = DevicesContext;
componentDidMount() {
this.context.addHandler(C.update_all_method_name, this.updateSeries);
this.context.addHandler(C.update_method_name, this.updateSeries);
this.updateSeries();
this.updateDynamic();
}
componentWillUnmount() {
this.context.removeHandler(C.update_all_method_name, this.updateSeries);
this.context.removeHandler(C.update_method_name, this.updateSeries);
}
getItemsWithStatus(iterate, status) {
const items = [];
@ -91,190 +104,175 @@ class Dashboard extends Component {
updateSeries() {
this.setState({
deviceSeries: this.getDeviceSeries(),
sensorSeries: this.getSensorSeries(),
heatmapSecondsSeries: this.getHeatmapSecondsSeries(),
heatmapMinutesSeries: this.getHeatmapMinutesSeries(),
barSeries: this.getBarSeries(),
barCategories: this.getBarCategories(),
lineSeries: this.getLineSeries(),
sensorSeries: this.getSensorSeries()
});
}
updateDynamic() {
this.setState({
heatmapSecondsSeries: this.getHeatmapSecondsSeries(),
heatmapMinutesSeries: this.getHeatmapMinutesSeries(),
barSeries: this.getBarSeries(),
barCategories: this.getBarCategories(),
lineSeries: this.getLineSeries(),
});
}
componentDidMount() {
this.context.addHandler(C.update_all_method_name, this.updateSeries);
this.context.addHandler(C.update_method_name, this.updateSeries);
this.updateSeries();
window.setInterval(() => {
this.updateDynamic();
}, 1000);
}
componentWillUnmount() {
this.context.removeHandler(C.update_all_method_name, this.updateSeries);
this.context.removeHandler(C.update_method_name, this.updateSeries);
}
getHeatmapSecondsSeries() {
updateDynamic = () => {
const secondAgo = new Date();
secondAgo.setMilliseconds(0);
const minuteAgo = new Date( Date.now() - 1000 * 60 );
const devicePoints = {};
for (var d of this.context.devices) {
devicePoints[d.id] = Array(60).fill(0);
}
for (var p of this.context.heatmapPoints) {
if (p.date > minuteAgo) {
var seconds = Math.floor((p.date.getTime() - minuteAgo.getTime()) / 1000);
var oldProb = devicePoints[p.deviceId][seconds];
if (oldProb < p.prob) {
devicePoints[p.deviceId][seconds] = p.prob;
}
}
}
const series = [];
var i = 0;
for (var p in devicePoints) {
series.push({
name: "Device " + i,
data: devicePoints[p].map((value, index) => ({
x: new Date( Date.now() - (60 - index) * 1000 ).toLocaleTimeString('hu-HU'),
y: value
})),
});
i++;
};
return series;
}
getHeatmapMinutesSeries() {
const hourAgo = new Date( Date.now() - 1000 * 60 * 60 );
const devicePoints = {};
const minuteDevicePoints = {};
const hourDevicePoints = {};
const barDevicePoints = {};
const linePoints = {};
for (var d of this.context.devices) {
devicePoints[d.id] = Array(60).fill(0);
minuteDevicePoints[d.id] = Array(60).fill(0);
hourDevicePoints[d.id] = Array(60).fill(0);
barDevicePoints[d.id] = Array(3).fill(0);
}
for (var p of this.context.heatmapPoints) {
const processMethod = (items, index) => {
const p = items[index];
if (p.date > minuteAgo) {
var seconds = Math.floor((p.date.getTime() - minuteAgo.getTime()) / 1000);
var oldProb = minuteDevicePoints[p.deviceId][seconds];
if (oldProb < p.prob) {
minuteDevicePoints[p.deviceId][seconds] = p.prob;
}
}
if (p.date > hourAgo) {
var minutes = Math.floor((p.date.getTime() - hourAgo.getTime()) / (1000 * 60));
var oldProb = devicePoints[p.deviceId][minutes];
var oldProb = hourDevicePoints[p.deviceId][minutes];
if (oldProb < p.prob) {
devicePoints[p.deviceId][minutes] = p.prob;
hourDevicePoints[p.deviceId][minutes] = p.prob;
}
}
if (p.prob > 0.5 && p.prob <= 0.7) {
barDevicePoints[p.deviceId][0] += 1;
}
if (p.prob > 0.7 && p.prob <= 0.9) {
barDevicePoints[p.deviceId][1] += 1;
}
if (p.prob > 0.9) {
barDevicePoints[p.deviceId][2] += 1;
}
if (p.date < secondAgo) {
var shortDate = p.date.toUTCString();
var point = linePoints[shortDate];
if (point === undefined) {
linePoints[shortDate] = 1;
} else {
linePoints[shortDate] += 1;
}
}
}
const series = [];
const finishMethod = () => {
const minuteHeatmapSeries = [];
var i = 0;
for (var p in devicePoints) {
series.push({
name: "Device " + i,
data: devicePoints[p].map((value, index) => ({
x: new Date( Date.now() - (60 - index) * 1000 * 60 ).toLocaleTimeString('hu-HU').substring(0, 5),
y: value
})),
var i = 0;
for (var p in minuteDevicePoints) {
minuteHeatmapSeries.push({
name: "Device " + i,
data: minuteDevicePoints[p].map((value, index) => ({
x: new Date( Date.now() - (60 - index) * 1000 ).toLocaleTimeString('hu-HU'),
y: value
})),
});
i++;
};
const hourHeatmapSeries = [];
var i = 0;
for (var p in hourDevicePoints) {
hourHeatmapSeries.push({
name: "Device " + i,
data: hourDevicePoints[p].map((value, index) => ({
x: new Date( Date.now() - (60 - index) * 1000 * 60 ).toLocaleTimeString('hu-HU').substring(0, 5),
y: value
})),
});
i++;
};
const barSeries = [];
const getCount = column => {
var counts = [];
for (var p in barDevicePoints) {
counts.unshift(barDevicePoints[p][column]);
}
return counts;
};
barSeries.push({
name: "Prob > 0.5",
data: getCount(0),
});
barSeries.push({
name: "Prob > 0.7",
data: getCount(1),
});
barSeries.push({
name: "Prob > 0.9",
data: getCount(2),
});
i++;
};
return series;
const lineSeries = [{name: "message/sec", data: []}];
for (var m in linePoints) {
lineSeries[0].data.push({
x: new Date(m).getTime(),
y: linePoints[m],
})
}
const getBarCategories = () => {
const categories = [];
for (var i = this.context.devices.length - 1; i >= 0; i--) {
categories.push("Device " + i)
}
return categories;
}
this.setState({
heatmapSecondsSeries: minuteHeatmapSeries,
heatmapMinutesSeries: hourHeatmapSeries,
barSeries: barSeries,
barCategories: getBarCategories(),
lineSeries: lineSeries,
});
setTimeout(this.updateDynamic, 1000);
}
const processHeatmapItem = processMethod.bind(this);
const onFinished = finishMethod.bind(this)
this.performTask(this.context.heatmapPoints, Math.ceil(this.context.heatmapPoints.length / 100), 10,
processHeatmapItem, onFinished);
}
getBarSeries() {
const devicePoints = {};
for (var d of this.context.devices) {
devicePoints[d.id] = Array(3).fill(0);
}
for (var p of this.context.heatmapPoints) {
if (p.prob > 0.5 && p.prob <= 0.7) {
devicePoints[p.deviceId][0] += 1;
}
if (p.prob > 0.7 && p.prob <= 0.9) {
devicePoints[p.deviceId][1] += 1;
}
if (p.prob > 0.9) {
devicePoints[p.deviceId][2] += 1;
performTask(items, numToProcess, wait, processItem, onFinished) {
var pos = 0;
// This is run once for every numToProcess items.
function iteration() {
// Calculate last position.
var j = Math.min(pos + numToProcess, items.length);
// Start at current position and loop to last position.
for (var i = pos; i < j; i++) {
processItem(items, i);
}
// Increment current position.
pos += numToProcess;
// Only continue if there are more items to process.
if (pos < items.length)
setTimeout(iteration, wait); // Wait 10 ms to let the UI update.
else
onFinished();
}
const series = [];
const getCount = column => {
var counts = [];
for (var p in devicePoints) {
counts.unshift(devicePoints[p][column]);
}
return counts;
};
series.push({
name: "Prob > 0.5",
data: getCount(0),
});
series.push({
name: "Prob > 0.7",
data: getCount(1),
});
series.push({
name: "Prob > 0.9",
data: getCount(2),
});
return series;
}
getBarCategories() {
const categories = [];
for (var i = this.context.devices.length - 1; i >= 0; i--) {
categories.push("Device " + i)
}
return categories;
}
getLineSeries() {
const xSecondsAgo = new Date( Date.now() - 1000 * 2 );
const aSecondAgo = new Date( Date.now() - 1000 * 1);
const messages = {};
var counter = 0;
for (var p of this.context.heatmapPoints) {
var shortDate = p.date.toUTCString();
var message = messages[shortDate];
if (message === undefined) {
messages[shortDate] = 1;
} else {
messages[shortDate] += 1;
}
}
const series = [{data: []}];
for (var m in messages) {
series[0].data.push({
x: new Date(m).getTime(),
y: messages[m],
})
}
return series;
iteration();
}
render() {
@ -297,22 +295,22 @@ class Dashboard extends Component {
</Grid>
<Grid item xs={12}>
<Paper className={classes.paper}>
<HeatmapChart label="Highest probability per devices by seconds" series={this.state.heatmapSecondsSeries}/>
<HeatmapChart label="Highest probability per second by devices" series={this.state.heatmapSecondsSeries}/>
</Paper>
</Grid>
<Grid item xs={12}>
<Paper className={classes.paper}>
<HeatmapChart label="Highest probability per devices by minutes" series={this.state.heatmapMinutesSeries}/>
<HeatmapChart label="Highest probability per minute by devices" series={this.state.heatmapMinutesSeries}/>
</Paper>
</Grid>
<Grid item xs={6}>
<Paper className={classes.paper}>
<BarChart label="# of messages per device" series={this.state.barSeries} categories={this.state.barCategories}/>
<BarChart label="# of messages by devices" series={this.state.barSeries} categories={this.state.barCategories}/>
</Paper>
</Grid>
<Grid item xs={6}>
<Paper className={classes.paper}>
<LineChart label="# of messages by second" series={this.state.lineSeries}/>
<LineChart label="# of messages per second" series={this.state.lineSeries}/>
</Paper>
</Grid>
</Grid>

View File

@ -17,17 +17,17 @@ export class BarChart extends Component {
chart: {
stacked: true,
animations: {
enabled: false,
enabled: true,
easing: 'linear',
speed: 1000,
speed: 250,
animateGradually: {
enabled: false,
},
dynamicAnimation: {
enabled: true,
speed: 500
speed: 250
}
}
},
},
plotOptions: {
bar: {

View File

@ -9,20 +9,6 @@ export class DonutChart extends Component {
this.state = {
options: {
chart: {
animations: {
enabled: false,
easing: 'linear',
speed: 1000,
animateGradually: {
enabled: false,
},
dynamicAnimation: {
enabled: true,
speed: 500
}
}
},
legend: {
fontSize: '18px',
},

View File

@ -8,20 +8,6 @@ export class HeatmapChart extends Component {
this.state = {
options: {
chart: {
animations: {
enabled: false,
easing: 'linear',
speed: 1000,
animateGradually: {
enabled: false,
},
dynamicAnimation: {
enabled: true,
speed: 500
}
}
},
dataLabels: {
enabled: false
},

View File

@ -10,15 +10,15 @@ export class LineChart extends Component {
options: {
chart: {
animations: {
enabled: false,
enabled: true,
easing: 'linear',
speed: 1000,
speed: 250,
animateGradually: {
enabled: false,
},
dynamicAnimation: {
enabled: true,
speed: 500
speed: 250
}
},
zoom: {

View File

@ -1,4 +1,4 @@
import { Box, Grid, IconButton, Paper, Typography } from '@material-ui/core';
import { Grid, IconButton, Paper, Typography } from '@material-ui/core';
import { blueGrey } from '@material-ui/core/colors';
import { AddBox, Refresh } from '@material-ui/icons/';
import { withStyles } from '@material-ui/styles';

View File

@ -16,9 +16,9 @@ class DeviceMarker extends Component {
getColor() {
const { device } = this.props;
if (device.status == "Online") {
if (device.status === "Online") {
return { color: blue[800] };
} else if (device.status == "Offline") {
} else if (device.status === "Offline") {
return { color: yellow[800] };
} else /* if (device.status == "unknown") */ {
return { color: red[800] };