D3 Updating stacked bar chart

https://codereview.stackexchange.com/q/204586/120114

by samonela

HTML

<script src="https://cdn.rawgit.com/chrisvfritz/459a93673c5f2e362464125381e51515/raw/9e07d5bda30203dc788894cba18749a3bb44e79d/get-players.js"></script>
<script src="https://unpkg.com/d3"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<div id="app">
  <chart :stacked-xor-y="stacked" :tasks="tasks" :svg-width="svgWidth" :svg-height="svgHeight"></chart>
  <button @click="toggleStacked">
  change bars layout
  </button> {{stacked}}
</div>
<script type="text/x-template" id="chart-template">
  <div>
    <svg ref="stacked-svg-tasks" id="stacked-svg-tasks" :width="svgWidth" :height="svgHeight"></svg>
  </div>
</script>

JavaScript

Vue.component('chart', {
  template: '#chart-template',
  name: 'TasksStackedBarChart',
  props: ['tasks', 'svgWidth', 'svgHeight', 'stackedXorY'],
  data() {
    return {
      X_AXIS_HEIGHT: 20,
      Y_AXIS_WIDTH: 50,
      svgMargin: {
        top: 20
      },
      barChartGroup: {
        width: 0,
        height: 0,
        x: 0,
        y: 0,
      },
      GbT: 50, // gap between tasks
      stageWidth: 0,
      toalStages: 0,
      xPosOfTasks: [],
      yScale: null,
      yScaleDomainEnd: 0,
    };
  },

  created() {
    this.barChartGroup.width = this.svgWidth - this.Y_AXIS_WIDTH;
    this.barChartGroup.height = this.svgHeight - this.X_AXIS_HEIGHT;
    this.barChartGroup.x = this.Y_AXIS_WIDTH;
    this.barChartGroup.y = this.X_AXIS_HEIGHT;

    this.toalStages = this.tasks.map(v => v.taskStages.length).reduce((s, v) => s + v, 0);
    this.stageWidth = this.getStageWidth();
    this.xPosOfTasks = this.getXPosOfTask(this.GbT, this.tasks, this.stageWidth, this.stackedXorY);
    this.yScaleDomainEnd = this.getLongestTask();
    this.yScale = this.getScaleForTask(this.barChartGroup.height, this.yScaleDomainEnd);
  },

  mounted() {
    this.chartBuilder();
  },

  methods: {
    getScaleForTask(rangeEnd, domainEnd) {
      const calcRangeEnd = rangeEnd - this.svgMargin.top - this.X_AXIS_HEIGHT;
      return d3.scaleLinear()
        .range([0, calcRangeEnd])
        .domain([0, domainEnd]);
    },

    getLongestTask() {
      return d3.max(this.tasks.map(t => t.taskTotalTime));
    },

    getStageWidth() { // will keep using this. to see if it's better to work like this or i should pass parameters
      const numOfChartBars = this.stackedXorY ? this.toalStages : this.tasks.length;
      return Math.floor((this.svgWidth - (this.GbT * (this.tasks.length + 1))) / numOfChartBars);
    },

    getPosOfStage(stage, stageIndex) {
      const x = stageIndex * this.stageWidth * this.stackedXorY;
      // this sets the bars at the bottom than this.yScale(s.y)...