JNP3 16/17

Dependencies:   mbed nRF24L01P

frontend/kubus.js

Committer:
Micha? ?azowik
Date:
2017-01-09
Revision:
21:959de2c64d28
Parent:
20:bdb2bf657f29
Child:
22:af4397ca4561

File content as of revision 21:959de2c64d28:

Chart.defaults.global.defaultFontFamily = "triplicate, Courier, 'Courier New', monospace";
Chart.defaults.global.defaultFontSize = 15;
Chart.defaults.global.defaultFontColor = "#efefef";

class Charts {
    constructor(containerId) {
        this.container = document.getElementById(containerId);
        this.charts = {};
    }

    addSensorData(sensors) {
        for (let sensor of sensors) {
            if (!(sensor.name in this.charts)) {
                this._addChart(SensorChartFactory.create(sensor));
            }

            this.charts[sensor.name].addDataPoint({
                x: new Date(),
                y: sensor.value
            });
        }
    }

    _addChart(chart) {
        this.charts[chart.getName()] = chart;
        this._addToContainer(chart);
    }

    _addToContainer(chart) {
        const chartContainer = this._createChartContainer();
        const title = this._createChartTitle(chart.getName());

        chartContainer.appendChild(title);
        chartContainer.appendChild(chart.getCanvas());

        this.container.appendChild(chartContainer);

        chart.render();
    }

    _createChartContainer() {
        const chartContainer = document.createElement("div");
        chartContainer.classList.add('chart');
        return chartContainer;
    }

    _createChartTitle(name) {
        const title = document.createElement("h2");
        title.innerHTML = name;
        title.classList.add('chart__title');
        return title;
    }
}

class SensorChart {
    constructor(name) {
        this.canvas = document.createElement("canvas");
        this.canvas.height = "70";
        this.name = name;
        this.dataSize = 0;
    }

    getCanvas() {
        return this.canvas;
    }

    getName() {
        return this.name;
    }

    render() {
        throw Error("Not implemented");
    }

    addDataPoint(dataPoint) {
        this.chart.data.datasets[0].data.push(dataPoint);
        this.dataSize++;

        if (this.dataSize > 10) {
            this.chart.data.datasets[0].data.shift();
            this.dataSize--;
        }

        this.chart.update();
    }

    _getConfig(data) {
        return {
            type: 'line',
            data: {
                datasets: [
                    {
                        label: this.name,
                        data: data,
                        backgroundColor: "rgba(75, 192, 192, 0.1)",
                        borderColor: "rgba(75, 192, 192, 1)"
                    }
                ]
            },
            options: {
                scales: {
                    xAxes: [{
                        type: 'time',
                        position: 'bottom'
                    }]
                },
                legend: {
                    display: false
                }
            }
        }
    }
}

class NumberChart extends SensorChart {
    render() {
        this.chart = new Chart(this.canvas, this._getConfig([]));
    }
}

class BoolChart extends SensorChart {
    render() {
        this.chart = new Chart(this.canvas, this._getConfig([]));
    }

    _getConfig(data) {
        const config = super._getConfig(data);
        config.data.datasets[0].steppedLine = true;
        return config;
    }
}

class SensorChartFactory {
    static create(sensor) {
        switch (sensor.type) {
            case "number":
                return new NumberChart(sensor.name);
                break;
            case "bool":
                return new BoolChart(sensor.name);
                break;
            default:
                throw Error(`Sensor type ${sensor.type} not supported`);
        }
    }
}

const sensorCharts = new Charts("charts");

function update() {
    sensorCharts.addSensorData([
        {
            name: "Distance at the entrance",
            type: "number",
            range: [0, 90],
            unit: "cm",
            value: Math.random() * 90,
        },
        {
            name: "Motion at the stairway",
            type: "bool",
            value: Math.random() >= 0.5
        }
    ]);

    setTimeout(update, 5000);
}

update();