zoukankan      html  css  js  c++  java
  • vue echarts图表组建封装,实现折线图饼图联动

    基于vue封装的柱状图,饼图,条形图,以及折线图饼图联动 

    效果展示

    详细代码如下

    折线图组件

    <template>
      <div :class="className" :style="{height:height,width}" />
    </template>
    
    <script>
    import echarts from 'echarts'
    require('echarts/theme/macarons') // echarts theme
    import resize from './mixins/resize'
    
    export default {
      mixins: [resize],
      props: {
        className: {
          type: String,
          default: 'chart'
        },
         {
          type: String,
          default: '100%'
        },
        height: {
          type: String,
          default: '350px'
        },
        autoResize: {
          type: Boolean,
          default: true
        },
        chartData: {
          type: Object,
          required: true
        }
      },
      data() {
        return {
          chart: null
        }
      },
      watch: {
        chartData: {
          deep: true,
          handler(val) {
            this.setOptions(val)
          }
        }
      },
      mounted() {
        this.$nextTick(() => {
          this.initChart()
        })
      },
      beforeDestroy() {
        if (!this.chart) {
          return
        }
        this.chart.dispose()
        this.chart = null
      },
      methods: {
        initChart() {
          this.chart = echarts.init(this.$el, 'macarons')
          this.setOptions(this.chartData)
        },
        setOptions({ expectedData, actualData } = {}) {
          this.chart.setOption({
            xAxis: {
              data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
              boundaryGap: false,
              axisTick: {
                show: false
              }
            },
            grid: {
              left: 10,
              right: 10,
              bottom: 20,
              top: 30,
              containLabel: true
            },
            tooltip: {
              trigger: 'axis',
              axisPointer: {
                type: 'cross'
              },
              padding: [5, 10]
            },
            yAxis: {
              axisTick: {
                show: false
              }
            },
            legend: {
              data: ['expected', 'actual']
            },
            series: [{
              name: 'expected', itemStyle: {
                normal: {
                  color: '#FF005A',
                  lineStyle: {
                    color: '#FF005A',
                     2
                  }
                }
              },
              smooth: true,
              type: 'line',
              data: expectedData,
              animationDuration: 2800,
              animationEasing: 'cubicInOut'
            },
            {
              name: 'actual',
              smooth: true,
              type: 'line',
              itemStyle: {
                normal: {
                  color: '#3888fa',
                  lineStyle: {
                    color: '#3888fa',
                     2
                  },
                  areaStyle: {
                    color: '#f3f8ff'
                  }
                }
              },
              data: actualData,
              animationDuration: 2800,
              animationEasing: 'quadraticOut'
            }]
          })
        }
      }
    }
    </script>
    LineChart.vue

    面板组件

    <template>
      <el-row :gutter="40" class="panel-group">
        <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
          <div class="card-panel" @click="handleSetLineChartData('newVisitis')">
            <div class="card-panel-icon-wrapper icon-people">
              <svg-icon icon-class="peoples" class-name="card-panel-icon" />
            </div>
            <div class="card-panel-description">
              <div class="card-panel-text">
                New Visits
              </div>
              <count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" />
            </div>
          </div>
        </el-col>
        <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
          <div class="card-panel" @click="handleSetLineChartData('messages')">
            <div class="card-panel-icon-wrapper icon-message">
              <svg-icon icon-class="message" class-name="card-panel-icon" />
            </div>
            <div class="card-panel-description">
              <div class="card-panel-text">
                Messages
              </div>
              <count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num" />
            </div>
          </div>
        </el-col>
        <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
          <div class="card-panel" @click="handleSetLineChartData('start')">
            <div class="card-panel-icon-wrapper icon-money">
              <svg-icon icon-class="star" class-name="card-panel-icon" />
            </div>
            <div class="card-panel-description">
              <div class="card-panel-text">
                Purchases
              </div>
              <count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" />
            </div>
          </div>
        </el-col>
        <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
          <div class="card-panel" @click="handleSetLineChartData('zip')">
            <div class="card-panel-icon-wrapper icon-money">
              <svg-icon icon-class="zip" class-name="card-panel-icon" />
            </div>
            <div class="card-panel-description">
              <div class="card-panel-text">
                Purchases
              </div>
              <count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" />
            </div>
          </div>
        </el-col>
      </el-row>
    </template>
    
    <script>
    import CountTo from 'vue-count-to'
    
    export default {
      components: {
        CountTo
      },
      methods: {
        handleSetLineChartData(type) {
          this.$emit('handleSetLineChartData', type)
        }
      }
    }
    </script>
    
    <style lang="scss" scoped>
    .panel-group {
      margin-top: 18px;
    
      .card-panel-col {
        margin-bottom: 32px;
      }
    
      .card-panel {
        height: 108px;
        cursor: pointer;
        font-size: 12px;
        position: relative;
        overflow: hidden;
        color: #666;
        background: #fff;
        box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
        border-color: rgba(0, 0, 0, .05);
    
        &:hover {
          .card-panel-icon-wrapper {
            color: #fff;
          }
    
          .icon-people {
            background: #40c9c6;
          }
    
          .icon-message {
            background: #36a3f7;
          }
    
          .icon-money {
            background: #f4516c;
          }
    
          .icon-shopping {
            background: #34bfa3
          }
        }
    
        .icon-people {
          color: #40c9c6;
        }
    
        .icon-message {
          color: #36a3f7;
        }
    
        .icon-money {
          color: #f4516c;
        }
    
        .icon-shopping {
          color: #34bfa3
        }
    
        .card-panel-icon-wrapper {
          float: left;
          margin: 14px 0 0 14px;
          padding: 16px;
          transition: all 0.38s ease-out;
          border-radius: 6px;
        }
    
        .card-panel-icon {
          float: left;
          font-size: 48px;
        }
    
        .card-panel-description {
          float: right;
          font-weight: bold;
          margin: 26px;
          margin-left: 0px;
    
          .card-panel-text {
            line-height: 18px;
            color: rgba(0, 0, 0, 0.45);
            font-size: 16px;
            margin-bottom: 12px;
          }
    
          .card-panel-num {
            font-size: 20px;
          }
        }
      }
    }
    
    @media (max-550px) {
      .card-panel-description {
        display: none;
      }
    
      .card-panel-icon-wrapper {
        float: none !important;
        width: 100%;
        height: 100%;
        margin: 0 !important;
    
        .svg-icon {
          display: block;
          margin: 14px auto !important;
          float: none !important;
        }
      }
    }
    </style>
    PanelGroup.vue

    折线图饼图联动组件

    <template>
      <div id="centerid" :class="className" :style="{height:height,width}"/>
    </template>
    
    <script>import echarts from 'echarts'
    
    require('echarts/theme/macarons') // echarts theme
    import resize from './mixins/resize'
    
    export default {
      mixins: [resize],
      props: {
        className: {
          type: String,
          default: 'chart'
        },
         {
          type: String,
          default: '100%'
        },
        height: {
          type: String,
          default: '400px'
        },
        autoResize: {
          type: Boolean,
          default: true
        },
        chartData: {
          type: Object,
          required: true
        }
      },
      data() {
        return {
          chart: null
        }
      },
      watch: {
        chartData: {
          deep: true,
          handler(val) {
            this.setOptions(val)
          }
        }
      },
      mounted() {
        this.$nextTick(() => {
          this.initChart()
        })
      },
      beforeDestroy() {
        if (!this.chart) {
          return
        }
        this.chart.dispose()
        this.chart = null
      },
      methods: {
        initChart() {
          debugger
          this.chart = echarts.init(this.$el, 'macarons')
          this.setOptions(this.chartData)
          this.chart.on('updateAxisPointer', event => {
            let xAxisInfo = event.axesInfo[0];
            if (xAxisInfo) {
              let dimension = xAxisInfo.value + 1;
              this.chart.setOption({
                series: {
                  id: 'pie',
                  label: {
                    formatter: '{b}: {@[' + dimension + ']} ({d}%)'
                  },
                  encode: {
                    value: dimension,
                    tooltip: dimension
                  }
                }
              });
            }
          })
        },
        setOptions({newVisitis} = {}) {
          this.chart.setOption({
            legend: {},
            title: {
              text: newVisitis.title
            },
            tooltip: {
              trigger: 'axis',
              axisPointer: {
                type: 'cross'
              },
              padding: [5, 10]
            },
            dataset: {
              source: newVisitis.source
            },
            xAxis: {
              type: 'category',
              boundaryGap: false,
              axisTick: {
                show: false
              }},
            yAxis: {
              gridIndex: 0,
              axisTick: {
                show: false
              }},
            grid: {
               '40%',
              height: '60%',
              left: '5%',
              bottom: 20,
              top: 30,
              containLabel: true},
            series: [
              {
                type: 'line',
                smooth: true,
                seriesLayoutBy: 'row',
                animationDuration: 2800,
                animationEasing: 'cubicInOut'
              },
              {
                type: 'line',
                smooth: true,
                seriesLayoutBy: 'row',
                animationDuration: 2800,
                animationEasing: 'cubicInOut'
              },
              {
                type: 'line',
                smooth: true,
                seriesLayoutBy: 'row',
                animationDuration: 2800,
                animationEasing: 'cubicInOut'
              },
              {
                type: 'line',
                smooth: true,
                seriesLayoutBy: 'row',
                animationDuration: 2800,
                animationEasing: 'cubicInOut'
              },
              {
                type: 'pie',
                id: 'pie',
                radius: '30%',
                center: ['70%', '45%'],
                height: '70%',
                left: '50%',
                label: {
                  formatter: '{b}: {@2012} ({d}%)'
                },
                encode: {
                  itemName: 'product',
                  value: '2012',
                  tooltip: '2012'
                }
              }
            ]
          })
        },
      },
    
    }
    </script>
    LinePieChart.vue

    调用饼图并组装数据

    <template>
      <div class="dashboard-editor-container">
        <el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
          <panel-group @handleSetLineChartData="handleSetLineChartData" />
        </el-row>
        <el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
          <line-pie-chart :chart-data="linePieChartData"></line-pie-chart>
        </el-row>
    
        <el-row :gutter="32">
          <el-col :xs="24" :sm="24" :lg="8">
            <div class="chart-wrapper">
              <raddar-chart />
            </div>
          </el-col>
          <el-col :xs="24" :sm="24" :lg="8">
            <div class="chart-wrapper">
              <pie-chart />
            </div>
          </el-col>
          <el-col :xs="24" :sm="24" :lg="8">
            <div class="chart-wrapper">
              <bar-chart />
            </div>
          </el-col>
        </el-row>
    
      </div>
    </template>
    
    <script>
    import LineChart from './components/LineChart'
    import RaddarChart from './components/RaddarChart'
    import PieChart from './components/PieChart'
    import BarChart from './components/BarChart'
    import LinePieChart from './components/LinePieChart'
    import PanelGroup from './components/PanelGroup'
    const lineChartData = {
      newVisitis: {
        expectedData: [100, 120, 161, 134, 105, 160, 165],
        actualData: [120, 82, 91, 154, 162, 140, 145]
      }
    }
    const linePieChartData = {
      newVisitis:{
        newVisitis: {
          title:'newVisitis',
          source: [
            ['product', '2012', '2013', '2014', '2015', '2016', '2017'],
            ['成功', 4, 3, 6, 5, 8, 9],
            ['失败', 86, 92, 85, 83, 73, 55],
            ['拉了', 24, 67, 79, 86, 65, 82],
            ['失联', 15, 27, 29, 12, 23, 19]
          ]
        }
      },
      messages:{
        newVisitis: {
          title:'messages',
          source: [
            ['product', '2012', '2013', '2014', '2015', '2016', '2017'],
            ['成功', 41, 30, 65, 53, 83, 98],
            ['失败', 8, 9, 5, 8, 3, 5],
            ['拉了', 14, 17, 7, 16, 15, 12],
            ['失联', 55, 67, 69, 72, 53, 39]
          ]
        }
      },
      start:{
        newVisitis: {
          title:'start',
          source: [
            ['product', '2012', '2013', '2014', '2015', '2016', '2017'],
            ['成功', 41, 30, 65, 53, 83, 98],
            ['失败', 86, 92, 85, 83, 73, 55],
            ['拉了', 4, 7, 9, 6, 5, 2],
            ['失联', 15, 17, 19, 12, 13, 19]
          ]
        }
      },
      zip:{
        newVisitis: {
          title:'start',
          source: [
            ['product', '2012', '2013', '2014', '2015', '2016', '2017'],
            ['成功', 4, 3, 6, 5, 8, 9],
            ['失败', 26, 12, 25, 33, 23, 15],
            ['拉了', 44, 47, 49, 46, 45, 42],
            ['失联', 15, 17, 19, 12, 13, 19]
          ]
        }
      },
    }
    
    export default {
      name: 'DashboardAdmin',
      components: {
        LineChart,
        RaddarChart,
        PieChart,
        BarChart,
        LinePieChart,
        PanelGroup
      },
      data() {
        return {
          lineChartData: lineChartData.newVisitis,
          linePieChartData: linePieChartData.newVisitis
        }
      },
      methods: {
        handleSetLineChartData(type) {
          this.linePieChartData = linePieChartData[type]
        }
      }
    }
    </script>
    
    <style lang="scss" scoped>
    .dashboard-editor-container {
      padding: 32px;
      background-color: rgb(240, 242, 245);
    
      .github-corner {
        position: absolute;
        top: 0px;
        border: 0;
        right: 0;
      }
    
      .chart-wrapper {
        background: #fff;
        padding: 16px 16px 0;
        margin-bottom: 32px;
      }
    }
    
    @media (max-1024px) {
      .chart-wrapper {
        padding: 8px;
      }
    }
    </style>
    index.vue
    博客园:https://www.cnblogs.com/xianquan
    Copyright ©2020 l-coil
    【转载文章务必保留出处和署名,谢谢!】
查看全文
  • 相关阅读:
    visio中插入顶边大括号
    undefined reference to `SetPduPowerConsumptionCnt'的解决办法
    JMS : Java Message Service (Java消息服务)
    C#自己编写的一个函数 可以删除字符串中指定开头和结尾中间的字符串
    完全JSP分页代码
    用ASP+Access创建网站RSS格式内容摘要
    微软考试杭州考点
    split 分隔字符串
    JSP连接SQL Server 2000系统配置
    全球测试管理系统TestDirector(上)
  • 原文地址:https://www.cnblogs.com/xianquan/p/12782093.html
  • Copyright © 2011-2022 走看看