-
-
Notifications
You must be signed in to change notification settings - Fork 318
/
hvlines.jl
90 lines (77 loc) · 2.85 KB
/
hvlines.jl
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
"""
hlines(ys; xmin = 0.0, xmax = 1.0, attrs...)
Create horizontal lines across a `Scene` with 2D projection.
The lines will be placed at `ys` in data coordinates and `xmin` to `xmax`
in scene coordinates (0 to 1). All three of these can have single or multiple values because
they are broadcast to calculate the final line segments.
All style attributes are the same as for `LineSegments`.
"""
@recipe(HLines) do scene
Theme(;
xautolimits = false,
xmin = 0,
xmax = 1,
default_theme(scene, LineSegments)...,
cycle = :color,
)
end
"""
vlines(xs; ymin = 0.0, ymax = 1.0, attrs...)
Create vertical lines across a `Scene` with 2D projection.
The lines will be placed at `xs` in data coordinates and `ymin` to `ymax`
in scene coordinates (0 to 1). All three of these can have single or multiple values because
they are broadcast to calculate the final line segments.
All style attributes are the same as for `LineSegments`.
"""
@recipe(VLines) do scene
Theme(;
yautolimits = false,
ymin = 0,
ymax = 1,
default_theme(scene, LineSegments)...,
cycle = :color,
)
end
function projview_to_2d_limits(pv)
xmin, xmax = minmax((((-1, 1) .- pv[1, 4]) ./ pv[1, 1])...)
ymin, ymax = minmax((((-1, 1) .- pv[2, 4]) ./ pv[2, 2])...)
origin = Vec2f(xmin, ymin)
return Rect2f(origin, Vec2f(xmax, ymax) - origin)
end
function Makie.plot!(p::Union{HLines, VLines})
scene = parent_scene(p)
transf = transform_func_obs(scene)
limits = lift(projview_to_2d_limits, p, scene.camera.projectionview)
points = Observable(Point2f[])
mi = p isa HLines ? p.xmin : p.ymin
ma = p isa HLines ? p.xmax : p.ymax
onany(p, limits, p[1], mi, ma, transf) do lims, vals, mi, ma, transf
inv = inverse_transform(transf)
empty!(points[])
min_x, min_y = minimum(lims)
max_x, max_y = maximum(lims)
broadcast_foreach(vals, mi, ma) do val, mi, ma
if p isa HLines
x_mi = min_x + (max_x - min_x) * mi
x_ma = min_x + (max_x - min_x) * ma
x_mi = _apply_x_transform(inv, x_mi)
x_ma = _apply_x_transform(inv, x_ma)
push!(points[], Point2f(x_mi, val))
push!(points[], Point2f(x_ma, val))
elseif p isa VLines
y_mi = min_y + (max_y - min_y) * mi
y_ma = min_y + (max_y - min_y) * ma
y_mi = _apply_y_transform(inv, y_mi)
y_ma = _apply_y_transform(inv, y_ma)
push!(points[], Point2f(val, y_mi))
push!(points[], Point2f(val, y_ma))
end
end
notify(points)
end
notify(p[1])
line_attributes = copy(p.attributes)
delete!.(line_attributes, (:ymin, :ymax, :yautolimits))
linesegments!(p, line_attributes, points)
p
end