gridviz 2.1.17 → 3.0.1
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.
- package/README.md +2 -3
- package/dist/gridviz.js +8659 -9294
- package/dist/gridviz.min.js +1 -1
- package/package.json +3 -2
- package/src/button/Button.js +14 -15
- package/src/button/FullscreenButton.js +14 -14
- package/src/button/ZoomButtons.js +2 -2
- package/src/{DatasetComponent.js → core/Dataset.js} +33 -13
- package/src/core/Drawable.js +60 -0
- package/src/{GeoCanvas.js → core/GeoCanvas.js} +65 -155
- package/src/core/Layer.js +24 -0
- package/src/{Legend.js → core/Legend.js} +24 -1
- package/src/core/Map.js +474 -0
- package/src/core/MultiResolutionDataset.js +96 -0
- package/src/core/Style.js +84 -0
- package/src/dataset/COGeo.js +5 -5
- package/src/dataset/CSVGrid.js +43 -41
- package/src/dataset/GeoTIFF.js +9 -14
- package/src/dataset/{LGrid.js → JSGrid.js} +9 -11
- package/src/dataset/TiledGrid.js +68 -45
- package/src/index.js +22 -29
- package/src/{BackgroundLayer.js → layer/BackgroundLayer.js} +27 -52
- package/src/{BackgroundLayerWMS.js → layer/BackgroundLayerWMS.js} +21 -45
- package/src/{LineLayer.js → layer/GeoJSONLayer.js} +22 -23
- package/src/layer/GridLayer.js +160 -0
- package/src/{LabelLayer.js → layer/LabelLayer.js} +25 -23
- package/src/legend/ColorCategoryLegend.js +9 -24
- package/src/legend/ColorDiscreteLegend.js +20 -24
- package/src/legend/ColorLegend.js +21 -33
- package/src/legend/OrientationLegend.js +90 -0
- package/src/legend/SizeLegend.js +153 -72
- package/src/style/CompositionStyle.js +71 -84
- package/src/style/ContourStyle.js +2 -36
- package/src/style/DotDensityStyle.js +50 -73
- package/src/style/IsoFenceStyle.js +59 -70
- package/src/style/JoyPlotStyle.js +41 -48
- package/src/style/LegoStyle.js +4 -4
- package/src/style/MosaicStyle.js +30 -39
- package/src/style/NinjaStarStyle.js +45 -68
- package/src/style/PillarStyle.js +70 -93
- package/src/style/SegmentStyle.js +37 -75
- package/src/style/ShapeColorSizeStyle.js +49 -98
- package/src/style/SideCategoryStyle.js +112 -0
- package/src/style/SideStyle.js +99 -133
- package/src/style/{SquareColorCatWGLStyle.js → SquareColorCategoryWebGLStyle.js} +28 -41
- package/src/style/{SquareColorWGLStyle.js → SquareColorWebGLStyle.js} +28 -49
- package/src/style/StrokeStyle.js +43 -70
- package/src/style/TanakaStyle.js +34 -132
- package/src/style/TextStyle.js +43 -64
- package/src/style/TimeSeriesStyle.js +44 -75
- package/src/utils/WebGLSquareColoringAdvanced.js +4 -4
- package/src/utils/scale.js +217 -0
- package/src/utils/stretching.js +86 -129
- package/src/utils/{Utils.js → utils.js} +15 -0
- package/src/utils/webGLUtils.js +4 -5
- package/src/utils/zoomUtils.js +30 -30
- package/src/App.js +0 -760
- package/src/Dataset.js +0 -76
- package/src/Layer.js +0 -103
- package/src/Style.js +0 -131
- package/src/dataset/GridTile.js +0 -41
- package/src/legend/SegmentOrientationLegend.js +0 -87
- package/src/legend/SegmentWidthLegend.js +0 -101
- package/src/style/CompositionStyle_.js +0 -293
- package/src/style/ShapeColorSizeStyle_.js +0 -108
- package/src/style/SideCatStyle.js +0 -172
- /package/src/{Tooltip.js → core/Tooltip.js} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
//@ts-check
|
|
2
2
|
'use strict'
|
|
3
3
|
|
|
4
|
+
import { Layer } from '../core/Layer.js'
|
|
4
5
|
import { csv } from 'd3-fetch'
|
|
5
6
|
|
|
6
7
|
/** A label. The name is the text to show. (x,y) are the coordinates in the same CRS as the grid.
|
|
@@ -14,11 +15,12 @@ import { csv } from 'd3-fetch'
|
|
|
14
15
|
*
|
|
15
16
|
* @author Joseph Davies, Julien Gaffuri
|
|
16
17
|
*/
|
|
17
|
-
export class LabelLayer {
|
|
18
|
+
export class LabelLayer extends Layer {
|
|
18
19
|
/**
|
|
19
20
|
* @param {object} opts
|
|
20
21
|
*/
|
|
21
22
|
constructor(opts) {
|
|
23
|
+
super(opts)
|
|
22
24
|
opts = opts || {}
|
|
23
25
|
|
|
24
26
|
/**
|
|
@@ -82,60 +84,60 @@ export class LabelLayer {
|
|
|
82
84
|
/**
|
|
83
85
|
* Draw the label layer.
|
|
84
86
|
*
|
|
85
|
-
* @param {import("
|
|
87
|
+
* @param {import("../core/GeoCanvas").GeoCanvas} geoCanvas The canvas where to draw the layer.
|
|
86
88
|
* @returns {void}
|
|
87
89
|
*/
|
|
88
|
-
draw(
|
|
90
|
+
draw(geoCanvas) {
|
|
89
91
|
//load labels, if not done yet.
|
|
90
92
|
if (!this.labels) {
|
|
91
|
-
this.load(
|
|
93
|
+
this.load(geoCanvas.redraw)
|
|
92
94
|
return
|
|
93
95
|
}
|
|
94
96
|
|
|
95
|
-
//
|
|
96
|
-
const
|
|
97
|
+
//
|
|
98
|
+
const z = geoCanvas.view.z
|
|
97
99
|
|
|
98
100
|
//text align
|
|
99
|
-
|
|
101
|
+
geoCanvas.ctx.textAlign = this.textAlign || 'start'
|
|
100
102
|
|
|
101
103
|
//line join and cap
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
geoCanvas.ctx.lineJoin = 'bevel' //|| "round" || "miter";
|
|
105
|
+
geoCanvas.ctx.lineCap = 'butt' //|| "round" || "square";
|
|
104
106
|
|
|
105
107
|
//draw in pix coordinates
|
|
106
|
-
|
|
108
|
+
geoCanvas.initCanvasTransform()
|
|
107
109
|
|
|
108
110
|
//draw labels, one by one
|
|
109
111
|
for (const lb of this.labels) {
|
|
110
112
|
//get label style
|
|
111
|
-
const st = this.style(lb,
|
|
113
|
+
const st = this.style(lb, z)
|
|
112
114
|
if (!st) continue
|
|
113
|
-
|
|
115
|
+
geoCanvas.ctx.font = st
|
|
114
116
|
|
|
115
117
|
//check label within the view, to be drawn
|
|
116
|
-
if (!
|
|
118
|
+
if (!geoCanvas.toDraw(lb)) continue
|
|
117
119
|
|
|
118
120
|
//position
|
|
119
|
-
const xP =
|
|
120
|
-
const yP =
|
|
121
|
+
const xP = geoCanvas.geoToPixX(lb.x) + this.offsetPix[0]
|
|
122
|
+
const yP = geoCanvas.geoToPixY(lb.y) - this.offsetPix[1]
|
|
121
123
|
|
|
122
124
|
//label stroke, for the halo
|
|
123
125
|
if (this.haloColor && this.haloWidth) {
|
|
124
|
-
const hc = this.haloColor(lb,
|
|
125
|
-
const hw = this.haloWidth(lb,
|
|
126
|
+
const hc = this.haloColor(lb, z)
|
|
127
|
+
const hw = this.haloWidth(lb, z)
|
|
126
128
|
if (hc && hw && hw > 0) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
129
|
+
geoCanvas.ctx.strokeStyle = hc
|
|
130
|
+
geoCanvas.ctx.lineWidth = hw
|
|
131
|
+
geoCanvas.ctx.strokeText(lb.name, xP, yP)
|
|
130
132
|
}
|
|
131
133
|
}
|
|
132
134
|
|
|
133
135
|
//label fill
|
|
134
136
|
if (this.color) {
|
|
135
|
-
const col = this.color(lb,
|
|
137
|
+
const col = this.color(lb, z)
|
|
136
138
|
if (col) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
+
geoCanvas.ctx.fillStyle = col
|
|
140
|
+
geoCanvas.ctx.fillText(lb.name, xP, yP)
|
|
139
141
|
}
|
|
140
142
|
}
|
|
141
143
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
//@ts-check
|
|
2
2
|
'use strict'
|
|
3
3
|
|
|
4
|
-
import { Legend } from '../Legend.js'
|
|
4
|
+
import { Legend } from '../core/Legend.js'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* A legend element for color categrories.
|
|
@@ -17,49 +17,34 @@ export class ColorCategoryLegend extends Legend {
|
|
|
17
17
|
//col/categories array, in display order
|
|
18
18
|
/**
|
|
19
19
|
* @private
|
|
20
|
-
* @type {Array.<
|
|
21
|
-
this.
|
|
20
|
+
* @type {Array.<[string,string]>} */
|
|
21
|
+
this.colorLabel = opts.colorLabel || [['gray', '-']]
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* @private
|
|
25
|
-
* @type {import("../Style").Shape} */
|
|
25
|
+
* @type {import("../core/Style.js").Shape} */
|
|
26
26
|
this.shape = opts.shape || 'circle'
|
|
27
27
|
this.dimension = opts.dimension || { r: 8 }
|
|
28
28
|
this.strokeColor = opts.strokeColor || 'gray'
|
|
29
29
|
this.strokeWidth = opts.strokeWidth || 1
|
|
30
|
-
|
|
31
|
-
this.title = opts.title
|
|
32
|
-
this.titleFontSize = opts.titleFontSize || '0.8em'
|
|
33
|
-
this.titleFontWeight = opts.titleFontWeight || 'bold'
|
|
34
|
-
|
|
35
|
-
//label
|
|
36
|
-
this.labelFontSize = opts.labelFontSize || '0.8em'
|
|
37
30
|
}
|
|
38
31
|
|
|
39
32
|
/**
|
|
40
|
-
* @param {{ style: import("../Style").Style, r: number, zf: number, sSize: import("../Style").Stat, sColor: import("../Style").Stat }} opts
|
|
41
33
|
*/
|
|
42
|
-
update(
|
|
34
|
+
update() {
|
|
35
|
+
|
|
43
36
|
//clear
|
|
44
37
|
this.div.selectAll('*').remove()
|
|
45
38
|
|
|
46
|
-
//build
|
|
47
|
-
|
|
48
39
|
//title
|
|
49
|
-
|
|
50
|
-
this.div
|
|
51
|
-
.append('div')
|
|
52
|
-
.style('font-size', this.titleFontSize)
|
|
53
|
-
.style('font-weight', this.titleFontWeight)
|
|
54
|
-
.style('margin-bottom', '7px')
|
|
55
|
-
.text(this.title)
|
|
40
|
+
this.makeTitle()
|
|
56
41
|
|
|
57
42
|
//categories
|
|
58
|
-
const nb = this.
|
|
43
|
+
const nb = this.colorLabel.length
|
|
59
44
|
if (nb == 0) return
|
|
60
45
|
|
|
61
46
|
for (let i = 0; i < nb; i++) {
|
|
62
|
-
const cat = this.
|
|
47
|
+
const cat = this.colorLabel[i]
|
|
63
48
|
|
|
64
49
|
//make div for category
|
|
65
50
|
const d = this.div.append('div')
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
//@ts-check
|
|
2
2
|
'use strict'
|
|
3
3
|
|
|
4
|
-
import { Legend } from '../Legend.js'
|
|
4
|
+
import { Legend } from '../core/Legend.js'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* A legend element for discrete color style.
|
|
@@ -15,45 +15,37 @@ export class ColorDiscreteLegend extends Legend {
|
|
|
15
15
|
super(opts)
|
|
16
16
|
opts = opts || {}
|
|
17
17
|
|
|
18
|
-
/** @private @type {Array.<
|
|
18
|
+
/** @private @type {function(import('../core/Style').ViewScale):Array.<string>} */
|
|
19
19
|
this.colors = opts.colors
|
|
20
|
-
/** @private @type {Array.<
|
|
21
|
-
this.
|
|
20
|
+
/** @private @type {function(import('../core/Style').ViewScale):Array.<number>} */
|
|
21
|
+
this.breaks = opts.breaks
|
|
22
22
|
|
|
23
23
|
this.width = opts.width || 300
|
|
24
24
|
this.height = opts.height || 15
|
|
25
25
|
|
|
26
|
-
this.title = opts.title
|
|
27
|
-
this.titleFontSize = opts.titleFontSize || '0.8em'
|
|
28
|
-
this.titleFontWeight = opts.titleFontWeight || 'bold'
|
|
29
|
-
|
|
30
26
|
this.tickSize = opts.tickSize || 3
|
|
31
27
|
|
|
32
28
|
//label
|
|
33
|
-
this.labelFontSize = opts.labelFontSize || '0.8em'
|
|
34
29
|
this.invert = opts.invert
|
|
35
30
|
}
|
|
36
31
|
|
|
37
32
|
/**
|
|
38
|
-
* @param {{
|
|
33
|
+
* @param {{viewScale:import('../core/Style').ViewScale} } opts
|
|
39
34
|
*/
|
|
40
35
|
update(opts) {
|
|
36
|
+
|
|
41
37
|
//clear
|
|
42
38
|
this.div.selectAll('*').remove()
|
|
43
39
|
|
|
44
|
-
//build
|
|
45
|
-
|
|
46
40
|
//title
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
.style('margin-bottom', '7px')
|
|
53
|
-
.text(this.title)
|
|
41
|
+
this.makeTitle()
|
|
42
|
+
|
|
43
|
+
//get colors and breaks
|
|
44
|
+
const colors = this.colors(opts.viewScale)
|
|
45
|
+
const breaks = this.breaks(opts.viewScale)
|
|
54
46
|
|
|
55
47
|
//classes
|
|
56
|
-
const nb =
|
|
48
|
+
const nb = colors.length
|
|
57
49
|
if (nb == 0) return
|
|
58
50
|
const w = this.width / nb
|
|
59
51
|
|
|
@@ -70,7 +62,7 @@ export class ColorDiscreteLegend extends Legend {
|
|
|
70
62
|
.attr('y', 0)
|
|
71
63
|
.attr('width', w)
|
|
72
64
|
.attr('height', this.height)
|
|
73
|
-
.style('fill',
|
|
65
|
+
.style('fill', colors[i])
|
|
74
66
|
}
|
|
75
67
|
|
|
76
68
|
//tick line
|
|
@@ -85,7 +77,11 @@ export class ColorDiscreteLegend extends Legend {
|
|
|
85
77
|
|
|
86
78
|
//labels
|
|
87
79
|
for (let i = 1; i < nb; i++) {
|
|
88
|
-
|
|
80
|
+
|
|
81
|
+
let label = breaks[i - 1]
|
|
82
|
+
if (isNaN(label) || label == undefined) continue
|
|
83
|
+
|
|
84
|
+
//label
|
|
89
85
|
svg.append('text')
|
|
90
86
|
.attr('id', 'ticklabel_' + i)
|
|
91
87
|
.attr('x', w * i)
|
|
@@ -93,11 +89,11 @@ export class ColorDiscreteLegend extends Legend {
|
|
|
93
89
|
.style('font-size', this.labelFontSize)
|
|
94
90
|
//.style("font-weight", "bold")
|
|
95
91
|
//.style("font-family", "Arial")
|
|
96
|
-
.style('text-anchor',
|
|
92
|
+
.style('text-anchor', 'middle')
|
|
97
93
|
.style('alignment-baseline', 'top')
|
|
98
94
|
.style('dominant-baseline', 'hanging')
|
|
99
95
|
.style('pointer-events', 'none')
|
|
100
|
-
.text(
|
|
96
|
+
.text(label)
|
|
101
97
|
}
|
|
102
98
|
}
|
|
103
99
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
//@ts-check
|
|
2
2
|
'use strict'
|
|
3
3
|
|
|
4
|
-
import { Legend } from '../Legend.js'
|
|
5
|
-
import { format } from 'd3-format'
|
|
4
|
+
import { Legend } from '../core/Legend.js'
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* A legend element for continuous color style.
|
|
@@ -16,58 +15,47 @@ export class ColorLegend extends Legend {
|
|
|
16
15
|
super(opts)
|
|
17
16
|
opts = opts || {}
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
//a function [0,1]->color for continuous colors
|
|
19
|
+
//or array of colors for discrete colors
|
|
20
|
+
this.colorScale = opts.colorScale
|
|
20
21
|
|
|
21
|
-
//function (t[0,1]
|
|
22
|
-
this.
|
|
22
|
+
//function (t[0,1]) -> value (for label text)
|
|
23
|
+
this.textScale = opts.textScale || (t => t)
|
|
23
24
|
|
|
24
|
-
this.title = opts.title
|
|
25
|
-
this.tickSize = opts.tickSize || 6
|
|
26
|
-
this.width = opts.width || 300
|
|
27
|
-
this.height = opts.height || 15
|
|
28
25
|
this.margin = opts.margin || 5
|
|
26
|
+
|
|
27
|
+
//replace with labels ?
|
|
28
|
+
this.tickSize = opts.tickSize || 6
|
|
29
29
|
this.ticks = opts.ticks || Math.floor(this.width / 50)
|
|
30
|
-
this.tickFormat = opts.tickFormat
|
|
30
|
+
this.tickFormat = opts.tickFormat
|
|
31
31
|
this.tickUnit = opts.tickUnit
|
|
32
32
|
|
|
33
33
|
this.fontSize = opts.fontSize || '0.8em'
|
|
34
34
|
this.invert = opts.invert
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
this.
|
|
36
|
+
this.width = opts.width || 300
|
|
37
|
+
this.height = opts.height || 15
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
|
-
* @param {{
|
|
41
|
+
* @param {{viewScale:import('../core/Style').ViewScale} } opts
|
|
42
42
|
*/
|
|
43
43
|
update(opts) {
|
|
44
|
-
//could happen when data is still loading
|
|
45
|
-
if (!opts.sColor) return
|
|
46
44
|
|
|
47
45
|
//clear
|
|
48
46
|
this.div.selectAll('*').remove()
|
|
49
47
|
|
|
50
|
-
|
|
48
|
+
//title
|
|
49
|
+
this.makeTitle()
|
|
51
50
|
|
|
52
51
|
const svgW = this.width + 2 * this.margin
|
|
53
|
-
const svgH = this.height +
|
|
52
|
+
const svgH = this.height + this.margin + this.tickSize + 10
|
|
54
53
|
const svg = this.div.append('svg').attr('width', svgW).attr('height', svgH)
|
|
55
54
|
// <rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
|
|
56
55
|
|
|
57
|
-
//title
|
|
58
|
-
svg.append('text')
|
|
59
|
-
.attr('x', this.margin)
|
|
60
|
-
.attr('y', this.margin)
|
|
61
|
-
.style('font-size', '0.8em')
|
|
62
|
-
.style('font-weight', 'bold')
|
|
63
|
-
.style('alignment-baseline', 'top')
|
|
64
|
-
.style('dominant-baseline', 'hanging')
|
|
65
|
-
.style('pointer-events', 'none')
|
|
66
|
-
.text(this.title)
|
|
67
|
-
|
|
68
56
|
const g = svg
|
|
69
57
|
.append('g')
|
|
70
|
-
.attr('transform', 'translate(' + this.margin + ' ' +
|
|
58
|
+
.attr('transform', 'translate(' + this.margin + ' ' + 0 + ')')
|
|
71
59
|
|
|
72
60
|
//draw color bar
|
|
73
61
|
const w = this.width,
|
|
@@ -81,7 +69,7 @@ export class ColorLegend extends Legend {
|
|
|
81
69
|
.attr('y', 0)
|
|
82
70
|
.attr('width', step)
|
|
83
71
|
.attr('height', h)
|
|
84
|
-
.style('fill', this.
|
|
72
|
+
.style('fill', this.colorScale(t, opts.viewScale))
|
|
85
73
|
}
|
|
86
74
|
|
|
87
75
|
for (let i = 0; i < this.ticks; i++) {
|
|
@@ -113,13 +101,13 @@ export class ColorLegend extends Legend {
|
|
|
113
101
|
//update tick labels
|
|
114
102
|
|
|
115
103
|
//label text format
|
|
116
|
-
const f = this.tickFormat && this.tickFormat != 'text' ?
|
|
117
|
-
const stat = this.getStats(opts)
|
|
104
|
+
const f = this.tickFormat && this.tickFormat != 'text' ? this.tickFormat : (v) => v
|
|
118
105
|
for (let i = 0; i < this.ticks; i++) {
|
|
119
106
|
let t = i / (this.ticks - 1)
|
|
120
107
|
|
|
121
|
-
const v = this.
|
|
108
|
+
const v = this.textScale(t, opts.viewScale)
|
|
122
109
|
const text = (v ? f(v) : '0') + (this.tickUnit ? this.tickUnit : '')
|
|
110
|
+
if (text == undefined) continue
|
|
123
111
|
|
|
124
112
|
//tick label
|
|
125
113
|
this.div.select('#' + 'ticklabel_' + i).text(text)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Legend } from '../core/Legend.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A legend element for segment orientation.
|
|
8
|
+
*
|
|
9
|
+
* @author Joseph Davies, Julien Gaffuri
|
|
10
|
+
*/
|
|
11
|
+
export class OrientationLegend extends Legend {
|
|
12
|
+
/** @param {Object} opts */
|
|
13
|
+
constructor(opts) {
|
|
14
|
+
super(opts)
|
|
15
|
+
opts = opts || {}
|
|
16
|
+
|
|
17
|
+
//orientation
|
|
18
|
+
this.orientation = opts.orientation || 0
|
|
19
|
+
//color
|
|
20
|
+
this.color = opts.color || ((resolution, z, viewScale) => 'gray')
|
|
21
|
+
//width
|
|
22
|
+
this.width = opts.width || ((resolution, z, viewScale) => 3 * z)
|
|
23
|
+
//length
|
|
24
|
+
this.length = opts.length || ((resolution, z, viewScale) => resolution)
|
|
25
|
+
|
|
26
|
+
//label
|
|
27
|
+
this.label = opts.label || "-"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @param {{ style: import("../style/SegmentStyle.js").SegmentStyle, resolution: number, z: number, viewScale:object }} opts
|
|
32
|
+
*/
|
|
33
|
+
update(opts) {
|
|
34
|
+
|
|
35
|
+
//clear
|
|
36
|
+
this.div.selectAll('*').remove()
|
|
37
|
+
|
|
38
|
+
//title
|
|
39
|
+
this.makeTitle()
|
|
40
|
+
|
|
41
|
+
const d = this.div.append('div')
|
|
42
|
+
|
|
43
|
+
//compute segment color, width and length
|
|
44
|
+
const color = this.color(opts.resolution, opts.z, opts.viewScale)
|
|
45
|
+
const widthPix = this.width(opts.resolution, opts.z, opts.viewScale) / opts.z
|
|
46
|
+
const lengthPix = this.length(opts.resolution, opts.z, opts.viewScale) / opts.z
|
|
47
|
+
|
|
48
|
+
//draw SVG segment
|
|
49
|
+
const svgS = Math.max(lengthPix, widthPix)
|
|
50
|
+
const svg = d.append('svg').attr('width', svgS).attr('height', svgS).style('', 'inline-block')
|
|
51
|
+
|
|
52
|
+
const cos = Math.cos((-this.orientation * Math.PI) / 180)
|
|
53
|
+
const sin = Math.sin((-this.orientation * Math.PI) / 180)
|
|
54
|
+
const dc = svgS * 0.5,
|
|
55
|
+
l2 = lengthPix * 0.5
|
|
56
|
+
svg.append('line')
|
|
57
|
+
.attr('x1', dc - cos * l2)
|
|
58
|
+
.attr('y1', dc - sin * l2)
|
|
59
|
+
.attr('x2', dc + cos * l2)
|
|
60
|
+
.attr('y2', dc + sin * l2)
|
|
61
|
+
.style('stroke', color)
|
|
62
|
+
.style('stroke-width', widthPix)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
//label
|
|
66
|
+
d.append('div')
|
|
67
|
+
.style('display', 'inline')
|
|
68
|
+
.style('padding-left', '5px')
|
|
69
|
+
.style('font-size', this.labelFontSize)
|
|
70
|
+
.text(this.label + (this.labelUnitText ? ' ' : '') + this.labelUnitText)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
*
|
|
76
|
+
* @param {Array.<number>} orientations
|
|
77
|
+
* @param {Array.<string>} labels
|
|
78
|
+
* @param {object} opts
|
|
79
|
+
* @returns { Array.<OrientationLegend> }
|
|
80
|
+
*/
|
|
81
|
+
export function orientationLegend(orientations, labels, opts = {}) {
|
|
82
|
+
const legends = []
|
|
83
|
+
for (let i = 0; i < orientations.length; i++) {
|
|
84
|
+
opts.title = i == 0 ? opts.title : undefined;
|
|
85
|
+
opts.orientation = orientations[i]
|
|
86
|
+
opts.label = labels[i]
|
|
87
|
+
legends.push(new OrientationLegend(opts))
|
|
88
|
+
}
|
|
89
|
+
return legends
|
|
90
|
+
}
|