核心实体类设计
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]()