forked from hyoo-ru/mam_mol
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfill.view.ts
92 lines (70 loc) · 2.08 KB
/
fill.view.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
namespace $.$$ {
export class $mol_plot_fill extends $.$mol_plot_fill {
@ $mol_mem
indexes() {
const threshold = this.threshold()
const {
x: {min: viewport_left, max: viewport_right},
y: {min: viewport_bottom, max: viewport_top},
} = this.viewport()
const [shift_x, shift_y] = this.shift()
const [scale_x, scale_y] = this.scale()
const indexes = [] as number[]
let last = [ Number.NEGATIVE_INFINITY , Number.NEGATIVE_INFINITY ] as const
let first_x = null as number | null
let first_y = null as number | null
let last_x = null as number | null
let last_y = null as number | null
const series_x = this.series_x()
const series_y = this.series_y()
for (let i = 0; i < series_x.length; i++) {
const scaled = [
Math.round( shift_x + series_x[i] * scale_x ),
Math.round( shift_y + series_y[i] * scale_y ),
] as const
if (
Math.abs( scaled[0] - last[ 0 ] ) < threshold
&& Math.abs( scaled[1] - last[ 1 ] ) < threshold
) continue
last = scaled
if (scaled[0] < viewport_left) {
first_x = i
continue
}
if (scaled[1] < viewport_bottom) {
first_y = i
continue
}
if (scaled[0] > viewport_right) {
last_x = i
continue
}
if (scaled[1] > viewport_top) {
last_y = i
continue
}
if (first_x !== null) indexes.push(first_x)
if (first_y !== null) indexes.push(first_y)
indexes.push(i)
if (last_x !== null) indexes.push(last_x)
if (last_y !== null) indexes.push(last_y)
first_x = first_y = last_x = last_y = null
}
if (first_x !== null) indexes.push(first_x)
if (first_y !== null) indexes.push(first_y)
if (last_x !== null) indexes.push(last_x)
if (last_y !== null) indexes.push(last_y)
return indexes
}
curve() {
const points = this.points()
if( points.length === 0 ) return ''
const [, shift_y] = this.shift()
const main = points.map( point => `L ${point.join(' ')}`).join(' ')
return `M ${points[0].join(' ')} ${main} V ${shift_y} H ${points[0][0]}`
}
back() {
return [ this ]
}
}
}