Use echarts in vue to realize dynamic data binding and obtain back-end interface data

The previous echarts articles implemented static histograms, line charts, pie charts, and maps. In the project, we definitely need to obtain the back-end interface and display the data returned by the back-end on the chart, so this time Record how to realize the dynamic data binding of echarts.

To put it simply, the data obtained from the interface needs to be defined again in the method of the chart, and then it can be obtained by using the setOption method.

1. Histogram

First look at the data sent by the interface, an array is passed, the first entry is 2021, the quantity is 1, the second entry is 2022, the quantity is 3

Because there are two data in the histogram, the abscissa and the ordinate, we make an array of the transmitted data, the abscissa and the ordinate.

First define in data

lwData: {}, // 论文数据
lwndArr: [], // 年度数组
lwtsArr: [], // 论文发表天数数组

Then get the interface data, process the interface data and put it into two arrays. The year is the abscissa, put the year cycle from data into the year array. The number of days is the ordinate, and the number of days passed in the data is put into the number of days array in a loop.

this.axios.post(this.counturl, {
  type:'paper'
}).then(res => {
  if (res.result === '00000') {
    this.lwData = res.data
    for(let i=0;i<this.lwData.length; i++) {
      this.lwndArr[i] = this.lwData[i].nd
    }
    for(let i=0;i<this.lwData.length; i++) {
      this.lwtsArr[i] = this.lwData[i].count
    }
    lwndArr = this.lwndArr
    lwtsArr = this.lwtsArr
  } else {
      this.$Message.error(res.data.information)
    }
})

The difference between echarts and other interface data acquisition is that in echarts, you need to define the array again, and then put the data obtained by the interface into it, and you cannot directly refer to the data in this.

In the method of obtaining the echarts chart, define the two data of the horizontal and vertical coordinates, and then use the setOption method to refer to the defined data to display the data in the interface. (const option is no longer needed)

// 论文发表天数柱状图
getLwBar () {
  let lwndArr = []
  let lwtsArr = []
  const lwBar = echarts.init(document.getElementById('lwBar'))// 图标初始化
    this.axios.post(this.counturl, {
      type:'paper'
    }).then(res => {
      if (res.result === '00000') {
        this.lwData = res.data
        for(let i=0;i<this.lwData.length; i++) {
          this.lwndArr[i] = this.lwData[i].nd
        }
        for(let i=0;i<this.lwData.length; i++) {
          this.lwtsArr[i] = this.lwData[i].count
        }
        lwndArr = this.lwndArr
        lwtsArr = this.lwtsArr
        lwBar.setOption({
          title: {
            text: '论文发表天数柱状图'
          },
          tooltip: {
          },
          legend: {
            data: ['论文发表天数']
          },
          xAxis:{
            name: '年份',
            data:lwndArr
          },
          yAxis:{
            name:'论文发表天数',
            type:'value'
          },
          series:[
            {
              name: '论文发表天数',
              type: 'bar', // 类型为柱状图
              data: lwtsArr,
              barWidth: '20%', // 柱条宽度 每个柱条的宽度就是类目宽度的 20%
              // 柱子的样式
              itemStyle: {
                color: '#5574c2'
              }
            }
          ]
        })
        } else {
          this.$Message.error(res.data.information)
        }
      })
      // 随着屏幕大小调节图表
      window.addEventListener('resize', () => {
        lwBar.resize()
      })
   },

Effect:

2. Line chart 

 The line chart is the same as the histogram, the abscissa and the ordinate need to be separated.

First define in data

zzData: {}, // 著作数据
zzndArr: [], // 著作年度数组
zzslArr: [], // 著作出版数量数组

Then get the interface data, setOption

// 著作折线图
getZzLine () {
  let zzndArr = []
  let zzslArr = []
  const zzLine = echarts.init(document.getElementById('zzLine'))// 图标初始化
  this.axios.post(this.counturl, {
    type:'book'
  }).then(res => {
    if (res.result === '00000') {
      this.zzData = res.data
      for(let i=0;i<this.zzData.length; i++) {
        this.zzndArr[i] = this.zzData[i].nd
      }
      for(let i=0;i<this.zzData.length; i++) {
        this.zzslArr[i] = this.zzData[i].count
      }
      zzndArr = this.zzndArr
      zzslArr = this.zzslArr
      zzLine.setOption({
      title: {
        text: '著作出版数量折线图'
      },
      tooltip: {
        trigger: 'axis'   // axis   item   none三个值
      },
      legend: {
        data: ['著作']
      },
      xAxis:{
        name: '年份',
        data:zzndArr
      },
      yAxis:{
        name:'数量',
        type:'value'
      },
      series:[
        {
          name: '著作出版数量',
          type: 'line', // 类型为z折线图
          data: zzslArr,
          type: 'line',
          stack: 'x',
          itemStyle: {
            color: '#ef6567',
            width: 4
          }
        }
      ]
    })
  } else {
    this.$Message.error(res.data.information)
  }
})
// 随着屏幕大小调节图表
window.addEventListener('resize', () => {
  zzLine.resize()
})
},

Effect:

3. Pie chart 

The difference between a pie chart and a column and line chart is that a pie chart only needs to obtain one data, and the data format is as follows:

data: [
  {
     value: 335,
     name: '初级会计师'
  },
{
     value: 200,
     name: '中级会计师'
  },
]

So we only need the data passed from the backend to be the same. Pay attention to define it again in the chart method.

Interface data:

In addition, the pie chart also has a header data that is very important, because it has a lot of header data, so it cannot be combined with columns and polylines

The same direct definition also needs to be obtained from the interface, so we first define these two data in data.

scaleData: [], // 饼状图数据
scaleLegend: [], // 饼状图标注

 Then get the interface, get the corresponding data, use setOption

// 毕业人数
      getPieEcharts () {
        let scaleData= []
        let scaleLegend = []
        const kjjgPie = echarts.init(document.getElementById('kjjgPie'))// 图标初始化
        this.axios.post(this.scaleurl, {
          type:this.selectedScale
        }).then(res => {
          if (res.result === '00000') {
            this.scaleData = res.data
            scaleData = this.scaleData
            for(let i = 0; i<res.data.length; i++) {
              this.scaleLegend[i] = res.data[i].name
            }
            scaleLegend = this.scaleLegend
            kjjgPie.setOption({
              legend: {
                data: scaleLegend
              },
              tooltip: {},
              color:['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'],
              series: [
                {
                  radius: '50%',
                  // name: '毕业人数',
                  type: 'pie', // 类型为柱状图
                  label: {
                    //echarts饼图内部显示百分比设置
                    show: true,
                    position: "outside", //outside 外部显示  inside 内部显示
                    formatter: '{b}({d}%)',
                  },
                  data: scaleData
                }
              ]
            })
          } else {
            this.$Message.error(res.data.information)
          }
        })
        // 随着屏幕大小调节图表
        window.addEventListener('resize', () => {
          kjjgPie.resize()
        })
      },

Effect:

Here there is a selection box in the upper right corner, which can display the corresponding pie chart according to the selected data.

Here you can briefly mention that the first is the select selection box:

<Select  v-model="selectedScale"  style="display:inline-block;width:200px;float:right;margin-right:10px;" @on-change="scaleChange">
  <Option v-for="item in selectList.scale" :value="item.code" :key="item.code" placeholder="请选择">
  {
   
   { item.name }}
  </Option>
</Select>

 Define the default data in data:

selectedScale: 'zyzg', // 被选择的饼状图类别

Use the on-change event of the select selection box, when the option changes, pass the changed value to the defined selectedScale, and the interface will return different data according to the content of the selectedScale.

scaleChange(value) {
  this.selectedScale = value
  this.getPieEcharts()
},

4. Map 

 The specific content of the map can be seen in the previous two map articles. The requirement is to display the corresponding content when the mouse is placed in a certain area. The new requirement is to provide multiple scattered points and data of the whole province.

The map is the same as the pie chart. You can request the backend to transmit it in a specified format, which will be much more convenient. You only need to obtain the corresponding data for the scatter chart.

The interface data passed over:

defined in data:

profileData: [], // 地图数据
sdData: [], // 散点数据
qsljnumber: '', // 全省领军人数
qslwnumber: '', // 全省论文数量
qszznumber: '', // 全省著作数量

Interface data:

initCharts () {
        const charts = echarts.init(this.$refs['charts'])
        let airData = []
        let currentSdData = []
        this.axios.post(this.profileurl, {
        }).then(res => {
          if (res.result === '00000') {
            this.profileData = res.data
            airData=this.profileData
            this.sdData[0] = res.data[0]
            this.sdData[1] = res.data[14]
            this.sdData[2] = res.data[15]
            this.sdData[3] = res.data[16]
            currentSdData = this.sdData
            this.qsljnumber = res.data[17].text.ljnumber
            this.qslwnumber = res.data[17].text.lwnumber
            this.qszznumber = res.data[17].text.zznumber
            charts.setOption({
              series:[
                {
                  type: 'map',
                  data:airData
                },
                {
                  type: 'effectScatter',
                  data:currentSdData
                }
              ]
            })
          } else {
            this.$Message.error(res.data.information)
          }
        })
        const option = {
          // 背景颜色
          backgroundColor: 'white',
          // 提示浮窗样式
          tooltip: {
            show: true,
            trigger: 'item',
            alwaysShowContent: false,
            backgroundColor: '#0C121C',
            borderColor: 'rgba(0, 0, 0, 0.16);',
            hideDelay: 100,
            triggerOn: 'mousemove',
            enterable: true,
            textStyle: {
              color: '#DADADA',
              fontSize: '12',
              width: 20,
              height: 30,
              overflow: 'break'
            },
            formatter (params) {
              console.log(params)
              return `地区:${params.data.name}</br>领军人数:${params.data.text.ljnumber}</br>论文数量:${params.data.text.lwnumber}</br>著作数量:${params.data.text.zznumber}`
            },
            showDelay: 100
          },
          // 地图配置
          geo: {
            map: 'jiangsu',
            // 地图文字
            label: {
              // 通常状态下的样式
              normal: {
                // 默认是否显示地区名称
                show: true,
                textStyle: {
                  color: 'black'
                }
              },
              // 鼠标放上去的样式
              emphasis: {
                textStyle: {
                  color: 'black'
                }
              }
            },
            // 地图区域的样式设置
            itemStyle: {
              normal: {
                // 地图边界颜色
                borderColor: '#fff',
                // 地图区域背景颜色
                areaColor: '#AAD5FF',
              },
              // 鼠标放上去高亮的样式
              emphasis: {
                // 鼠标放上去地图区域背景颜色
                areaColor: '#0057da',
                borderWidth: 0
              }
            }
          },
          series: [
            {
              data: airData,
              geoIndex: 0,  
              type:'map'
            },
            {
              type: 'effectScatter',
              coordinateSystem: 'geo',
              effectType: 'ripple',
              showEffectOn: 'render',
              rippleEffect: {
                period: 1,
                scale: 2,
                brushType: 'fill'
              },
              symbolSize: [15, 15],
              // 这里渲染标志里的内容以及样式
              tooltip: {
                show: true,
                formatter (value) {
                  return `地区:${value.data.name}</br>领军人数:${value.data.text.ljnumber}</br>论文数量:${value.data.text.lwnumber}</br>著作数量:${value.data.text.zznumber}`
                },
                color: '#fff'
              },
              hoverAnimation: true,
              // 标志的样式
              itemStyle: {
                normal: {
                  color: 'rgba(255, 235, 59, .7)',
                  shadowBlur: 10,
                  shadowColor: '#333'
                }
              },
              zlevel: 1,
              data: currentSdData
            }
          ],
          // 视觉映射组件
          visualMap:{
            min:1,
            max:300,
            inRange:{
              color:['#e0ffff', '#006edd']
            },
            calculable: true //出现滑块
          }
        }
        // 地图注册,第一个参数的名字必须和option.geo.map一致
        echarts.registerMap('jiangsu', zhongguo)

        charts.setOption(option)
      },

Effect:

Links to articles about static charts written before:

Use echart in vue to draw histograms, discounted charts, and pie charts - Programmer Sought

Links to articles about custom map styles written before:

Use echarts in vue to realize map custom floating window content and style_Cheese Baked Sweet Potato Blog-CSDN Blog_echarts map custom style

Use echarts in vue to realize map color gradient and customize floating window content

Using echarts in vue to realize map scatter diagram

Guess you like

Origin blog.csdn.net/weixin_44320032/article/details/125393860