springboot集成echarts显示图表

news/2025/10/20 17:17:37/文章来源:https://www.cnblogs.com/yumeixiaosheng/p/19153152

核心实体类设计

1.统一返回结果类 (Result.java)
import lombok.Data;@Data
public class Result<T> {private boolean success;private String message;private T data;public static <T> Result<T> success(T data) {Result<T> result = new Result<>();result.setSuccess(true);result.setData(data);return result;}public static <T> Result<T> error(String message) {Result<T> result = new Result<>();result.setSuccess(false);result.setMessage(message);return result;}
}2.图表数据实体 (ChartData.java)
import lombok.Data;import java.io.Serializable;
import java.util.List;@Data
public class ChartData implements Serializable {/*** 图表标题*/private String title;/*** X轴分类数据*/private List<String> categories;/*** 系列数据*/private List<SeriesConfig> series;
}3.系列配置实体 (SeriesConfig.java)import lombok.Data;import java.util.ArrayList;
import java.util.List;@Data
public class SeriesConfig {/*** 系列名称*/private String name;/*** 图表类型:line, bar, pie, scatter等*/private String type;/*** 普通数据值 - 用于line, bar, pie等图表*/private List<Object> data;/*** 散点图专用数据 - 用于scatter图表* 格式:List<Object[]> 其中每个Object[]包含[x, y]坐标*/private List<Object[]> scatterData;/*** 颜色*/private String color;/*** 是否为面积图*/private boolean areaStyle = false;/*** 堆叠标识*/private String stack;/*** 获取实际数据 - 根据图表类型返回对应的数据*/public List<Object> getActualData() {if ("scatter".equals(type) && scatterData != null) {// 散点图数据需要转换为ECharts格式List<Object> result = new ArrayList<>();for (Object[] point : scatterData) {if (point.length >= 2) {result.add(new Object[]{point[0], point[1]});}}return result;}return data;}}
4.图表数据构建工具 (ChartUtil.java)
import org.example.flowable.entity.ChartData;
import org.example.flowable.entity.SeriesConfig;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;/*** 图表数据构建工具类* 提供各种图表类型的数据构建方法*/
public class ChartUtil {/*** 构建通用图表数据* @param title 图表标题* @param categories X轴分类数据* @param seriesConfigs 系列配置列表* @return ChartData*/public static ChartData buildChartData(String title, List<String> categories, List<SeriesConfig> seriesConfigs) {ChartData chartData = new ChartData();chartData.setTitle(title);chartData.setCategories(categories);chartData.setSeries(seriesConfigs);return chartData;}/*** 构建趋势图数据(折线图)* @param title 图表标题* @param categories X轴分类数据* @param seriesDataMap 系列数据映射 (系列名 -> 数据列表)* @return ChartData*/public static ChartData buildTrendChart(String title, List<String> categories,Map<String, List<Object>> seriesDataMap) {List<SeriesConfig> configs = new ArrayList<>();seriesDataMap.forEach((name, data) -> {SeriesConfig config = new SeriesConfig();config.setName(name);config.setType("line");config.setData(data);configs.add(config);});return buildChartData(title, categories, configs);}/*** 构建柱状图数据* @param title 图表标题* @param categories X轴分类数据* @param seriesDataMap 系列数据映射 (系列名 -> 数据列表)* @return ChartData*/public static ChartData buildBarChart(String title, List<String> categories,Map<String, List<Object>> seriesDataMap) {List<SeriesConfig> configs = new ArrayList<>();seriesDataMap.forEach((name, data) -> {SeriesConfig config = new SeriesConfig();config.setName(name);config.setType("bar");config.setData(data);configs.add(config);});return buildChartData(title, categories, configs);}/*** 构建饼图数据* @param title 图表标题* @param categories 分类名称列表* @param data 对应的数据值列表* @return ChartData*/public static ChartData buildPieChart(String title, List<String> categories, List<Object> data) {List<SeriesConfig> configs = new ArrayList<>();SeriesConfig config = new SeriesConfig();config.setName(title);config.setType("pie");config.setData(data);configs.add(config);return buildChartData(title, categories, configs);}/*** 构建面积图数据* @param title 图表标题* @param categories X轴分类数据* @param seriesDataMap 系列数据映射* @return ChartData*/public static ChartData buildAreaChart(String title, List<String> categories,Map<String, List<Object>> seriesDataMap) {List<SeriesConfig> configs = new ArrayList<>();seriesDataMap.forEach((name, data) -> {SeriesConfig config = new SeriesConfig();config.setName(name);config.setType("line");config.setData(data);config.setAreaStyle(true); // 标记为面积图configs.add(config);});return buildChartData(title, categories, configs);}/*** 构建散点图数据* @param title 图表标题* @param seriesDataMap 系列数据映射 (系列名 -> 散点数据列表)* @return ChartData*/public static ChartData buildScatterChart(String title, Map<String, List<Object[]>> seriesDataMap) {List<SeriesConfig> configs = new ArrayList<>();seriesDataMap.forEach((name, data) -> {SeriesConfig config = new SeriesConfig();config.setName(name);config.setType("scatter");config.setScatterData(data);configs.add(config);});return buildChartData(title, new ArrayList<>(), configs);}/*** 快速构建单系列图表* @param title 图表标题* @param categories X轴分类数据* @param seriesName 系列名称* @param seriesType 系列类型 (line, bar, pie等)* @param data 数据列表* @return ChartData*/public static ChartData buildSingleSeriesChart(String title, List<String> categories,String seriesName, String seriesType, List<Object> data) {SeriesConfig config = new SeriesConfig();config.setName(seriesName);config.setType(seriesType);config.setData(data);return buildChartData(title, categories, Arrays.asList(config));}/*** 构建堆叠柱状图* @param title 图表标题* @param categories X轴分类数据* @param seriesDataMap 系列数据映射* @param stackName 堆叠名称* @return ChartData*/public static ChartData buildStackedBarChart(String title, List<String> categories,Map<String, List<Object>> seriesDataMap, String stackName) {List<SeriesConfig> configs = new ArrayList<>();seriesDataMap.forEach((name, data) -> {SeriesConfig config = new SeriesConfig();config.setName(name);config.setType("bar");config.setData(data);config.setStack(stackName);configs.add(config);});return buildChartData(title, categories, configs);}/*** 构建堆叠面积图* @param title 图表标题* @param categories X轴分类数据* @param seriesDataMap 系列数据映射* @param stackName 堆叠名称* @return ChartData*/public static ChartData buildStackedAreaChart(String title, List<String> categories,Map<String, List<Object>> seriesDataMap, String stackName) {List<SeriesConfig> configs = new ArrayList<>();seriesDataMap.forEach((name, data) -> {SeriesConfig config = new SeriesConfig();config.setName(name);config.setType("line");config.setData(data);config.setAreaStyle(true);config.setStack(stackName);configs.add(config);});return buildChartData(title, categories, configs);}/*** 构建雷达图数据* @param title 图表标题* @param indicators 雷达图指标* @param seriesDataMap 系列数据映射* @return ChartData*/public static ChartData buildRadarChart(String title, List<String> indicators,Map<String, List<Object>> seriesDataMap) {List<SeriesConfig> configs = new ArrayList<>();seriesDataMap.forEach((name, data) -> {SeriesConfig config = new SeriesConfig();config.setName(name);config.setType("radar");config.setData(data);configs.add(config);});return buildChartData(title, indicators, configs);}/*** 构建仪表盘数据* @param title 图表标题* @param seriesName 系列名称* @param value 数值* @param max 最大值* @return ChartData*/public static ChartData buildGaugeChart(String title, String seriesName, Object value, Object max) {List<SeriesConfig> configs = new ArrayList<>();SeriesConfig config = new SeriesConfig();config.setName(seriesName);config.setType("gauge");config.setData(Arrays.asList(value));configs.add(config);return buildChartData(title, new ArrayList<>(), configs);}
}

图表数据控制器

import lombok.extern.slf4j.Slf4j;
import org.example.flowable.common.Result;
import org.example.flowable.entity.ChartData;
import org.example.flowable.entity.SeriesConfig;
import org.example.flowable.utils.ChartUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.*;@RestController
@RequestMapping("/api/chart")
@Slf4j
public class ChartController {@GetMapping("/trend")public Result<ChartData> getTrendData() {try {String title = "流程处理效率趋势图";List<String> categories = Arrays.asList("2024-01-01", "2024-01-02", "2024-01-03", "2024-01-04","2024-01-05", "2024-01-06", "2024-01-07", "2024-01-08");Map<String, List<Object>> seriesDataMap = new HashMap<>();seriesDataMap.put("处理效率", Arrays.asList(65, 68, 72, 70, 75, 78, 80, 82));seriesDataMap.put("处理数量", Arrays.asList(120, 135, 150, 140, 160, 170, 180, 185));ChartData chartData = ChartUtil.buildTrendChart(title, categories, seriesDataMap);return Result.success(chartData);} catch (Exception e) {return Result.error("获取趋势图数据失败");}}@GetMapping("/stats")public Result<ChartData> getStatsData() {try {String title = "流程实例统计";List<String> categories = Arrays.asList("进行中", "已完成", "已暂停", "已取消");Map<String, List<Object>> seriesDataMap = new HashMap<>();seriesDataMap.put("流程数量", Arrays.asList(45, 120, 30, 15));ChartData chartData = ChartUtil.buildBarChart(title, categories, seriesDataMap);return Result.success(chartData);} catch (Exception e) {return Result.error("获取统计图数据失败");}}@GetMapping("/user-activity")public Result<ChartData> getUserActivityData() {try {String title = "用户活跃度统计";List<String> categories = Arrays.asList("周一", "周二", "周三", "周四", "周五", "周六", "周日");Map<String, List<Object>> seriesDataMap = new HashMap<>();seriesDataMap.put("活跃用户", Arrays.asList(120, 132, 101, 134, 90, 230, 210));seriesDataMap.put("新增用户", Arrays.asList(20, 25, 18, 30, 15, 45, 35));ChartData chartData = ChartUtil.buildTrendChart(title, categories, seriesDataMap);return Result.success(chartData);} catch (Exception e) {return Result.error("获取用户活跃度数据失败");}}@GetMapping("/task-completion")public Result<ChartData> getTaskCompletionData() {try {String title = "任务完成率";List<String> categories = Arrays.asList("已完成", "进行中", "待处理", "已取消");List<Object> data = Arrays.asList(65, 20, 10, 5);ChartData chartData = ChartUtil.buildPieChart(title, categories, data);return Result.success(chartData);} catch (Exception e) {return Result.error("获取任务完成率数据失败");}}@GetMapping("/sales-trend")public Result<ChartData> getSalesTrendData() {try {String title = "销售趋势分析";List<String> categories = Arrays.asList("Q1", "Q2", "Q3", "Q4");Map<String, List<Object>> seriesDataMap = new HashMap<>();seriesDataMap.put("产品A", Arrays.asList(100, 120, 150, 180));seriesDataMap.put("产品B", Arrays.asList(80, 90, 110, 130));ChartData chartData = ChartUtil.buildBarChart(title, categories, seriesDataMap);return Result.success(chartData);} catch (Exception e) {return Result.error("获取销售趋势数据失败");}}@GetMapping("/area-chart")public Result<ChartData> getAreaChartData() {try {String title = "销售面积图";List<String> categories = Arrays.asList("1月", "2月", "3月", "4月", "5月", "6月");Map<String, List<Object>> seriesDataMap = new HashMap<>();seriesDataMap.put("销售额", Arrays.asList(120, 150, 180, 200, 220, 250));seriesDataMap.put("利润", Arrays.asList(30, 40, 50, 60, 70, 80));ChartData chartData = ChartUtil.buildAreaChart(title, categories, seriesDataMap);return Result.success(chartData);} catch (Exception e) {return Result.error("获取面积图数据失败");}}@GetMapping("/scatter")public Result<ChartData> getScatterData() {try {String title = "用户行为分析";Map<String, List<Object[]>> seriesDataMap = new HashMap<>();// 用户A的行为数据 [x, y] 坐标List<Object[]> userAData = Arrays.asList(new Object[]{10, 20},new Object[]{15, 25},new Object[]{20, 30},new Object[]{25, 35});seriesDataMap.put("用户A", userAData);// 用户B的行为数据List<Object[]> userBData = Arrays.asList(new Object[]{12, 18},new Object[]{18, 28},new Object[]{22, 32},new Object[]{28, 38});seriesDataMap.put("用户B", userBData);ChartData chartData = ChartUtil.buildScatterChart(title, seriesDataMap);return Result.success(chartData);} catch (Exception e) {return Result.error("获取散点图数据失败");}}@GetMapping("/stacked-bar")public Result<ChartData> getStackedBarData() {try {String title = "部门业绩统计";List<String> categories = Arrays.asList("Q1", "Q2", "Q3", "Q4");Map<String, List<Object>> seriesDataMap = new HashMap<>();seriesDataMap.put("销售部", Arrays.asList(100, 120, 150, 180));seriesDataMap.put("技术部", Arrays.asList(80, 90, 110, 130));seriesDataMap.put("市场部", Arrays.asList(60, 70, 80, 90));ChartData chartData = ChartUtil.buildStackedBarChart(title, categories, seriesDataMap, "部门业绩");log.info("堆叠柱状图数据构建完成");return Result.success(chartData);} catch (Exception e) {log.error("获取堆叠柱状图数据失败", e);return Result.error("获取堆叠柱状图数据失败");}}@GetMapping("/radar")public Result<ChartData> getRadarData() {try {String title = "员工能力评估";List<String> indicators = Arrays.asList("技术能力", "沟通能力", "学习能力", "创新能力", "团队协作", "执行力");Map<String, List<Object>> seriesDataMap = new HashMap<>();seriesDataMap.put("张三", Arrays.asList(85, 90, 80, 75, 88, 82));seriesDataMap.put("李四", Arrays.asList(78, 85, 90, 88, 80, 85));seriesDataMap.put("王五", Arrays.asList(92, 75, 85, 90, 85, 88));ChartData chartData = ChartUtil.buildRadarChart(title, indicators, seriesDataMap);return Result.success(chartData);} catch (Exception e) {return Result.error("获取雷达图数据失败");}}@GetMapping("/gauge")public Result<ChartData> getGaugeData() {try {String title = "系统性能监控";String seriesName = "CPU使用率";Object value = 75; // 当前值Object max = 100;  // 最大值ChartData chartData = ChartUtil.buildGaugeChart(title, seriesName, value, max);return Result.success(chartData);} catch (Exception e) {return Result.error("获取仪表盘数据失败");}}@GetMapping("/multi-gauge")public Result<ChartData> getMultiGaugeData() {try {String title = "系统监控面板";// 构建多个仪表盘数据List<SeriesConfig> configs = new ArrayList<>();// CPU使用率SeriesConfig cpuConfig = new SeriesConfig();cpuConfig.setName("CPU使用率");cpuConfig.setType("gauge");cpuConfig.setData(Arrays.asList(75));configs.add(cpuConfig);// 内存使用率SeriesConfig memoryConfig = new SeriesConfig();memoryConfig.setName("内存使用率");memoryConfig.setType("gauge");memoryConfig.setData(Arrays.asList(60));configs.add(memoryConfig);// 磁盘使用率SeriesConfig diskConfig = new SeriesConfig();diskConfig.setName("磁盘使用率");diskConfig.setType("gauge");diskConfig.setData(Arrays.asList(45));configs.add(diskConfig);ChartData chartData = ChartUtil.buildChartData(title, new ArrayList<>(), configs);return Result.success(chartData);} catch (Exception e) {return Result.error("获取多仪表盘数据失败");}}
}

前端图表组件

1.ChartComponent.vue
<template><div class="chart-container"><div class="chart-header"><h3>{{ chartTitle }}</h3><div class="chart-controls"><button @click="refreshChart" class="btn-refresh">刷新数据</button><select v-model="selectedChartType" @change="switchChartType"><option value="trend">折线图</option><option value="stats">单柱状图</option>
<!--          <option value="user-activity">用户活跃度</option>--><option value="task-completion">饼图</option><option value="sales-trend">双柱状图</option><option value="area-chart">面积图</option><option value="scatter">散点图</option><option value="stacked-bar">堆叠柱状图</option><option value="radar">雷达图</option><option value="gauge">仪表盘</option><option value="multi-gauge">多仪表盘</option></select></div></div><div ref="chartContainer" class="chart-content"></div><div class="data-explanation"><h4>数据说明:</h4><ul><li><strong>数据来源:</strong>后端ChartController接口</li><li><strong>连接方式:</strong>前端通过axios调用/api/chart接口</li><li><strong>数据处理:</strong>获取JSON数据后转换为ECharts配置</li><li><strong>渲染方式:</strong>使用ECharts库渲染图表</li><li><strong>数据更新:</strong>支持实时刷新和图表类型切换</li><li><strong>交互功能:</strong>点击图例可切换线条显示/隐藏</li></ul></div></div>
</template><script>
import axios from 'axios'
import * as echarts from 'echarts'export default {name: 'ChartComponent',data() {return {selectedChartType: 'trend',chartTitle: '流程处理效率趋势图',apiEndpoints: {trend: '/api/chart/trend',stats: '/api/chart/stats','user-activity': '/api/chart/user-activity','task-completion': '/api/chart/task-completion','sales-trend': '/api/chart/sales-trend','area-chart': '/api/chart/area-chart',scatter: '/api/chart/scatter','stacked-bar': '/api/chart/stacked-bar',radar: '/api/chart/radar',gauge: '/api/chart/gauge','multi-gauge': '/api/chart/multi-gauge'}}},mounted() {this.$nextTick(() => {this.initChart()// 改为调用真实接口this.loadChartData()})},beforeUnmount() {if (this.chartInstance) {this.chartInstance.dispose()}},methods: {initChart() {if (this.$refs.chartContainer) {this.chartInstance = echarts.init(this.$refs.chartContainer)// 添加窗口大小变化监听window.addEventListener('resize', () => {if (this.chartInstance) {this.chartInstance.resize()}})}},// 调用真实接口获取数据async loadChartData() {try {console.log(`正在请求接口: ${this.apiEndpoints[this.selectedChartType]}`)const response = await axios.get(this.apiEndpoints[this.selectedChartType])// console.log('接口响应:', response.data)if (response.data.success) {const chartData = response.data.datathis.chartTitle = chartData.title || '图表'console.log('接收到的图表数据:', chartData)// 验证数据完整性if (this.validateChartData(chartData)) {// 构建ECharts配置const option = this.buildEChartsOption(chartData)console.log('ECharts配置:', option)if (this.chartInstance) {this.chartInstance.clear()this.chartInstance.setOption(option, true)console.log('图表渲染成功')}} else {console.error('数据验证失败,使用默认数据')this.loadDefaultData()}} else {console.error('获取图表数据失败:', response.data.message)this.loadDefaultData()}} catch (error) {console.error('请求图表数据出错:', error)console.log('使用默认数据作为备用')this.loadDefaultData()}},// 验证图表数据的完整性validateChartData(chartData) {if (!chartData) {console.error('chartData为空')return false}if (!chartData.series || !Array.isArray(chartData.series)) {console.error('series数据无效')return false}// 检查每个series是否有效for (let i = 0; i < chartData.series.length; i++) {const series = chartData.series[i]if (!series || typeof series !== 'object') {console.error(`series[${i}]为空或不是对象`)return false}if (!series.name || !series.type) {console.error(`series[${i}]缺少必需字段:`, series)return false}}return true},// 构建ECharts配置buildEChartsOption(chartData) {// console.log('原始数据字段:', Object.keys(chartData))// console.log('series数据:', chartData.series)const option = {title: {text: chartData.title || '图表',left: 'center'},tooltip: {trigger: 'axis'},legend: {data: [],top: 30},grid: {left: '3%',right: '4%',bottom: '3%',containLabel: true},xAxis: {type: 'category',data: chartData.categories || []},yAxis: {type: 'value'},series: []}// 处理series数据if (chartData.series && Array.isArray(chartData.series)) {option.series = chartData.series.map(series=> {const seriesConfig = {name: series.name,type: series.type,data: this.getSeriesData(series),color: series.color || ''}// 面积图特殊处理if (series.areaStyle) {seriesConfig.areaStyle = {}}// 堆叠图特殊处理if (series.stack) {seriesConfig.stack = series.stack}return seriesConfig})// 设置图例数据option.legend.data = option.series.map(s => s.name)}// 特殊处理饼图if (chartData.series && chartData.series.length > 0 && chartData.series[0].type === 'pie') {const pieData = chartData.categories.map((name, index) => ({name: name,value: this.getSeriesData(chartData.series[0])[index]}))option.series[0] = {name: chartData.series[0].name,type: 'pie',radius: ['40%', '70%'], // 环形饼图center: ['50%', '60%'], // 饼图位置data: pieData,emphasis: {itemStyle: {shadowBlur: 10,shadowOffsetX: 0,shadowColor: 'rgba(0, 0, 0, 0.5)'},label: {show: true,fontSize: '16',fontWeight: 'bold'}},label: {show: true,formatter: '{b}: {c} ({d}%)', // 显示名称、数值和百分比fontSize: 12},labelLine: {show: true},itemStyle: {borderRadius: 8, // 圆角borderColor: '#fff',borderWidth: 2}}// 饼图专用tooltip配置option.tooltip = {trigger: 'item',formatter: '{a} <br/>{b}: {c} ({d}%)',backgroundColor: 'rgba(0,0,0,0.8)',borderColor: '#ccc',borderWidth: 1,textStyle: {color: '#fff'}}// 饼图专用legend配置option.legend = {orient: 'vertical',left: 'left',top: 'center',data: chartData.categories,textStyle: {fontSize: 12}}// 饼图不需要x轴和y轴delete option.xAxisdelete option.yAxisdelete option.grid}// 特殊处理雷达图if (chartData.series && chartData.series.length > 0 && chartData.series[0].type === 'radar') {const indicators = (chartData.categories || []).map(name => ({ name, max: 100 }))option.radar = {indicator: indicators,center: ['50%', '58%'],   radius: '56%',            splitNumber: 5,shape: 'polygon',axisName: { color: '#666', fontSize: 11, padding: [1, 3] },axisLine: { lineStyle: { color: 'rgba(0,0,0,0.14)' } },splitLine: { lineStyle: { color: 'rgba(0,0,0,0.10)' } },splitArea: { areaStyle: { color: ['rgba(24,144,255,0.03)','rgba(24,144,255,0.05)'] } }}const colors = ['#5470C6','#91CC75','#FAC858','#EE6666','#73C0DE']option.series = chartData.series.map((s, i) => {const color = s.color || colors[i % colors.length]return {name: s.name,type: 'radar',symbol: 'circle',symbolSize: 4,         lineStyle: { width: 2, color },itemStyle: { color },areaStyle: { color, opacity: 0.15 }, emphasis: { focus: 'series', lineStyle: { width: 3 } },data: [{ value: this.getSeriesData(s), name: s.name }]}})option.legend = {top: 34,left: 'center',icon: 'circle',itemWidth: 8,itemHeight: 8,itemGap: 14,textStyle: { fontSize: 12 },data: chartData.series.map(s => s.name)}option.tooltip = {trigger: 'item',confine: true,formatter: (p) => {const vals = p.value || []return `${p.seriesName}<br/>` + (chartData.categories || []).map((n, i) => `${n}:${vals[i] ?? '-'}`).join('<br/>')}}delete option.xAxisdelete option.yAxisdelete option.grid}// 特殊处理仪表盘if (chartData.series && chartData.series.length > 0 && chartData.series[0].type === 'gauge') {if (chartData.series.length === 1) {// 单仪表盘const value = this.getSeriesData(chartData.series[0])[0]option.series = [{name: chartData.series[0].name,type: 'gauge',center: ['50%', '60%'],radius: '80%',min: 0,max: 100,splitNumber: 10,axisLine: {lineStyle: {width: 8,color: [[0.3, '#67e0e3'],[0.7, '#37a2da'],[1, '#fd666d']]}},pointer: {itemStyle: {color: 'auto'}},axisTick: {distance: -30,splitNumber: 5,lineStyle: {width: 2,color: '#999'}},splitLine: {distance: -30,length: 30,lineStyle: {width: 4,color: '#999'}},axisLabel: {color: 'auto',distance: 40,fontSize: 12},detail: {valueAnimation: true,formatter: '{value}%',color: 'auto',fontSize: 20,offsetCenter: [0, '70%']},data: [{value: value,name: chartData.series[0].name}]}]} else {// 多仪表盘option.series = chartData.series.map((series, index) => {const value = this.getSeriesData(series)[0]const centerX = 25 + (index % 2) * 50const centerY = 30 + Math.floor(index / 2) * 60return {name: series.name,type: 'gauge',center: [centerX + '%', centerY + '%'],radius: '30%',min: 0,max: 100,splitNumber: 5,axisLine: {lineStyle: {width: 4,color: [[0.3, '#67e0e3'],[0.7, '#37a2da'],[1, '#fd666d']]}},pointer: {itemStyle: {color: 'auto'}},axisTick: {distance: -15,splitNumber: 5,lineStyle: {width: 1,color: '#999'}},splitLine: {distance: -15,length: 15,lineStyle: {width: 2,color: '#999'}},axisLabel: {color: 'auto',distance: 20,fontSize: 10},detail: {valueAnimation: true,formatter: '{value}%',color: 'auto',fontSize: 14,offsetCenter: [0, '60%']},data: [{value: value,name: series.name}]}})}option.tooltip = {trigger: 'item',formatter: '{a} <br/>{b}: {c}%'}delete option.xAxisdelete option.yAxisdelete option.griddelete option.legend}// 特殊处理散点图if (chartData.series && chartData.series.length > 0 && chartData.series[0].type === 'scatter') {// 散点图不需要x轴分类option.xAxis.type = 'value'delete option.xAxis.data}return option},// 获取系列数据getSeriesData(series) {if(series.type==='scatter' && series.scatterData){// 散点图数据格式转化return series.scatterData.map(point => [point[0], point[1]])}return series.data || []},// 保留默认数据作为备用loadDefaultData() {const option = {title: {text: '暂无数据',left: 'center'},series: [{type: 'line',data: []}]}if (this.chartInstance) {this.chartInstance.clear()this.chartInstance.setOption(option, true)}},// 刷新图表数据refreshChart() {console.log('刷新图表数据')this.loadChartData()},// 切换图表类型switchChartType() {console.log(`切换图表类型为: ${this.selectedChartType}`)this.loadChartData()}}
}
</script><style scoped>
.chart-container {padding: 20px;background: #fff;border-radius: 8px;box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}.chart-header {display: flex;justify-content: space-between;align-items: center;margin-bottom: 20px;padding-bottom: 15px;border-bottom: 1px solid #eee;
}.chart-header h3 {margin: 0;color: #333;
}.chart-controls {display: flex;gap: 10px;align-items: center;
}.btn-refresh {padding: 8px 16px;background: #1890ff;color: white;border: none;border-radius: 4px;cursor: pointer;transition: background 0.3s;
}.btn-refresh:hover {background: #40a9ff;
}select {padding: 8px 12px;border: 1px solid #d9d9d9;border-radius: 4px;background: white;
}.chart-content {width: 100%;height: 400px;margin-bottom: 20px;
}.data-explanation {background: #f5f5f5;padding: 15px;border-radius: 4px;border-left: 4px solid #1890ff;
}.data-explanation h4 {margin: 0 0 10px 0;color: #333;
}.data-explanation ul {margin: 0;padding-left: 20px;
}.data-explanation li {margin-bottom: 5px;color: #666;line-height: 1.5;
}
</style>2.页面引入组件
<!-- Dashboard.vue -->
<template><div class="dashboard"><h1>流程管理仪表板</h1><!-- 图表组件 --><ChartComponent /><!-- 其他仪表板内容 --><div class="dashboard-grid"><div class="card"><h3>流程概览</h3><p>当前运行中的流程实例数量</p></div><div class="card"><h3>任务统计</h3><p>待处理任务数量</p></div></div></div>
</template><script>
import ChartComponent from '@/components/ChartComponent.vue'export default {name: 'Dashboard',components: {ChartComponent}
}
</script><style scoped>
.dashboard {padding: 20px;
}.dashboard-grid {display: grid;grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));gap: 20px;margin-top: 20px;
}.card {background: white;padding: 20px;border-radius: 8px;box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
</style>

页面效果图

image
image
image
image
image
image
image
image
image
image

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/941403.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年储罐厂家权威推荐榜:钢衬塑储罐/钢塑复合储罐/化工储罐/防腐储罐/PE储罐/盐酸储罐/硫酸储罐/聚丙烯储罐/不锈钢储罐/次氯酸钠储罐专业选购指南

2025年储罐厂家权威推荐榜:钢衬塑储罐/钢塑复合储罐/化工储罐/防腐储罐/PE储罐/盐酸储罐/硫酸储罐/聚丙烯储罐/不锈钢储罐/次氯酸钠储罐专业选购指南 在化工、制药、环保等工业领域,储罐作为关键设备,其性能和质量直…

Avalonia使用代码更改滑动条的颜色

由于使用Style更改滑动条样式没生效,遂通过c#代码通过逻辑树获取元素的方式来进行样式修改,以此博客记录。注意点就是目标元素的生成和渲染时间。 AttachedToVisualTree事件在控件​​被添加到视觉树时触发​​,然而…

【SPIE出版】第四届云计算、性能计算与深度学习国际学术会议 (CCPCDL 2025)

CCPCDL 已成功召开三届,第四届会议将继续深耕云计算、性能计算、深度学习等前沿研究领域,助力促进全球范围内的科学创新。【CCPCDL 2025已成功通过 SPIE 出版!ISSN: 0277-786X!】 【往届均由SPIE出版,已见刊检索,…

【IC原厂】VKD104CB 内建稳压电路低电流4路触摸检测IC

VKD104CB是4通道触摸检测芯片,功耗低、工作电压范围宽以及稳定的触摸检测效果可以广泛的满足不同应用的需求,此触摸检测芯片是专为取代传统按键而设计,内建稳压电路,提供稳定电压给触摸检测电路使用,触摸检测PAD的大小…

实用指南:LTU-AS:一种具备音频感知、识别、理解的大模型架构

实用指南:LTU-AS:一种具备音频感知、识别、理解的大模型架构pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Con…

上班摸鱼新姿势!抖音爆火的线稿涂鸦也太治愈了~

最近上班摸鱼圈又有新玩法了—— 不是看剧、不是小游戏,而是刷爆抖音的 【线稿涂鸦图】! 简单几笔,就能让人放空大脑、重启心情,堪称打工人精神续命神器 😂GitHub地址 点击这里🖊 什么是“线稿涂鸦”? 就是一…

Ubuntu材料权限管理指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

n8n错误处理全攻略:构建稳定可靠的自动化工作流

关注 霍格沃兹测试学院公众号,回复「资料」, 领取人工智能测试开发技术合集 在自动化工作流中,错误不是绊脚石,而是构建更健壮系统的指引。掌握n8n错误处理,让您的自动化流程真正具备生产可靠性。 在自动化工作流中…

深入解析:HarmonyOS 应用开发深度解析:ArkTS 状态管理与渲染控制的艺术

深入解析:HarmonyOS 应用开发深度解析:ArkTS 状态管理与渲染控制的艺术pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family:…

【ACM出版】2025年计算机技术、数字媒体与传播国际学术会议(ICCDC 2025)

由西南财经大学天府学院主办的ICCDC 2025将于2025年10月31日至11月2日在成都召开。【ACM出版、IEEEfellow加盟、稳定EI检索】 【西南财经大学天府学院、成都师范学院主办 | 计算机类、数字媒体传播类主题皆可投稿】 20…

版本号搞得鬼!Winsows VSCode 和 Trae 的 Terminal 不识别 conda 环境

问题简述 在 Win 11 系统自带的终端(Powershell)和CMD窗口中,可以正常调用conda,命令行回显: (base) PS C:\Users\DELL>然而,在 VSCode 和 Trae 上无法正确使用 conda 报错为: PS C:\Users\DELL> conda act…

2025年氧化镁厂家最新权威推荐榜:活性氧化镁,肥料级氧化镁,高纯度氧化镁源头厂家深度解析及选购指南

2025年氧化镁厂家最新权威推荐榜:活性氧化镁,肥料级氧化镁,高纯度氧化镁源头厂家深度解析及选购指南 一、行业背景与发展现状 氧化镁作为一种重要的无机化工原料,在工业生产中扮演着不可或缺的角色。随着环保政策的…

客户端使用ceph服务器的块设备

环境:Os:Centos 7[root@master /]# ceph versionceph version 14.2.22 (ca74598065096e6fcbd8433c8779a2be0c889351) nautilus (stable)#############################管理节点上前置事项####################1.在管理…

[随笔11] 最近的心情 - 枝-致

我在想,现在是不是我人生的低谷期? 一边是职业生涯看不到什么发展空间,不太感兴趣,没有什么成就感。 一边是家庭关系紧张,不仅是跟丈夫紧张,还跟他们真个家庭紧张,这种紧张感压得我喘不过气来。我一点都没有回家…

2025年智能照明系统/模块厂家推荐排行榜,工厂/车间/改建/高亮/高光效/泛光/免维护/投光/大功率智能照明系统及模块公司精选

2025年智能照明系统/模块厂家推荐排行榜,工厂/车间/改建/高亮/高光效/泛光/免维护/投光/大功率智能照明系统及模块公司精选 智能照明行业发展趋势分析 随着工业4.0时代的深入发展,智能照明系统正经历着前所未有的技术…

DxO Nik Collection 8.0:7 款专业摄影插件套装,一站式图像后期解决方案

Nik Collection 8.0是由DxO开发的一款功能强大的摄影后期处理插件套装。它包含了Viveza 2、Silver Efex Pro 3、Dfine 2等7款专业插件,能够为用户提供全面的图像后期处理解决方案。该软件的U Point 3.0技术可实现像素…

启动JAVA

目录启动JAVA直接类启动JAR 包启动类路径例子启动方式总结 启动JAVA 直接类启动 # 当你不指定 -cp 时,JVM 使用: java com.example.Main # 等效于:只包含当前目录,不包含其他 JAR! java -cp . com.example.MainJA…

2025年通风天窗厂家最新权威推荐榜:通风天窗,排烟天窗,通风气楼,屋顶通风器,顺坡气楼,10A通风天窗,1型通风天窗,TC5A通风天窗,TC12B通风天窗,屋脊通风天窗专业制造与高效通风解决方案

2025年通风天窗厂家最新权威推荐榜:专业制造与高效通风解决方案 随着工业建筑对通风排烟要求的不断提高,通风天窗、排烟天窗、通风气楼等设备已成为现代工业厂房不可或缺的重要组成部分。这些设备不仅关系到车间的空…

三款AI平台部署实战体验:Dify、扣子与BuildingAI深度对比

最近在为客户选型AI应用平台时,我系统地测试了几款热门的开源解决方案。今天主要从部署体验这个关键维度,分享对 Dify、扣子 和 BuildingAI 的实际使用感受。从一键部署到商业闭环,开发者需要考量的不只是技术参数 …

#OO之接口-DAO模式代码阅读及应用

1.StudenDaoListImpl.java与StudentDaoArrayImpl.java有何不同? 存储底层结构:StudentDaoListImpl基于动态数组存储学生;StudentDaoArrayImpl基于普通数组存储,长度是固定的。 初始化要求:StudentDaoListImpl无需…