初试Echarts(之一)拼接两个折线图&不同区间不同样式

①效果

折线1和折线2为拆分版本,折线3为合并版本。

合并方法是采用两个series元素,并分别设置lineStyle

最开始参考(https://blog.csdn.net/weixin_33991418/article/details/89369690),在折线2数据组前面插入大量“-”,这样就可以把折线2数据组推到折线1数据组之后显示,后面发现多此一举。直接连接两个数据组,通过折线图的重叠也可以达到相同效果,并且还无需额外处理实现了交点(t50和t51)的连线。

②原生JS版本

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>ECharts</title>
    <!-- 引入刚刚下载的 ECharts 文件 -->
    <script src="echarts.js"></script>
    <style>
            main {
                /*对子元素开启弹性布局*/
                display: flex;
                /*弹性元素在必要的时候换行*/
                flex-wrap: wrap;
                /*将弹性元素居中*/
                justify-content: center;
            }
    </style>
  </head>
  <body>
    <main>
    </main>
    <script type="text/javascript">
      const WIDTH = 600;
      const HEIGHT = 400;

      // main用来放div1 div2 div3
      let container = document.querySelector('main')

      // div1用来放折线图1
      let div1 = createDiv(WIDTH, HEIGHT)
      container.appendChild(div1)

      // div2用来放折线图2
      let div2 = createDiv(WIDTH, HEIGHT)   
      container.appendChild(div2)

      // div3用来放折线图3
      let div3 = createDiv(WIDTH * 2, HEIGHT, 'none')   
      container.appendChild(div3)      

      // 创建空图
      let lineChart1 = echarts.init(div1)
      let lineChart2 = echarts.init(div2)
      let lineChart3 = echarts.init(div3)

      // 模拟两份数据
      const DATA_SIZE = 100;
      let packets = makeDate(DATA_SIZE)
      let packets1 = packets.slice(0, DATA_SIZE / 2)
      let packets2 = packets.slice(DATA_SIZE / 2, DATA_SIZE)

      // 将数据填充到折线图
      lineChart1.setOption({
          title: {
            text: '折线1',
          },
          xAxis: {
            data: packets1.map(p => p.time)
          },
          yAxis: {},
          series: [
            {
              data: packets1.map(p => p.data),
              type: 'line',
              lineStyle: {
                color: 'black',
              }
            }
          ]          
      })

      lineChart2.setOption({
          title: {
            text: '折线2',
          },
          xAxis: {
            data: packets2.map(p => p.time)
          },
          yAxis: {},
          series: [
            {
              data: packets2.map(p => p.data),
              type: 'line',
              lineStyle: {
                color: 'black',
                type: 'dashed',
                opacity: 0.5,
              }
            }
          ]          
      })  
      
      lineChart3.setOption({
          title: {
            text: '折线3',
          },
          xAxis: {
            data: packets1.concat(packets2).map(p => p.time)
          },
          yAxis: {},
          series: [
            {
              data: packets1.map(p => p.data),
              type: 'line',
              lineStyle: {
                color: 'black',
              }
            },
            {
              data: packets1.concat(packets2).map(p => p.data),
              type: 'line',
              lineStyle: {
                color: 'black',
                type: 'dashed',
                opacity: 0.5,
              }
            }        
          ]          
      }) 
      
      function createDiv(width, height, display = 'block') {
        let result = document.createElement('div')
        result.style.width = width + 'px'
        result.style.height = height + 'px'
        // result.style.display = display
        return result
      }      

      function makeDate(dataSize) {
        let result = [];
        for (let i = 0; i != dataSize; ++i) {
          result.push({
            time: "t" + i,
            data: Math.random(),
          })
        }
        return result;
      }
    </script>
  </body>
</html>

③Vue.js版本

依赖及其版本:

  "dependencies": {
    "core-js": "^3.6.5",
    "echarts": "^5.3.0",
    "vue": "^2.6.11",
    "vuex": "^3.6.  "dependencies": {
    "core-js": "^3.6.5",
    "echarts": "^5.3.0",
    "vue": "^2.6.11",
    "vuex": "^3.6.2"
  },2"
  },

main.js:

import Vue from 'vue'
import App from './App.vue'
import store from './store'
//引入echarts 5.0版本以上要使用如下引用方式
import * as echarts from 'echarts'

Vue.config.productionTip = false

Vue.prototype.$echarts = echarts

new Vue({
  render: h => h(App),
  store,
}).$mount('#app')

store/index.js:

import Vue from 'vue'
import Vuex from 'vuex'
// 应用vuex插件
Vue.use(Vuex)

const DATA_SIZE = 100

function makeDate(dataSize) {
    let result = [];
    for (let i = 0; i != dataSize; ++i) {
        result.push({
        time: "t" + i,
        data: Math.random(),
        })
    }
    return result;
}

let packets = makeDate(DATA_SIZE)
let packets1 = packets.slice(0, DATA_SIZE / 2)
let packets2 = packets.slice(DATA_SIZE / 2, DATA_SIZE)

// 用于响应组件中的动作(业务逻辑放这里)
const actions = {
}

// 用于操作state
const mutations = {
}

// 用于存储数据
const state = {
    packets1,
    packets2,
}

// 创建并暴露store
export default new Vuex.Store({
    actions,
    mutations,
    state
})

App.vue:

<template>
  <div>
    <button id="btnChange" @click="changeMode">改变显示模式</button>
    <Chart1 v-show="mode === 1" />
    <Chart2 v-show="mode === 2" />
  </div>
</template>

<script>
import Chart1 from './components/Chart1.vue'
import Chart2 from './components/Chart2.vue'

export default {
  name: 'App',
  data() {
    return {
      mode: 1,
    }
  },
  components: {
    Chart1,
    Chart2,
  },
  methods: {
    changeMode() {
      this.mode = (this.mode === 1) ? 2 : 1
    }
  },
}
</script>

<style>
  #btnChange {
    margin: 10px;
  }
</style>

Chart1.vue:

<template>
  <main>
    <div id="realData" style="width: 600px;height: 400px;"></div>
    <div id="predictedData" style="width: 600px;height: 400px;"></div>
  </main>
</template>

<script>
import { mapState } from 'vuex'

export default {
  name: 'Chart1',
  computed: {
    ...mapState(['packets1', 'packets2']),
  },
  mounted() {
    let div1 = document.querySelector("#realData")
    let div2 = document.querySelector("#predictedData")
    let lineChart1 = this.$echarts.init(div1)
    let lineChart2 = this.$echarts.init(div2)
    
    lineChart1.setOption({
      title: {
        text: '折线1',
      },
      xAxis: {
        data: this.packets1.map(p => p.time)
      },
      yAxis: {},
      series: [
        {
          data: this.packets1.map(p => p.data),
          type: 'line',
          lineStyle: {
            color: 'black',
          },
        },
      ],          
    })

    lineChart2.setOption({
      title: {
        text: '折线2',
      },
      xAxis: {
        data: this.packets2.map(p => p.time)
      },
      yAxis: {},
      series: [
        {
          data: this.packets2.map(p => p.data),
          type: 'line',
          lineStyle: {
            color: 'black',
            type: 'dashed',
            opacity: 0.5,
          },
        },
      ],          
    });
  },
}
</script>

<style scoped>
  main {
    display: flex;
  }
</style>

Chart2.vue:

<template>
  <div>
    <div id="MyChart" style="width: 1200px;height: 400px;"></div>
  </div>
</template>

<script>
import { mapState } from 'vuex'

export default {
  name: 'Chart2',
  computed: {
    ...mapState(['packets1', 'packets2']),
  },
  mounted() {
    let myDiv = document.querySelector("#MyChart")
    let lineChart = this.$echarts.init(myDiv)

    lineChart.setOption({
      title: {
        text: '折线3',
      },
      xAxis: {
        data: this.packets1.concat(this.packets2).map(p => p.time)
      },
      yAxis: {},
      series: [
        {
          data: this.packets1.map(p => p.data),
          type: 'line',
          lineStyle: {
            color: 'black',
          },
        },
        {
          data: this.packets1.concat(this.packets2).map(p => p.data),
          type: 'line',
          lineStyle: {
            color: 'black',
            type: 'dashed',
            opacity: 0.5,
          },
        },        
      ],          
    }); 
  },
};
</script>

 

posted @ 2022-02-08 22:54  xkfx  阅读(3089)  评论(0)    收藏  举报