ucharts的堆叠正负柱状图,设置最大值和最小值已经让分隔线坐标永远为0

1,动态设置最大值和最小值

在yAxis的data中设置   min: 0, // Y 轴最小值   max: 0,  // Y 轴最大值

yAxis: {
            data: [
                {
                    unit: "度",
                    min: 0, // Y 轴最小值
                    max: 0,  // Y 轴最大值

                    splitLine: {
                        show: true, // 显示分割线
                    },
                    axisLabel: {
                        formatter: (value : number) => {
                            // 自定义 Y 轴标签
                            if (value === 0) return '0';
                            if (value > 0) return `${value}`;
                            if (value < 0) return `${value}`;
                        },
                    },
                }
            ],
           splitNumber: 10
        },

然后在渲染数据时加上根据渲染数据计算出来的最大值和最小值

opts.value.yAxis.data[0].min = zhengFu.value;
opts.value.yAxis.data[0].max = zhengValue.value;

2,让分隔线坐标永远为0

在yAxis的添加splitNumber: 6,也就是Y轴坐标显示7个数据

然后添加splitLine: {
                        show: true, // 显示分割线
                    },
                    axisLabel: {
                        formatter: (value : number) => {
                            // 自定义 Y 轴标签
                            if (value === 0) return '0';
                            if (value > 0) return `${value}`;
                            if (value < 0) return `${value}`;
                        },
                    },

yAxis: {
			data: [
				{
					unit: "度",
					min: 0, // Y 轴最小值
					max: 0,  // Y 轴最大值

					splitLine: {
						show: true, // 显示分割线
					},
					axisLabel: {
						formatter: (value : number) => {
							// 自定义 Y 轴标签
							if (value === 0) return '0';
							if (value > 0) return `${value}`;
							if (value < 0) return `${value}`;
						},
					},
				}
			],
			splitNumber: 6
		},

然后在渲染的先算出Y轴应该渲染的最大值和最小值,它处理了不同类型的电量数据,并根据数据的最大值和最小值动态调整 Y 轴的范围。

<template>
	<!-- 月 -->
	<view class="daily">
		<view class="daily_s">
			<view>
				<view>
					发电量
				</view>
				<view class="daily_x">
					<view class="daily_d">
						<view class="daily_f">
							<view><text class="daily_r">{{ (chartD.selfPowerCount || 0).toFixed(2) }}</text>度</view>
							<view>自发自用</view>
							<view>(<text>{{ chartD.selfRate || 0 }}</text>%)</view>
						</view>
						<view class="daily_c">
							<view class="daily_v">{{ (chartD.inverterPowerCount || 0).toFixed(2) }}</view>
							<view>度</view>
						</view>
						<view class="daily_t">
							<view><text class="daily_g">{{ (chartD.uploadPowerCount || 0).toFixed(2) }}</text>度</view>
							<view>上网电量</view>
							<view>(<text>{{ chartD.uploadRate || 0 }}</text>%)</view>
						</view>
					</view>
				</view>
				<view>
					<view>
						用电量
					</view>
					<view class="daily_x">
						<view class="daily_d">
							<view class="daily_f">
								<view><text class="daily_r">{{ (chartD.useSelfPowerCount || 0).toFixed(2) }}</text>度
								</view>
								<view>自给自足</view>
								<view>(<text>{{ chartD.useSelfRate || 0 }}</text>%)</view>
							</view>
							<view class="daily_c">
								<view class="daily_v">{{ (chartD.iallUsePowerCount || 0).toFixed(2) }}</view>
								<view>度</view>
							</view>
							<view class="daily_t">
								<view><text class="daily_g">{{ (chartD.gridDownPowerCount || 0).toFixed(2) }}</text>度
								</view>
								<view>购买电量</view>
								<view>(<text>{{ chartD.gridDownRate || 0 }}</text>%)</view>
							</view>
						</view>
					</view>
				</view>
			</view>
		</view>
		<view class="daily_q">
			<view @click="decrementDate">
				<img src="http://47.104.232.49/appimages/向左箭头.png" alt="" class="daily_z" />
			</view>
			<view class="daily_w">
				<view class="example-body">
					<picker mode="date" fields="month" @change="handleDateChange">
						{{ single }}
					</picker>
				</view>
			</view>
			<view @click="incrementDate">
				<img src="http://47.104.232.49/appimages/向右箭头.png" alt="" class="daily_z" />
			</view>
		</view>
		<view class="daily_a">
			<view class="daily_e">
				<qiun-data-charts type="column" :opts="opts" :chartData="chartData" />
			</view>
		</view>
	</view>
</template>

<script setup lang="ts">
	import { ref, onMounted } from 'vue';
	import { getpowercount } from '@/src/api/api.js';

	const props = defineProps({
		siteId: {
			type: String,
			default: null
		},
	});

	// 用于存储图表数据
	const chartD = ref({});
	const single = ref(new Date().toISOString().slice(0, 7));

	// 处理日期减一月的函数
	const decrementDate = () => {
		const currentDate = new Date(single.value + '-01');
		currentDate.setMonth(currentDate.getMonth() - 1);
		single.value = currentDate.toISOString().slice(0, 7);
		updateChartData();
	};
	// 处理日期加一月的函数
	const incrementDate = () => {
		const currentDate = new Date(single.value + '-01');
		currentDate.setMonth(currentDate.getMonth() + 1);
		single.value = currentDate.toISOString().slice(0, 7);
		updateChartData();
	};
	// 处理日期选择器 点击的时间
	const handleDateChange = (event : any) => {
		single.value = event.detail.value.slice(0, 7);
		updateChartData();
	};

	const opts = ref({
		color: ["#1890FF", "#91CB74", "#FAC858", "#EE6666", "#73C0DE", "#3CA272", "#FC8452", "#9A60B4", "#ea7ccc"],
		padding: [15, 15, 0, 5],
		enableScroll: false,
		legend: {},
		dataLabel: false,
		xAxis: {
			disableGrid: true,
			labelCount: 7, // 设置显示个数
		},
		yAxis: {
			data: [
				{
					unit: "度",
					min: 0, // Y 轴最小值
					max: 0,  // Y 轴最大值

					splitLine: {
						show: true, // 显示分割线
					},
					axisLabel: {
						formatter: (value : number) => {
							// 自定义 Y 轴标签
							if (value === 0) return '0';
							if (value > 0) return `${value}`;
							if (value < 0) return `${value}`;
						},
					},
				}
			],
			splitNumber: 6
		},
		extra: {
			column: {
				type: "meter",
				width: 4,
				activeBgColor: "#000000",
				activeBgOpacity: 0.00,
				meterBorder: 0,
				meterFillColor: "#EBFBD6",
				data: [0, 0, 0],
			}
		}
	});

	// 柱状图数据
	const chartData = ref({});
	const minValue = ref();
	const maxValue = ref();
	const roundedValue = ref();
	const zhengValue = ref();
	const roundedFu = ref();
	const zhengFu = ref();

	const updateChartData = async () => {
		try {
			const response = await getpowercount(props.siteId, single.value, 2);
			chartD.value = response.data;
			// console.log("lllll", response.data)

			const gridDownData = response.data.gridDownPowerCountArray.map(value => Math.floor(value * -1));
			const inverterData = response.data.inverterPowerCountArray;
			const gridUploadData = response.data.gridUploadPowerCountArray; // 将电网卖电量变为负数并取整
			const loadUseData = response.data.selfPowerCountArray; // 将负载用电量变为负数并取整

			// 更新图表数据
			chartData.value = {
				categories: response.data.timeStrArray.map(date => date.slice(-2)),
				series: [
					{ name: "自发自用电量", data: inverterData },
					{ name: "上网电量", data: gridUploadData },
					{ name: "电网供电电量", data: gridDownData },
					{ name: "自发自用电量", data: loadUseData }
				]
			};
			
			//动态处理Y轴
			//算出负坐标最小值
			const maxGridDown = Math.min(...gridDownData);
			const minLoadUse = Math.min(...loadUseData);
			//负坐标相比最小值
			minValue.value = Math.min(maxGridDown, minLoadUse);
			
            //算出正坐标最大值
			const minGridUpload = Math.max(...gridUploadData);
			const maxInverter = Math.max(...inverterData);
			maxValue.value = Math.max(minGridUpload, maxInverter);
			// console.log("正坐标最大值",maxValue.value)
			const jiut = Math.abs(minValue.value);
			
			function roundUpToNearestThousand(value) {
				return Math.ceil(value / 10) * 10;
			}
			function roundUpThousand(value) {
				return Math.floor(value / 10) * 10;
			}
			//负坐标大时
			//负坐标内容
			roundedValue.value = roundUpThousand(minValue.value);
             // 负坐标内容
			roundedFu.value = Math.abs(roundedValue.value);
			
			//正坐标大时
            //正坐标内容
			zhengValue.value = roundUpToNearestThousand(maxValue.value);
			// 负坐标内容
			zhengFu.value = zhengValue.value * -1;

			if (jiut > maxValue.value) {
				//如果负轴的坐标比正轴的坐标大根据负轴最大数据渲染Y轴
				if (minValue.value >= roundedValue.value) {
					opts.value.yAxis.data[0].min = roundedValue.value;
					opts.value.yAxis.data[0].max = roundedFu.value;
				}

			} else if (jiut > minValue.value) {
				//如果正轴的坐标比负轴的坐标大根据正轴最大数据渲染Y轴
				if (maxValue.value <= zhengValue.value) {
					opts.value.yAxis.data[0].min = zhengFu.value;
					opts.value.yAxis.data[0].max = zhengValue.value;
				}
			} else {
				opts.value.yAxis.data[0].min = zhengFu.value;
				opts.value.yAxis.data[0].max = zhengValue.value;
			}


		} catch (error) {
			console.error('获取数据出错:', error);
		}
	};

	// 生命周期钩子
	onMounted(() => {
		updateChartData();
	});
</script>

<style lang="scss" scoped>
	.daily {
		width: 100%;
		height: 451rpx;
	}

	.daily_q {
		width: 100%;
		height: 90rpx;
		display: flex;
		justify-content: space-between;
		align-items: center;
	}

	.daily_z {
		width: 70rpx;
		height: 70rpx;
	}

	.daily_w {
		width: 50%;
		height: 70rpx;
		display: flex;
		justify-content: center;
		align-items: center;
	}

	uni-datetime-picker {
		display: block;
	}

	.daily_a {
		width: 100%;
		height: calc(451rpx - 90rpx);
	}

	.daily_e {
		width: 100%;
		height: 360rpx;
	}

	.daily_s {
		margin-top: 10rpx;
		width: 100%;
	}

	.daily_x {
		margin-top: 10rpx;
		width: 100%;
		height: 200rpx;
		background-color: #fff;
		border-radius: 30rpx;
		display: flex;
		justify-content: center;
		align-items: center;
	}

	.daily_d {
		width: 94%;
		height: 180rpx;
		display: flex;
		justify-content: space-between;
		align-items: center;
	}

	.daily_f,
	.daily_t {
		width: 30%;
		height: 170rpx;
		border-radius: 100rpx;
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
	}

	.daily_r {
		color: #91CB74;
	}

	.daily_c {
		height: 170rpx;
		border-radius: 100rpx;
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		padding: 10rpx;
		border: 5rpx solid #73C0DE;
		width: 170rpx;
	}

	.daily_v {
		color: #73C0DE;
		font-size: 36rpx;
	}

	.daily_g {
		color: #FC8452;
	}
</style>

在 UniApp 中创建一个正负柱状图并保持中间值为0,你可以通过JavaScript或者其提供的图表库(如 ECharts 或者 H5-Charts)来实现。这里我会以 ECharts 为例来说明: 首先,确保已经在项目中引入了 ECharts 的库。如果还没有,可以按照官方文档进行安装:https://echarts.apache.org/docs/get-started/installation.html 1. 初始化图表: ```javascript import echarts from 'echarts'; const chart = echarts.init(document.getElementById('chart')); ``` 2. 创建数据,包括正常的正值、负值以及零值: ```javascript const data = [ { value: -50, name: '负值', color: '#ff0000' }, // 负数 { value: 0, name: '零', color: '#000' }, // 零值 { value: 50, name: '正值', color: '#00ff00' } // 正数 ]; ``` 3. 设置柱状图配置,其中 `series` 部分设置 `stack` 属性来堆叠数据,并且设置 `dataLine` 来显示一条穿过所有柱子的线: ```javascript const option = { xAxis: {}, yAxis: { stack: true, }, series: [{ type: 'bar', stack: '总量', // 同一组数据会被堆叠在一起 data, itemStyle: { normal: { color: function(data) { return data.value > 0 ? '#00ff00' : (data.value < 0 ? '#ff0000' : '#000'); // 根据值颜色编码 } } } }, { type: 'line', stack: '', data: [0, 0, 0], // 水平线的数据,始终为0 lineStyle: { type: 'dashed', // 线条样式为虚线 color: '#000' // 黑色线条 }, areaStyle: {} // 如果需要填充区域,可以在此添加配置 }], }; ``` 4. 绘制图表: ```javascript chart.setOption(option); ``` 这样就实现了正负柱状图中中间总是保持为0的效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值