Mercurial > gemma
comparison client/src/components/gauge/Waterlevel.vue @ 2590:1686ec185155
client: added gauge waterlevel example diagram
author | Markus Kottlaender <markus@intevation.de> |
---|---|
date | Tue, 12 Mar 2019 08:37:09 +0100 |
parents | |
children | 8774054959a7 |
comparison
equal
deleted
inserted
replaced
2589:f4c399a496cb | 2590:1686ec185155 |
---|---|
1 <template> | |
2 <div class="flex-fill diagram-container"></div> | |
3 </template> | |
4 | |
5 <style lang="sass" scoped> | |
6 .diagram-container | |
7 /deep/ .area | |
8 stroke: steelblue | |
9 stroke-width: 2 | |
10 fill: transparent | |
11 clip-path: url(#clip) | |
12 | |
13 /deep/ .zoom | |
14 cursor: move | |
15 fill: none | |
16 pointer-events: all | |
17 </style> | |
18 | |
19 <script> | |
20 /* This is Free Software under GNU Affero General Public License v >= 3.0 | |
21 * without warranty, see README.md and license for details. | |
22 * | |
23 * SPDX-License-Identifier: AGPL-3.0-or-later | |
24 * License-Filename: LICENSES/AGPL-3.0.txt | |
25 * | |
26 * Copyright (C) 2018 by via donau | |
27 * – Österreichische Wasserstraßen-Gesellschaft mbH | |
28 * Software engineering by Intevation GmbH | |
29 * | |
30 * Author(s): | |
31 * Markus Kottländer <markus.kottlaender@intevation.de> | |
32 */ | |
33 | |
34 import { mapState } from "vuex"; | |
35 import * as d3 from "d3"; | |
36 import debounce from "debounce"; | |
37 | |
38 export default { | |
39 computed: { | |
40 ...mapState("gauges", ["selectedGauge"]), | |
41 waterlevels() { | |
42 let data = []; | |
43 let waterlevel = 2.5; | |
44 for (let i = 1; i <= 365; i++) { | |
45 let date = new Date(); | |
46 date.setFullYear(2018); | |
47 date.setDate(date.getDate() + i); | |
48 waterlevel *= Math.random() * (1.02 - 0.98) + 0.98; | |
49 data.push({ date, waterlevel }); | |
50 } | |
51 return data; | |
52 } | |
53 }, | |
54 methods: { | |
55 drawDiagram() { | |
56 var svgWidth = document.querySelector(".diagram-container").clientWidth; | |
57 var svgHeight = document.querySelector(".diagram-container").clientHeight; | |
58 d3.select(".diagram-container svg").remove(); | |
59 var svg = d3.select(".diagram-container").append("svg"); | |
60 svg.attr("width", "100%").attr("height", "100%"); | |
61 let margin = { top: 20, right: 20, bottom: 110, left: 40 }, | |
62 margin2 = { | |
63 top: svgHeight - margin.top - 50, | |
64 right: 20, | |
65 bottom: 30, | |
66 left: 40 | |
67 }, | |
68 width = +svgWidth - margin.left - margin.right, | |
69 height = +svgHeight - margin.top - margin.bottom, | |
70 height2 = +svgHeight - margin2.top - margin2.bottom; | |
71 | |
72 var x = d3.scaleTime().range([0, width]), | |
73 x2 = d3.scaleTime().range([0, width]), | |
74 y = d3.scaleLinear().range([height, 0]), | |
75 y2 = d3.scaleLinear().range([height2, 0]); | |
76 | |
77 var xAxis = d3.axisBottom(x), | |
78 xAxis2 = d3.axisBottom(x2), | |
79 yAxis = d3.axisLeft(y); | |
80 | |
81 var brush = d3 | |
82 .brushX() | |
83 .extent([[0, 0], [width, height2]]) | |
84 .on("brush end", brushed); | |
85 | |
86 var zoom = d3 | |
87 .zoom() | |
88 .scaleExtent([1, Infinity]) | |
89 .translateExtent([[0, 0], [width, height]]) | |
90 .extent([[0, 0], [width, height]]) | |
91 .on("zoom", zoomed); | |
92 | |
93 var area = d3 | |
94 .line() | |
95 .curve(d3.curveMonotoneX) | |
96 .x(function(d) { | |
97 return x(d.date); | |
98 }) | |
99 .y(function(d) { | |
100 return y(d.waterlevel); | |
101 }); | |
102 | |
103 var area2 = d3 | |
104 .line() | |
105 .curve(d3.curveMonotoneX) | |
106 .x(function(d) { | |
107 return x2(d.date); | |
108 }) | |
109 .y(function(d) { | |
110 return y2(d.waterlevel); | |
111 }); | |
112 | |
113 svg | |
114 .append("defs") | |
115 .append("clipPath") | |
116 .attr("id", "clip") | |
117 .append("rect") | |
118 .attr("width", width) | |
119 .attr("height", height); | |
120 | |
121 var focus = svg | |
122 .append("g") | |
123 .attr("class", "focus") | |
124 .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
125 | |
126 var context = svg | |
127 .append("g") | |
128 .attr("class", "context") | |
129 .attr( | |
130 "transform", | |
131 "translate(" + margin2.left + "," + margin2.top + ")" | |
132 ); | |
133 | |
134 x.domain( | |
135 d3.extent(this.waterlevels, function(d) { | |
136 return d.date; | |
137 }) | |
138 ); | |
139 y.domain([0, 5]); | |
140 x2.domain(x.domain()); | |
141 y2.domain(y.domain()); | |
142 | |
143 focus | |
144 .append("path") | |
145 .datum(this.waterlevels) | |
146 .attr("class", "area") | |
147 .attr("d", area); | |
148 | |
149 focus | |
150 .append("g") | |
151 .attr("class", "axis axis--x") | |
152 .attr("transform", "translate(0," + height + ")") | |
153 .call(xAxis); | |
154 | |
155 focus | |
156 .append("g") | |
157 .attr("class", "axis axis--y") | |
158 .call(yAxis); | |
159 | |
160 context | |
161 .append("path") | |
162 .datum(this.waterlevels) | |
163 .attr("class", "area") | |
164 .attr("d", area2); | |
165 | |
166 context | |
167 .append("g") | |
168 .attr("class", "axis axis--x") | |
169 .attr("transform", "translate(0," + height2 + ")") | |
170 .call(xAxis2); | |
171 | |
172 context | |
173 .append("g") | |
174 .attr("class", "brush") | |
175 .call(brush) | |
176 .call(brush.move, x.range()); | |
177 | |
178 svg | |
179 .append("rect") | |
180 .attr("class", "zoom") | |
181 .attr("width", width) | |
182 .attr("height", height) | |
183 .attr("transform", "translate(" + margin.left + "," + margin.top + ")") | |
184 .call(zoom); | |
185 | |
186 function brushed() { | |
187 if (d3.event.sourceEvent && d3.event.sourceEvent.type === "zoom") | |
188 return; // ignore brush-by-zoom | |
189 var s = d3.event.selection || x2.range(); | |
190 x.domain(s.map(x2.invert, x2)); | |
191 focus.select(".area").attr("d", area); | |
192 focus.select(".axis--x").call(xAxis); | |
193 svg | |
194 .select(".zoom") | |
195 .call( | |
196 zoom.transform, | |
197 d3.zoomIdentity.scale(width / (s[1] - s[0])).translate(-s[0], 0) | |
198 ); | |
199 } | |
200 | |
201 function zoomed() { | |
202 if (d3.event.sourceEvent && d3.event.sourceEvent.type === "brush") | |
203 return; // ignore zoom-by-brush | |
204 var t = d3.event.transform; | |
205 x.domain(t.rescaleX(x2).domain()); | |
206 focus.select(".area").attr("d", area); | |
207 focus.select(".axis--x").call(xAxis); | |
208 context.select(".brush").call(brush.move, x.range().map(t.invertX, t)); | |
209 } | |
210 } | |
211 }, | |
212 created() { | |
213 window.addEventListener("resize", debounce(this.drawDiagram), 100); | |
214 }, | |
215 mounted() { | |
216 this.drawDiagram(); | |
217 }, | |
218 updated() { | |
219 this.drawDiagram(); | |
220 } | |
221 }; | |
222 </script> |