gridviz 2.1.8 → 2.1.9
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 +125 -125
- package/dist/gridviz.js +8021 -8013
- package/dist/gridviz.min.js +1 -1
- package/package.json +77 -77
- package/src/App.js +705 -705
- package/src/BackgroundLayer.js +182 -182
- package/src/BackgroundLayerWMS.js +131 -131
- package/src/Dataset.js +76 -76
- package/src/DatasetComponent.js +101 -101
- package/src/GeoCanvas.js +420 -420
- package/src/LabelLayer.js +190 -190
- package/src/Layer.js +103 -103
- package/src/Legend.js +86 -86
- package/src/LineLayer.js +150 -150
- package/src/Style.js +129 -129
- package/src/Tooltip.js +180 -172
- package/src/dataset/COGeo.js +24 -24
- package/src/dataset/CSVGrid.js +104 -104
- package/src/dataset/GeoTIFF.js +127 -127
- package/src/dataset/GridTile.js +41 -41
- package/src/dataset/LGrid.js +54 -54
- package/src/dataset/TiledGrid.js +264 -264
- package/src/index.js +71 -71
- package/src/legend/ColorCategoryLegend.js +124 -124
- package/src/legend/ColorDiscreteLegend.js +103 -103
- package/src/legend/ColorLegend.js +124 -124
- package/src/legend/SegmentOrientationLegend.js +87 -87
- package/src/legend/SegmentWidthLegend.js +97 -97
- package/src/legend/SizeLegend.js +141 -141
- package/src/style/CompositionStyle.js +300 -300
- package/src/style/ContourStyle.js +54 -54
- package/src/style/DotDensityStyle.js +156 -156
- package/src/style/IsoFenceStyle.js +262 -262
- package/src/style/JoyPlotStyle.js +135 -135
- package/src/style/LegoStyle.js +112 -112
- package/src/style/MosaicStyle.js +107 -107
- package/src/style/NinjaStarStyle.js +125 -125
- package/src/style/PillarStyle.js +230 -230
- package/src/style/SegmentStyle.js +142 -142
- package/src/style/ShapeColorSizeStyle.js +126 -126
- package/src/style/SideCatStyle.js +172 -172
- package/src/style/SideStyle.js +216 -216
- package/src/style/SquareColorCatWGLStyle.js +120 -120
- package/src/style/SquareColorWGLStyle.js +146 -146
- package/src/style/StrokeStyle.js +131 -131
- package/src/style/TanakaStyle.js +160 -160
- package/src/style/TextStyle.js +132 -132
- package/src/style/TimeSeriesStyle.js +250 -250
- package/src/utils/Utils.js +35 -35
- package/src/utils/WebGLRectangleColoring.js +106 -106
- package/src/utils/WebGLSquareColoring.js +118 -118
- package/src/utils/WebGLSquareColoringAdvanced.js +230 -230
- package/src/utils/WebGLSquareColoringCatAdvanced.js +133 -133
- package/src/utils/WebGLSquareColoringKS.js +153 -153
- package/src/utils/stretching.js +131 -131
- package/src/utils/webGLUtils.js +71 -71
- package/src/utils/zoomUtils.js +142 -142
|
@@ -1,124 +1,124 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Legend } from '../Legend.js'
|
|
5
|
-
import { format } from 'd3-format'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* A legend element for continuous color style.
|
|
9
|
-
* Inspiration: https://observablehq.com/@d3/color-legend
|
|
10
|
-
*
|
|
11
|
-
* @author Joseph Davies, Julien Gaffuri
|
|
12
|
-
*/
|
|
13
|
-
export class ColorLegend extends Legend {
|
|
14
|
-
/** @param {Object} opts */
|
|
15
|
-
constructor(opts) {
|
|
16
|
-
super(opts)
|
|
17
|
-
opts = opts || {}
|
|
18
|
-
|
|
19
|
-
this.colorRamp = opts.colorRamp
|
|
20
|
-
|
|
21
|
-
//function (t[0,1], r, s) -> v (for label text)
|
|
22
|
-
this.fun = opts.fun
|
|
23
|
-
|
|
24
|
-
this.title = opts.title
|
|
25
|
-
this.tickSize = opts.tickSize || 6
|
|
26
|
-
this.width = opts.width || 300
|
|
27
|
-
this.height = opts.height || 15
|
|
28
|
-
this.margin = opts.margin || 5
|
|
29
|
-
this.ticks = opts.ticks || Math.floor(this.width / 50)
|
|
30
|
-
this.tickFormat = opts.tickFormat || ',.0f'
|
|
31
|
-
this.tickUnit = opts.tickUnit
|
|
32
|
-
|
|
33
|
-
this.fontSize = opts.fontSize || '0.8em'
|
|
34
|
-
this.invert = opts.invert
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* @param {{ style: import("../Style").Style, r: number, zf: number, sSize: import("../Style").Stat, sColor: import("../Style").Stat }} opts
|
|
39
|
-
*/
|
|
40
|
-
update(opts) {
|
|
41
|
-
//could happen when data is still loading
|
|
42
|
-
if (!opts.sColor) return
|
|
43
|
-
|
|
44
|
-
//clear
|
|
45
|
-
this.div.selectAll('*').remove()
|
|
46
|
-
|
|
47
|
-
const titleHeight = 12
|
|
48
|
-
|
|
49
|
-
const svgW = this.width + 2 * this.margin
|
|
50
|
-
const svgH = this.height + 3 * this.margin + titleHeight + this.tickSize + 10
|
|
51
|
-
const svg = this.div.append('svg').attr('width', svgW).attr('height', svgH)
|
|
52
|
-
// <rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
|
|
53
|
-
|
|
54
|
-
//title
|
|
55
|
-
svg.append('text')
|
|
56
|
-
.attr('x', this.margin)
|
|
57
|
-
.attr('y', this.margin)
|
|
58
|
-
.style('font-size', '0.8em')
|
|
59
|
-
.style('font-weight', 'bold')
|
|
60
|
-
.style('alignment-baseline', 'top')
|
|
61
|
-
.style('dominant-baseline', 'hanging')
|
|
62
|
-
.style('pointer-events', 'none')
|
|
63
|
-
.text(this.title)
|
|
64
|
-
|
|
65
|
-
const g = svg
|
|
66
|
-
.append('g')
|
|
67
|
-
.attr('transform', 'translate(' + this.margin + ' ' + (2 * this.margin + titleHeight) + ')')
|
|
68
|
-
|
|
69
|
-
//draw color bar
|
|
70
|
-
const w = this.width,
|
|
71
|
-
h = this.height
|
|
72
|
-
const step = 5
|
|
73
|
-
for (let i = 0; i < w; i += step) {
|
|
74
|
-
let t = i / (w - 1)
|
|
75
|
-
if (this.invert) t = 1 - t
|
|
76
|
-
g.append('rect')
|
|
77
|
-
.attr('x', i)
|
|
78
|
-
.attr('y', 0)
|
|
79
|
-
.attr('width', step)
|
|
80
|
-
.attr('height', h)
|
|
81
|
-
.style('fill', this.colorRamp(t))
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
for (let i = 0; i < this.ticks; i++) {
|
|
85
|
-
let t = i / (this.ticks - 1)
|
|
86
|
-
|
|
87
|
-
//tick line
|
|
88
|
-
g.append('line')
|
|
89
|
-
.attr('x1', w * t)
|
|
90
|
-
.attr('y1', 0)
|
|
91
|
-
.attr('x2', w * t)
|
|
92
|
-
.attr('y2', h + this.tickSize)
|
|
93
|
-
.style('stroke', 'black')
|
|
94
|
-
|
|
95
|
-
//prepare tick label
|
|
96
|
-
g.append('text')
|
|
97
|
-
.attr('id', 'ticklabel_' + i)
|
|
98
|
-
.attr('x', w * t)
|
|
99
|
-
.attr('y', h + this.tickSize + 2)
|
|
100
|
-
.style('font-size', this.fontSize)
|
|
101
|
-
//.style("font-weight", "bold")
|
|
102
|
-
//.style("font-family", "Arial")
|
|
103
|
-
.style('text-anchor', i == 0 ? 'start' : i == this.ticks - 1 ? 'end' : 'middle')
|
|
104
|
-
.style('alignment-baseline', 'top')
|
|
105
|
-
.style('dominant-baseline', 'hanging')
|
|
106
|
-
.style('pointer-events', 'none')
|
|
107
|
-
//.text("-")
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
//update tick labels
|
|
111
|
-
|
|
112
|
-
//label text format
|
|
113
|
-
const f = this.tickFormat && this.tickFormat != 'text' ? format(this.tickFormat) : (v) => v
|
|
114
|
-
for (let i = 0; i < this.ticks; i++) {
|
|
115
|
-
let t = i / (this.ticks - 1)
|
|
116
|
-
|
|
117
|
-
const v = this.fun(t, opts.r, opts.sColor)
|
|
118
|
-
const text = (v ? f(v) : '0') + (this.tickUnit ? this.tickUnit : '')
|
|
119
|
-
|
|
120
|
-
//tick label
|
|
121
|
-
this.div.select('#' + 'ticklabel_' + i).text(text)
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Legend } from '../Legend.js'
|
|
5
|
+
import { format } from 'd3-format'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A legend element for continuous color style.
|
|
9
|
+
* Inspiration: https://observablehq.com/@d3/color-legend
|
|
10
|
+
*
|
|
11
|
+
* @author Joseph Davies, Julien Gaffuri
|
|
12
|
+
*/
|
|
13
|
+
export class ColorLegend extends Legend {
|
|
14
|
+
/** @param {Object} opts */
|
|
15
|
+
constructor(opts) {
|
|
16
|
+
super(opts)
|
|
17
|
+
opts = opts || {}
|
|
18
|
+
|
|
19
|
+
this.colorRamp = opts.colorRamp
|
|
20
|
+
|
|
21
|
+
//function (t[0,1], r, s) -> v (for label text)
|
|
22
|
+
this.fun = opts.fun
|
|
23
|
+
|
|
24
|
+
this.title = opts.title
|
|
25
|
+
this.tickSize = opts.tickSize || 6
|
|
26
|
+
this.width = opts.width || 300
|
|
27
|
+
this.height = opts.height || 15
|
|
28
|
+
this.margin = opts.margin || 5
|
|
29
|
+
this.ticks = opts.ticks || Math.floor(this.width / 50)
|
|
30
|
+
this.tickFormat = opts.tickFormat || ',.0f'
|
|
31
|
+
this.tickUnit = opts.tickUnit
|
|
32
|
+
|
|
33
|
+
this.fontSize = opts.fontSize || '0.8em'
|
|
34
|
+
this.invert = opts.invert
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @param {{ style: import("../Style").Style, r: number, zf: number, sSize: import("../Style").Stat, sColor: import("../Style").Stat }} opts
|
|
39
|
+
*/
|
|
40
|
+
update(opts) {
|
|
41
|
+
//could happen when data is still loading
|
|
42
|
+
if (!opts.sColor) return
|
|
43
|
+
|
|
44
|
+
//clear
|
|
45
|
+
this.div.selectAll('*').remove()
|
|
46
|
+
|
|
47
|
+
const titleHeight = 12
|
|
48
|
+
|
|
49
|
+
const svgW = this.width + 2 * this.margin
|
|
50
|
+
const svgH = this.height + 3 * this.margin + titleHeight + this.tickSize + 10
|
|
51
|
+
const svg = this.div.append('svg').attr('width', svgW).attr('height', svgH)
|
|
52
|
+
// <rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
|
|
53
|
+
|
|
54
|
+
//title
|
|
55
|
+
svg.append('text')
|
|
56
|
+
.attr('x', this.margin)
|
|
57
|
+
.attr('y', this.margin)
|
|
58
|
+
.style('font-size', '0.8em')
|
|
59
|
+
.style('font-weight', 'bold')
|
|
60
|
+
.style('alignment-baseline', 'top')
|
|
61
|
+
.style('dominant-baseline', 'hanging')
|
|
62
|
+
.style('pointer-events', 'none')
|
|
63
|
+
.text(this.title)
|
|
64
|
+
|
|
65
|
+
const g = svg
|
|
66
|
+
.append('g')
|
|
67
|
+
.attr('transform', 'translate(' + this.margin + ' ' + (2 * this.margin + titleHeight) + ')')
|
|
68
|
+
|
|
69
|
+
//draw color bar
|
|
70
|
+
const w = this.width,
|
|
71
|
+
h = this.height
|
|
72
|
+
const step = 5
|
|
73
|
+
for (let i = 0; i < w; i += step) {
|
|
74
|
+
let t = i / (w - 1)
|
|
75
|
+
if (this.invert) t = 1 - t
|
|
76
|
+
g.append('rect')
|
|
77
|
+
.attr('x', i)
|
|
78
|
+
.attr('y', 0)
|
|
79
|
+
.attr('width', step)
|
|
80
|
+
.attr('height', h)
|
|
81
|
+
.style('fill', this.colorRamp(t))
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
for (let i = 0; i < this.ticks; i++) {
|
|
85
|
+
let t = i / (this.ticks - 1)
|
|
86
|
+
|
|
87
|
+
//tick line
|
|
88
|
+
g.append('line')
|
|
89
|
+
.attr('x1', w * t)
|
|
90
|
+
.attr('y1', 0)
|
|
91
|
+
.attr('x2', w * t)
|
|
92
|
+
.attr('y2', h + this.tickSize)
|
|
93
|
+
.style('stroke', 'black')
|
|
94
|
+
|
|
95
|
+
//prepare tick label
|
|
96
|
+
g.append('text')
|
|
97
|
+
.attr('id', 'ticklabel_' + i)
|
|
98
|
+
.attr('x', w * t)
|
|
99
|
+
.attr('y', h + this.tickSize + 2)
|
|
100
|
+
.style('font-size', this.fontSize)
|
|
101
|
+
//.style("font-weight", "bold")
|
|
102
|
+
//.style("font-family", "Arial")
|
|
103
|
+
.style('text-anchor', i == 0 ? 'start' : i == this.ticks - 1 ? 'end' : 'middle')
|
|
104
|
+
.style('alignment-baseline', 'top')
|
|
105
|
+
.style('dominant-baseline', 'hanging')
|
|
106
|
+
.style('pointer-events', 'none')
|
|
107
|
+
//.text("-")
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
//update tick labels
|
|
111
|
+
|
|
112
|
+
//label text format
|
|
113
|
+
const f = this.tickFormat && this.tickFormat != 'text' ? format(this.tickFormat) : (v) => v
|
|
114
|
+
for (let i = 0; i < this.ticks; i++) {
|
|
115
|
+
let t = i / (this.ticks - 1)
|
|
116
|
+
|
|
117
|
+
const v = this.fun(t, opts.r, opts.sColor)
|
|
118
|
+
const text = (v ? f(v) : '0') + (this.tickUnit ? this.tickUnit : '')
|
|
119
|
+
|
|
120
|
+
//tick label
|
|
121
|
+
this.div.select('#' + 'ticklabel_' + i).text(text)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -1,87 +1,87 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Legend } from '../Legend.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* A legend element for segment orientation.
|
|
8
|
-
*
|
|
9
|
-
* @author Joseph Davies, Julien Gaffuri
|
|
10
|
-
*/
|
|
11
|
-
export class SegmentOrientationLegend extends Legend {
|
|
12
|
-
/** @param {Object} opts */
|
|
13
|
-
constructor(opts) {
|
|
14
|
-
super(opts)
|
|
15
|
-
opts = opts || {}
|
|
16
|
-
|
|
17
|
-
//title
|
|
18
|
-
this.title = opts.title
|
|
19
|
-
this.titleFontSize = opts.titleFontSize || '0.8em'
|
|
20
|
-
this.titleFontWeight = opts.titleFontWeight || 'bold'
|
|
21
|
-
|
|
22
|
-
//exageration
|
|
23
|
-
this.exaggerationFactor = opts.exaggerationFactor || 0.5
|
|
24
|
-
|
|
25
|
-
//color
|
|
26
|
-
this.color = opts.color || 'gray'
|
|
27
|
-
//orientation
|
|
28
|
-
this.orientation = opts.orientation || 0
|
|
29
|
-
//width
|
|
30
|
-
this.widthPix = opts.widthPix || 3
|
|
31
|
-
|
|
32
|
-
//label
|
|
33
|
-
this.labelFontSize = opts.labelFontSize || '0.8em'
|
|
34
|
-
this.labelUnitText = opts.labelUnitText || ''
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* @param {{ style: import("../style/SegmentStyle").SegmentStyle, r: number, zf: number, sColor: import("../Style").Stat, sLength: import("../Style").Stat, sWidth: import("../Style").Stat }} opts
|
|
39
|
-
*/
|
|
40
|
-
update(opts) {
|
|
41
|
-
//could happen when data is still loading
|
|
42
|
-
if (!opts.sWidth) return
|
|
43
|
-
|
|
44
|
-
//clear
|
|
45
|
-
this.div.selectAll('*').remove()
|
|
46
|
-
|
|
47
|
-
const d = this.div.append('div')
|
|
48
|
-
|
|
49
|
-
//title
|
|
50
|
-
if (this.title) {
|
|
51
|
-
d.append('div')
|
|
52
|
-
.attr('class', 'title')
|
|
53
|
-
.style('font-size', this.titleFontSize)
|
|
54
|
-
.style('font-weight', this.titleFontWeight)
|
|
55
|
-
.text(this.title)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
//compute segment width and length, in pix
|
|
59
|
-
const sWidth = this.widthPix
|
|
60
|
-
const sLength = (1 * opts.r) / opts.zf
|
|
61
|
-
|
|
62
|
-
//draw SVG segment
|
|
63
|
-
const svgS = Math.max(sLength, sWidth)
|
|
64
|
-
const svg = d.append('svg').attr('width', svgS).attr('height', svgS).style('', 'inline-block')
|
|
65
|
-
|
|
66
|
-
const cos = Math.cos((-this.orientation * Math.PI) / 180)
|
|
67
|
-
const sin = Math.sin((-this.orientation * Math.PI) / 180)
|
|
68
|
-
const dc = svgS * 0.5,
|
|
69
|
-
l2 = sLength * 0.5
|
|
70
|
-
svg.append('line')
|
|
71
|
-
.attr('x1', dc - cos * l2)
|
|
72
|
-
.attr('y1', dc - sin * l2)
|
|
73
|
-
.attr('x2', dc + cos * l2)
|
|
74
|
-
.attr('y2', dc + sin * l2)
|
|
75
|
-
.style('stroke', this.color)
|
|
76
|
-
.style('stroke-width', sWidth)
|
|
77
|
-
|
|
78
|
-
//text label
|
|
79
|
-
d.append('div')
|
|
80
|
-
//show on right of svg
|
|
81
|
-
.style('display', 'inline')
|
|
82
|
-
.style('padding-left', '5px')
|
|
83
|
-
.style('font-size', this.labelFontSize)
|
|
84
|
-
//.style("font-weight", "bold")
|
|
85
|
-
.text(this.labelUnitText)
|
|
86
|
-
}
|
|
87
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Legend } from '../Legend.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A legend element for segment orientation.
|
|
8
|
+
*
|
|
9
|
+
* @author Joseph Davies, Julien Gaffuri
|
|
10
|
+
*/
|
|
11
|
+
export class SegmentOrientationLegend extends Legend {
|
|
12
|
+
/** @param {Object} opts */
|
|
13
|
+
constructor(opts) {
|
|
14
|
+
super(opts)
|
|
15
|
+
opts = opts || {}
|
|
16
|
+
|
|
17
|
+
//title
|
|
18
|
+
this.title = opts.title
|
|
19
|
+
this.titleFontSize = opts.titleFontSize || '0.8em'
|
|
20
|
+
this.titleFontWeight = opts.titleFontWeight || 'bold'
|
|
21
|
+
|
|
22
|
+
//exageration
|
|
23
|
+
this.exaggerationFactor = opts.exaggerationFactor || 0.5
|
|
24
|
+
|
|
25
|
+
//color
|
|
26
|
+
this.color = opts.color || 'gray'
|
|
27
|
+
//orientation
|
|
28
|
+
this.orientation = opts.orientation || 0
|
|
29
|
+
//width
|
|
30
|
+
this.widthPix = opts.widthPix || 3
|
|
31
|
+
|
|
32
|
+
//label
|
|
33
|
+
this.labelFontSize = opts.labelFontSize || '0.8em'
|
|
34
|
+
this.labelUnitText = opts.labelUnitText || ''
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @param {{ style: import("../style/SegmentStyle").SegmentStyle, r: number, zf: number, sColor: import("../Style").Stat, sLength: import("../Style").Stat, sWidth: import("../Style").Stat }} opts
|
|
39
|
+
*/
|
|
40
|
+
update(opts) {
|
|
41
|
+
//could happen when data is still loading
|
|
42
|
+
if (!opts.sWidth) return
|
|
43
|
+
|
|
44
|
+
//clear
|
|
45
|
+
this.div.selectAll('*').remove()
|
|
46
|
+
|
|
47
|
+
const d = this.div.append('div')
|
|
48
|
+
|
|
49
|
+
//title
|
|
50
|
+
if (this.title) {
|
|
51
|
+
d.append('div')
|
|
52
|
+
.attr('class', 'title')
|
|
53
|
+
.style('font-size', this.titleFontSize)
|
|
54
|
+
.style('font-weight', this.titleFontWeight)
|
|
55
|
+
.text(this.title)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
//compute segment width and length, in pix
|
|
59
|
+
const sWidth = this.widthPix
|
|
60
|
+
const sLength = (1 * opts.r) / opts.zf
|
|
61
|
+
|
|
62
|
+
//draw SVG segment
|
|
63
|
+
const svgS = Math.max(sLength, sWidth)
|
|
64
|
+
const svg = d.append('svg').attr('width', svgS).attr('height', svgS).style('', 'inline-block')
|
|
65
|
+
|
|
66
|
+
const cos = Math.cos((-this.orientation * Math.PI) / 180)
|
|
67
|
+
const sin = Math.sin((-this.orientation * Math.PI) / 180)
|
|
68
|
+
const dc = svgS * 0.5,
|
|
69
|
+
l2 = sLength * 0.5
|
|
70
|
+
svg.append('line')
|
|
71
|
+
.attr('x1', dc - cos * l2)
|
|
72
|
+
.attr('y1', dc - sin * l2)
|
|
73
|
+
.attr('x2', dc + cos * l2)
|
|
74
|
+
.attr('y2', dc + sin * l2)
|
|
75
|
+
.style('stroke', this.color)
|
|
76
|
+
.style('stroke-width', sWidth)
|
|
77
|
+
|
|
78
|
+
//text label
|
|
79
|
+
d.append('div')
|
|
80
|
+
//show on right of svg
|
|
81
|
+
.style('display', 'inline')
|
|
82
|
+
.style('padding-left', '5px')
|
|
83
|
+
.style('font-size', this.labelFontSize)
|
|
84
|
+
//.style("font-weight", "bold")
|
|
85
|
+
.text(this.labelUnitText)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -1,97 +1,97 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Legend } from '../Legend.js'
|
|
5
|
-
import { format } from 'd3-format'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* A legend element for segment width.
|
|
9
|
-
*
|
|
10
|
-
* @author Joseph Davies, Julien Gaffuri
|
|
11
|
-
*/
|
|
12
|
-
export class SegmentWidthLegend extends Legend {
|
|
13
|
-
/** @param {Object} opts */
|
|
14
|
-
constructor(opts) {
|
|
15
|
-
super(opts)
|
|
16
|
-
opts = opts || {}
|
|
17
|
-
|
|
18
|
-
//title
|
|
19
|
-
this.title = opts.title
|
|
20
|
-
this.titleFontSize = opts.titleFontSize || '0.8em'
|
|
21
|
-
this.titleFontWeight = opts.titleFontWeight || 'bold'
|
|
22
|
-
|
|
23
|
-
//exageration
|
|
24
|
-
this.exaggerationFactor = opts.exaggerationFactor || 0.5
|
|
25
|
-
|
|
26
|
-
//color
|
|
27
|
-
this.color = opts.color || 'gray'
|
|
28
|
-
//orientation
|
|
29
|
-
this.orientation = opts.orientation || 0
|
|
30
|
-
|
|
31
|
-
//label
|
|
32
|
-
this.labelFontSize = opts.labelFontSize || '0.8em'
|
|
33
|
-
this.labelUnitText = opts.labelUnitText || ''
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* @param {{ style: import("../style/SegmentStyle").SegmentStyle, r: number, zf: number, sColor: import("../Style").Stat, sLength: import("../Style").Stat, sWidth: import("../Style").Stat }} opts
|
|
38
|
-
*/
|
|
39
|
-
update(opts) {
|
|
40
|
-
//could happen when data is still loading
|
|
41
|
-
if (!opts.sWidth) return
|
|
42
|
-
|
|
43
|
-
//clear
|
|
44
|
-
this.div.selectAll('*').remove()
|
|
45
|
-
|
|
46
|
-
const d = this.div.append('div')
|
|
47
|
-
|
|
48
|
-
//title
|
|
49
|
-
if (this.title) {
|
|
50
|
-
d.append('div')
|
|
51
|
-
.attr('class', 'title')
|
|
52
|
-
.style('font-size', this.titleFontSize)
|
|
53
|
-
.style('font-weight', this.titleFontWeight)
|
|
54
|
-
.text(this.title)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
//get max value
|
|
58
|
-
const value_ = opts.sWidth.max * this.exaggerationFactor
|
|
59
|
-
|
|
60
|
-
//take 'nice' value (power of ten, or multiple)
|
|
61
|
-
let pow10 = Math.log10(value_)
|
|
62
|
-
pow10 = Math.floor(pow10)
|
|
63
|
-
let value = Math.pow(10, pow10)
|
|
64
|
-
if (value * 8 <= value_) value *= 8
|
|
65
|
-
else if (value * 6 <= value_) value *= 6
|
|
66
|
-
else if (value * 5 <= value_) value *= 5
|
|
67
|
-
else if (value * 4 <= value_) value *= 4
|
|
68
|
-
else if (value * 2.5 <= value_) value *= 2.5
|
|
69
|
-
else if (value * 2 <= value_) value *= 2
|
|
70
|
-
|
|
71
|
-
//compute segment width and length, in pix
|
|
72
|
-
const sWidth = opts.style.width(value, opts.r, opts.sWidth, opts.zf) / opts.zf
|
|
73
|
-
const sLength = (1 * opts.r) / opts.zf
|
|
74
|
-
|
|
75
|
-
//TODO use orientation
|
|
76
|
-
|
|
77
|
-
const svg = d.append('svg').attr('width', sLength).attr('height', sWidth).style('', 'inline-block')
|
|
78
|
-
|
|
79
|
-
//<line x1="0" y1="0" x2="200" y2="200" style="stroke:rgb(255,0,0);stroke-width:2" />
|
|
80
|
-
svg.append('line')
|
|
81
|
-
.attr('x1', 0)
|
|
82
|
-
.attr('y1', sWidth / 2)
|
|
83
|
-
.attr('x2', sLength)
|
|
84
|
-
.attr('y2', sWidth / 2)
|
|
85
|
-
.style('stroke', this.color)
|
|
86
|
-
.style('stroke-width', sWidth)
|
|
87
|
-
|
|
88
|
-
const valueT = format(',.2r')(value)
|
|
89
|
-
d.append('div')
|
|
90
|
-
//show on right of graphic
|
|
91
|
-
.style('display', 'inline')
|
|
92
|
-
.style('padding-left', '5px')
|
|
93
|
-
.style('font-size', this.labelFontSize)
|
|
94
|
-
//.style("font-weight", "bold")
|
|
95
|
-
.text(valueT + (this.labelUnitText ? ' ' : '') + this.labelUnitText)
|
|
96
|
-
}
|
|
97
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Legend } from '../Legend.js'
|
|
5
|
+
import { format } from 'd3-format'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A legend element for segment width.
|
|
9
|
+
*
|
|
10
|
+
* @author Joseph Davies, Julien Gaffuri
|
|
11
|
+
*/
|
|
12
|
+
export class SegmentWidthLegend extends Legend {
|
|
13
|
+
/** @param {Object} opts */
|
|
14
|
+
constructor(opts) {
|
|
15
|
+
super(opts)
|
|
16
|
+
opts = opts || {}
|
|
17
|
+
|
|
18
|
+
//title
|
|
19
|
+
this.title = opts.title
|
|
20
|
+
this.titleFontSize = opts.titleFontSize || '0.8em'
|
|
21
|
+
this.titleFontWeight = opts.titleFontWeight || 'bold'
|
|
22
|
+
|
|
23
|
+
//exageration
|
|
24
|
+
this.exaggerationFactor = opts.exaggerationFactor || 0.5
|
|
25
|
+
|
|
26
|
+
//color
|
|
27
|
+
this.color = opts.color || 'gray'
|
|
28
|
+
//orientation
|
|
29
|
+
this.orientation = opts.orientation || 0
|
|
30
|
+
|
|
31
|
+
//label
|
|
32
|
+
this.labelFontSize = opts.labelFontSize || '0.8em'
|
|
33
|
+
this.labelUnitText = opts.labelUnitText || ''
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @param {{ style: import("../style/SegmentStyle").SegmentStyle, r: number, zf: number, sColor: import("../Style").Stat, sLength: import("../Style").Stat, sWidth: import("../Style").Stat }} opts
|
|
38
|
+
*/
|
|
39
|
+
update(opts) {
|
|
40
|
+
//could happen when data is still loading
|
|
41
|
+
if (!opts.sWidth) return
|
|
42
|
+
|
|
43
|
+
//clear
|
|
44
|
+
this.div.selectAll('*').remove()
|
|
45
|
+
|
|
46
|
+
const d = this.div.append('div')
|
|
47
|
+
|
|
48
|
+
//title
|
|
49
|
+
if (this.title) {
|
|
50
|
+
d.append('div')
|
|
51
|
+
.attr('class', 'title')
|
|
52
|
+
.style('font-size', this.titleFontSize)
|
|
53
|
+
.style('font-weight', this.titleFontWeight)
|
|
54
|
+
.text(this.title)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
//get max value
|
|
58
|
+
const value_ = opts.sWidth.max * this.exaggerationFactor
|
|
59
|
+
|
|
60
|
+
//take 'nice' value (power of ten, or multiple)
|
|
61
|
+
let pow10 = Math.log10(value_)
|
|
62
|
+
pow10 = Math.floor(pow10)
|
|
63
|
+
let value = Math.pow(10, pow10)
|
|
64
|
+
if (value * 8 <= value_) value *= 8
|
|
65
|
+
else if (value * 6 <= value_) value *= 6
|
|
66
|
+
else if (value * 5 <= value_) value *= 5
|
|
67
|
+
else if (value * 4 <= value_) value *= 4
|
|
68
|
+
else if (value * 2.5 <= value_) value *= 2.5
|
|
69
|
+
else if (value * 2 <= value_) value *= 2
|
|
70
|
+
|
|
71
|
+
//compute segment width and length, in pix
|
|
72
|
+
const sWidth = opts.style.width(value, opts.r, opts.sWidth, opts.zf) / opts.zf
|
|
73
|
+
const sLength = (1 * opts.r) / opts.zf
|
|
74
|
+
|
|
75
|
+
//TODO use orientation
|
|
76
|
+
|
|
77
|
+
const svg = d.append('svg').attr('width', sLength).attr('height', sWidth).style('', 'inline-block')
|
|
78
|
+
|
|
79
|
+
//<line x1="0" y1="0" x2="200" y2="200" style="stroke:rgb(255,0,0);stroke-width:2" />
|
|
80
|
+
svg.append('line')
|
|
81
|
+
.attr('x1', 0)
|
|
82
|
+
.attr('y1', sWidth / 2)
|
|
83
|
+
.attr('x2', sLength)
|
|
84
|
+
.attr('y2', sWidth / 2)
|
|
85
|
+
.style('stroke', this.color)
|
|
86
|
+
.style('stroke-width', sWidth)
|
|
87
|
+
|
|
88
|
+
const valueT = format(',.2r')(value)
|
|
89
|
+
d.append('div')
|
|
90
|
+
//show on right of graphic
|
|
91
|
+
.style('display', 'inline')
|
|
92
|
+
.style('padding-left', '5px')
|
|
93
|
+
.style('font-size', this.labelFontSize)
|
|
94
|
+
//.style("font-weight", "bold")
|
|
95
|
+
.text(valueT + (this.labelUnitText ? ' ' : '') + this.labelUnitText)
|
|
96
|
+
}
|
|
97
|
+
}
|