首页 > 解决方案 > 如何使用 Chartjs + Nodejs + Express + Api 消耗在服务器端实时生成图表?

问题描述

我正在用 nodejs + express + ejs 构建一个系统......这个系统是一个图形面板,为此我选择使用新 Chartjs 2x 的 api......

我知道在客户端使用 Chartjs api,通常当我这样做时,我使用面向对象的 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
                        }
                    }
                  });
            });    
}

标签: node.jsexpresschart.jschartjs-2.6.0

解决方案


推荐阅读