You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vaadin 24+SpringBoot项目中集成ApexCharts.js并动态传参

Vaadin 24 + SpringBoot 集成ApexCharts 实现动态数据传递

1. 放置ApexCharts资源文件

将apexcharts.min.css和apexcharts.min.js放到Vaadin项目的frontend/resources/apexcharts/目录下(无此目录则新建),确保前端能正常访问资源。

2. 创建Java自定义Chart组件

新建继承自Div的Java类,封装ApexCharts饼图组件,通过Vaadin的JS通信机制实现Java到前端的数据传递:

import com.vaadin.flow.component.AttachEvent;
import com.vaadin.flow.component.Div;
import com.vaadin.flow.component.dependency.CssImport;
import com.vaadin.flow.component.dependency.JsModule;
import elemental.json.JsonArray;
import elemental.json.Json;

@CssImport("./resources/apexcharts/apexcharts.min.css")
@JsModule("./resources/apexcharts/apexcharts.min.js")
@JsModule("./apex-pie-chart.js") // 关联前端JS模块
public class ApexPieChart extends Div {

    private JsonArray series;
    private JsonArray labels;

    public ApexPieChart() {
        setId("chart-container");
        getElement().setAttribute("aria-label", "Apex Pie Chart");
    }

    @Override
    protected void onAttach(AttachEvent attachEvent) {
        super.onAttach(attachEvent);
        updateChart();
    }

    // 设置数据系列
    public void setSeries(int[] seriesData) {
        this.series = Json.createArray();
        for (int i = 0; i < seriesData.length; i++) {
            this.series.set(i, seriesData[i]);
        }
        updateChart();
    }

    // 设置标签
    public void setLabels(String[] labelData) {
        this.labels = Json.createArray();
        for (int i = 0; i < labelData.length; i++) {
            this.labels.set(i, labelData[i]);
        }
        updateChart();
    }

    // 通知前端更新图表
    private void updateChart() {
        if (series == null || labels == null) {
            return;
        }
        getElement().callJsFunction("updateChart", series, labels);
    }
}

3. 编写前端JS模块(apex-pie-chart.js)

在frontend/目录下新建apex-pie-chart.js,封装图表初始化与更新逻辑,接收Java端传递的数据:

// 给Vaadin的Div元素扩展updateChart方法,对应Java端的callJsFunction
customElements.whenDefined('vaadin-div').then(() => {
    const DivElement = customElements.get('vaadin-div');
    DivElement.prototype.updateChart = function(series, labels) {
        // 销毁旧图表实例,避免重复渲染
        if (this.chartInstance) {
            this.chartInstance.destroy();
        }

        const options = {
            series: series,
            chart: {
                width: 380,
                type: 'pie',
            },
            labels: labels,
            responsive: [{
                breakpoint: 480,
                options: {
                    chart: {
                        width: 200
                    },
                    legend: {
                        position: 'bottom'
                    }
                }
            }]
        };

        // 初始化并渲染新图表
        this.chartInstance = new ApexCharts(this, options);
        this.chartInstance.render();
    };
});

4. 绑定数据库动态数据

在View类中注入数据服务,从数据库查询数据并传递给图表组件:

import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;
import org.springframework.beans.factory.annotation.Autowired;

@Route("chart") // 访问/chart路径查看图表
public class ChartView extends VerticalLayout {

    @Autowired
    private TeamDataService teamDataService; // 自定义的数据库数据服务类

    public ChartView() {
        ApexPieChart pieChart = new ApexPieChart();
        
        // 从数据库获取动态数据
        int[] series = teamDataService.getTeamSeries();
        String[] labels = teamDataService.getTeamLabels();
        
        pieChart.setSeries(series);
        pieChart.setLabels(labels);
        
        add(pieChart);
        setAlignItems(Alignment.CENTER);
    }
}

关键注意事项

  • 资源路径要匹配:Vaadin 24会自动映射frontend/下的资源,确保@CssImport和@JsModule的路径与文件存放位置一致。
  • 更新图表时必须销毁旧实例,避免内存泄漏和渲染异常。
  • 若需实时刷新数据,只需在Java端重新调用setSeries和setLabels方法,组件会自动触发前端更新。

内容的提问来源于stack exchange,提问作者Abdalrazag Al-Shrufat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 01:35:19