DashChartDemo.vue 4.06 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>