| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- <!--
- * @description: ECharts仪表盘组件
- * @features:
- * 1. 可复用:支持在同一页面多次引用
- * 2. 响应式:页面缩放时自动调整大小
- * 3. 可配置:支持自定义各种属性和样式
- * 4. 数据驱动:支持通过props更新数据
- *
- * @example:
- * ```vue
- * <template>
- * <div class="gauge-container">
- * 基本用法
- * <GaugeChart :value="65" title="速度" unit="km/h" />
- *
- * 自定义配置
- * <GaugeChart
- * :value="80"
- * :min="0"
- * :max="100"
- * title="温度"
- * unit="°C"
- * :colors="['#36CFC9', '#FF7D00', '#F5222D']"
- * width="300px"
- * height="300px"
- * />
- * </div>
- * </template>
- *
- * <script>
- * import GaugeChart from '@/views/ledgerAssets/components/details/components/GaugeChart.vue';
- *
- * export default {
- * components: {
- * GaugeChart
- * },
- * data() {
- * return {
- * // 可以通过data属性动态更新图表数据
- * };
- * }
- * };
- * </script>
- * ```
- -->
- <template>
- <l-echart ref="chartRef" :style="{ width:width, height: height }"></l-echart >
- </template>
- <script>
- // import * as echarts from 'echarts';
- import * as echarts from '@/uni_modules/lime-echart/static/echarts.min'
- export default {
- name: 'GaugeChart',
- props: {
- /**
- * 图表宽度
- * @default '100%'
- * @type {string}
- */
- width: {
- type: String,
- default: '100%'
- },
- /**
- * 图表高度
- * @default '300px'
- * @type {string}
- */
- height: {
- type: String,
- default: '300px'
- },
- /**
- * 当前值 - 仪表盘显示的数值
- * @required true
- * @type {number}
- */
- value: {
- type: Number,
- required: true
- },
- /**
- * 最小值 - 仪表盘的最小值范围
- * @default 0
- * @type {number}
- */
- min: {
- type: Number,
- default: 0
- },
- /**
- * 最大值 - 仪表盘的最大值范围
- * @default 100
- * @type {number}
- */
- max: {
- type: Number,
- default: 100
- },
- /**
- * 标题 - 仪表盘的标题文本
- * @default ''
- * @type {string}
- */
- title: {
- type: String,
- default: ''
- },
- /**
- * 单位 - 数值的单位
- * @default ''
- * @type {string}
- */
- unit: {
- type: String,
- default: ''
- },
- /**
- * 颜色配置 - 仪表盘颜色渐变区间
- * 数组长度决定了颜色分段数量
- * @default ['#5470C6', '#91CC75', '#FAC858', '#EE6666']
- * @type {Array<string>}
- */
- colors: {
- type: Array,
- default: () => ['#5470C6', '#5470C6', '#5470C6', '#5470C6']
- },
- /**
- * 分割线数量 - 仪表盘刻度线数量
- * @default 10
- * @type {number}
- */
- splitNumber: {
- type: Number,
- default: 10
- },
- /**
- * 自定义配置 - 直接覆盖ECharts配置项
- * 可以用于高级自定义
- * @default {}
- * @type {Object}
- */
- options: {
- type: Object,
- default: () => ({})
- }
- },
- data() {
- return {
- chartInstance: null
- };
- },
- mounted() {
- this.initChart();
- this.handleResize();
- window.addEventListener('resize', this.handleResize);
- },
- beforeDestroy() {
- window.removeEventListener('resize', this.handleResize);
- if (this.chartInstance) {
- this.chartInstance.dispose();
- }
- },
- watch: {
- value: {
- handler() {
- this.updateChart();
- },
- immediate: false
- },
- min: 'updateChart',
- max: 'updateChart',
- title: 'updateChart',
- unit: 'updateChart',
- colors: {
- handler() {
- this.updateChart();
- },
- deep: true
- },
- splitNumber: 'updateChart',
- options: {
- handler() {
- this.updateChart();
- },
- deep: true
- }
- },
- methods: {
- /**
- * 初始化图表实例
- * 创建ECharts实例并设置初始配置
- * @private
- */
- initChart() {
-
- if (!this.$refs.chartRef) return;
-
- // 创建唯一的实例以支持在同一页面多次引用
- // this.chartInstance = echarts.init(this.$refs.chartRef);
- this.updateChart();
- },
-
- /**
- * 更新图表数据和配置
- * 根据props中的最新数据重新渲染图表
- * @private
- */
- updateChart() {
- // if (!this.chartInstance) return;
-
- const option = {
- // 移除顶部标题,改为在底部显示
- backgroundColor: 'transparent',
- series: [
- {
- name: this.title || '',
- type: 'gauge',
- // startAngle: 180,
- // endAngle: 0,
- min: this.min,
- max: this.max,
- splitNumber: this.splitNumber,
- radius: '90%',
- center: ['50%', '50%'],
- itemStyle: {
- color: '#7a71ff',
- shadowColor: 'rgba(0,138,255,0.45)',
- shadowBlur: 10,
- shadowOffsetX: 2,
- shadowOffsetY: 2,
- borderCap: 'round'
- },
- progress: {
- show: true,
- roundCap: true,
- width: 12,
- itemStyle: {
- color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
- {
- offset: 0,
- color: '#15b4ff'
- },
- {
- offset: 1,
- color: '#716dff'
- }
- ]),
- shadowColor: 'rgba(0,138,255,0.45)',
- shadowBlur: 10,
- shadowOffsetX: 2,
- shadowOffsetY: 2
- }
- },
- // progress: {
- // show: true,
- // width: 15,
- // roundCap: true,
- // },
- // 优化仪表盘轴线样式 - 采用单一蓝色调
- axisLine: {
- lineStyle: {
- width: 12,
- roundCap: true,
- // color: this.calculateColorRanges(),
- // shadowBlur: 10,
- // shadowColor: 'rgba(84, 112, 198, 0.3)'
- }
- },
- // 优化指针样式 - 更细,蓝色
- pointer: {
- show: true,
- width: 5,
- length: '65%',
- itemStyle: {
- color: '#716dff',
- // borderWidth: 1,
- // borderType: 'solid',
- // borderColor: '#333'
- }
- },
- // 优化刻度线 - 更细、更短,分布在弧上
- axisTick: {
- show: false,
- distance: 0,
- length: 6,
- lineStyle: {
- color: '#666',
- width: 1
- }
- },
- // 优化分割线 - 与示例图保持一致
- splitLine: {
- distance: 0,
- length: 8,
- lineStyle: {
- color: '#5470C6',
- width: 2
- }
- },
- // 优化标签位置和样式
- axisLabel: {
- color: '#333',
- distance: 20,
- fontSize: 12,
- fontWeight: 'normal'
- },
- // 优化中心显示内容 - 居中显示数值
- detail: {
- valueAnimation: true,
- formatter: `{value}${this.unit}`,
- color: '#333',
- fontSize: 18,
- fontWeight: 'bold',
- offsetCenter: [0, '40%'],
- borderColor: 'transparent'
- },
- // 添加单位显示
- title: {
- offsetCenter: [0, '65%'],
- fontSize: 14,
- color: '#333',
- fontWeight: 'normal'
- },
- data: [
- {
- value: this.value,
- name: this.title
- }
- ]
- }
- ],
- // 合并自定义配置,允许用户覆盖默认设置
- ...this.options
- };
- this.$refs.chartRef.init(echarts, chart => {
- chart.setOption(option,true)
- })
- // 使用true参数强制更新所有配置项
- // this.chartInstance.setOption(option, true);
- },
-
- /**
- * 计算仪表盘颜色渐变范围
- * 根据最小值、最大值和颜色数组计算分段颜色区间
- * @private
- * @returns {Array<Array<number|string>>} 颜色范围数组
- */
- calculateColorRanges() {
- // 对于压力计等场景,使用单一蓝色调更合适
- // 但保持配置灵活性,允许用户自定义颜色
- const ranges = [];
- const step = (this.max - this.min) / this.colors.length;
-
- for (let i = 0; i < this.colors.length; i++) {
- ranges.push([
- this.min + step * i,
- this.min + step * (i + 1),
- this.colors[i]
- ]);
- }
-
- return ranges;
- },
-
- /**
- * 处理窗口大小变化
- * 当页面缩放时自动调整图表大小以保持显示正常
- * @private
- */
- handleResize() {
- if (this.chartInstance) {
- this.chartInstance.resize();
- }
- },
-
- /**
- * 手动触发重绘
- * 提供给父组件调用的公共方法,用于强制刷新图表
- * @public
- */
- redraw() {
-
- if (!this.chartInstance) {
- this.initChart();
- } else {
- this.updateChart();
- }
- }
- }
- };
- </script>
- <style scoped>
- :deep(.echarts) {
- width: 100%;
- height: 100%;
- }
- </style>
|