echarts-当折线图有多组数据且数据需要显示在同一图表时

前言

1.多组数据长度不同,比如一组是[12,20,30],另一组是[22,32,15,45,55],这里只是举例子告诉长度不同,实际的数组是对象数组,不是这样的普通数组

2.多组数据返回时有重复值,并且不同组数据混在一起返回形成一个大数组

3.数据去重得通过两个条件,分别是名称和时间。数据里的id没什么用,名字是分组条件,时间是x轴,dataValue是值

4.数据得和时间对应,不能后端返回时9点对应值为40,图上却因为数据缺失导致10点的50对应到9点的40位置

5.没有一段代码是我自己想的(@^@)

一、后端返回值举例

        1. 数据按名称分类,“测试温度描述”和“测试温度描述4”是两组数据

        2. 同一组数据会有重复值,比如返回值举例里的"id:15"和"id:17",虽然id不同,但是是同一组数据且时间、数据相同

[
    {
        "id":7,
        "sendTime":"2023-01-03 09:00:00",
        "dataDetail":"测试温度描述",
        "dataValue":"100",
    },
    {
        "id":9,
        "sendTime":"2023-01-03 09:10:00",
        "dataDetail":"测试温度描述",
        "dataValue":"100",
    },
    {
        "id":11,
        "sendTime":"2023-01-03 09:20:00",
        "dataDetail":"测试温度描述",
        "dataValue":"100",
    },
    {
        "id":13,
        "sendTime":"2023-01-03 09:30:00",
        "dataDetail":"测试温度描述",
        "dataValue":"100",
    },
    {
        "id":15,
        "sendTime":"2023-01-03 09:40:00",
        "dataDetail":"测试温度描述",
        "dataValue":"110",
    },
    {
        "id":17,
        "sendTime":"2023-01-03 09:40:00",
        "dataDetail":"测试温度描述",
        "dataValue":"110",
    },
    {
        "id":19,
        "sendTime":"2023-01-03 09:50:00",
        "dataDetail":"测试温度描述",
        "dataValue":"110",
    },
    {
        "id":21,
        "sendTime":"2023-01-03 10:00:00",
        "dataDetail":"测试温度描述",
        "dataValue":"110",
    },
    {
        "id":25,
        "sendTime":"2023-01-03 10:00:00",
        "dataDetail":"测试温度描述",
        "dataValue":"110",
    },
    {
        "id":31,
        "sendTime":"2023-01-03 10:00:00",
        "dataDetail":"测试温度描述4",
        "dataValue":"410",
    },
    {
        "id":33,
        "sendTime":"2023-01-03 10:00:00",
        "dataDetail":"测试温度描述",
        "dataValue":"110",
    },
    {
        "id":39,
        "devId":0,
        "sendTime":"2023-01-03 10:00:00",
        "dataDetail":"测试温度描述4",
        "dataValue":"410",
    },
    {
        "id":41,
        "sendTime":"2023-01-03 10:10:00",
        "dataDetail":"测试温度描述",
        "dataValue":"110",
    },
    {
        "id":47,
        "sendTime":"2023-01-03 10:10:00",
        "dataDetail":"测试温度描述4",
        "dataValue":"410",
    }
]

        

二、数据去重

        1.首先将重复的数据去掉,这里要判断两次,首先是名称,其次是时间

刚开始想用filter或者some什么的函数,但是我不太会用,所以第一次修改失败,参考

filter去重

失败代码:

let arrAll=arr.filter(function(item,index){
  let myArr=[]  // 对象的某个属性放入临时数组,对比临时数组中元素所在对象的索引,
  let myArr2 = []
  // 多个对象可push多个,均不相同return ..&&..   有一不同 return ..||..
  arr.forEach(item2=>{
    myArr.push(item2.dataDetail)
  })
  arr.forEach(item2=>{
    myArr2.push(item2.sendTime)
  })
  return myArr.indexOf(item.dataDetail)==index||myArr2.indexOf(item.sendTime)==index
})

失败原因就是分组这里,先判断名字,第一次出现的名字放入数组,之后判断时间,第一次出现的时间也放入另一个数组,但是如果名字1名字2有相同的时间,也就是出现上面数据示例里id为39,41,47时,47的名字和39重复,47的时间和41重复,导致两个数组都认为他是重复的,但实际上他们并不重复,所以我另外使用了其他方法,参考:

js数组对象去重同时判断两个属性条件相同去重

成功代码:

process(arr) {
    // 缓存用于记录
    const cache = [];
    for (const t of arr) {
    // 检查缓存中是否已经存在
        if (cache.find(c => c.dataDetail === t.dataDetail && c.sendTime === t.sendTime)) {
            // 已经存在说明以前记录过,现在这个就是多余的,直接忽略
            continue;
        }
        // 不存在就说明以前没遇到过,把它记录下来
        cache.push(t);
    }

    // 记录结果就是过滤后的结果
    return cache;
},

三、数据补位

1.echarts的x轴必须补位少的数据,不然数据起始一样

数据未补位:

 数据补位:

而且数据必须按时间来,也就是数据有可能是断的,或者中间缺失,所以前端先将数据分组并获取所有时间(x轴所有数据),并且补位(每个组缺失的时间补齐)

2.获取时间并去重

// echarts的xAxis的data的数据,x轴,只有时间并且时间去重
this.xAxisData = this.duplicateRemoval(res.data.map(item=>{
    return item.sendTime
}))


// 数组去重(非对象)
duplicateRemoval(arr){
    let newsArr = [];
    for (let i = 0; i < arr.length; i++) {
        if(newsArr.indexOf(arr[i]) === -1){
            // 数组如果不存在该元素则push
            newsArr.push(arr[i]);
        }
    }
    return newsArr;
},

 3.数据补位

这里我想的有点乱和杂,但是好歹能运行正确,希望有更简单的办法

具体就是先将数据变为[{time:时间,value:数值},...]这样的数据,让时间和数据对应,看看缺少哪些时间节点,将缺少的时间节点和对应的数据补充(时间节点缺失的部分,数值直接赋空就行

// 数组补位,echarts的seriesdata的数据如果长度不够补位空字符串
// timeList是上面的x轴数据,nameList是按名字分组的数组,data是上面去重后的大数组
complementArray(timeList,nameList,data){
    let obj = {}
    // 定义对象
    for(let i = 0;i<nameList.length;i++){
        obj['name'+i] = {
            name: nameList[i],
            data: []
        }
    }
    // 数据分组
    nameList.map((nameItem,index) => {
        data.map(item=>{
            if(item.dataDetail == nameItem){
                obj['name'+index].data.push({dataDetail:item.dataDetail,time: item.sendTime,data: item.dataValue})
            }
        })
    })
// 缺少的数据进行增加,data长度一定是最长的但是有时间缺失和重复,timeList第二长但时间不重复且不缺失,nameList长度一定与obj的第一层对象一样多
// timeList.indexOf(每个对象里的时间) 
    for(let i = 0;i<nameList.length;i++){
        let arr = []
        for(let j = 0;j<obj['name'+i].data.length;j++){
            arr.push(obj['name'+i].data[j].time)
        }
        // arr是少的,timeList是总的,看看arr里的数据全不全
        timeList.map((item,index)=>{
            if(arr.indexOf(item) == -1){
                // 如果arr里没有timeList当前元素
                obj['name'+i].data.push({dataDetail:obj['name'+i].name,time: item,data: ''})
            }
        })
    }
    return obj
},

4.时间排序

将数据处理完毕后要按照时间顺序排列数据,不然列表里对应的时间和图上的不一样,参考:

js对象数组按时间进行排序

// obj里的键值对数量取决于之前的按名称的分组
for(let k in obj){
    obj[k].data.sort(this.compare('time','positive'))
}
// 排序
compare(prop,align){
    return function(a,b){
        var value1=a[prop];
        var value2=b[prop];
        if(align=="positive"){//正序
            return new Date(value1)-new Date(value2);
        }else if(align=="inverted"){//倒序
            return new Date(value2)-new Date(value1);
        }
    }
}

之后获得对应的值


总代码

// res.data就是后台返回的没有分页的有重复数据的对象数组
// 双条件去重方法1
let arr = this.process(res.data)
// 双条件去重第二种方法
// let arr2 = this.process2(res.data)
// 获取图例长度,也就是大数组分几组,我这里按名称分的
// choseDataNameList是选择的数组,没什么用,数据大概是['name1','name2'……],可以用duplicateRemoval方法获取
this.legendData = this.choseDataNameList.map(item=>{
    return item.dataDetail
})
// 获取所有时间节点并去重变为一个大的时间节点数组
this.xAxisData = this.duplicateRemoval(res.data.map(item=>{
    return item.sendTime
}))
// echarts的x轴必须补位少的数据,不然数据起始一样
// 需要处理的数据的个数和选择的采集点个数有关
let obj = this.complementArray(this.xAxisData,this.legendData,arr)
// 排序
for(let k in obj){
    obj[k].data.sort(this.compare('time','positive'))
}
// debugger
// 处理数据
this.seriesData = this.dataUpData(obj)



// 上面大方法调用的各个小方法
/** *
 * 对象数组去重
 * 
 */
process(arr) {
    // 缓存用于记录
    const cache = [];
    for (const t of arr) {
    // 检查缓存中是否已经存在
        if (cache.find(c => c.dataDetail === t.dataDetail && c.sendTime === t.sendTime)) {
            // 已经存在说明以前记录过,现在这个就是多余的,直接忽略
            continue;
        }
        // 不存在就说明以前没遇到过,把它记录下来
        cache.push(t);
    }

    // 记录结果就是过滤后的结果
    return cache;
},
/** 
 * 数组去重(非对象)
 */
duplicateRemoval(arr){
    let newsArr = [];
    for (let i = 0; i < arr.length; i++) {
        if(newsArr.indexOf(arr[i]) === -1){
            // 数组如果不存在该元素则push
            newsArr.push(arr[i]);
        }
    }
    return newsArr;
},
// 数组补位,echarts的seriesdata的数据如果长度不够补位空字符串
// timeList是上面的x轴数据,nameList是按名字分组的数组,data是上面去重后的大数组
complementArray(timeList,nameList,data){
    let obj = {}
    // 定义对象
    for(let i = 0;i<nameList.length;i++){
        obj['name'+i] = {
            name: nameList[i],
            data: []
        }
    }
    // 数据分组
    nameList.map((nameItem,index) => {
        data.map(item=>{
            if(item.dataDetail == nameItem){
                obj['name'+index].data.push({dataDetail:item.dataDetail,time: item.sendTime,data: item.dataValue})
            }
        })
    })
// 缺少的数据进行增加,data长度一定是最长的但是有时间缺失和重复,timeList第二长但时间不重复且不缺失,nameList长度一定与obj的第一层对象一样多
// timeList.indexOf(每个对象里的时间) 
    for(let i = 0;i<nameList.length;i++){
        let arr = []
        for(let j = 0;j<obj['name'+i].data.length;j++){
            arr.push(obj['name'+i].data[j].time)
        }
        // arr是少的,timeList是总的,看看arr里的数据全不全
        timeList.map((item,index)=>{
            if(arr.indexOf(item) == -1){
                // 如果arr里没有timeList当前元素
                obj['name'+i].data.push({dataDetail:obj['name'+i].name,time: item,data: ''})
            }
        })
    }
    return obj
},
// 按对象数组某一参数排序
compare(prop,align){
    return function(a,b){
        var value1=a[prop];
        var value2=b[prop];
        if(align=="positive"){//正序
            return new Date(value1)-new Date(value2);
        }else if(align=="inverted"){//倒序
            return new Date(value2)-new Date(value1);
        }
    }
},
// 数据处理为series里data想要的
dataUpData(data){
    let arr = []
    for(let i in data){
        let sonArr = data[i].data.map(item=>{
            return item.data
        })
        arr.push({name: data[i].name, type: 'line' ,data: sonArr})
     }
     return arr
},

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值