Vue Line Graph

by Wave7KN

HTML

<div id="line-graph">
  <svg :width="100 * ratio"
    :height="svgHeight"
    :viewBox="'0 0 ' + 100 * ratio + ' ' + svgHeight"
    class="line-graph">
    <g v-for="data in all_data" :class="'type-' + data.type">
      <g v-for="(score, index) in data.scores" :key="index">
        <line v-if="index != 0"
          :x1="data.scores[index - 1] * ratio"
          :y1="(index - 1) * row_height"
          :x2="score * ratio"
          :y2="index * row_height"/>
        <circle
          :cx="score * ratio"
          :cy="index * row_height"/>
      </g>
    </g>
  </svg>
</div>

SCSS

$types: (
  'a': #838a90,
  'b': #62b2f7,
  'c': #e24f7c,
  'd': #e69042
);

.line-graph{
  background-color: #fff;
  padding: 20px;
  @each $type, $color in $types{
    .type-#{$type}{
      circle{
        cursor: pointer;
        fill: $color;
        r: 4;
        transition: all .1s;
        &:hover{
          r: 6;
        }
      }
      line{
        stroke: rgba($color, .5);
        stroke-width: 1.5;
      }
    }
  }
}

JavaScript

new Vue({
  el: '#line-graph',
  data: {
    all_data: [
      {
      	type: 'a',
	      scores: [34, 46, 28, 39, 60]
      },
      {
      	type: 'b',
	      scores: [47, 32, 52, 33, 52]  
      },
      {
      	type: 'c',
	      scores: [38, 29, 42, 53, 41]
      },
      {
      	type: 'd',
	      scores: [52, 57, 69, 48, 46]
      }
    ],
    ratio: 3,
    row_height: 30,
  },
  computed: {
  	svgHeight(){
    	return (this.all_data[0].scores.length - 1) * this.row_height
    }
  },
  mounted () {
  }
})