view client/src/components/Fairwayprofile.vue @ 572:59b22dc924c8

feat: Added sample profile to graph
author Thomas Junk <thomas.junk@intevation.de>
date Wed, 05 Sep 2018 16:14:06 +0200
parents fb519eaa462d
children 03c15abb8372
line wrap: on
line source

<template>
  <div class="fairwayprofile">
    <svg :width="width +'px'" :height="height +'px'">
    </svg>
  </div>
</template>

<style lang="scss">
.fairwayprofile {
  background-color: white;
  margin-left: auto;
  margin-right: auto;
  margin-top: auto;
  margin-bottom: auto;
}
</style>

<script>
import * as d3 from "d3";

const BLUE_WATER = "#005DFF";
const GROUND_COLOR = "#4A2F06";

const sampleData = [
  { x: 3, y: -3.0 },
  { x: 25, y: -2.0 },
  { x: 50, y: -4.5 },
  { x: 75, y: -4.0 },
  { x: 100, y: -3.0 },
  { x: 125, y: -4.0 },
  { x: 150, y: -5.0 },
  { x: 175, y: -4.0 },
  { x: 200, y: -3.0 },
  { x: 225, y: -3.5 },
  { x: 250, y: -3.0 },
  { x: 297, y: -2.5 }
];

export default {
  name: "fairwayprofile",
  props: ["width", "height", "xScale", "yScaleLeft", "yScaleRight", "margin"],
  data() {
    return {};
  },
  methods: {
    generateCoordinates(svg, height, width) {
      let xScale = d3
        .scaleLinear()
        .domain(this.xScale)
        .rangeRound([0, width]);

      xScale.ticks(5);
      let yScaleLeft = d3
        .scaleLinear()
        .domain(this.yScaleLeft)
        .rangeRound([height, 0]);

      let yScaleRight = d3
        .scaleLinear()
        .domain(this.yScaleRight)
        .rangeRound([height, 0]);

      let xAxis = d3.axisBottom(xScale);
      let yAxis = d3.axisLeft(yScaleLeft);
      let yAxis2 = d3.axisRight(yScaleRight);
      let graph = svg
        .append("g")
        .attr(
          "transform",
          "translate(" + this.margin.left + "," + this.margin.top + ")"
        );
      graph
        .append("g")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis.ticks(5));
      graph.append("g").call(yAxis);
      graph
        .append("g")
        .attr("transform", "translate(" + width + ",0)")
        .call(yAxis2);
      return { xScale, yScaleLeft, yScaleRight, graph };
    },
    drawWaterlevel(graph, height, width) {
      const zerolevel = this.height / 2 - this.margin.top;
      const toBottom = height / 2;
      graph
        .append("rect")
        .attr("x", 0)
        .attr("y", zerolevel)
        .attr("width", width)
        .attr("height", toBottom)
        .style("fill", BLUE_WATER);
    },
    drawProfile({ graph, xScale, yScaleRight, sampleData, height }) {
      let profileLine = d3
        .line()
        .x(d => {
          return xScale(d.x);
        })
        .y(d => {
          return yScaleRight(d.y);
        });
      let profileArea = d3
        .area()
        .x(function(d) {
          return xScale(d.x);
        })
        .y0(height)
        .y1(function(d) {
          return yScaleRight(d.y);
        });
      graph
        .append("path")
        .datum(sampleData)
        .attr("fill", GROUND_COLOR)
        .attr("stroke", GROUND_COLOR)
        .attr("stroke-width", 3)
        .attr("d", profileArea);
      graph
        .append("path")
        .datum(sampleData)
        .attr("fill", "none")
        .attr("stroke", "black")
        .attr("stroke-linejoin", "round")
        .attr("stroke-linecap", "round")
        .attr("stroke-width", 3)
        .attr("d", profileLine);
    }
  },
  mounted() {
    let svg = d3.select("svg");
    const width = this.width - this.margin.right - this.margin.left;
    const height = this.height - this.margin.top - this.margin.bottom;

    const { xScale, yScaleRight, graph } = this.generateCoordinates(
      svg,
      height,
      width
    );
    this.drawWaterlevel(graph, height, width);
    this.drawProfile({
      graph,
      xScale,
      yScaleRight,
      sampleData,
      height,
      width
    });
  }
};
</script>