0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Vue + SVGでシンプルなドーナツチャートコンポーネント

Posted at

シンプルなドーナツチャートが必要になったのでvue+svgで作りました

成果物

See the Pen donut-chart vue component by sqrt3 (@sqrt3) on CodePen.

内容

template.pug
.donutChart(:style="{ width: `${width}px`, height: `${height}px` }")
    svg.donutChart_circleWrapper(:width="width" :height="height" viewBox="0 0 42 42")
      circle(v-if="border" :cx="cxy" :cy="cxy" :r="radius" fill="transparent" stroke="grey" :stroke-width="borderStrokeWidth")
      circle.donutChart_circle(
        v-for="(e, i) in chartData"
        :cx="cxy"
        :cy="cxy"
        :r="radius"
        fill="transparent"
        :stroke="e.color"
        :stroke-width="strokeWidth"
        :data-fill="e.value")
    svg(:width="width" :height="height" viewBox="0 0 42 42")
      text.donutChart_text(x="50%" y="50%" text-anchor="middle" dominant-baseline="central") {{ text }}
css.styl
.donutChart
  position relative

  &_circleWrapper
    position absolute
    transform-origin center
    transform rotate(-90deg)
    transform-box fill-box

  &_circle
    transform-box fill-box

  &_text
    font-size 0.4em
script.js
export default DonutChart {
  props: {
    value: {
      type: Array,
      required: true
    },
    width: {
      type: Number,
      default: 100
    },
    height: {
      type: Number,
      default: 100
    },
    strokeWidth: {
      type: Number,
      default: 6
    },
    text: String,
    border: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      radius: 15.91549430918954,
      cxy: 21      
    }
  },
  computed: {
    totalValue () {
      return this.value.map(e => e.value).reduce((prev, e) => prev + e)
    },
    criteriaValue () {
      return 100 / this.totalValue
    },
    chartData () {
      return this.value.filter(e => (e.value > 0)).map(e => {
        return {
          value: e.value * this.criteriaValue,
          color: e.color
        }
      })
    },
    borderStrokeWidth () {
      return this.strokeWidth + 0.5
    }
  },
  mounted () {
    this.draw()
  },
  methods: {
    draw () {
      const elms = this.$el.querySelectorAll(".donutChart_circle")
      let offset = 0
      elms.forEach((e, i) => {
        const val = parseFloat(e.getAttribute('data-fill'))
        const dasharray = [val, 100 - val]
        e.setAttribute("stroke-dasharray", dasharray)
        e.setAttribute("stroke-dashoffset", offset * -1)
        offset = offset + val
      })
    }
  }                 
})

stroke-dasharrayで点線の間隔をうまく調整してstroke-dashoffsetでずらして描画していく感じですね
数値を出したいところですが大変そうなのでとりあえずここまで

参考

Scratch-made SVG Donut & Pie Charts in HTML5

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?