Mercurial > gemma
diff client/src/components/gauge/HydrologicalConditions.vue @ 2791:2b79c0871138
client: spuc8: draw diagrams
The line and area charts from spuc 8 are being drawn but there's a lot missing like tooltips
and toggeling individual charts.
author | Markus Kottlaender <markus@intevation.de> |
---|---|
date | Mon, 25 Mar 2019 12:07:00 +0100 |
parents | 71e7237110ba |
children | 49c1570919ae |
line wrap: on
line diff
--- a/client/src/components/gauge/HydrologicalConditions.vue Mon Mar 25 11:42:31 2019 +0100 +++ b/client/src/components/gauge/HydrologicalConditions.vue Mon Mar 25 12:07:00 2019 +0100 @@ -11,8 +11,24 @@ <style lang="sass" scoped> .diagram-container /deep/ + .hide + opacity: 0 .line clip-path: url(#clip) + stroke-width: 2 + fill: none + &.mean + stroke: steelblue + &.median + stroke: black + &.q25 + stroke: orange + &.q75 + stroke: purple + .area + clip-path: url(#clip) + stroke: none + fill: lightsteelblue .hdc-line, .ldc-line, @@ -64,15 +80,10 @@ */ import { mapState, mapGetters } from "vuex"; -import * as d3Base from "d3"; +import * as d3 from "d3"; import debounce from "debounce"; -import { lineChunked } from "d3-line-chunked"; import { startOfYear, endOfYear } from "date-fns"; -// we should load only d3 modules we need but for now we'll go with the lazy way -// https://www.giacomodebidda.com/how-to-import-d3-plugins-with-webpack/ -const d3 = Object.assign(d3Base, { lineChunked }); - export default { computed: { ...mapState("gauges", ["meanWaterlevels"]), @@ -158,6 +169,9 @@ .tickSizeInner(mainHeight) .tickSizeOuter(0) .tickFormat(date => { + // make the x-axis label formats dynamic, based on zoom + // but never display year numbers since they don't make any sense in + // this diagram return (d3.timeSecond(date) < date ? d3.timeFormat(".%L") : d3.timeMinute(date) < date @@ -180,27 +194,28 @@ // PREPARING CHART FUNCTIONS - // points are "next to each other" when they are exactly 1 day apart - const isNext = (prev, current) => - current.date - prev.date === 24 * 60 * 60 * 1000; + // waterlevel line charts in big chart + const lineChart = type => + d3 + .line() + .x(d => x(d.date)) + .y(d => y(d[type])) + .curve(d3.curveLinear); - // waterlevel line in big chart - // d3-line-chunked plugin: https://github.com/pbeshai/d3-line-chunked - var mainLineChart = d3 - .lineChunked() + // overall min/max area chart + const areaChart = d3 + .area() .x(d => x(d.date)) - .y(d => y(d.waterlevel)) - .curve(d3.curveLinear) - .isNext(isNext) - .pointAttrs({ r: 2.2 }); - // waterlevel line in small chart - let navLineChart = d3 - .lineChunked() + .y0(d => y(d.min)) + .y1(d => y(d.max)); + + // overall min/max area chart in nav + const areaChartNav = d3 + .area() .x(d => x2(d.date)) - .y(d => y2(d.waterlevel)) - .curve(d3.curveMonotoneX) - .isNext(isNext) - .pointAttrs({ r: 1.7 }); + .y0(d => y2(d.min)) + .y1(d => y2(d.max)); + // hdc/ldc/mw let refWaterlevelLine = d3 .line() @@ -243,6 +258,13 @@ .selectAll(".tick text") .attr("x", -25); + // overall min/max area chart + mainChart + .append("path") + .datum(this.meanWaterlevels) + .attr("class", "area") + .attr("d", areaChart); + // reference waterlevels // HDC mainChart @@ -290,12 +312,30 @@ .attr("x", x(yearEnd) - 20) .attr("y", y(refWaterLevels.MW) - 3); - // waterlevel chart + // mean waterlevel chart + mainChart + .append("path") + .attr("class", "line mean") + .datum(this.meanWaterlevels) + .attr("d", lineChart("mean")); + // median waterlevel chart mainChart - .append("g") - .attr("class", "line") - .datum([]) - .call(mainLineChart); + .append("path") + .attr("class", "line median") + .datum(this.meanWaterlevels) + .attr("d", lineChart("median")); + // q25 waterlevel chart + mainChart + .append("path") + .attr("class", "line q25") + .datum(this.meanWaterlevels) + .attr("d", lineChart("q25")); + // q75 waterlevel chart + mainChart + .append("path") + .attr("class", "line q75") + .datum(this.meanWaterlevels) + .attr("d", lineChart("q75")); // DRAWING NAVCHART @@ -311,15 +351,28 @@ .attr("transform", `translate(0, ${navHeight})`) .call(xAxis2); - // waterlevel chart + // overall min/max area chart navChart - .append("g") - .attr("class", "line") - .datum([]) - .call(navLineChart); + .append("path") + .datum(this.meanWaterlevels) + .attr("class", "area") + .attr("d", areaChartNav); // INTERACTIVITY + const updateChart = () => { + mainChart.select(".line.mean").attr("d", lineChart("mean")); + mainChart.select(".line.median").attr("d", lineChart("median")); + mainChart.select(".line.q25").attr("d", lineChart("q25")); + mainChart.select(".line.q75").attr("d", lineChart("q75")); + mainChart.select(".area").attr("d", areaChart); + mainChart + .select(".axis--x") + .call(xAxis) + .selectAll(".tick text") + .attr("y", 15); + }; + // selecting time period in nav chart let brush = d3 .brushX() @@ -330,12 +383,7 @@ return; // ignore brush-by-zoom let s = d3.event.selection || x2.range(); x.domain(s.map(x2.invert, x2)); - mainChart.select(".line").call(mainLineChart); - mainChart - .select(".axis--x") - .call(xAxis) - .selectAll(".tick text") - .attr("y", 15); + updateChart(); svg .select(".zoom") .call( @@ -355,12 +403,7 @@ return; // ignore zoom-by-brush let t = d3.event.transform; x.domain(t.rescaleX(x2).domain()); - mainChart.select(".line").call(mainLineChart); - mainChart - .select(".axis--x") - .call(xAxis) - .selectAll(".tick text") - .attr("y", 15); + updateChart(); navChart .select(".brush") .call(brush.move, x.range().map(t.invertX, t));