Skip to content

Instantly share code, notes, and snippets.

@zezic
Created July 9, 2018 08:31
Show Gist options
  • Select an option

  • Save zezic/c6d6e77bb1da853339e8f821455fd3b6 to your computer and use it in GitHub Desktop.

Select an option

Save zezic/c6d6e77bb1da853339e8f821455fd3b6 to your computer and use it in GitHub Desktop.

Revisions

  1. zezic created this gist Jul 9, 2018.
    117 changes: 117 additions & 0 deletions SvgChart.vue
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,117 @@
    <template lang='pug'>
    .svg-chart
    button(@click='randomize') Randomize
    transition-group(name='list', tag='div')
    svg.chart(
    v-for='item in list',
    :width='width',
    :height='height',
    :key='item.key'
    )
    path(
    :d='pathD',
    fill='transparent',
    stroke='#0088ff',
    stroke-width='3'
    )
    </template>

    <script>
    import TWEEN from '@tweenjs/tween.js'
    const getDataSet = () => {
    return [...Array(15)].map(() => Math.random())
    }
    const getUUID = () => Math.random().toString()
    export default {
    name: 'svg-chart',
    data () {
    return {
    height: 200,
    width: 500,
    dataSet: getDataSet(),
    tweenedSet: [],
    tween: null,
    key: getUUID()
    }
    },
    created () {
    this.tweenedSet = [...this.dataSet]
    },
    computed: {
    list () {
    return [{key: this.key}]
    },
    stepSize () {
    return this.width / (this.dataSet.length - 1)
    },
    points () {
    return this.tweenedSet.map((item, idx) => {
    return {
    y: this.height * item,
    x: idx * this.stepSize
    }
    })
    },
    pathD () {
    return this.points.reduce((acc, point, idx) => {
    let op = idx === 0 ? 'M' : 'L'
    return `${acc} ${op} ${point.x},${point.y}`
    }, '')
    }
    },
    methods: {
    randomize () {
    this.dataSet = getDataSet()
    }
    },
    watch: {
    dataSet (newSet, oldSet) {
    if (this.tween) {
    this.tween.stop()
    }
    this.key = getUUID()
    function animate () {
    if (TWEEN.update()) {
    requestAnimationFrame(animate)
    }
    }
    this.tween = new TWEEN.Tween(
    oldSet
    ).to(
    newSet,
    1000
    ).onUpdate(set => {
    this.tweenedSet = [...set]
    }).start()
    animate()
    }
    }
    }
    </script>

    <style scoped lang='sass'>
    .svg-chart
    position: relative
    .chart
    position: absolute
    left: 0
    .list-enter-active, .list-leave-active
    transition: all 1s
    .list-leave-to
    opacity: 0
    .list-enter-active
    stroke-dasharray: 1300
    stroke-dashoffset: 1300
    .list-enter-to
    stroke-dashoffset: 0
    </style>