-
-
Notifications
You must be signed in to change notification settings - Fork 59
/
dot.view.ts
94 lines (73 loc) · 2.46 KB
/
dot.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
93
94
namespace $.$$ {
export class $mol_plot_dot extends $.$mol_plot_dot {
@$mol_mem
filled(): Set<number> {
return new Set()
}
@ $mol_mem
indexes() {
const radius = this.diameter() / 2
// calculate by cpu
const points_max = this.points_max()
const viewport = this.viewport()
const viewport_left = viewport.x.min - radius
const viewport_right = viewport.x.max + radius
const viewport_bottom = viewport.y.min - radius
const viewport_top = viewport.y.max + radius
const [shift_x, shift_y] = this.shift()
const [scale_x, scale_y] = this.scale()
let last_x = Number.NEGATIVE_INFINITY
let last_y = Number.NEGATIVE_INFINITY
let spacing = 0
let filled: Set<number> = this.filled()
let indexes: number[]
const series_x = this.series_x()
const series_y = this.series_y()
do {
indexes = []
for (let i = 0; i < series_x.length; i++) {
const point_x = this.repos_x( series_x[i] )
const point_y = this.repos_y( series_y[i] )
const scaled_x = Math.round(shift_x + point_x * scale_x)
const scaled_y = Math.round(shift_y + point_y * scale_y)
if (
Math.abs( scaled_x - last_x ) < radius
&& Math.abs( scaled_y - last_y ) < radius
) continue
last_x = scaled_x
last_y = scaled_y
if (scaled_x < viewport_left) continue
if (scaled_y < viewport_bottom) continue
if (scaled_x > viewport_right) continue
if (scaled_y > viewport_top) continue
if (spacing !== 0) {
const key = $mol_coord_pack(
Math.round(point_x * scale_x / spacing) * spacing,
Math.round(point_y * scale_y / spacing) * spacing
)
if (filled.has(key)) continue
filled.add(key)
}
indexes.push(i)
if (indexes.length > points_max) break
}
spacing += Math.ceil(radius)
filled.clear()
} while (indexes.length > points_max)
return indexes
}
curve() {
const points = this.points()
if( points.length === 0 ) return ''
const diameter = this.diameter()
const aspect = this.aspect()
const shift_y = Math.max( 0, Math.floor( ( aspect - 1 ) * diameter / 2 ) )
const shift_x = Math.max( 0, Math.floor( ( 1/aspect - 1 ) * diameter / 2 ) )
const size_y = Math.max( 0, Math.ceil( ( aspect - 1 ) * diameter ) )
const size_x = Math.max( 0, Math.ceil( ( 1/aspect - 1 ) * diameter ) )
return points.map(
point => `M ${ point[0] - shift_x } ${ point[1] - shift_y } l ${ size_x } ${ size_y }`
).join( ' ' )
}
}
}