DashChartDemo.vue 4.29 KB
<template>
  <div :style="{ padding: '0 0 32px 32px' }">
    <v-chart :forceFit="true" :height="300" :data="chartData" :scale="scale">
      <v-coord type="polar" :startAngle="-202.5" :endAngle="22.5" :radius="0.75"></v-coord>
      <v-axis
        dataKey="value"
        :zIndex="2"
        :line="null"
        :label="axisLabel"
        :subTickCount="4"
        :subTickLine="axisSubTickLine"
        :tickLine="axisTickLine"
        :grid="null"
      ></v-axis>
      <v-axis dataKey="1" :show="false"></v-axis>
      <v-series
        gemo="point"
        position="value*1"
        shape="pointer"
        color="#1890FF"
        :active="false"
      ></v-series>
      <v-guide
        type="arc"
        :zIndex="0"
        :top="false"
        :start="arcGuide1Start"
        :end="arcGuide1End"
        :vStyle="arcGuide1Style"
      ></v-guide>
      <v-guide
        type="arc"
        :zIndex="1"
        :start="arcGuide2Start"
        :end="getArcGuide2End"
        :vStyle="arcGuide2Style"
      ></v-guide>
      <v-guide
        type="html"
        :position="htmlGuidePosition"
        :html="getHtmlGuideHtml()"
      ></v-guide>
    </v-chart>
  </div>
</template>

<script>
  import { registerShape } from 'viser-vue';

  registerShape('point', 'pointer', {
    draw(cfg, container) {
      let point = cfg.points[0];
      point = this.parsePoint(point);
      const center = this.parsePoint({
        x: 0,
        y: 0,
      });
      container.addShape('line', {
        attrs: {
          x1: center.x,
          y1: center.y,
          x2: point.x,
          y2: point.y + 15,
          stroke: cfg.color,
          lineWidth: 5,
          lineCap: 'round',
        }
      });
      return container.addShape('circle', {
        attrs: {
          x: center.x,
          y: center.y,
          r: 9.75,
          stroke: cfg.color,
          lineWidth: 4.5,
          fill: '#fff',
        }
      });
    }
  });

  const scale = [{
    dataKey: 'value',
    min: 0,
    max: 9,
    tickInterval: 1,
    nice: false,
  }];

  const data = [
    { value: 7.0 },
  ];

  export default {
    name:"DashChartDemo",
    props:{
      datasource:{
        type: Number,
        default:7
      },
      title: {
        type: String,
        default: ''
      }
    },
    created(){
      if(!this.datasource){
        this.chartData = data;
      }else{
        this.chartData = [
          { value: this.datasource },
        ];
      }
      this.getChartData()
    },
    watch: {
      'datasource': function (val) {
        this.chartData = [
          { value: val},
        ];
        this.getChartData();
      }
    },
    methods:{
      getChartData(){
        if(this.chartData && this.chartData.length>0){
          this.abcd = this.chartData[0].value * 10
        }else{
          this.abcd = 70
        }
      },
      getHtmlGuideHtml(){
        return '<div style="width: 300px;text-align: center;">\n' +
          '<p style="font-size: 14px;color: #545454;margin: 0;">'+this.title+'</p>\n' +
          '<p style="font-size: 36px;color: #545454;margin: 0;">'+this.abcd+'%</p>\n' +
          '</div>'
      },
      getArcGuide2End(){
        return [this.chartData[0].value, 0.945]
      }
    },
    data() {
      return {
        chartData:[],
        height: 400,
        scale: scale,
        abcd:70,
        axisLabel: {
          offset: -16,
          textStyle: {
            fontSize: 18,
            textAlign: 'center',
            textBaseline: 'middle'
          }
        },
        axisSubTickLine: {
          length: -8,
          stroke: '#fff',
          strokeOpacity: 1,
        },
        axisTickLine: {
          length: -17,
          stroke: '#fff',
          strokeOpacity: 1,
        },
        arcGuide1Start: [0, 0.945],
        arcGuide1End: [9, 0.945],
        arcGuide1Style: {
          stroke: '#CBCBCB',
          lineWidth: 18,
        },
        arcGuide2Start: [0, 0.945],
        arcGuide2Style: {
          stroke: '#1890FF',
          lineWidth: 18,
        },
        htmlGuidePosition: ['50%', '100%'],
        htmlGuideHtml: `
        <div style="width: 300px;text-align: center;">
          <p style="font-size: 14px;color: #545454;margin: 0;">${this.title}</p>
          <p style="font-size: 36px;color: #545454;margin: 0;">${this.abcd}%</p>
        </div>
      `,
      };
    },
  };
</script>