@geoblocks/elevation-profile 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import {LitElement, svg} from 'lit';
2
2
  import {customElement, state, property} from 'lit/decorators.js';
3
3
  import {ResizeController} from '@lit-labs/observers/resize-controller.js';
4
- import {createRef, ref} from 'lit/directives/ref.js';
4
+ import type {PropertyValues} from 'lit';
5
5
 
6
6
  import {extent, bisector} from 'd3-array';
7
7
  import {scaleLinear} from 'd3-scale';
@@ -9,6 +9,7 @@ import {line, area} from 'd3-shape';
9
9
  import {axisBottom, axisLeft} from 'd3-axis';
10
10
  import {select, pointer} from 'd3-selection';
11
11
 
12
+ type PlotPoint = number[];
12
13
 
13
14
  @customElement('elevation-profile')
14
15
  export class ElevationProfile extends LitElement {
@@ -17,42 +18,49 @@ export class ElevationProfile extends LitElement {
17
18
  @property({type: Object}) tickSize = {x: 100, y: 40};
18
19
 
19
20
  @state() pointer = {x: 0, y: 0};
20
- private resizeController = new ResizeController(this, {});
21
+ private _resizeController = new ResizeController(this, {});
21
22
 
22
- private plotData: number[][] = [];
23
+ private plotData: PlotPoint[] = [];
23
24
  private scaleX = scaleLinear();
24
25
  private scaleY = scaleLinear();
25
26
 
26
- private bisectDistance = bisector((data) => data[0]).left;
27
+ private bisectDistance = bisector((point: PlotPoint) => point[0]);
27
28
 
28
29
  private line = line()
29
- .x((point) => this.scaleX(point[0]))
30
- .y((point) => this.scaleY(point[1]));
30
+ .x((point: PlotPoint) => this.scaleX(point[0]))
31
+ .y((point: PlotPoint) => this.scaleY(point[1]));
31
32
  private area = area()
32
- .x((point) => this.scaleX(point[0]))
33
- .y1((point) => this.scaleY(point[1]));
34
- private xAxis = axisBottom(this.scaleX)
35
- .tickFormat((i) => i + ' m');
36
- private yAxis = axisLeft(this.scaleY)
37
- .tickFormat((i) => i + ' m');
38
- private xGrid = axisBottom(this.scaleX).tickFormat(() => '');
39
- private yGrid = axisLeft(this.scaleY).tickFormat(() => '');
40
-
41
- private xRef = createRef();
42
- private yRef = createRef();
43
- private yGridRef = createRef();
44
- private xGridRef = createRef();
45
-
46
- willUpdate(changedProperties) {
33
+ .x((point: PlotPoint) => this.scaleX(point[0]))
34
+ .y1((point: PlotPoint) => this.scaleY(point[1]));
35
+ private xAxis = axisBottom(this.scaleX).tickFormat((value: number) => this.tickFormat(value));
36
+ private yAxis = axisLeft(this.scaleY).tickFormat((value: number) => this.tickFormat(value));
37
+ private xGrid = axisBottom(this.scaleX).tickFormat(() => '');
38
+ private yGrid = axisLeft(this.scaleY).tickFormat(() => '');
39
+
40
+ private meterFormat = Intl.NumberFormat('de-CH', {
41
+ style: 'unit',
42
+ unit: 'meter',
43
+ });
44
+
45
+ private kilometerFormat = Intl.NumberFormat('de-CH', {
46
+ style: 'unit',
47
+ unit: 'kilometer',
48
+ });
49
+
50
+ override willUpdate(changedProperties: PropertyValues) {
47
51
  if (changedProperties.has('lines')) {
48
52
  this.plotData = this.lines.map((coordinate) => [coordinate[3], coordinate[2]]);
49
53
 
50
- this.scaleX.domain(extent(this.plotData, (data) => data[0]));
51
- this.scaleY.domain(extent(this.plotData, (data) => data[1])).nice();
54
+ this.scaleX.domain(extent(this.plotData, (data: PlotPoint) => data[0]));
55
+ this.scaleY.domain(extent(this.plotData, (data: PlotPoint) => data[1])).nice();
52
56
  }
53
57
  }
54
58
 
55
- render() {
59
+ // override shouldUpdate(): boolean {
60
+ // return this.lines.length > 0;
61
+ // }
62
+
63
+ override render() {
56
64
  const width = this.offsetWidth;
57
65
  const height = this.offsetHeight;
58
66
 
@@ -71,22 +79,22 @@ export class ElevationProfile extends LitElement {
71
79
  this.yAxis.ticks(yTicks);
72
80
  this.yGrid.ticks(yTicks);
73
81
 
74
- select(this.xRef.value).call(this.xAxis);
75
- select(this.yRef.value).call(this.yAxis);
76
- select(this.xGridRef.value).call(this.xGrid);
77
- select(this.yGridRef.value).call(this.yGrid);
82
+ select(this.querySelector('.axis.x')).call(this.xAxis);
83
+ select(this.querySelector('.axis.y')).call(this.yAxis);
84
+ select(this.querySelector('.grid.x')).call(this.xGrid);
85
+ select(this.querySelector('.grid.y')).call(this.yGrid);
78
86
 
79
87
  return svg`
80
- <svg width="${width}" height="${height}">
81
- <g class="grid y" ${ref(this.yGridRef)} transform="translate(${this.margin.left}, 0)" />
82
- <g class="grid x" ${ref(this.xGridRef)} transform="translate(0, ${this.margin.bottom})" />
83
- <g class="axis x" ${ref(this.xRef)} transform="translate(0, ${height - this.margin.bottom})" />
84
- <g class="axis y" ${ref(this.yRef)} transform="translate(${this.margin.left}, 0)" />
88
+ <svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg">
89
+ <g class="grid y" transform="translate(${this.margin.left}, 0)" />
90
+ <g class="grid x" transform="translate(0, ${this.margin.bottom})" />
91
+ <g class="axis x" transform="translate(0, ${height - this.margin.bottom})" />
92
+ <g class="axis y" transform="translate(${this.margin.left}, 0)" />
85
93
  <path class="area" d="${this.area(this.plotData)}" />
86
94
  <path class="elevation" d="${this.line(this.plotData)}" fill="none" />
87
95
  <g style="visibility: ${this.pointer.x > 0 ? 'visible' : 'hidden'}">
88
96
  <path class="elevation highlight" d="${this.line(this.plotData)}" fill="none"
89
- clip-path="polygon(0 0, ${this.pointer.x - 40} 0, ${this.pointer.x - 40} 100%, 0 100%)"
97
+ clip-path="polygon(0 0, ${this.pointer.x - this.margin.left} 0, ${this.pointer.x - this.margin.left} 100%, 0 100%)"
90
98
  />
91
99
  <line
92
100
  class="pointer-line y"
@@ -102,6 +110,7 @@ export class ElevationProfile extends LitElement {
102
110
  height="${height}"
103
111
  fill="none"
104
112
  pointer-events="all"
113
+ style="touch-action: none;"
105
114
  @pointermove="${this.pointerMove}"
106
115
  @pointerout="${this.pointerOut}"
107
116
  />
@@ -109,9 +118,26 @@ export class ElevationProfile extends LitElement {
109
118
  `;
110
119
  }
111
120
 
121
+ private tickFormat(value: number) {
122
+ if (value < 1000) {
123
+ return this.meterFormat.format(value);
124
+ } else {
125
+ return this.kilometerFormat.format(value / 1000);
126
+ }
127
+ }
128
+
129
+ override firstUpdated() {
130
+ // FIXME: because the ref element are used before render is done, we need to force an update
131
+ this.requestUpdate();
132
+ }
133
+
112
134
  private pointerMove(event: PointerEvent) {
113
135
  const pointerDistance = this.scaleX.invert(pointer(event)[0]);
114
- const index = Math.min(this.bisectDistance(this.plotData, pointerDistance), this.plotData.length - 1);
136
+ const index = Math.min(this.bisectDistance.left(this.plotData, pointerDistance), this.plotData.length - 1);
137
+
138
+ if (index < 0) {
139
+ return;
140
+ }
115
141
  // FIXME:
116
142
  // var d0 = data[i - 1]
117
143
  // var d1 = data[i];
@@ -143,7 +169,7 @@ export class ElevationProfile extends LitElement {
143
169
  this.dispatchEvent(new CustomEvent('out'));
144
170
  }
145
171
 
146
- createRenderRoot() {
172
+ override createRenderRoot() {
147
173
  return this;
148
174
  }
149
175
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geoblocks/elevation-profile",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "license": "BSD-3-Clause",
5
5
  "repository": "github:geoblocks/elevation-profile",
6
6
  "type": "module",