Mercurial > gemma
changeset 2775:2feb9f8f6c66
client: waterlevel diagram: implemented display of forecast data
author | Markus Kottlaender <markus@intevation.de> |
---|---|
date | Fri, 22 Mar 2019 13:00:10 +0100 |
parents | 6c1c4f55d99b |
children | a0b63e2fca99 |
files | client/src/components/gauge/Waterlevel.vue client/src/store/gauges.js |
diffstat | 2 files changed, 108 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/client/src/components/gauge/Waterlevel.vue Fri Mar 22 12:45:53 2019 +0100 +++ b/client/src/components/gauge/Waterlevel.vue Fri Mar 22 13:00:10 2019 +0100 @@ -41,7 +41,19 @@ font-size: 11px fill: #999 .hdc-ldc-area - fill: rgba(0, 255, 0, 0.15) + fill: rgba(0, 255, 0, 0.1) + .now-line + stroke: #999 + stroke-width: 1 + stroke-dasharray: 5, 5 + clip-path: url(#clip) + .now-line-label + font-size: 11px + fill: #999 + .prediction-area + fill: steelblue + fill-opacity: 0.2 + clip-path: url(#clip) path.nash-sutcliffe fill: none @@ -219,6 +231,15 @@ const isNext = (prev, current) => current.date - prev.date === 15 * 60 * 1000; + const preditionStyle = { + predicted: { + pointStyles: { + fill: "steelblue", + "fill-opacity": 0.6 + } + } + }; + // waterlevel line in big chart // d3-line-chunked plugin: https://github.com/pbeshai/d3-line-chunked var mainLineChart = d3 @@ -227,7 +248,9 @@ .y(d => y(d.waterlevel)) .curve(d3.curveLinear) .isNext(isNext) - .pointAttrs({ r: 2.2 }); + .pointAttrs({ r: 2.2 }) + .chunk(d => (d.predicted ? "predicted" : "line")) + .chunkDefinitions(preditionStyle); // waterlevel line in small chart let navLineChart = d3 .lineChunked() @@ -235,12 +258,42 @@ .y(d => y2(d.waterlevel)) .curve(d3.curveMonotoneX) .isNext(isNext) - .pointAttrs({ r: 1.7 }); + .pointAttrs({ r: 1.7 }) + .chunk(d => (d.predicted ? "predicted" : "line")) + .chunkDefinitions(preditionStyle); // hdc/ldc/mw let refWaterlevelLine = d3 .line() .x(d => x(d.x)) .y(d => y(d.y)); + // now + let nowLine = d3 + .line() + .x(d => x(d.x)) + .y(d => y(d.y)); + let nowLineNav = d3 + .line() + .x(d => x2(d.x)) + .y(d => y2(d.y)); + let nowLineLabel = selection => { + selection.attr( + "transform", + `translate(${x(new Date())}, ${y(WaterlevelMinMax[1] - 16)})` + ); + }; + // prediction area + let predictionArea = d3 + .area() + .defined(d => d.predicted && d.min && d.max) + .x(d => x(d.date)) + .y0(d => y(d.min)) + .y1(d => y(d.max)); + let predictionAreaNav = d3 + .area() + .defined(d => d.predicted && d.min && d.max) + .x(d => x2(d.date)) + .y0(d => y2(d.min)) + .y1(d => y2(d.max)); // DRAWING MAINCHART @@ -334,6 +387,29 @@ .attr("x", x(dateTo) - 20) .attr("y", y(refWaterLevels.MW) - 3); + // now + mainChart + .append("path") + .datum([ + { x: new Date(), y: WaterlevelMinMax[0] }, + { x: new Date(), y: WaterlevelMinMax[1] - 20 } + ]) + .attr("class", "now-line") + .attr("d", nowLine); + mainChart // label + .append("text") + .text(this.$gettext("Now")) + .attr("class", "now-line-label") + .attr("text-anchor", "middle") + .call(nowLineLabel); + + // prediction area + mainChart + .append("path") + .datum(this.waterlevels) + .attr("class", "prediction-area") + .attr("d", predictionArea); + // waterlevel chart mainChart .append("g") @@ -355,6 +431,23 @@ .attr("transform", `translate(0, ${navHeight})`) .call(xAxis2); + // now + navChart + .append("path") + .datum([ + { x: new Date(), y: WaterlevelMinMax[0] }, + { x: new Date(), y: WaterlevelMinMax[1] - 20 } + ]) + .attr("class", "now-line") + .attr("d", nowLineNav); + + // prediction area + navChart + .append("path") + .datum(this.waterlevels) + .attr("class", "prediction-area") + .attr("d", predictionAreaNav); + // waterlevel chart navChart .append("g") @@ -391,10 +484,10 @@ .attr("y", mainHeight - (15 * days + 0.5) + 12); }; - // Show nash-sutcliffe only when x-axis extent is smaller than 31 days - // (2678400000 ms). Since it shows squares representing 1, 2 and 3 days + // Show nash-sutcliffe only when x-axis extent is smaller than 35 days + // (3024000000 ms). Since it shows squares representing 1, 2 and 3 days // it does not make sense to show them on a x-axis with hundres of days. - if (this.nashSutcliffe && x.domain()[1] - x.domain()[0] < 2678400000) { + if (this.nashSutcliffe && x.domain()[1] - x.domain()[0] < 3024000000) { if (nashSut24.samples) { mainChart .append("path") @@ -467,6 +560,9 @@ let s = d3.event.selection || x2.range(); x.domain(s.map(x2.invert, x2)); mainChart.select(".line").call(mainLineChart); + mainChart.select(".now-line").attr("d", nowLine); + mainChart.select(".now-line-label").call(nowLineLabel); + mainChart.select(".prediction-area").attr("d", predictionArea); mainChart .select("path.nash-sutcliffe.ns24") .attr("d", nashSutcliffeBox(24)); @@ -510,6 +606,9 @@ let t = d3.event.transform; x.domain(t.rescaleX(x2).domain()); mainChart.select(".line").call(mainLineChart); + mainChart.select(".now-line").attr("d", nowLine); + mainChart.select(".now-line-label").call(nowLineLabel); + mainChart.select(".prediction-area").attr("d", predictionArea); mainChart .select("path.nash-sutcliffe.ns24") .attr("d", nashSutcliffeBox(24));
--- a/client/src/store/gauges.js Fri Mar 22 12:45:53 2019 +0100 +++ b/client/src/store/gauges.js Fri Mar 22 13:00:10 2019 +0100 @@ -17,6 +17,8 @@ let dateFrom = new Date(); dateFrom.setDate(dateFrom.getDate() - 30); +let dateTo = new Date(); +dateTo.setDate(dateTo.getDate() + 3); const init = () => { return { @@ -26,7 +28,7 @@ meanWaterlevels: [], nashSutcliffe: null, dateFrom: dateFrom, - dateTo: new Date() + dateTo: dateTo }; }; @@ -163,27 +165,6 @@ }) .then(response => { commit("nashSutcliffe", response.data); - // dest data - // commit("nashSutcliffe", { - // when: "2019-03-20T10:38:05.687", - // coeffs: [ - // { - // value: 0.814, - // samples: 18, - // hours: 24 - // }, - // { - // value: 0.319, - // samples: 36, - // hours: 48 - // }, - // { - // value: -0.20546757, - // samples: 54, - // hours: 72 - // } - // ] - // }); resolve(response.data); }) .catch(error => {