Как генерировать графики в режиме реального времени на стороне сервера, используя Chartjs + Nodejs + Express + Потребление Api? - PullRequest
0 голосов
/ 30 октября 2018

Я строю систему с помощью nodejs + express + ejs ... Эта система представляет собой панель графики, и для этого я решил использовать API нового Chartjs 2x ...

Я знаю, как использовать API Chartjs на стороне клиента, и обычно, когда я делаю это, я использую объектно-ориентированный JavaScript с es6 ...

В чем проблема?

Поскольку я использую API для генерации графики, я не знаю количество графики и намного меньше информации о ней (пока все хорошо), однако, поскольку я пытаюсь использовать nodejs, мне бы хотелось Я знаю лучший вариант для меня, чтобы генерировать эти динамические графики и случайно на стороне сервера, прямо к клиенту.

Мой вопрос касается генерации и вставки графики в EJS и главным образом манипуляции с определенной графикой.

Пример функции:

class GraphBar extends Graph {
    constructor(id){
        super(id, 'bar');
    }

    /** @description: MANIPULAÇÃO DE DADOS NO GRÁFICO */
    set data(value) { this.value = value; }
    get data(     ) { return this.value;  }

    addData(){
        return {
            labels:              super.graphLabels,
            datasets: [{
                label:           super.graphLabel,
                data:            super.graphData,
                backgroundColor: super.graphBgColors,
                borderColor:     super.graphBorderColors,
                borderWidth:     1
            }]
        };
    }

    addOptions(){
        return {
            legend: {
                display: false
            },
            scales: {
                yAxes: [{
                    display: false,
                    ticks: {
                        fontColor: "white",
                        beginAtZero:true
                    },
                    gridLines: {
                        display:    false,
                        drawBorder: false
                    }
                }],
                xAxes: [{
                    display: true,
                    ticks: {
                        fontColor: "white",
                        beginAtZero: true,
                        display: false
                    },
                    gridLines: {
                        display:    false,
                        drawBorder: false
                    }
                }]
            },
        }
    }

    //NÚCLEOS DE PLUGINS DA API DO GRÁFICO
    /** @description: APÓS O DESENHO DO DATASETS NO GRÁFICO */
    afterDatasetDraw(){
        return {
            afterDatasetDraw: chartInstance => this.showValueOnTopBar(chartInstance)
        }
    }

    /** @description: ANTES DE RENDERIZAR O GRÁFICO */
    beforeRender(){
        return {
            beforeRender: chartInstance => this.showBarZeroValue(chartInstance)
        }
    }

    //PLUGINS
    /** @description: INSERE OS VALORES EM CIMA DO GRÁFICO */
    showValueOnTopBar(chartInstance){ 
        if(chartInstance !== undefined){
            super.graphChangeFontStyleOnTopGraph(chartInstance, Chart.defaults.global.defaultFontFamily, '15', 'white', 'bold', 'center', 'bottom');

            Chart.helpers.each(this.data.datasets.forEach((dataset, indexDataset) => {
                Chart.helpers.each(chartInstance.getDatasetMeta(indexDataset).data.forEach((data, indexData) => {
                    const graphCenterPoint = data.getCenterPoint();
                    chartInstance.ctx.fillText(dataset.data[indexData], graphCenterPoint.x, graphCenterPoint.y);
                }), this);
            }), this);
        }
    }

    /** @description: ALTERA O TAMANHO DAS BARRAS NO GRÁFICO, DE VALORES ENTRE 0 ~ -0.3 */
    showBarZeroValue(chartInstance){
        Chart.helpers.each(this.data.datasets.forEach((datasets, indexDataset) => {
            Chart.helpers.each(chartInstance.getDatasetMeta(indexDataset).data.forEach((data, indexData) => {
                const graphValue = datasets.data[indexData];

                if(graphValue <= 0 && graphValue >= -0.3) {
                    const graphMeta  = datasets._meta[0];
                    const graphModel = graphMeta.data[indexData]._model;

                    (graphValue >= -0.1) ? graphModel.y = (graphModel.base - 10) : graphModel.y = (graphModel.base + 10);
                }
            }), this);
        }), this);
    }    
}

Пример контроллера:

module.exports.home = (app, req, res) => {
    res.render('home/view', {
        data: {
            general: {
              titlePage:           'TELA 1',
              titleNavbar:         'ANALYTICAL PANEL',
              mainIndicatorValue:  '0 m²',
              mainPercentageValue: '-100%',
            }
        },
        check: {
            general: { 
                hasHomePage:              true, 
                hasShoppingPage:          false, 
                hasShopkeeperPage:        false, 
                hasShopkeeperDetailPage:  false,
                hasShopkeeperComparePage: false
            },
            api:{ 
                hasConsuptionApi: false,
                hasApiError:      false
            }
        }
    });
}

module.exports.homeConsumeApi = (app, req, res) => {
    const apiDAO = new app.models.DAO.api(req, res);
          apiDAO.getResponseAxios().then ( response => {
              res.render('home/view', {
                  data: {
                      general: {
                          titlePage: 'TELA 1',
                          titleNavbar: 'ANALYTICAL PANEL'
                      },
                      api: { apiResponse: response.data }
                  },
                  check: {
                      general: {
                          hasHomePage:              true,
                          hasShoppingPage:          false,
                          hasShopkeeperPage:        false,
                          hasShopkeeperDetailPage:  false,
                          hasShopkeeperComparePage: false
                      },
                      api: {
                          hasConsuptionApi: true,
                          hasApiError:      false
                      }
                  }
                });
            }).catch (error => {
                res.render('home/view', {
                    data: {
                        general: { 
                            titlePage:   'TELA 1', 
                            titleNavbar: 'ANALYTICAL PANEL' 
                        },
                        apiErrorMsg: { 
                            Status:     error.response.status, 
                            StatusText: error.response.statusText 
                        }
                    },
                    check: {
                        general: {
                            hasHomePage:              true,
                            hasShoppingPage:          false,
                            hasShopkeeperPage:        false,
                            hasShopkeeperDetailPage:  false,
                            hasShopkeeperComparePage: false
                        },
                        api: {
                            hasConsuptionApi: true,
                            hasApiError:      true
                        }
                    }
                  });
            });    
}
...