echarts 两个曲线之间填充并且不遮挡的办法

news/发布时间2024/5/17 14:43:31

echarts 两个曲线之间填充 可以用两条曲线 ,第一条填充白色 ,然后 第2条填充想要的颜色 ,如下面的代码

option = {title: {text: '堆叠区域图'},tooltip : {trigger: 'axis'},legend: {data:['最小值','最大值']},toolbox: {feature: {saveAsImage: {}}},grid: {left: '3%',right: '4%',bottom: '3%',containLabel: true},xAxis : [{type : 'category',boundaryGap : false,data : ['周一','周二','周三','周四','周五','周六','周日']}],yAxis : [{type : 'value'}],series : [{name:'最小值',type:'line',//  stack: '总量',areaStyle: {color:'#8DA2E4',opacity:1,origin:"start"},data:[320, 332, 301, -40, -30, 330, 320]},{name:'最大值',type:'line',//   stack: '总量',label: {normal: {show: true}},areaStyle: {color:'#ffffff',opacity:1,origin:"start"},data:[10, 30, 40, -60, -50, 40, 50]}]
};

这样有个弊端,当你 想要绘制markarea 区域的时候 ,由于下面的 曲线填充是白色的会被遮住

所以想了个办法 ,分两片区域绘制 分上半部分和下半部分 ,代码如下

import { useMemo, useState } from "react";
import ReactECharts from "echarts-for-react";
import dayjs from "dayjs";const areaStyle = {opacity: 0.8,color: {type: "linear",x: 0,y: 0,x2: 0,y2: 1,colorStops: [{offset: 0,color: "rgb(0, 221, 255)",},{offset: 1,color: "rgb(77, 119, 255)",},],},
};
const getCommonSeries = (name, data, markAreaData, areaStyle = undefined) => {return {name,areaStyle,data,type: "line",smooth: true,lineStyle: { width: 0 },showSymbol: false,markArea: {itemStyle: {color: "rgba(255, 0, 0, 0.2)",},data: markAreaData,},};
};export const AlarmCurve = ({pointCurveData = [], // 点曲线数据alarmData = [], // 报警数据max = 0, // 最大值min = 0, // 最小值predictData = [], // 点预测数据
}) => {const pointCurveMaxData = useMemo(() => {return pointCurveData.map((item) => [item[0], item[1] + max]);}, [pointCurveData, max]);const pointCurveMinData = useMemo(() => {return pointCurveData.map((item) => [item[0], item[1] - min]);}, [pointCurveData, min]);const markAreaData = useMemo(() => {// 获取 alarmData 中连续的1的区间,记录的是 的开始和结束item[0]let result = [];let start = null;for (let i = 0; i < alarmData.length; i++) {if (alarmData[i][1] === 1) {if (start === null) {start = alarmData[i][0];}if (i === alarmData.length - 1 || alarmData[i + 1][1] === 0) {result.push([{ xAxis: dayjs(start).format("MM-DD HH:mm:ss") },{ xAxis: dayjs(alarmData[i][0]).format("MM-DD HH:mm:ss") },]);start = null;}}}console.log("result", result);return result;}, [alarmData]);const opt = useMemo(() => {if (pointCurveData.length === 0) {return {};}// line optreturn {title: {text: "报警曲线",// align centerleft: "center",},tooltip: {trigger: "axis",axisPointer: {type: "cross",label: {backgroundColor: "#6a7985",},},},grid: {top: 30,left: "3%",right: "4%",bottom: "3%",containLabel: true,},xAxis: [{type: "category",boundaryGap: false,data: pointCurveData.map((item) =>dayjs(item[0]).format("MM-DD HH:mm:ss"),),},],yAxis: {type: "value",},series: [{name: "Line 1-max",type: "line",stack: "max",smooth: true,lineStyle: {width: 0,},showSymbol: false,data: pointCurveData.map((item) => item[1]),},{name: "Line 1-base",type: "line",stack: "max",smooth: true,lineStyle: {width: 0,},showSymbol: false,emphasis: {focus: "series",},areaStyle: {opacity: 0.3,color: "rgb(13,185,88)",},data: pointCurveData.map((item) => max),},{...getCommonSeries("实时值",pointCurveData.map((item) => item[1]),undefined,),lineStyle: {width: 2,},},{name: "Line 1-min",type: "line",stack: "min",smooth: true,lineStyle: {width: 0,},showSymbol: false,emphasis: {focus: "series",},data: pointCurveData.map((item) => item[1] - min),},{name: "Line 3",type: "line",stack: "min",smooth: true,lineStyle: {width: 0,},showSymbol: false,areaStyle: {opacity: 0.3,color: "rgb(13,185,88)",},data: pointCurveData.map((item) => min),},{...getCommonSeries("预测值",predictData.map((item) => item[1]),markAreaData,),lineStyle: {width: 2,},},],};}, [pointCurveData,alarmData,max,min,predictData,pointCurveMaxData,pointCurveMinData,]);return <ReactECharts option={opt} />;
};

模拟数据调用

import dayjs from "dayjs";
import { AlarmCurve } from "./alarm-curve";export const movingAverage = (data, numberOfPricePoints) => {return data.map((row, index, total) => {const start = Math.max(0, index - numberOfPricePoints);const subset = total.map((x) => x[1]).slice(start, index + 1);const sum = subset.reduce((a, b) => a + b, 0);return [row[0], sum / subset.length];});
};export const FuXianAlarmCurve = () => {const now = dayjs();const max = 20;const min = 10;// 模拟一个1000个点的数据1秒const pointCurveData = movingAverage(Array.from({ length: 1000 }, (_, i) => [now.add(i, "second").valueOf(),Math.random() * 100,]),20,);// 模拟一个1000个点的数据1秒const predictData = movingAverage(Array.from({ length: 1000 }, (_, i) => [now.add(i, "second").valueOf(),Math.random() * 100,]),100,);// 遍历pointCurveData和 predictData,如果predictData 对应的值在min和max之间, 则返回0 否则返回1const alarmData = pointCurveData.map((item, index) => {const predictItem = predictData[index];if (predictItem[1] > item[1] + max || predictItem[1] < item[1] - min) {return [item[0], 1];}return [item[0], 0];});return (<AlarmCurvepointCurveData={pointCurveData}predictData={predictData}alarmData={alarmData}max={max}min={min}/>);
};

效果

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

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

相关文章

球体与正方体[正六面体]

主要整理球体与正方体[正六面体]的切接问题前言 常用结论:给定一个棱长为 \(a\) 的正方体[即正六面体],则其面对角线长为\(\sqrt{2}a\),其体对角线长为\(\sqrt{3}a\);且正六面体棱长、面对角线、体对角线三者之比为\(1\)\(\;:\;\)\(\sqrt{2}\)\(\;:\;\)\(\sqrt{3}\);设正方…

Python 物联网入门指南(八)

原文:zh.annas-archive.org/md5/4fe4273add75ed738e70f3d05e428b06 译者:飞龙 协议:CC BY-NC-SA 4.0第三十章:制作机械臂 最后,我们终于到达了大多数人自本书开始以来就想要到达的地方。制作一个机械臂!在本章中,我们将学习机械臂工作背后的概念。毫无疑问,我们也将制作…

甘特图使用小诀窍,项目把控游刃有余

在项目管理过程中,掌握甘特图的使用技巧可以让你事半功倍,高效规划和监控项目进度。作为一种视觉化的工具,甘特图直观地展示了任务的开始和结束时间、持续时间以及任务之间的依赖关系,有助于预测和优化资源分配。掌握以下几个小诀窍,你就能驾驭甘特图,游刃有余地把控整个项目。…

实验一 二手交易平台APP原型设计

一、实验题目:原型设计 二、实验目的:掌握产品原型设计方法和相应工具使用。 三、实验要求 1.对比分析墨刀、Axure、Mockplus等原型设计工具的各自的适用领域及优缺点(至少3条)。 墨刀的适用领域及优缺点 适用领域 墨刀是一款在线原型设计与协同工具,借助墨刀,产品经理、…

一周涨 15k Star 的开源项目「GitHub 热点速览」

https://www.cnblogs.com/xueweihan/p/18137334你训练大语言模型(LLM)用的什么框架?有没有想过不用框架训练 GPT-2? GitHub 上就有这么一位大神(Andrej Karpathy),他仅用大约 1k 行的 C 代码就完成了 GPT-2 模型的训练,代码纯手撸、不依赖任何机器学习框架,作者这么做…

大报文之道:优化策略与实践

写在前面 在做正常的需求开发时,当我们提供了一个接口或是调用别人接口时,我们需要考虑接口除了正常的逻辑处理外,还需要考虑接口能接收报文的上限,性能,响应时间等一系列非功能性需求。如果不注意这些问题,就可能在某一天的某个时刻收到一系列系统告警,严重者甚至导致系…