diff --git a/.github/workflows/Check.yml b/.github/workflows/Check.yml new file mode 100644 index 00000000000..fd1879d61a4 --- /dev/null +++ b/.github/workflows/Check.yml @@ -0,0 +1,23 @@ +--- +name: Check +on: + push: + branches: + - 'master' + - 'release-' + tags: + - '*' + pull_request: +jobs: + runic: + name: Runic formatting + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 + with: + version: '1' + - uses: julia-actions/cache@v2 + - uses: fredrikekre/runic-action@v1 + with: + version: '1.2' diff --git a/CairoMakie/src/CairoMakie.jl b/CairoMakie/src/CairoMakie.jl index 04b1c4b6c7f..5042e702851 100644 --- a/CairoMakie/src/CairoMakie.jl +++ b/CairoMakie/src/CairoMakie.jl @@ -15,7 +15,7 @@ using Makie: numbers_to_colors using Makie: Mat3f, Mat4f, Mat3d, Mat4d # re-export Makie, including deprecated names -for name in names(Makie, all=true) +for name in names(Makie, all = true) if Base.isexported(Makie, name) @eval using Makie: $(name) @eval export $(name) @@ -31,7 +31,7 @@ include("primitives.jl") include("overrides.jl") function __init__() - activate!() + return activate!() end include("precompiles.jl") diff --git a/CairoMakie/src/cairo-extension.jl b/CairoMakie/src/cairo-extension.jl index 4857f666c9b..78a489b224d 100644 --- a/CairoMakie/src/cairo-extension.jl +++ b/CairoMakie/src/cairo-extension.jl @@ -1,7 +1,7 @@ # TODO, move those to Cairo? function set_font_matrix(ctx, matrix) - ccall((:cairo_set_font_matrix, Cairo.libcairo), Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}), ctx.ptr, Ref(matrix)) + return ccall((:cairo_set_font_matrix, Cairo.libcairo), Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}), ctx.ptr, Ref(matrix)) end function get_font_matrix(ctx) @@ -11,7 +11,7 @@ function get_font_matrix(ctx) end function pattern_set_matrix(ctx, matrix) - ccall((:cairo_pattern_set_matrix, Cairo.libcairo), Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}), ctx.ptr, Ref(matrix)) + return ccall((:cairo_pattern_set_matrix, Cairo.libcairo), Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}), ctx.ptr, Ref(matrix)) end function pattern_get_matrix(ctx) @@ -21,7 +21,7 @@ function pattern_get_matrix(ctx) end function cairo_font_face_destroy(font_face) - ccall( + return ccall( (:cairo_font_face_destroy, Cairo.libcairo), Cvoid, (Ptr{Cvoid},), font_face @@ -29,7 +29,7 @@ function cairo_font_face_destroy(font_face) end function cairo_transform(ctx, cairo_matrix) - ccall( + return ccall( (:cairo_transform, Cairo.libcairo), Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}), ctx.ptr, Ref(cairo_matrix) @@ -57,30 +57,35 @@ end function show_glyph(ctx, glyph, x, y) cg = Ref(CairoGlyph(glyph, x, y)) - ccall((:cairo_show_glyphs, Cairo.libcairo), - Nothing, (Ptr{Nothing}, Ptr{CairoGlyph}, Cint), - ctx.ptr, cg, 1) + return ccall( + (:cairo_show_glyphs, Cairo.libcairo), + Nothing, (Ptr{Nothing}, Ptr{CairoGlyph}, Cint), + ctx.ptr, cg, 1 + ) end function glyph_path(ctx, glyph, x, y) cg = Ref(CairoGlyph(glyph, x, y)) - ccall((:cairo_glyph_path, Cairo.libcairo), - Nothing, (Ptr{Nothing}, Ptr{CairoGlyph}, Cint), - ctx.ptr, cg, 1) + return ccall( + (:cairo_glyph_path, Cairo.libcairo), + Nothing, (Ptr{Nothing}, Ptr{CairoGlyph}, Cint), + ctx.ptr, cg, 1 + ) end -function surface_set_device_scale(surf, device_x_scale, device_y_scale=device_x_scale) +function surface_set_device_scale(surf, device_x_scale, device_y_scale = device_x_scale) # this sets a scaling factor on the lowest level that is "hidden" so its even # enabled when the drawing space is reset for strokes # that means it can be used to increase or decrease the image resolution - ccall( + return ccall( (:cairo_surface_set_device_scale, Cairo.libcairo), Cvoid, (Ptr{Nothing}, Cdouble, Cdouble), - surf.ptr, device_x_scale, device_y_scale) + surf.ptr, device_x_scale, device_y_scale + ) end function set_miter_limit(ctx, limit) - ccall((:cairo_set_miter_limit, Cairo.libcairo), Cvoid, (Ptr{Nothing}, Cdouble), ctx.ptr, limit) + return ccall((:cairo_set_miter_limit, Cairo.libcairo), Cvoid, (Ptr{Nothing}, Cdouble), ctx.ptr, limit) end function get_render_type(surface::Cairo.CairoSurface) @@ -96,6 +101,8 @@ end function restrict_pdf_version!(surface::Cairo.CairoSurface, v::Integer) @assert surface.ptr != C_NULL 0 ≤ v ≤ 3 || throw(ArgumentError("version must be 0, 1, 2, or 3 (received $v)")) - ccall((:cairo_pdf_surface_restrict_to_version, Cairo.libcairo), Nothing, - (Ptr{UInt8}, Int32), surface.ptr, v) + return ccall( + (:cairo_pdf_surface_restrict_to_version, Cairo.libcairo), Nothing, + (Ptr{UInt8}, Int32), surface.ptr, v + ) end diff --git a/CairoMakie/src/display.jl b/CairoMakie/src/display.jl index 813b53b7b10..dfd4158c913 100644 --- a/CairoMakie/src/display.jl +++ b/CairoMakie/src/display.jl @@ -1,4 +1,3 @@ - ######################################### # Backend interface to Makie # ######################################### @@ -28,17 +27,17 @@ function openurl(url::String) tryrun(`python -mwebbrowser $(url)`) && return # our last hope tryrun(`python3 -mwebbrowser $(url)`) && return - @warn("Can't find a way to open a browser, open $(url) manually!") + return @warn("Can't find a way to open a browser, open $(url) manually!") end -function Base.display(screen::Screen, scene::Scene; connect=false) +function Base.display(screen::Screen, scene::Scene; connect = false) # Nothing to do, since drawing is done in the other functions # TODO write to file and implement upenurl return screen end -function Base.display(screen::Screen{IMAGE}, scene::Scene; connect=false, screen_config...) - config = Makie.merge_screen_config(ScreenConfig, Dict{Symbol,Any}(screen_config)) +function Base.display(screen::Screen{IMAGE}, scene::Scene; connect = false, screen_config...) + config = Makie.merge_screen_config(ScreenConfig, Dict{Symbol, Any}(screen_config)) screen = Makie.apply_screen_config!(screen, config, scene) path = joinpath(mktempdir(), "display.png") Makie.push_screen!(scene, screen) @@ -75,7 +74,7 @@ function Makie.backend_show(screen::Screen{SVG}, io::IO, ::MIME"image/svg+xml", # across svgs when embedding them on websites. # the hash and therefore the salt will always be the same for the same file # so the output is deterministic - salt = repr(CRC32c.crc32c(svg))[end-7:end] + salt = repr(CRC32c.crc32c(svg))[(end - 7):end] # matches: # id="someid" @@ -111,15 +110,17 @@ end # Disabling mimes and showable const DISABLED_MIMES = Set{String}() -const SUPPORTED_MIMES = Set([ - map(x->string(x()), Makie.WEB_MIMES)..., - "image/svg+xml", - "application/pdf", - "application/postscript", - "image/png" -]) - -function Makie.backend_showable(::Type{Screen}, ::MIME{SYM}) where SYM +const SUPPORTED_MIMES = Set( + [ + map(x -> string(x()), Makie.WEB_MIMES)..., + "image/svg+xml", + "application/pdf", + "application/postscript", + "image/png", + ] +) + +function Makie.backend_showable(::Type{Screen}, ::MIME{SYM}) where {SYM} supported_mimes = Base.setdiff(SUPPORTED_MIMES, DISABLED_MIMES) return string(SYM) in supported_mimes end diff --git a/CairoMakie/src/infrastructure.jl b/CairoMakie/src/infrastructure.jl index 5179ede8a3f..c32049d50f6 100644 --- a/CairoMakie/src/infrastructure.jl +++ b/CairoMakie/src/infrastructure.jl @@ -12,7 +12,7 @@ function cairo_draw(screen::Screen, scene::Scene) draw_background(screen, scene) allplots = Makie.collect_atomic_plots(scene; is_atomic_plot = is_cairomakie_atomic_plot) - sort!(allplots; by=Makie.zvalue2d) + sort!(allplots; by = Makie.zvalue2d) # If the backend is not a vector surface (i.e., PNG/ARGB), # then there is no point in rasterizing twice. should_rasterize = is_vector_backend(screen.surface) @@ -116,7 +116,7 @@ function draw_background(screen::Screen, scene::Scene, root_h) Cairo.save(cr) if scene.clear[] bg = scene.backgroundcolor[] - Cairo.set_source_rgba(cr, red(bg), green(bg), blue(bg), alpha(bg)); + Cairo.set_source_rgba(cr, red(bg), green(bg), blue(bg), alpha(bg)) r = viewport(scene)[] # Makie has (0,0) at bottom left, Cairo at top left. Makie extends up, # Cairo down. Negative height breaks other backgrounds @@ -125,7 +125,7 @@ function draw_background(screen::Screen, scene::Scene, root_h) fill(cr) end Cairo.restore(cr) - foreach(child_scene-> draw_background(screen, child_scene, root_h), scene.children) + return foreach(child_scene -> draw_background(screen, child_scene, root_h), scene.children) end function draw_plot(scene::Scene, screen::Screen, primitive::Plot) @@ -149,7 +149,7 @@ end # instead of the whole Scene # - Recognize when a screen is an image surface, and set scale to render the plot # at the scale of the device pixel -function draw_plot_as_image(scene::Scene, screen::Screen{RT}, primitive::Plot, scale::Number = 1) where RT +function draw_plot_as_image(scene::Scene, screen::Screen{RT}, primitive::Plot, scale::Number = 1) where {RT} # you can provide `p.rasterize = scale::Int` or `p.rasterize = true`, both of which are numbers # Extract scene width in device independent units @@ -183,5 +183,5 @@ function draw_plot_as_image(scene::Scene, screen::Screen{RT}, primitive::Plot, s end function draw_atomic(::Scene, ::Screen, x) - @warn "$(typeof(x)) is not supported by cairo right now" + return @warn "$(typeof(x)) is not supported by cairo right now" end diff --git a/CairoMakie/src/overrides.jl b/CairoMakie/src/overrides.jl index 6b7e0d6ef2e..6da895d2b23 100644 --- a/CairoMakie/src/overrides.jl +++ b/CairoMakie/src/overrides.jl @@ -15,11 +15,11 @@ function draw_plot(scene::Scene, screen::Screen, poly::Poly) # before conversion: return if Base.hasmethod(draw_poly, Tuple{Scene, Screen, typeof(poly), typeof.(to_value.(poly.args))...}) draw_poly(scene, screen, poly, to_value.(poly.args)...) - # If not, we check whether a `draw_poly` method exists for the arguments after conversion - # (`plot.converted`). This allows anything which decomposes to be checked for. + # If not, we check whether a `draw_poly` method exists for the arguments after conversion + # (`plot.converted`). This allows anything which decomposes to be checked for. elseif Base.hasmethod(draw_poly, Tuple{Scene, Screen, typeof(poly), typeof.(to_value.(poly.converted))...}) draw_poly(scene, screen, poly, to_value.(poly.converted)...) - # In the worst case, we return to drawing the polygon as a mesh + lines. + # In the worst case, we return to drawing the polygon as a mesh + lines. else draw_poly_as_mesh(scene, screen, poly) end @@ -34,24 +34,27 @@ function draw_poly_as_mesh(scene, screen, poly) for i in eachindex(poly.plots) draw_plot(scene, screen, poly.plots[i]) end + return end # As a general fallback, draw all polys as meshes. # This also applies for e.g. per-vertex color. function draw_poly(scene::Scene, screen::Screen, poly, points, color, model, strokecolor, strokestyle, strokewidth) - draw_poly_as_mesh(scene, screen, poly) + return draw_poly_as_mesh(scene, screen, poly) end function draw_poly(scene::Scene, screen::Screen, poly, points::Vector{<:Point2}) color = to_cairo_color(poly.color[], poly) strokecolor = to_cairo_color(poly.strokecolor[], poly) strokestyle = Makie.convert_attribute(poly.linestyle[], key"linestyle"()) - draw_poly(scene, screen, poly, points, color, poly.model[], strokecolor, strokestyle, poly.strokewidth[]) + return draw_poly(scene, screen, poly, points, color, poly.model[], strokecolor, strokestyle, poly.strokewidth[]) end # when color is a Makie.AbstractPattern, we don't need to go to Mesh -function draw_poly(scene::Scene, screen::Screen, poly, points::Vector{<:Point2}, color::Union{Colorant, Cairo.CairoPattern}, - model, strokecolor, strokestyle, strokewidth) +function draw_poly( + scene::Scene, screen::Screen, poly, points::Vector{<:Point2}, color::Union{Colorant, Cairo.CairoPattern}, + model, strokecolor, strokestyle, strokewidth + ) space = to_value(get(poly, :space, :data)) points = clip_poly(poly.clip_planes[], points, space, model) points = _project_position(scene, space, points, model, true) @@ -67,7 +70,7 @@ function draw_poly(scene::Scene, screen::Screen, poly, points::Vector{<:Point2}, Cairo.set_source_rgba(screen.context, rgbatuple(to_color(strokecolor))...) Cairo.set_line_width(screen.context, strokewidth) isnothing(strokestyle) || Cairo.set_dash(screen.context, diff(Float64.(strokestyle)) .* strokewidth) - Cairo.stroke(screen.context) + return Cairo.stroke(screen.context) end function draw_poly(scene::Scene, screen::Screen, poly, points_list::Vector{<:Vector{<:Point2}}) @@ -75,9 +78,11 @@ function draw_poly(scene::Scene, screen::Screen, poly, points_list::Vector{<:Vec strokecolor = to_cairo_color(poly.strokecolor[], poly) strokestyle = Makie.convert_attribute(poly.linestyle[], key"linestyle"()) - broadcast_foreach(points_list, color, - strokecolor, strokestyle, poly.strokewidth[], Ref(poly.model[])) do points, color, strokecolor, strokestyle, strokewidth, model - draw_poly(scene, screen, poly, points, color, model, strokecolor, strokestyle, strokewidth) + return broadcast_foreach( + points_list, color, + strokecolor, strokestyle, poly.strokewidth[], Ref(poly.model[]) + ) do points, color, strokecolor, strokestyle, strokewidth, model + draw_poly(scene, screen, poly, points, color, model, strokecolor, strokestyle, strokewidth) end end @@ -105,7 +110,7 @@ function draw_poly(scene::Scene, screen::Screen, poly, shapes::Vector{<:Union{Re error("Wrong type for linestyle: $(poly.linestyle[]).") end strokecolor = to_cairo_color(poly.strokecolor[], poly) - broadcast_foreach(projected_shapes, color, strokecolor, poly.strokewidth[]) do shape, c, sc, sw + return broadcast_foreach(projected_shapes, color, strokecolor, poly.strokewidth[]) do shape, c, sc, sw create_shape_path!(screen.context, shape) set_source(screen.context, c) Cairo.fill_preserve(screen.context) @@ -128,17 +133,18 @@ function project_shape(scene, space, shape::BezierPath, model) push!(commands, project_command(cmd, scene, space, model)) end end - BezierPath(commands) + return BezierPath(commands) end function create_shape_path!(ctx, r::Rect2) - Cairo.rectangle(ctx, origin(r)..., widths(r)...) + return Cairo.rectangle(ctx, origin(r)..., widths(r)...) end function create_shape_path!(ctx, b::BezierPath) for cmd in b.commands path_command(ctx, cmd) end + return end function polypath(ctx, polygon) @@ -161,6 +167,7 @@ function polypath(ctx, polygon) end Cairo.close_path(ctx) end + return end draw_poly(scene::Scene, screen::Screen, poly, polygon::Polygon) = draw_poly(scene, screen, poly, [polygon]) @@ -178,7 +185,7 @@ function draw_poly(scene::Scene, screen::Screen, poly, polygons::AbstractArray{< strokecolor = to_cairo_color(poly.strokecolor[], poly) strokestyle = Makie.convert_attribute(poly.linestyle[], key"linestyle"()) - broadcast_foreach(projected_polys, color, strokecolor, strokestyle, poly.strokewidth[]) do po, c, sc, ss, sw + return broadcast_foreach(projected_polys, color, strokecolor, strokestyle, poly.strokewidth[]) do po, c, sc, ss, sw polypath(screen.context, po) set_source(screen.context, c) Cairo.fill_preserve(screen.context) @@ -189,7 +196,7 @@ function draw_poly(scene::Scene, screen::Screen, poly, polygons::AbstractArray{< end -function draw_poly(scene::Scene, screen::Screen, poly, polygons::AbstractArray{<: MultiPolygon}) +function draw_poly(scene::Scene, screen::Screen, poly, polygons::AbstractArray{<:MultiPolygon}) model = poly.model[] space = to_value(get(poly, :space, :data)) projected_polys = map(polygons) do polygon @@ -199,7 +206,7 @@ function draw_poly(scene::Scene, screen::Screen, poly, polygons::AbstractArray{< color = to_cairo_color(poly.color[], poly) strokecolor = to_cairo_color(poly.strokecolor[], poly) strokestyle = Makie.convert_attribute(poly.linestyle[], key"linestyle"()) - broadcast_foreach(projected_polys, color, strokecolor, strokestyle, poly.strokewidth[]) do mpo, c, sc, ss, sw + return broadcast_foreach(projected_polys, color, strokecolor, strokestyle, poly.strokewidth[]) do mpo, c, sc, ss, sw for po in mpo.polygons polypath(screen.context, po) set_source(screen.context, c) @@ -227,7 +234,7 @@ function band_segment_ranges(lowerpoints, upperpoints) for i in eachindex(lowerpoints, upperpoints) if isnan(lowerpoints[i]) || isnan(upperpoints[i]) if start !== nothing && i - start > 1 # more than one point - push!(ranges, start:i-1) + push!(ranges, start:(i - 1)) end start = nothing elseif start === nothing @@ -239,8 +246,10 @@ function band_segment_ranges(lowerpoints, upperpoints) return ranges end -function draw_plot(scene::Scene, screen::Screen, - band::Band{<:Tuple{<:AbstractVector{<:Point2},<:AbstractVector{<:Point2}}}) +function draw_plot( + scene::Scene, screen::Screen, + band::Band{<:Tuple{<:AbstractVector{<:Point2}, <:AbstractVector{<:Point2}}} + ) if !(band.color[] isa AbstractArray) basecolor = to_cairo_color(band.color[], band) @@ -270,12 +279,12 @@ function draw_plot(scene::Scene, screen::Screen, end end - nothing + return nothing end # Override `is_cairomakie_atomic_plot` to allow this dispatch of `band` to remain a unit, # instead of auto-decomposing in lines and mesh. -function is_cairomakie_atomic_plot(plot::Band{<:Tuple{<:AbstractVector{<:Point2},<:AbstractVector{<:Point2}}}) +function is_cairomakie_atomic_plot(plot::Band{<:Tuple{<:AbstractVector{<:Point2}, <:AbstractVector{<:Point2}}}) return true end @@ -299,7 +308,7 @@ function draw_plot(scene::Scene, screen::Screen, tric::Tricontourf) function draw_tripolys(polys, colornumbers, colors) for (i, (pol, colnum, col)) in enumerate(zip(polys, colornumbers, colors)) polypath(screen.context, pol) - if i == length(colornumbers) || colnum != colornumbers[i+1] + if i == length(colornumbers) || colnum != colornumbers[i + 1] set_source(screen.context, col) Cairo.fill(screen.context) end diff --git a/CairoMakie/src/precompiles.jl b/CairoMakie/src/precompiles.jl index d6cdbef3efa..b32cc786794 100644 --- a/CairoMakie/src/precompiles.jl +++ b/CairoMakie/src/precompiles.jl @@ -16,9 +16,13 @@ let end end precompile(openurl, (String,)) -precompile(draw_atomic_scatter, (Scene, Cairo.CairoContext, Tuple{typeof(identity),typeof(identity)}, - Vector{ColorTypes.RGBA{Float32}}, Vec{2,Float32}, ColorTypes.RGBA{Float32}, - Float32, BezierPath, Vec{3,Float32}, Quaternionf, - Mat4f, Vector{Point{2,Float32}}, - Mat4f, Makie.FreeTypeAbstraction.FTFont, Symbol, - Symbol, Vector{Plane3f}, Bool)) +precompile( + draw_atomic_scatter, ( + Scene, Cairo.CairoContext, Tuple{typeof(identity), typeof(identity)}, + Vector{ColorTypes.RGBA{Float32}}, Vec{2, Float32}, ColorTypes.RGBA{Float32}, + Float32, BezierPath, Vec{3, Float32}, Quaternionf, + Mat4f, Vector{Point{2, Float32}}, + Mat4f, Makie.FreeTypeAbstraction.FTFont, Symbol, + Symbol, Vector{Plane3f}, Bool, + ) +) diff --git a/CairoMakie/src/primitives.jl b/CairoMakie/src/primitives.jl index 306da4c21f8..2a139befcb4 100644 --- a/CairoMakie/src/primitives.jl +++ b/CairoMakie/src/primitives.jl @@ -46,7 +46,7 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Unio end # joinstyle - miter_angle = to_value(get(primitive, :miter_limit, 2pi/3)) + miter_angle = to_value(get(primitive, :miter_limit, 2pi / 3)) set_miter_limit(ctx, 2.0 * Makie.miter_angle_to_distance(miter_angle)) joinstyle = to_value(get(primitive, :joinstyle, :miter)) @@ -79,7 +79,7 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Unio Cairo.set_source_rgba(ctx, red(color), green(color), blue(color), alpha(color)) draw_single(primitive, ctx, projected_positions) end - nothing + return nothing end function draw_bezierpath_lines(ctx, bezierpath::BezierPath, scene, color, space, model, linewidth) @@ -94,15 +94,15 @@ function draw_bezierpath_lines(ctx, bezierpath::BezierPath, scene, color, space, end function project_command(m::MoveTo, scene, space, model) - MoveTo(project_position(scene, space, m.p, model)) + return MoveTo(project_position(scene, space, m.p, model)) end function project_command(l::LineTo, scene, space, model) - LineTo(project_position(scene, space, l.p, model)) + return LineTo(project_position(scene, space, l.p, model)) end function project_command(c::CurveTo, scene, space, model) - CurveTo( + return CurveTo( project_position(scene, space, c.c1, model), project_position(scene, space, c.c2, model), project_position(scene, space, c.p, model), @@ -122,13 +122,13 @@ function draw_single(primitive::Lines, ctx, positions) # only take action for non-NaNs if !isnan(p) # new line segment at beginning or if previously NaN - if i == 1 || isnan(positions[i-1]) + if i == 1 || isnan(positions[i - 1]) Cairo.move_to(ctx, p...) start = p else Cairo.line_to(ctx, p...) # complete line segment at end or if next point is NaN - if i == n || isnan(positions[i+1]) + if i == n || isnan(positions[i + 1]) if p ≈ start Cairo.close_path(ctx) end @@ -138,16 +138,16 @@ function draw_single(primitive::Lines, ctx, positions) end end # force clearing of path in case of skipped NaN - Cairo.new_path(ctx) + return Cairo.new_path(ctx) end function draw_single(primitive::LineSegments, ctx, positions) @assert iseven(length(positions)) - @inbounds for i in 1:2:length(positions)-1 + @inbounds for i in 1:2:(length(positions) - 1) p1 = positions[i] - p2 = positions[i+1] + p2 = positions[i + 1] if isnan(p1) || isnan(p2) continue @@ -158,7 +158,7 @@ function draw_single(primitive::LineSegments, ctx, positions) end end # force clearing of path in case of skipped NaN - Cairo.new_path(ctx) + return Cairo.new_path(ctx) end # getindex if array, otherwise just return value @@ -168,27 +168,27 @@ function draw_multi(primitive::LineSegments, ctx, positions, colors, linewidths, @assert iseven(length(positions)) for i in 1:2:length(positions) - if isnan(positions[i+1]) || isnan(positions[i]) + if isnan(positions[i + 1]) || isnan(positions[i]) continue end lw = sv_getindex(linewidths, i) - if lw != sv_getindex(linewidths, i+1) - error("Cairo doesn't support two different line widths ($lw and $(sv_getindex(linewidths, i+1)) at the endpoints of a line.") + if lw != sv_getindex(linewidths, i + 1) + error("Cairo doesn't support two different line widths ($lw and $(sv_getindex(linewidths, i + 1)) at the endpoints of a line.") end Cairo.move_to(ctx, positions[i]...) - Cairo.line_to(ctx, positions[i+1]...) + Cairo.line_to(ctx, positions[i + 1]...) Cairo.set_line_width(ctx, lw) !isnothing(dash) && Cairo.set_dash(ctx, dash .* lw) c1 = sv_getindex(colors, i) - c2 = sv_getindex(colors, i+1) + c2 = sv_getindex(colors, i + 1) # we can avoid the more expensive gradient if the colors are the same # this happens if one color was given for each segment if c1 == c2 Cairo.set_source_rgba(ctx, red(c1), green(c1), blue(c1), alpha(c1)) Cairo.stroke(ctx) else - pat = Cairo.pattern_create_linear(positions[i]..., positions[i+1]...) + pat = Cairo.pattern_create_linear(positions[i]..., positions[i + 1]...) Cairo.pattern_add_color_stop_rgba(pat, 0, red(c1), green(c1), blue(c1), alpha(c1)) Cairo.pattern_add_color_stop_rgba(pat, 1, red(c2), green(c2), blue(c2), alpha(c2)) Cairo.set_source(ctx, pat) @@ -196,6 +196,7 @@ function draw_multi(primitive::LineSegments, ctx, positions, colors, linewidths, Cairo.destroy(pat) end end + return end function draw_multi(primitive::Lines, ctx, positions, colors, linewidths, dash) @@ -218,7 +219,7 @@ function draw_multi(primitive::Lines, ctx, positions, colors, linewidths, dash) # first is nan, do nothing end - for i in eachindex(positions)[begin+1:end] + for i in eachindex(positions)[(begin + 1):end] this_position = positions[i] this_color = sv_getindex(colors, i) this_nan = isnan(this_position) @@ -250,7 +251,7 @@ function draw_multi(primitive::Lines, ctx, positions, colors, linewidths, dash) # this color is like the previous if !this_nan # and this is not nan, so line_to and set prev_continued - this_linewidth != prev_linewidth && error("Encountered two different linewidth values $prev_linewidth and $this_linewidth in `lines` at index $(i-1). Different linewidths in one line are only permitted in CairoMakie when separated by a NaN point.") + this_linewidth != prev_linewidth && error("Encountered two different linewidth values $prev_linewidth and $this_linewidth in `lines` at index $(i - 1). Different linewidths in one line are only permitted in CairoMakie when separated by a NaN point.") Cairo.line_to(ctx, this_position...) prev_continued = true @@ -275,7 +276,7 @@ function draw_multi(primitive::Lines, ctx, positions, colors, linewidths, dash) Cairo.stroke(ctx) if !this_nan - this_linewidth != prev_linewidth && error("Encountered two different linewidth values $prev_linewidth and $this_linewidth in `lines` at index $(i-1). Different linewidths in one line are only permitted in CairoMakie when separated by a NaN point.") + this_linewidth != prev_linewidth && error("Encountered two different linewidth values $prev_linewidth and $this_linewidth in `lines` at index $(i - 1). Different linewidths in one line are only permitted in CairoMakie when separated by a NaN point.") # this is not nan # and this color is different than the previous, so move_to prev and line_to this # create gradient pattern and stroke @@ -302,6 +303,7 @@ function draw_multi(primitive::Lines, ctx, positions, colors, linewidths, dash) prev_linewidth = this_linewidth prev_position = this_position end + return end ################################################################################ @@ -309,9 +311,11 @@ end ################################################################################ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Scatter)) - @get_attribute(primitive, ( - markersize, strokecolor, strokewidth, marker, marker_offset, rotation, - transform_marker, model, markerspace, space, clip_planes) + @get_attribute( + primitive, ( + markersize, strokecolor, strokewidth, marker, marker_offset, rotation, + transform_marker, model, markerspace, space, clip_planes, + ) ) marker = cairo_scatter_marker(primitive.marker[]) # this goes through CairoMakie's conversion system and not Makie's... @@ -327,9 +331,11 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Scat transfunc = Makie.transform_func(primitive) billboard = primitive.rotation[] isa Billboard - return draw_atomic_scatter(scene, ctx, transfunc, colors, markersize, strokecolor, strokewidth, marker, - marker_offset, rotation, model, positions, size_model, font, markerspace, - space, clip_planes, billboard) + return draw_atomic_scatter( + scene, ctx, transfunc, colors, markersize, strokecolor, strokewidth, marker, + marker_offset, rotation, model, positions, size_model, font, markerspace, + space, clip_planes, billboard + ) end function draw_atomic_scatter( @@ -344,10 +350,12 @@ function draw_atomic_scatter( Makie.space_to_clip(scene.camera, space) * Makie.f32_convert_matrix(scene.float32convert, space) * model - model33 = size_model[Vec(1,2,3), Vec(1,2,3)] + model33 = size_model[Vec(1, 2, 3), Vec(1, 2, 3)] - Makie.broadcast_foreach_index(view(transformed, indices), indices, colors, markersize, strokecolor, - strokewidth, marker, marker_offset, remove_billboard(rotation)) do pos, col, + Makie.broadcast_foreach_index( + view(transformed, indices), indices, colors, markersize, strokecolor, + strokewidth, marker, marker_offset, remove_billboard(rotation) + ) do pos, col, markersize, strokecolor, strokewidth, m, mo, rotation isnan(pos) && return @@ -356,8 +364,10 @@ function draw_atomic_scatter( p4d = transform * to_ndim(Point4d, to_ndim(Point3d, pos, 0), 1) o = p4d[Vec(1, 2, 3)] ./ p4d[4] .+ model33 * to_ndim(Vec3d, mo, 0) - proj_pos, mat, jl_mat = project_marker(scene, markerspace, o, - markersize, rotation, size_model, billboard) + proj_pos, mat, jl_mat = project_marker( + scene, markerspace, o, + markersize, rotation, size_model, billboard + ) # mat and jl_mat are the same matrix, once as a CairoMatrix, once as a Mat2f # They both describe an approximate basis transformation matrix from @@ -422,11 +432,11 @@ function draw_marker(ctx, marker::Char, font, pos, strokecolor, strokewidth, jl_ return end -function draw_marker(ctx, ::Type{<: Circle}, pos, strokecolor, strokewidth, mat) +function draw_marker(ctx, ::Type{<:Circle}, pos, strokecolor, strokewidth, mat) # There are already active transforms so we can't Cairo.set_matrix() here Cairo.translate(ctx, pos[1], pos[2]) cairo_transform(ctx, mat) - Cairo.arc(ctx, 0, 0, 0.5, 0, 2*pi) + Cairo.arc(ctx, 0, 0, 0.5, 0, 2 * pi) Cairo.fill_preserve(ctx) Cairo.set_line_width(ctx, Float64(strokewidth)) sc = to_color(strokecolor) @@ -435,7 +445,7 @@ function draw_marker(ctx, ::Type{<: Circle}, pos, strokecolor, strokewidth, mat) return end -function draw_marker(ctx, ::Union{Makie.FastPixel,<:Type{<:Rect}}, pos, strokecolor, strokewidth, mat) +function draw_marker(ctx, ::Union{Makie.FastPixel, <:Type{<:Rect}}, pos, strokecolor, strokewidth, mat) # There are already active transforms so we can't Cairo.set_matrix() here Cairo.translate(ctx, pos[1], pos[2]) cairo_transform(ctx, mat) @@ -479,6 +489,7 @@ function draw_path(ctx, bp::BezierPath) path_command(ctx, command) end end + return end path_command(ctx, c::MoveTo) = Cairo.move_to(ctx, c.p...) path_command(ctx, c::LineTo) = Cairo.line_to(ctx, c.p...) @@ -494,16 +505,18 @@ function path_command(ctx, c::EllipticalArc) else Cairo.arc_negative(ctx, 0, 0, c.r1, c.a1, c.a2) end - Cairo.restore(ctx) + return Cairo.restore(ctx) end -function draw_marker(ctx, marker::Matrix{T}, pos, - strokecolor #= unused =#, strokewidth #= unused =#, - mat) where T<:Colorant +function draw_marker( + ctx, marker::Matrix{T}, pos, + strokecolor #= unused =#, strokewidth #= unused =#, + mat + ) where {T <: Colorant} # convert marker to Cairo compatible image data - marker = permutedims(marker, (2,1)) + marker = permutedims(marker, (2, 1)) marker_surf = to_cairo_image(marker) w, h = size(marker) @@ -512,7 +525,7 @@ function draw_marker(ctx, marker::Matrix{T}, pos, Cairo.translate(ctx, pos[1], pos[2]) cairo_transform(ctx, mat) Cairo.scale(ctx, 1.0 / w, 1.0 / h) - Cairo.set_source_surface(ctx, marker_surf, -w/2, -h/2) + Cairo.set_source_surface(ctx, marker_surf, -w / 2, -h / 2) Cairo.paint(ctx) return end @@ -521,9 +534,9 @@ end # Text # ################################################################################ -function p3_to_p2(p::Point3{T}) where T - if p[3] == 0 || isnan(p[3]) - Point2{T}(p[Vec(1,2)]...) +function p3_to_p2(p::Point3{T}) where {T} + return if p[3] == 0 || isnan(p[3]) + Point2{T}(p[Vec(1, 2)]...) else error("Can't reduce Point3 to Point2 with nonzero third component $(p[3]).") end @@ -543,7 +556,7 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Text clip_planes ) - nothing + return nothing end function draw_glyph_collection( @@ -553,8 +566,10 @@ function draw_glyph_collection( ) # TODO: why is the Ref around model necessary? doesn't broadcast_foreach handle staticarrays matrices? - broadcast_foreach(positions, glyph_collections, rotation, Ref(model), space, - markerspace, offset) do pos, glayout, ro, mo, sp, msp, off + return broadcast_foreach( + positions, glyph_collections, rotation, Ref(model), space, + markerspace, offset + ) do pos, glayout, ro, mo, sp, msp, off draw_glyph_collection(scene, ctx, pos, glayout, ro, mo, sp, msp, off, transformation, transform_marker, clip_planes) end @@ -565,7 +580,8 @@ _deref(x::Ref) = x[] function draw_glyph_collection( scene, ctx, position, glyph_collection, rotation, _model, space, - markerspace, offsets, transformation, transform_marker, clip_planes) + markerspace, offsets, transformation, transform_marker, clip_planes + ) glyphs = glyph_collection.glyphs glyphoffsets = glyph_collection.origins @@ -590,15 +606,15 @@ function draw_glyph_collection( Makie.is_data_space(space) && is_clipped(clip_planes, p) && return Makie.clip_to_space(scene.camera, markerspace) * - Makie.space_to_clip(scene.camera, space) * - Makie.f32_convert_matrix(scene.float32convert, space) * - p + Makie.space_to_clip(scene.camera, space) * + Makie.f32_convert_matrix(scene.float32convert, space) * + p end Cairo.save(ctx) broadcast_foreach(glyphs, glyphoffsets, fonts, rotations, scales, colors, strokewidths, strokecolors, offsets) do glyph, - glyphoffset, font, rotation, scale, color, strokewidth, strokecolor, offset + glyphoffset, font, rotation, scale, color, strokewidth, strokecolor, offset cairoface = set_ft_font(ctx, font) old_matrix = get_font_matrix(ctx) @@ -660,13 +676,13 @@ If not, returns array unchanged. function regularly_spaced_array_to_range(arr) diffs = unique!(sort!(diff(arr))) step = sum(diffs) ./ length(diffs) - if all(x-> x ≈ step, diffs) + if all(x -> x ≈ step, diffs) m, M = extrema(arr) if step < zero(step) m, M = M, m end # don't use stop=M, since that may not include M - return range(m; step=step, length=length(arr)) + return range(m; step = step, length = length(arr)) else return arr end @@ -675,28 +691,28 @@ end regularly_spaced_array_to_range(arr::AbstractRange) = arr function premultiplied_rgba(a::AbstractArray{<:ColorAlpha}) - map(premultiplied_rgba, a) + return map(premultiplied_rgba, a) end premultiplied_rgba(a::AbstractArray{<:Color}) = RGBA.(a) premultiplied_rgba(r::RGBA) = RGBA(r.r * r.alpha, r.g * r.alpha, r.b * r.alpha, r.alpha) premultiplied_rgba(c::Colorant) = premultiplied_rgba(RGBA(c)) -function draw_atomic(scene::Scene, screen::Screen{RT}, @nospecialize(primitive::Union{Heatmap, Image})) where RT +function draw_atomic(scene::Scene, screen::Screen{RT}, @nospecialize(primitive::Union{Heatmap, Image})) where {RT} ctx = screen.context image = primitive[3][] xs, ys = primitive[1][], primitive[2][] if xs isa Makie.EndPoints l, r = xs N = size(image, 1) - xs = range(l, r, length = N+1) + xs = range(l, r, length = N + 1) else xs = regularly_spaced_array_to_range(xs) end if ys isa Makie.EndPoints l, r = ys N = size(image, 2) - ys = range(l, r, length = N+1) + ys = range(l, r, length = N + 1) else ys = regularly_spaced_array_to_range(ys) end @@ -710,7 +726,7 @@ function draw_atomic(scene::Scene, screen::Screen{RT}, @nospecialize(primitive:: # Vector backends don't support FILTER_NEAREST for interp == false, so in that case we also need to draw rects is_vector = is_vector_backend(ctx) t = Makie.transform_func(primitive) - identity_transform = (t === identity || t isa Tuple && all(x-> x === identity, t)) && (abs(model[1, 2]) < 1e-15) + identity_transform = (t === identity || t isa Tuple && all(x -> x === identity, t)) && (abs(model[1, 2]) < 1.0e-15) regular_grid = xs isa AbstractRange && ys isa AbstractRange xy_aligned = Makie.is_translation_scale_matrix(scene.camera.projectionview[]) @@ -740,17 +756,17 @@ function draw_atomic(scene::Scene, screen::Screen{RT}, @nospecialize(primitive:: # invert y. T3 = Mat3f(T[1], T[2], 0, T[3], T[4], 0, T[5], T[6], 1) T3 = Makie.uv_transform(Vec2f(size(image))) * T3 * - Makie.uv_transform(Vec2f(0, 1), 1f0 ./ Vec2f(size(image, 1), -size(image, 2))) - T3[Vec(1, 2), Vec(1,2,3)] + Makie.uv_transform(Vec2f(0, 1), 1.0f0 ./ Vec2f(size(image, 1), -size(image, 2))) + T3[Vec(1, 2), Vec(1, 2, 3)] else - Mat{2, 3, Float32}(1,0,0,1,0,0) + Mat{2, 3, Float32}(1, 0, 0, 1, 0, 0) end can_use_fast_path = !(is_vector && !interpolate) && regular_grid && identity_transform && (interpolate || xy_aligned) && isempty(primitive.clip_planes[]) use_fast_path = can_use_fast_path && !disable_fast_path - if use_fast_path + return if use_fast_path s = to_cairo_image(to_color(primitive.calculated_colors[])) weird_cairo_limit = (2^15) - 23 @@ -809,11 +825,11 @@ function draw_atomic(scene::Scene, screen::Screen{RT}, @nospecialize(primitive:: end function _draw_rect_heatmap(ctx, xys, ni, nj, colors) - @inbounds for i in 1:ni, j in 1:nj + return @inbounds for i in 1:ni, j in 1:nj p1 = xys[i, j] - p2 = xys[i+1, j] - p3 = xys[i+1, j+1] - p4 = xys[i, j+1] + p2 = xys[i + 1, j] + p3 = xys[i + 1, j + 1] + p4 = xys[i, j + 1] if isnan(p1) || isnan(p2) || isnan(p3) || isnan(p4) continue end @@ -885,14 +901,14 @@ function draw_mesh2D(scene, screen, @nospecialize(plot::Makie.Mesh), @nospeciali return draw_mesh2D(screen, cols, vs, fs) end -function draw_mesh2D(screen, per_face_cols, vs::Vector{<: Point2}, fs::Vector{GLTriangleFace}) +function draw_mesh2D(screen, per_face_cols, vs::Vector{<:Point2}, fs::Vector{GLTriangleFace}) ctx = screen.context # Prioritize colors of the mesh if present # This is a hack, which needs cleaning up in the Mesh plot type! for (f, (c1, c2, c3)) in zip(fs, per_face_cols) - t1, t2, t3 = vs[f] #triangle points + t1, t2, t3 = vs[f] #triangle points # don't draw any mesh faces with NaN components. if isnan(t1) || isnan(t2) || isnan(t3) @@ -922,7 +938,7 @@ end function average_z(positions, face) vs = positions[face] - sum(v -> v[3], vs) / length(vs) + return sum(v -> v[3], vs) / length(vs) end nan2zero(x) = !isnan(x) * x @@ -938,7 +954,7 @@ end function draw_mesh3D( scene, screen, attributes, mesh; pos = Vec3d(0), scale = 1.0, rotation = Mat4d(I), - uv_transform = Mat{2, 3, Float32}(1,0,0,1,0,0) + uv_transform = Mat{2, 3, Float32}(1, 0, 0, 1, 0, 0) ) @get_attribute(attributes, (shading, diffuse, specular, shininess, faceculling, clip_planes)) @@ -993,7 +1009,7 @@ function draw_mesh3D( meshnormals .= -meshnormals end - draw_mesh3D( + return draw_mesh3D( scene, screen, space, meshpoints, meshfaces, meshnormals, per_face_col, pos, scale, rotation, f32c_model::Mat4d, shading_bool::Bool, diffuse::Vec3f, @@ -1042,7 +1058,7 @@ function draw_mesh3D( dirlight = Makie.get_directional_light(scene) if !isnothing(dirlight) lightdirection = if dirlight.camera_relative - T = inv(scene.camera.view[][Vec(1,2,3), Vec(1,2,3)]) + T = inv(scene.camera.view[][Vec(1, 2, 3), Vec(1, 2, 3)]) normalize(T * dirlight.direction[]) else normalize(dirlight.direction[]) @@ -1050,7 +1066,7 @@ function draw_mesh3D( c = dirlight.color[] light_color = Vec3f(red(c), green(c), blue(c)) else - lightdirection = Vec3f(0,0,-1) + lightdirection = Vec3f(0, 0, -1) light_color = Vec3f(0) end @@ -1068,7 +1084,7 @@ function draw_mesh3D( @inbounds begin p = (clip ./ clip[4])[Vec(1, 2)] p_yflip = Vec2f(p[1], -p[2]) - p_0_to_1 = (p_yflip .+ 1f0) ./ 2f0 + p_0_to_1 = (p_yflip .+ 1.0f0) ./ 2.0f0 end p = p_0_to_1 .* scene.camera.resolution[] return Vec3f(p[1], p[2], clip[3]) @@ -1092,20 +1108,21 @@ function draw_mesh3D( draw_pattern( ctx, zorder, shading, meshfaces, ts, per_face_col, ns, vs, - lightdirection, light_color, shininess, diffuse, ambient, specular) + lightdirection, light_color, shininess, diffuse, ambient, specular + ) return end function _calculate_shaded_vertexcolors(N, v, c, lightdir, light_color, ambient, diffuse, specular, shininess) L = lightdir - diff_coeff = max(dot(L, -N), 0f0) + diff_coeff = max(dot(L, -N), 0.0f0) H = normalize(L + v) - spec_coeff = max(dot(H, -N), 0f0)^shininess + spec_coeff = max(dot(H, -N), 0.0f0)^shininess c = RGBAf(c) # if this is one expression it introduces allocations?? new_c_part1 = (ambient .+ light_color .* diff_coeff .* diffuse) .* Vec3f(c.r, c.g, c.b) #.+ new_c = new_c_part1 .+ light_color .* specular * spec_coeff - RGBAf(new_c..., c.alpha) + return RGBAf(new_c..., c.alpha) end function draw_pattern(ctx, zorder, shading, meshfaces, ts, per_face_col, ns, vs, lightdir, light_color, shininess, diffuse, ambient, specular) @@ -1162,6 +1179,7 @@ function draw_pattern(ctx, zorder, shading, meshfaces, ts, per_face_col, ns, vs, Cairo.destroy(pattern) end + return end ################################################################################ @@ -1204,7 +1222,7 @@ function _transform_to_world(f32_model, tf, space, pos) transformed = Makie.apply_transform(tf, p, space) p4d = to_ndim(Point4d, to_ndim(Point3d, transformed, 0), 1) p4d = f32_model * p4d - return p4d[Vec(1,2,3)] / p4d[4] + return p4d[Vec(1, 2, 3)] / p4d[4] end end @@ -1217,11 +1235,13 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Maki # For correct z-ordering we need to be in view/camera or screen space view = scene.camera.view[] - zorder = sortperm(transformed_pos, by = p -> begin - p4d = to_ndim(Vec4d, p, 1) - cam_pos = view[Vec(3,4), Vec(1,2,3,4)] * p4d - cam_pos[1] / cam_pos[2] - end, rev=false) + zorder = sortperm( + transformed_pos, by = p -> begin + p4d = to_ndim(Vec4d, p, 1) + cam_pos = view[Vec(3, 4), Vec(1, 2, 3, 4)] * p4d + cam_pos[1] / cam_pos[2] + end, rev = false + ) color = to_color(primitive.calculated_colors[]) submesh = Attributes( @@ -1246,7 +1266,7 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Maki draw_mesh3D( scene, screen, submesh, marker, pos = transformed_pos[i], - scale = scale isa Real ? Vec3f(scale) : to_ndim(Vec3f, scale, 1f0), + scale = scale isa Real ? Vec3f(scale) : to_ndim(Vec3f, scale, 1.0f0), rotation = _rotation, uv_transform = _uv_transform ) end @@ -1255,7 +1275,6 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Maki end - ################################################################################ # Voxel # ################################################################################ @@ -1279,11 +1298,13 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Maki # For correct z-ordering we need to be in view/camera or screen space view = scene.camera.view[] - zorder = sortperm(transformed_pos, by = p -> begin - p4d = to_ndim(Vec4d, p, 1) - cam_pos = view[Vec(3,4), Vec(1,2,3,4)] * p4d - cam_pos[1] / cam_pos[2] - end, rev=false) + zorder = sortperm( + transformed_pos, by = p -> begin + p4d = to_ndim(Vec4d, p, 1) + cam_pos = view[Vec(3, 4), Vec(1, 2, 3, 4)] * p4d + cam_pos[1] / cam_pos[2] + end, rev = false + ) submesh = Attributes( model = primitive.model, diff --git a/CairoMakie/src/screen.jl b/CairoMakie/src/screen.jl index b6759fee88d..f70bf255a6c 100644 --- a/CairoMakie/src/screen.jl +++ b/CairoMakie/src/screen.jl @@ -2,7 +2,7 @@ using Base.Docs: doc @enum RenderType SVG IMAGE PDF EPS HTML -Base.convert(::Type{RenderType}, ::MIME{SYM}) where SYM = mime_to_rendertype(SYM) +Base.convert(::Type{RenderType}, ::MIME{SYM}) where {SYM} = mime_to_rendertype(SYM) function Base.convert(::Type{RenderType}, type::String) if type == "png" return IMAGE @@ -45,12 +45,12 @@ function mime_to_rendertype(mime::Symbol)::RenderType end end -function surface_from_output_type(mime::MIME{M}, io, w, h) where M - surface_from_output_type(M, io, w, h) +function surface_from_output_type(mime::MIME{M}, io, w, h) where {M} + return surface_from_output_type(M, io, w, h) end function surface_from_output_type(mime::Symbol, io, w, h) - surface_from_output_type(mime_to_rendertype(mime), io, w, h) + return surface_from_output_type(mime_to_rendertype(mime), io, w, h) end function surface_from_output_type(type::RenderType, io, w, h) @@ -104,11 +104,13 @@ struct ScreenConfig start_renderloop::Bool # Only used to satisfy the interface for record using `Screen(...; start_renderloop=false)` for GLMakie pdf_version::Union{Nothing, PDFVersion} - function ScreenConfig(px_per_unit::Real, pt_per_unit::Real, + function ScreenConfig( + px_per_unit::Real, pt_per_unit::Real, antialias::Symbol, visible::Bool, start_renderloop::Bool, - pdf_version::Union{Nothing, AbstractString}) + pdf_version::Union{Nothing, AbstractString} + ) v = isnothing(pdf_version) ? nothing : pdfversion(pdf_version) - new(px_per_unit, pt_per_unit, antialias, visible, start_renderloop, v) + return new(px_per_unit, pt_per_unit, antialias, visible, start_renderloop, v) end end @@ -125,7 +127,7 @@ function device_scaling_factor(surface::Cairo.CairoSurface, sc::ScreenConfig) return device_scaling_factor(get_render_type(surface), sc) end -const LAST_INLINE = Ref{Union{Makie.Automatic,Bool}}(Makie.automatic) +const LAST_INLINE = Ref{Union{Makie.Automatic, Bool}}(Makie.automatic) """ CairoMakie.activate!(; screen_config...) @@ -137,7 +139,7 @@ Note, that the `screen_config` can also be set permanently via `Makie.set_theme! $(Base.doc(ScreenConfig)) """ -function activate!(; inline=LAST_INLINE[], type="png", screen_config...) +function activate!(; inline = LAST_INLINE[], type = "png", screen_config...) Makie.inline!(inline) LAST_INLINE[] = inline Makie.set_screen_config!(CairoMakie, screen_config) @@ -211,7 +213,7 @@ function Base.empty!(screen::Screen) Cairo.set_operator(ctx, Cairo.OPERATOR_CLEAR) Cairo.rectangle(ctx, 0, 0, size(screen)...) Cairo.paint_with_alpha(ctx, 1.0) - Cairo.restore(ctx) + return Cairo.restore(ctx) end Base.close(screen::Screen) = empty!(screen) @@ -219,7 +221,7 @@ Base.close(screen::Screen) = empty!(screen) function destroy!(screen::Screen) isdefined(screen, :surface) || return Cairo.destroy(screen.surface) - Cairo.destroy(screen.context) + return Cairo.destroy(screen.context) end function Base.isopen(screen::Screen) @@ -228,7 +230,7 @@ end function Base.size(screen::Screen) isdefined(screen, :surface) || return (0, 0) - round.(Int, (screen.surface.width, screen.surface.height)) + return round.(Int, (screen.surface.width, screen.surface.height)) end # we render the scene directly, since we have # no screen dependent state like in e.g. opengl @@ -241,8 +243,8 @@ function Base.delete!(screen::Screen, scene::Scene, plot::AbstractPlot) # do something here. end -function Base.show(io::IO, ::MIME"text/plain", screen::Screen{S}) where S - println(io, "CairoMakie.Screen{$S}") +function Base.show(io::IO, ::MIME"text/plain", screen::Screen{S}) where {S} + return println(io, "CairoMakie.Screen{$S}") end function path_to_type(path) @@ -282,7 +284,8 @@ function scaled_scene_resolution(typ::RenderType, config::ScreenConfig, scene::S end function Makie.apply_screen_config!( - screen::Screen{SCREEN_RT}, config::ScreenConfig, scene::Scene, io::Union{Nothing, IO}, m::MIME{SYM}) where {SYM, SCREEN_RT} + screen::Screen{SCREEN_RT}, config::ScreenConfig, scene::Scene, io::Union{Nothing, IO}, m::MIME{SYM} + ) where {SYM, SCREEN_RT} # the surface size is the scene size scaled by the device scaling factor new_rendertype = mime_to_rendertype(SYM) # we need to re-create the screen if the rendertype changes, or for all vector backends @@ -302,7 +305,7 @@ end function Makie.apply_screen_config!(screen::Screen, config::ScreenConfig, scene::Scene, args...) # No mime as an argument implies we want an image based surface - Makie.apply_screen_config!(screen, config, scene, nothing, MIME"image/png"()) + return Makie.apply_screen_config!(screen, config, scene, nothing, MIME"image/png"()) end diff --git a/CairoMakie/src/utils.jl b/CairoMakie/src/utils.jl index d15f44813e3..b7e8d87758c 100644 --- a/CairoMakie/src/utils.jl +++ b/CairoMakie/src/utils.jl @@ -6,15 +6,15 @@ using Makie: apply_transform, transform_func, unclipped_indices, to_model_space, broadcast_foreach_index, is_clipped, is_visible -function project_position(scene::Scene, transform_func::T, space::Symbol, point, model::Mat4, yflip::Bool = true) where T +function project_position(scene::Scene, transform_func::T, space::Symbol, point, model::Mat4, yflip::Bool = true) where {T} # use transform func point = Makie.apply_transform(transform_func, point, space) - _project_position(scene, space, point, model, yflip) + return _project_position(scene, space, point, model, yflip) end # much faster than dot-ing `project_position` because it skips all the repeated mat * mat function project_position( - scene::Scene, space::Symbol, ps::Vector{<: VecTypes{N, T1}}, + scene::Scene, space::Symbol, ps::Vector{<:VecTypes{N, T1}}, indices::Vector{<:Integer}, model::Mat4, yflip::Bool = true ) where {N, T1} @@ -22,10 +22,10 @@ function project_position( f32convert = Makie.f32_convert_matrix(scene.float32convert, space) M = Makie.space_to_clip(scene.camera, space) * f32convert * model res = scene.camera.resolution[] - px_scale = Vec3d(0.5 * res[1], 0.5 * (yflip ? -res[2] : res[2]), 1) + px_scale = Vec3d(0.5 * res[1], 0.5 * (yflip ? -res[2] : res[2]), 1) px_offset = Vec3d(0.5 * res[1], 0.5 * res[2], 0) M = Makie.transformationmatrix(px_offset, px_scale) * M - M[Vec(1,2,4), Vec(1,2,3,4)] # skip z, i.e. calculate (x, y, w) + M[Vec(1, 2, 4), Vec(1, 2, 3, 4)] # skip z, i.e. calculate (x, y, w) end output = Vector{Point2f}(undef, length(indices)) @@ -39,12 +39,12 @@ function project_position( return output end -function _project_position(scene::Scene, space, ps::AbstractArray{<: VecTypes{N, T1}}, model, yflip::Bool) where {N, T1} +function _project_position(scene::Scene, space, ps::AbstractArray{<:VecTypes{N, T1}}, model, yflip::Bool) where {N, T1} return project_position(scene, space, ps, eachindex(ps), model, yflip) end function project_position( - scene::Scene, space::Symbol, ps::AbstractArray{<: VecTypes{N, T1}}, + scene::Scene, space::Symbol, ps::AbstractArray{<:VecTypes{N, T1}}, indices::Base.OneTo, model::Mat4, yflip::Bool = true ) where {N, T1} @@ -52,10 +52,10 @@ function project_position( f32convert = Makie.f32_convert_matrix(scene.float32convert, space) M = Makie.space_to_clip(scene.camera, space) * f32convert * model res = scene.camera.resolution[] - px_scale = Vec3d(0.5 * res[1], 0.5 * (yflip ? -res[2] : res[2]), 1) + px_scale = Vec3d(0.5 * res[1], 0.5 * (yflip ? -res[2] : res[2]), 1) px_offset = Vec3d(0.5 * res[1], 0.5 * res[2], 0) M = Makie.transformationmatrix(px_offset, px_scale) * M - M[Vec(1,2,4), Vec(1,2,3,4)] # skip z, i.e. calculate (x, y, w) + M[Vec(1, 2, 4), Vec(1, 2, 3, 4)] # skip z, i.e. calculate (x, y, w) end output = similar(ps, Point2f) @@ -79,9 +79,9 @@ function _project_position(scene::Scene, space, point::VecTypes{N, T1}, model, y # between -1 and 1 p = (clip ./ clip[4])[Vec(1, 2)] # flip y to match cairo - p_yflip = Vec2f(p[1], (1f0 - 2f0 * yflip) * p[2]) + p_yflip = Vec2f(p[1], (1.0f0 - 2.0f0 * yflip) * p[2]) # normalize to between 0 and 1 - p_0_to_1 = (p_yflip .+ 1f0) ./ 2f0 + p_0_to_1 = (p_yflip .+ 1.0f0) ./ 2.0f0 end # multiply with scene resolution for final position return p_0_to_1 .* res @@ -89,12 +89,12 @@ end function project_position(@nospecialize(scenelike), space, point, model, yflip::Bool = true) scene = Makie.get_scene(scenelike) - project_position(scene, Makie.transform_func(scenelike), space, point, model, yflip) + return project_position(scene, Makie.transform_func(scenelike), space, point, model, yflip) end function project_marker(scene, markerspace, origin, scale, rotation, model, billboard = false) scale3 = to_ndim(Vec2d, scale, first(scale)) - model33 = model[Vec(1,2,3), Vec(1,2,3)] + model33 = model[Vec(1, 2, 3), Vec(1, 2, 3)] origin3 = to_ndim(Point3d, origin, 0) return project_marker(scene, markerspace, origin3, scale3, rotation, model33, Mat4d(I), billboard) end @@ -111,8 +111,8 @@ function project_marker(scene, markerspace, origin::Point3, scale::Vec, rotation if billboard && Makie.is_data_space(markerspace) p4d = scene.camera.view[] * to_ndim(Point4d, origin, 1) - xproj = _project_position(scene, :eye, p4d[Vec(1,2,3)] / p4d[4] + xvec, id, true) - yproj = _project_position(scene, :eye, p4d[Vec(1,2,3)] / p4d[4] + yvec, id, true) + xproj = _project_position(scene, :eye, p4d[Vec(1, 2, 3)] / p4d[4] + xvec, id, true) + yproj = _project_position(scene, :eye, p4d[Vec(1, 2, 3)] / p4d[4] + yvec, id, true) else xproj = _project_position(scene, markerspace, origin + xvec, id, true) yproj = _project_position(scene, markerspace, origin + yvec, id, true) @@ -195,25 +195,25 @@ function project_polygon(@nospecialize(scenelike), space, poly::Polygon{N, T}, c ext_proj = PT[project(p) for p in clip_poly(clip_planes, ext, space, model)] interiors_proj = Vector{PT}[ PT[project(p) for p in clip_poly(clip_planes, decompose(PT, points), space, model)] - for points in poly.interiors] + for points in poly.interiors + ] return Polygon(ext_proj, interiors_proj) end -function project_multipolygon(@nospecialize(scenelike), space, multipoly::MP, clip_planes, model) where MP <: MultiPolygon +function project_multipolygon(@nospecialize(scenelike), space, multipoly::MP, clip_planes, model) where {MP <: MultiPolygon} return MultiPolygon(project_polygon.(Ref(scenelike), Ref(space), multipoly.polygons, Ref(clip_planes), Ref(model))) end scale_matrix(x, y) = Cairo.CairoMatrix(x, 0.0, 0.0, y, 0.0, 0.0) function clip2screen(p, res) - s = Vec2f(0.5f0, -0.5f0) .* p[Vec(1, 2)] / p[4].+ 0.5f0 + s = Vec2f(0.5f0, -0.5f0) .* p[Vec(1, 2)] / p[4] .+ 0.5f0 return res .* s end - -function project_line_points(scene, plot::T, positions::AbstractArray{<: Makie.VecTypes{N, FT}}, colors, linewidths) where {T <: Union{Lines, LineSegments}, N, FT <: Real} +function project_line_points(scene, plot::T, positions::AbstractArray{<:Makie.VecTypes{N, FT}}, colors, linewidths) where {T <: Union{Lines, LineSegments}, N, FT <: Real} # Standard transform from input space to clip space # Note that this is type unstable, so there is a function barrier in place. @@ -223,7 +223,7 @@ function project_line_points(scene, plot::T, positions::AbstractArray{<: Makie.V return project_transformed_line_points(scene, plot, points, colors, linewidths) end -function project_transformed_line_points(scene, plot::T, points::AbstractArray{<: Makie.VecTypes{N, FT}}, colors, linewidths) where {T <: Union{Lines, LineSegments}, N, FT <: Real} +function project_transformed_line_points(scene, plot::T, points::AbstractArray{<:Makie.VecTypes{N, FT}}, colors, linewidths) where {T <: Union{Lines, LineSegments}, N, FT <: Real} # Note that here, `points` has already had `transform_func` applied. # If colors are defined per point they need to be interpolated like positions # at clip planes @@ -251,34 +251,35 @@ function project_transformed_line_points(scene, plot::T, points::AbstractArray{< # Fix lines with points far outside the clipped region not drawing at all # TODO this can probably be done more efficiently by checking -1 ≤ x, y ≤ 1 # directly and calculating intersections directly (1D) - push!(clip_planes, - Plane3f(Vec3f(-1, 0, 0), -1f0), Plane3f(Vec3f(+1, 0, 0), -1f0), - Plane3f(Vec3f(0, -1, 0), -1f0), Plane3f(Vec3f(0, +1, 0), -1f0) + push!( + clip_planes, + Plane3f(Vec3f(-1, 0, 0), -1.0f0), Plane3f(Vec3f(+1, 0, 0), -1.0f0), + Plane3f(Vec3f(0, -1, 0), -1.0f0), Plane3f(Vec3f(0, +1, 0), -1.0f0) ) # outputs screen_points = sizehint!(Vec2f[], length(clip_points)) color_output = sizehint!(eltype(colors)[], length(clip_points)) - skipped_color = RGBAf(1,0,1,1) # for debug purposes, should not show + skipped_color = RGBAf(1, 0, 1, 1) # for debug purposes, should not show linewidth_output = sizehint!(eltype(linewidths)[], length(clip_points)) # Handling one segment per iteration if plot isa Lines last_is_nan = true - for i in 1:length(clip_points)-1 + for i in 1:(length(clip_points) - 1) hidden = false disconnect1 = false disconnect2 = false if per_point_colors c1 = colors[i] - c2 = colors[i+1] + c2 = colors[i + 1] end p1 = clip_points[i] - p2 = clip_points[i+1] + p2 = clip_points[i + 1] v = p2 - p1 # Handle near/far clipping @@ -304,7 +305,7 @@ function project_transformed_line_points(scene, plot::T, points::AbstractArray{< if (d1 < 0.0) && (d2 < 0.0) # start and end clipped by one plane -> not visible hidden = true - break; + break elseif (d1 < 0.0) # p1 clipped, move it towards p2 until unclipped disconnect1 = true @@ -362,7 +363,7 @@ function project_transformed_line_points(scene, plot::T, points::AbstractArray{< last_is_nan = true push!(screen_points, clip2screen(p2, res), Vec2f(NaN)) if per_point_linewidths - push!(linewidth_output, linewidths[i+1], linewidths[i+1]) + push!(linewidth_output, linewidths[i + 1], linewidths[i + 1]) end if per_point_colors push!(color_output, c2, c2) # relevant, irrelevant @@ -377,7 +378,7 @@ function project_transformed_line_points(scene, plot::T, points::AbstractArray{< if !last_is_nan push!(screen_points, clip2screen(clip_points[end], res)) if per_point_linewidths - push!(linewidth_output, linewidths[end]) + push!(linewidth_output, linewidths[end]) end if per_point_colors push!(color_output, colors[end]) @@ -386,14 +387,14 @@ function project_transformed_line_points(scene, plot::T, points::AbstractArray{< else # LineSegments - for i in 1:2:length(clip_points)-1 + for i in 1:2:(length(clip_points) - 1) if per_point_colors c1 = colors[i] - c2 = colors[i+1] + c2 = colors[i + 1] end p1 = clip_points[i] - p2 = clip_points[i+1] + p2 = clip_points[i + 1] v = p2 - p1 # Handle near/far clipping @@ -419,7 +420,7 @@ function project_transformed_line_points(scene, plot::T, points::AbstractArray{< # to keep index order we just set p1 and p2 to NaN and insert anyway p1 = Vec4f(NaN) p2 = Vec4f(NaN) - break; + break elseif (d1 < 0.0) # p1 clipped, move it towards p2 until unclipped p1 = p1 - d1 * (p2 - p1) / (d2 - d1) @@ -460,7 +461,7 @@ end function to_2d_rotation(::Makie.Billboard) @warn "This should not be reachable!" - 0 + return 0 end remove_billboard(x) = x @@ -486,7 +487,7 @@ to_2d_rotation(n::Real) = n function rgbatuple(c::Colorant) rgba = RGBA(c) - red(rgba), green(rgba), blue(rgba), alpha(rgba) + return red(rgba), green(rgba), blue(rgba), alpha(rgba) end function rgbatuple(c) @@ -502,7 +503,7 @@ to_uint32_color(c) = reinterpret(UInt32, convert(ARGB32, premultiplied_rgba(c))) # handle patterns function Cairo.CairoPattern(color::Makie.AbstractPattern) # the Cairo y-coordinate are fliped - bitmappattern = reverse!(ARGB32.(Makie.to_image(color)); dims=2) + bitmappattern = reverse!(ARGB32.(Makie.to_image(color)); dims = 2) cairoimage = Cairo.CairoImageSurface(bitmappattern) cairopattern = Cairo.CairoPattern(cairoimage) return cairopattern @@ -512,14 +513,14 @@ end # Common color utilities # ######################################## -function to_cairo_color(colors::Union{AbstractVector{<: Number},Number}, plot_object) +function to_cairo_color(colors::Union{AbstractVector{<:Number}, Number}, plot_object) cmap = Makie.assemble_colors(colors, Observable(colors), plot_object) return to_color(to_value(cmap)) end function to_cairo_color(color::Makie.AbstractPattern, plot_object) cairopattern = Cairo.CairoPattern(color) - Cairo.pattern_set_extend(cairopattern, Cairo.EXTEND_REPEAT); + Cairo.pattern_set_extend(cairopattern, Cairo.EXTEND_REPEAT) return cairopattern end @@ -553,7 +554,7 @@ cairo_scatter_marker(marker) = Makie.to_spritemarker(marker) ######################################## -to_cairo_image(img::AbstractMatrix{<: Colorant}) = to_cairo_image(to_uint32_color.(img)) +to_cairo_image(img::AbstractMatrix{<:Colorant}) = to_cairo_image(to_uint32_color.(img)) function to_cairo_image(img::Matrix{UInt32}) # we need to convert from column-major to row-major storage, @@ -572,16 +573,16 @@ struct FaceIterator{Iteration, T, F, ET} <: AbstractVector{ET} end function (::Type{FaceIterator{Typ}})(data::T, faces::F) where {Typ, T, F} - FaceIterator{Typ, T, F}(data, faces) + return FaceIterator{Typ, T, F}(data, faces) end function (::Type{FaceIterator{Typ, T, F}})(data::AbstractVector, faces::F) where {Typ, F, T} - FaceIterator{Typ, T, F, NTuple{3, eltype(data)}}(data, faces) + return FaceIterator{Typ, T, F, NTuple{3, eltype(data)}}(data, faces) end function (::Type{FaceIterator{Typ, T, F}})(data::T, faces::F) where {Typ, T, F} - FaceIterator{Typ, T, F, NTuple{3, T}}(data, faces) + return FaceIterator{Typ, T, F, NTuple{3, T}}(data, faces) end function FaceIterator(data::AbstractVector, faces) - if length(data) == length(faces) + return if length(data) == length(faces) FaceIterator{:PerFace}(data, faces) else FaceIterator{:PerVert}(data, faces) @@ -591,7 +592,7 @@ end Base.size(fi::FaceIterator) = size(fi.faces) Base.getindex(fi::FaceIterator{:PerFace}, i::Integer) = fi.data[i] Base.getindex(fi::FaceIterator{:PerVert}, i::Integer) = fi.data[fi.faces[i]] -Base.getindex(fi::FaceIterator{:Const}, i::Integer) = ntuple(i-> fi.data, 3) +Base.getindex(fi::FaceIterator{:Const}, i::Integer) = ntuple(i -> fi.data, 3) color_or_nothing(c) = isnothing(c) ? nothing : to_color(c) function get_color_attr(attributes, attribute)::Union{Nothing, RGBAf} @@ -604,19 +605,19 @@ function per_face_colors(_color, matcap, faces, normals, uv) wsize = reverse(size(matcap)) wh = wsize .- 1 cvec = map(normals) do n - muv = 0.5n[Vec(1,2)] .+ Vec2f(0.5) + muv = 0.5n[Vec(1, 2)] .+ Vec2f(0.5) x, y = clamp.(round.(Int, Tuple(muv) .* wh) .+ 1, 1, wh) return matcap[end - (y - 1), x] end return FaceIterator(cvec, faces) elseif color isa Colorant return FaceIterator{:Const}(color, faces) - elseif color isa AbstractVector{<: Colorant} + elseif color isa AbstractVector{<:Colorant} return FaceIterator{:PerVert}(color, faces) elseif color isa Makie.AbstractPattern # let next level extend and fill with CairoPattern return color - elseif color isa AbstractMatrix{<: Colorant} && !isnothing(uv) + elseif color isa AbstractMatrix{<:Colorant} && !isnothing(uv) wsize = size(color) wh = wsize .- 1 # nearest @@ -632,7 +633,7 @@ function per_face_colors(_color, matcap, faces, normals, uv) end function mesh_pattern_set_corner_color(pattern, id, c::Colorant) - Cairo.mesh_pattern_set_corner_color_rgba(pattern, id, rgbatuple(c)...) + return Cairo.mesh_pattern_set_corner_color_rgba(pattern, id, rgbatuple(c)...) end ################################################################################ diff --git a/CairoMakie/test/rasterization_tests.jl b/CairoMakie/test/rasterization_tests.jl index c5fc95a56ce..e2f92f213ba 100644 --- a/CairoMakie/test/rasterization_tests.jl +++ b/CairoMakie/test/rasterization_tests.jl @@ -1,7 +1,7 @@ # guard against some future changes silently making simple vector graphics be # rasterized if they are using features unsupported by the SVG spec function svg_has_image(x) - mktempdir() do path + return mktempdir() do path path = joinpath(path, "test.svg") save(path, x) # this is rough but an easy way to catch rasterization, @@ -12,9 +12,9 @@ end @testset "Internal rasterization" begin fig = Figure() - ax = Axis(fig[1,1]) + ax = Axis(fig[1, 1]) lp = lines!(ax, vcat(1:10, 10:-1:1)) - pts = Makie.GeometryBasics.Point2f[(0,0), (1,0), (0,1)] + pts = Makie.GeometryBasics.Point2f[(0, 0), (1, 0), (0, 1)] pl = poly!(ax, Makie.GeometryBasics.Polygon(pts)) @testset "Unrasterized SVG" begin @@ -28,4 +28,4 @@ end @test svg_has_image(fig) end -end \ No newline at end of file +end diff --git a/CairoMakie/test/runtests.jl b/CairoMakie/test/runtests.jl index c621d82b9de..e2dac575e9e 100644 --- a/CairoMakie/test/runtests.jl +++ b/CairoMakie/test/runtests.jl @@ -7,7 +7,7 @@ using ReferenceTests @testset "Runs without error" begin fig = Figure() scatter(fig[1, 1], rand(10)) - fn = tempname()*".png" + fn = tempname() * ".png" try save(fn, fig) finally @@ -40,8 +40,8 @@ include(joinpath(@__DIR__, "rasterization_tests.jl")) fig = Figure(size = (480, 792)) ax = Axis(fig[1, 1]) # The IO was shared between screens, which left the second figure empty - save("fig.pdf", fig, pt_per_unit=0.5) - save("fig2.pdf", fig, pt_per_unit=0.5) + save("fig.pdf", fig, pt_per_unit = 0.5) + save("fig2.pdf", fig, pt_per_unit = 0.5) @test !isempty("fig.pdf") @test !isempty("fig2.pdf") rm("fig.pdf") @@ -52,14 +52,14 @@ include(joinpath(@__DIR__, "rasterization_tests.jl")) # https://github.com/MakieOrg/Makie.jl/issues/2438 # This bug was caused by using the screen size of the pdf screen, which # has a different device_scaling_factor, and therefore a different screen size - fig = scatter(1:4, figure=(; size = (800, 800))) + fig = scatter(1:4, figure = (; size = (800, 800))) save("test.pdf", fig) size(Makie.colorbuffer(fig)) == (800, 800) rm("test.pdf") end @testset "switching from pdf screen to png, save" begin - fig = scatter(1:4, figure=(; size = (800, 800))) + fig = scatter(1:4, figure = (; size = (800, 800))) save("test.pdf", fig) save("test.png", fig) @test size(load("test.png")) == (1600, 1600) @@ -89,32 +89,32 @@ include(joinpath(@__DIR__, "rasterization_tests.jl")) @testset "changing resolution of same format" begin # see: https://github.com/MakieOrg/Makie.jl/issues/2433 # and: https://github.com/MakieOrg/AlgebraOfGraphics.jl/pull/441 - scene = Scene(size = (800, 800)); + scene = Scene(size = (800, 800)) load_save(s; kw...) = (save("test.png", s; kw...); load("test.png")) - @test size(load_save(scene, px_per_unit=2)) == (1600, 1600) - @test size(load_save(scene, px_per_unit=1)) == (800, 800) + @test size(load_save(scene, px_per_unit = 2)) == (1600, 1600) + @test size(load_save(scene, px_per_unit = 1)) == (800, 800) rm("test.png") end end @testset "mimes" begin f, ax, pl = scatter(1:4) - CairoMakie.activate!(type="pdf") + CairoMakie.activate!(type = "pdf") @test showable("application/pdf", f) - CairoMakie.activate!(type="eps") + CairoMakie.activate!(type = "eps") @test showable("application/postscript", f) - CairoMakie.activate!(type="svg") + CairoMakie.activate!(type = "svg") @test showable("image/svg+xml", f) - CairoMakie.activate!(type="png") + CairoMakie.activate!(type = "png") @test showable("image/png", f) # see https://github.com/MakieOrg/Makie.jl/pull/2167 @test !showable("blaaa", f) - CairoMakie.activate!(type="png") + CairoMakie.activate!(type = "png") @test showable("image/png", Scene()) @test !showable("image/svg+xml", Scene()) # setting svg should leave png as showable, since it's usually lower in the display stack priority - CairoMakie.activate!(type="svg") + CairoMakie.activate!(type = "svg") @test showable("image/png", Scene()) @test showable("image/svg+xml", Scene()) end @@ -124,9 +124,9 @@ end points = Observable(Point2f[]) width = 600 height = 800 - f, ax, pl = scatter(points, axis=(type=Axis, aspect=DataAspect(), limits=(0.4, N + 0.6, 0.4, N + 0.6),), figure=(size=(width, height),)) + f, ax, pl = scatter(points, axis = (type = Axis, aspect = DataAspect(), limits = (0.4, N + 0.6, 0.4, N + 0.6)), figure = (size = (width, height),)) - vio = Makie.VideoStream(f; format="mp4", px_per_unit=2.0, backend=CairoMakie) + vio = Makie.VideoStream(f; format = "mp4", px_per_unit = 2.0, backend = CairoMakie) tmp_path = vio.path @test vio.screen isa CairoMakie.Screen{CairoMakie.IMAGE} @@ -153,53 +153,55 @@ end @testset "plotlist no ambiguity (#4038)" begin f = plotlist([Makie.SpecApi.Scatter(1:10)]) - Makie.colorbuffer(f; backend=CairoMakie) + Makie.colorbuffer(f; backend = CairoMakie) plotlist!([Makie.SpecApi.Scatter(1:10)]) end @testset "multicolor line clipping (#4313)" begin - fig, ax, p = contour(rand(20,20)) + fig, ax, p = contour(rand(20, 20)) xlims!(ax, 0, 10) - Makie.colorbuffer(fig; backend=CairoMakie) + Makie.colorbuffer(fig; backend = CairoMakie) end -excludes = Set([ - "Line GIF", - "Streamplot animation", - "Axis + Surface", - "Streamplot 3D", - "Meshscatter Function", - "Record Video", - # "mesh textured and loaded", # bad texture resolution on mesh - "Comparing contours, image, surfaces and heatmaps", - "Animated surface and wireframe", - "surface + contour3d", - "Orthographic Camera", # This renders blank, why? - "3D Contour with 2D contour slices", - "Surface with image", - "FEM poly and mesh", # different color due to bad colormap resolution on mesh - "Image on Surface Sphere", # bad texture resolution - "Arrows 3D", - "Connected Sphere", - # markers too big, close otherwise, needs to be assimilated with glmakie - "Depth Shift", - "Order Independent Transparency", - "fast pixel marker", - "scatter with glow", # some are missing - "scatter with stroke", # stroke acts inward in CairoMakie, outwards in W/GLMakie - "heatmaps & surface", # different nan_colors in surface - "Textured meshscatter", # not yet implemented - "Voxel - texture mapping", # not yet implemented - "Miter Joints for line rendering", # CairoMakie does not show overlap here - "picking", # Not implemented - "MetaMesh (Sponza)", # makes little sense without per pixel depth order -]) +excludes = Set( + [ + "Line GIF", + "Streamplot animation", + "Axis + Surface", + "Streamplot 3D", + "Meshscatter Function", + "Record Video", + # "mesh textured and loaded", # bad texture resolution on mesh + "Comparing contours, image, surfaces and heatmaps", + "Animated surface and wireframe", + "surface + contour3d", + "Orthographic Camera", # This renders blank, why? + "3D Contour with 2D contour slices", + "Surface with image", + "FEM poly and mesh", # different color due to bad colormap resolution on mesh + "Image on Surface Sphere", # bad texture resolution + "Arrows 3D", + "Connected Sphere", + # markers too big, close otherwise, needs to be assimilated with glmakie + "Depth Shift", + "Order Independent Transparency", + "fast pixel marker", + "scatter with glow", # some are missing + "scatter with stroke", # stroke acts inward in CairoMakie, outwards in W/GLMakie + "heatmaps & surface", # different nan_colors in surface + "Textured meshscatter", # not yet implemented + "Voxel - texture mapping", # not yet implemented + "Miter Joints for line rendering", # CairoMakie does not show overlap here + "picking", # Not implemented + "MetaMesh (Sponza)", # makes little sense without per pixel depth order + ] +) functions = [:volume, :volume!, :uv_mesh] @testset "refimages" begin CairoMakie.activate!(type = "png", px_per_unit = 1) - ReferenceTests.mark_broken_tests(excludes, functions=functions) + ReferenceTests.mark_broken_tests(excludes, functions = functions) recorded_files, recording_dir = @include_reference_tests CairoMakie "refimages.jl" missing_images, scores = ReferenceTests.record_comparison(recording_dir, "CairoMakie") ReferenceTests.test_comparison(scores; threshold = 0.05) @@ -221,7 +223,7 @@ end filename = "$(tempname()).pdf" try - save(filename, Figure(), pdf_version=nothing) + save(filename, Figure(), pdf_version = nothing) @test startswith(magic_number(filename), "%PDF-") finally rm(filename) @@ -229,18 +231,18 @@ end for version in ["1.4", "1.5", "1.6", "1.7"] try - save(filename, Figure(), pdf_version=version) + save(filename, Figure(), pdf_version = version) @test magic_number(filename) == "%PDF-$version" finally rm(filename) end end - @test_throws ArgumentError save(filename, Figure(), pdf_version="foo") + @test_throws ArgumentError save(filename, Figure(), pdf_version = "foo") end @testset "Tick Events" begin - f, a, p = scatter(rand(10)); + f, a, p = scatter(rand(10)) @test events(f).tick[] == Makie.Tick() filename = "$(tempname()).png" @@ -263,8 +265,8 @@ end for (i, tick) in enumerate(tick_record) @test tick.state == Makie.OneTimeRenderTick - @test tick.count == i-1 - @test tick.time ≈ dt * (i-1) + @test tick.count == i - 1 + @test tick.time ≈ dt * (i - 1) @test tick.delta_time ≈ dt end finally @@ -272,7 +274,7 @@ end end # test destruction of tick overwrite - f, a, p = scatter(rand(10)); + f, a, p = scatter(rand(10)) let io = VideoStream(f) @test events(f).tick[] == Makie.Tick(Makie.OneTimeRenderTick, 0, 0.0, 1.0 / io.options.framerate) @@ -286,7 +288,7 @@ end @testset "line projection" begin # Check #4627 f = Figure(size = (600, 450)) - a, p = stephist(f[1, 1], 1:10, bins=[0,5,10], axis=(;limits=(0..10, nothing))) + a, p = stephist(f[1, 1], 1:10, bins = [0, 5, 10], axis = (; limits = (0 .. 10, nothing))) Makie.update_state_before_display!(f) lp = p.plots[1].plots[1] ps, _, _ = CairoMakie.project_line_points(a.scene, lp, lp[1][], nothing, nothing) @@ -295,13 +297,13 @@ end # as outside. The adjustment of 2, 5 should be negligible. necessary_points = Vec{2, Float32}[[0.0, 89.77272], [275.5, 89.77272], [275.5, 17.95454], [551.0, 17.95454]] @test length(ps) >= 4 - @test all(ref -> findfirst(p -> isapprox(p, ref, atol = 1e-4), ps) !== nothing, necessary_points) + @test all(ref -> findfirst(p -> isapprox(p, ref, atol = 1.0e-4), ps) !== nothing, necessary_points) - ls_points = lp[1][][[1,2,2,3,3,4,4,5,5,6]] + ls_points = lp[1][][[1, 2, 2, 3, 3, 4, 4, 5, 5, 6]] ls = linesegments!(a, ls_points, xautolimits = false, yautolimits = false) ps, _, _ = CairoMakie.project_line_points(a.scene, ls, ls_points, nothing, nothing) @test length(ps) >= 6 # at least 6 points: [2,3,3,4,4,5] - @test all(ref -> findfirst(p -> isapprox(p, ref, atol = 1e-4), ps) !== nothing, necessary_points) + @test all(ref -> findfirst(p -> isapprox(p, ref, atol = 1.0e-4), ps) !== nothing, necessary_points) # Check that `reinterpret`ed arrays of points are handled correctly # ref. https://github.com/MakieOrg/Makie.jl/issues/4661 @@ -313,4 +315,4 @@ end ps, _, _ = @test_nowarn CairoMakie.project_line_points(a.scene, p, data, nothing, nothing) @test length(ps) == length(data) # this should never clip! -end \ No newline at end of file +end diff --git a/CairoMakie/test/svg_tests.jl b/CairoMakie/test/svg_tests.jl index 8d7f4239437..5bb5db42bd2 100644 --- a/CairoMakie/test/svg_tests.jl +++ b/CairoMakie/test/svg_tests.jl @@ -1,7 +1,7 @@ # guard against some future changes silently making simple vector graphics be # rasterized if they are using features unsupported by the SVG spec function svg_isnt_rasterized(x) - mktempdir() do path + return mktempdir() do path path = joinpath(path, "test.svg") save(path, x) # this is rough but an easy way to catch rasterization, @@ -12,26 +12,46 @@ end @testset "SVG rasterization" begin @test svg_isnt_rasterized(Scene()) - @test svg_isnt_rasterized(begin f = Figure(); Axis(f[1, 1]); f end) - @test svg_isnt_rasterized(begin f = Figure(); Axis3(f[1, 1]); f end) - @test svg_isnt_rasterized(begin f = Figure(); PolarAxis(f[1, 1]); f end) + @test svg_isnt_rasterized( + begin + f = Figure(); Axis(f[1, 1]); f + end + ) + @test svg_isnt_rasterized( + begin + f = Figure(); Axis3(f[1, 1]); f + end + ) + @test svg_isnt_rasterized( + begin + f = Figure(); PolarAxis(f[1, 1]); f + end + ) @test svg_isnt_rasterized(scatter(1:3)) @test svg_isnt_rasterized(lines(1:3)) @test svg_isnt_rasterized(heatmap(rand(5, 5))) @test !svg_isnt_rasterized(image(rand(5, 5))) # issue 2510 - @test svg_isnt_rasterized(begin - fig = Figure() - ax = Axis(fig[1,1]) - poly!(ax, Makie.GeometryBasics.Polygon(Point2.([[0,0],[1,0],[0,1],[0,0]])), color = ("#FF0000", 0.7), label = "foo") - poly!(ax, Makie.GeometryBasics.Polygon(Point2.([[0,0],[1,0],[0,1],[0,0]])), color = (:blue, 0.7), label = "bar") - fig[1, 2] = Legend(fig, ax, "Bar") - fig - end) + @test svg_isnt_rasterized( + begin + fig = Figure() + ax = Axis(fig[1, 1]) + poly!(ax, Makie.GeometryBasics.Polygon(Point2.([[0, 0], [1, 0], [0, 1], [0, 0]])), color = ("#FF0000", 0.7), label = "foo") + poly!(ax, Makie.GeometryBasics.Polygon(Point2.([[0, 0], [1, 0], [0, 1], [0, 0]])), color = (:blue, 0.7), label = "bar") + fig[1, 2] = Legend(fig, ax, "Bar") + fig + end + ) @test svg_isnt_rasterized(poly(Circle(Point2f(0, 0), 10))) - @test svg_isnt_rasterized(poly(BezierPath([ - MoveTo(0.0, 0.0), LineTo(1.0, 0.0), LineTo(1.0, 1.0), CurveTo(1.0, 1.0, 0.5, 1.0, 0.5, 0.5), ClosePath() - ]))) + @test svg_isnt_rasterized( + poly( + BezierPath( + [ + MoveTo(0.0, 0.0), LineTo(1.0, 0.0), LineTo(1.0, 1.0), CurveTo(1.0, 1.0, 0.5, 1.0, 0.5, 0.5), ClosePath(), + ] + ) + ) + ) @test !svg_isnt_rasterized(poly(rand(Point2f, 10); color = rand(RGBAf, 10))) poly1 = Makie.GeometryBasics.Polygon(rand(Point2f, 10)) @@ -43,7 +63,7 @@ end struct PolyWrapper poly::Any end -function Makie.convert_arguments(::Type{<: Poly}, poly::PolyWrapper) +function Makie.convert_arguments(::Type{<:Poly}, poly::PolyWrapper) return convert_arguments(Poly, poly.poly) end struct MultiPolyWrapper @@ -57,8 +77,8 @@ end poly1 = Makie.GeometryBasics.Polygon(rand(Point2f, 10)) poly2 = PolyWrapper(poly1) @test svg_isnt_rasterized(poly(poly2)) - @test svg_isnt_rasterized(poly(poly2; color=:red)) - @test svg_isnt_rasterized(poly(MultiPolyWrapper([poly1, poly1]); color=[:red, :blue])) + @test svg_isnt_rasterized(poly(poly2; color = :red)) + @test svg_isnt_rasterized(poly(MultiPolyWrapper([poly1, poly1]); color = [:red, :blue])) end @testset "reproducible svg ids" begin diff --git a/GLMakie/experiments/cuda_interop.jl b/GLMakie/experiments/cuda_interop.jl index c149d4f7b4b..f9d1e6eaf4d 100644 --- a/GLMakie/experiments/cuda_interop.jl +++ b/GLMakie/experiments/cuda_interop.jl @@ -2,21 +2,23 @@ using CUDA, GLMakie, NVTX using GLMakie.GLAbstraction # from https://discourse.julialang.org/t/cuarray-glmakie/52461/11?u=maleadt -function cu_plot(; T=Float32, N=1024, resolution=(800, 600)) +function cu_plot(; T = Float32, N = 1024, resolution = (800, 600)) t = CUDA.rand(T, N) X = CUDA.rand(T, N) # so that we can create a GLBuffer before having rendered anything. fig = Figure(; resolution) - ax = Axis(fig[1, 1]; limits=(0, 1, 0, 1)) + ax = Axis(fig[1, 1]; limits = (0, 1, 0, 1)) screen = display(fig) # get a buffer object and register it with CUDA buffer = GLAbstraction.GLBuffer(Point2f, N) resource = let ref = Ref{CUDA.CUgraphicsResource}() - CUDA.cuGraphicsGLRegisterBuffer(ref, buffer.id, - CUDA.CU_GRAPHICS_MAP_RESOURCE_FLAGS_WRITE_DISCARD) + CUDA.cuGraphicsGLRegisterBuffer( + ref, buffer.id, + CUDA.CU_GRAPHICS_MAP_RESOURCE_FLAGS_WRITE_DISCARD + ) ref[] end @@ -53,7 +55,7 @@ function cu_plot(; T=Float32, N=1024, resolution=(800, 600)) NVTX.@range "Makie" begin scatter!(ax, buffer) # force everything to render (for benchmarking purposes) - GLMakie.render_frame(screen; resize_buffers=false) + GLMakie.render_frame(screen; resize_buffers = false) GLMakie.glFinish() end end diff --git a/GLMakie/experiments/shaderabstr.jl b/GLMakie/experiments/shaderabstr.jl index 5dfe724fe48..3f27015d8e3 100644 --- a/GLMakie/experiments/shaderabstr.jl +++ b/GLMakie/experiments/shaderabstr.jl @@ -1,13 +1,13 @@ using ShaderAbstractions: Buffer, Sampler, VertexArray # Mesh -mesh(Sphere(Point3f(0), 1f0)) |> display -mesh(Sphere(Point3f(0), 1f0), color=:red, ambient=Vec3f(0.9)) +mesh(Sphere(Point3f(0), 1.0f0)) |> display +mesh(Sphere(Point3f(0), 1.0f0), color = :red, ambient = Vec3f(0.9)) tocolor(x) = RGBf(x...) -positions = Observable(decompose(Point3f, Sphere(Point3f(0), 1f0))) -triangles = Observable(decompose(GLTriangleFace, Sphere(Point3f(0), 1f0))) -uv = Observable(GeometryBasics.decompose_uv(Sphere(Point3f(0), 1f0))) +positions = Observable(decompose(Point3f, Sphere(Point3f(0), 1.0f0))) +triangles = Observable(decompose(GLTriangleFace, Sphere(Point3f(0), 1.0f0))) +uv = Observable(GeometryBasics.decompose_uv(Sphere(Point3f(0), 1.0f0))) xyz_vertex_color = Observable(tocolor.(positions[])) texture = Observable(rand(RGBAf, 10, 10)) @@ -18,7 +18,7 @@ uv_buff = Buffer(uv) texture_buff = Sampler(texture) texsampler = Makie.sampler(:viridis, rand(length(positions))) -coords = VertexArray(pos_buff, triangles_buff, color=vert_color_buff) +coords = VertexArray(pos_buff, triangles_buff, color = vert_color_buff) mesh = GeometryBasics.Mesh(coords) GeometryBasics.coordinates(mesh); @@ -38,7 +38,7 @@ p = ShaderAbstractions.Program( OGLContext(), read(loadshader("mesh.vert"), String), read(loadshader("mesh.frag"), String), - instance; + instance ) println(p.vertex_source) @@ -52,78 +52,85 @@ rshader = GLMakie.GLAbstraction.gl_convert(shader, uniforms) vbo = GLMakie.GLAbstraction.GLVertexArray(program, posmeta, triangles_buff) m = GeometryBasics.Mesh(posmeta, triangles_buff) -disp = display(Makie.mesh(m, show_axis=false)); +disp = display(Makie.mesh(m, show_axis = false)); mesh_normals = GeometryBasics.normals(positions, triangles) -coords = meta(positions, color=xyz_vertex_color, normals=mesh_normals) +coords = meta(positions, color = xyz_vertex_color, normals = mesh_normals) vertexcolor_mesh = GeometryBasics.Mesh(coords, triangles) -scren = mesh(vertexcolor_mesh, show_axis=false) |> display +scren = mesh(vertexcolor_mesh, show_axis = false) |> display function getter_function(io::IO, ::Fragment, sampler::Sampler, name::Symbol) index_t = type_string(context, sampler.values) sampler_t = type_string(context, sampler.colors) - println(io, """ - in $(value_t) fragment_$(name)_index; - uniform $(sampler_t) $(name)_texture; + return println( + io, """ + in $(value_t) fragment_$(name)_index; + uniform $(sampler_t) $(name)_texture; - vec4 get_$(name)(){ - return texture($(name)_texture, fragment_$(name)_index); - } - """) + vec4 get_$(name)(){ + return texture($(name)_texture, fragment_$(name)_index); + } + """ + ) end function getter_function(io::IO, ::Vertex, sampler::Sampler, name::Symbol) index_t = type_string(context, sampler.values) - println(io, """ - in $(index_t) $(name)_index; - out $(index_t) fragment_$(name)_index; - - vec4 get_$(name)(){ - fragment_uv = uv; - // color gets calculated in fragment! - return vec4(0); - } - """) + return println( + io, """ + in $(index_t) $(name)_index; + out $(index_t) fragment_$(name)_index; + + vec4 get_$(name)(){ + fragment_uv = uv; + // color gets calculated in fragment! + return vec4(0); + } + """ + ) end -function getter_function(io::IO, ::Fragment, ::AbstractVector{T}, name) where T +function getter_function(io::IO, ::Fragment, ::AbstractVector{T}, name) where {T} t_str = type_string(context, T) - println(io, """ - in $(t_str) fragment_$(name); - $(t_str) get_$(name)(){ - return fragment_$(name); - } - """) + return println( + io, """ + in $(t_str) fragment_$(name); + $(t_str) get_$(name)(){ + return fragment_$(name); + } + """ + ) end -function getter_function(io::IO, ::Vertex, ::AbstractVector{T}, name) where T +function getter_function(io::IO, ::Vertex, ::AbstractVector{T}, name) where {T} t_str = type_string(context, T) - println(io, """ - in $(t_str) $(name); - out $(t_str) fragment_$(name); - - $(t_str) get_$(name)(){ - fragment_$(name) = $(name); - return $(name); - } - """) + return println( + io, """ + in $(t_str) $(name); + out $(t_str) fragment_$(name); + + $(t_str) get_$(name)(){ + fragment_$(name) = $(name); + return $(name); + } + """ + ) end texsampler = Makie.sampler(rand(RGBf, 4, 4), uv) -coords = meta(positions, color=texsampler, normals=mesh_normals) +coords = meta(positions, color = texsampler, normals = mesh_normals) texture_mesh = GeometryBasics.Mesh(coords, triangles) -scren = mesh(texture_mesh, show_axis=false) |> display +scren = mesh(texture_mesh, show_axis = false) |> display texsampler = Makie.sampler(:viridis, rand(length(positions))) -coords = meta(positions, color=texsampler, normals=mesh_normals) +coords = meta(positions, color = texsampler, normals = mesh_normals) texture_mesh = GeometryBasics.Mesh(coords, triangles) -scren = mesh(texture_mesh, show_axis=false) |> display - +scren = mesh(texture_mesh, show_axis = false) |> display glsl""" diff --git a/GLMakie/src/GLAbstraction/AbstractGPUArray.jl b/GLMakie/src/GLAbstraction/AbstractGPUArray.jl index edfba611746..91bddb963b8 100644 --- a/GLMakie/src/GLAbstraction/AbstractGPUArray.jl +++ b/GLMakie/src/GLAbstraction/AbstractGPUArray.jl @@ -14,13 +14,13 @@ abstract type GPUArray{T, NDim} <: AbstractArray{T, NDim} end size(A::GPUArray) = A.size function checkdimensions(value::Array, ranges::Union{Integer, UnitRange}...) - array_size = size(value) + array_size = size(value) indexes_size = map(length, ranges) (array_size != indexes_size) && throw(DimensionMismatch("Assigning a $array_size to a $(indexes_size) location")) return true end function to_range(index) - map(index) do val + return map(index) do val isa(val, Integer) && return val:val isa(val, AbstractRange) && return val error("Indexing only defined for integers or ranges. Found: $val") @@ -30,19 +30,19 @@ end setindex!(A::GPUArray{T, N}, value::Union{T, Array{T, N}}) where {T, N} = (A[1] = value) function setindex!(A::GPUArray{T, N}, value, indices::Vararg{Integer, N}) where {T, N} - v = Array{T, N}(undef, ntuple(i-> 1, N)) + v = Array{T, N}(undef, ntuple(i -> 1, N)) v[1] = convert(T, value) - setindex!(A, v, (:).(indices, indices)...) + return setindex!(A, v, (:).(indices, indices)...) end function setindex!(A::GPUArray{T, N}, value, indexes...) where {T, N} ranges = to_range(Base.to_indices(A, indexes)) - v = isa(value, T) ? [value] : convert(Array{T,N}, value) - setindex!(A, v, ranges...) + v = isa(value, T) ? [value] : convert(Array{T, N}, value) + return setindex!(A, v, ranges...) end setindex!(A::GPUArray{T, 2}, value::Vector{T}, i::Integer, range::UnitRange) where {T} = - (A[i, range] = reshape(value, (length(value),1))) + (A[i, range] = reshape(value, (length(value), 1))) function setindex!(A::GPUArray{T, N}, value::Array{T, N}, ranges::UnitRange...) where {T, N} checkbounds(A, ranges...) @@ -53,7 +53,7 @@ end ShaderAbstractions.switch_context!(A::GPUArray) = switch_context!(A.context) function update!(A::GPUArray{T, N}, value::AbstractArray{T2, N}) where {T, N, T2} - update!(A, convert(Array{T, N}, value)) + return update!(A, convert(Array{T, N}, value)) end function update!(A::GPUArray{T, N}, value::AbstractArray{T, N}) where {T, N} switch_context!(A) @@ -68,7 +68,7 @@ function update!(A::GPUArray{T, N}, value::AbstractArray{T, N}) where {T, N} error("Dynamic resizing not implemented for $(typeof(A))") end end - dims = map(x-> 1:x, size(A)) + dims = map(x -> 1:x, size(A)) A[dims...] = value return end @@ -76,11 +76,11 @@ update!(A::GPUArray, value::ShaderAbstractions.Sampler) = update!(A, value.data) function getindex(A::GPUArray{T, N}, i::Int) where {T, N} checkbounds(A, i) - gpu_getindex(A, i:i)[1] # not as bad as its looks, as so far gpu data must be loaded into an array anyways + return gpu_getindex(A, i:i)[1] # not as bad as its looks, as so far gpu data must be loaded into an array anyways end function getindex(A::GPUArray{T, N}, ranges::UnitRange...) where {T, N} checkbounds(A, ranges...) - gpu_getindex(A, ranges...) + return gpu_getindex(A, ranges...) end mutable struct GPUVector{T} <: GPUArray{T, 1} @@ -91,11 +91,11 @@ end GPUVector(x::GPUArray) = GPUVector{eltype(x)}(x, size(x), length(x)) -function update!(A::GPUVector{T}, value::AbstractVector{T}) where T +function update!(A::GPUVector{T}, value::AbstractVector{T}) where {T} if isa(A, GLBuffer) && (length(A) != length(value)) resize!(A, length(value)) end - dims = map(x->1:x, size(A)) + dims = map(x -> 1:x, size(A)) A.buffer[dims...] = value return end @@ -109,19 +109,19 @@ setindex!(v::GPUVector{T}, value::T, index::Int) where {T} = v.buffer[index] = v setindex!(v::GPUVector{T}, value::T, index::UnitRange) where {T} = v.buffer[index] = value -function grow_dimensions(real_length::Int, _size::Int, additonal_size::Int, growfactor::Real=1.5) - new_dim = round(Int, real_length*growfactor) - return max(new_dim, additonal_size+_size) +function grow_dimensions(real_length::Int, _size::Int, additonal_size::Int, growfactor::Real = 1.5) + new_dim = round(Int, real_length * growfactor) + return max(new_dim, additonal_size + _size) end -function Base.push!(v::GPUVector{T}, x::AbstractVector{T}) where T +function Base.push!(v::GPUVector{T}, x::AbstractVector{T}) where {T} lv, lx = length(v), length(x) - if (v.real_length < lv+lx) + if (v.real_length < lv + lx) resize!(v.buffer, grow_dimensions(v.real_length, lv, lx)) end - v.buffer[lv+1:(lv+lx)] = x - v.real_length = length(v.buffer) - v.size = (lv+lx,) - v + v.buffer[(lv + 1):(lv + lx)] = x + v.real_length = length(v.buffer) + v.size = (lv + lx,) + return v end push!(v::GPUVector{T}, x::T) where {T} = push!(v, [x]) push!(v::GPUVector{T}, x::T...) where {T} = push!(v, [x...]) @@ -131,7 +131,7 @@ resize!(A::GPUArray{T, NDim}, dims::Int...) where {T, NDim} = resize!(A, dims) function resize!(A::GPUArray{T, NDim}, newdims::NTuple{NDim, Int}) where {T, NDim} newdims == size(A) && return A gpu_resize!(A, newdims) - A + return A end function resize!(v::GPUVector, newlength::Int) @@ -139,58 +139,58 @@ function resize!(v::GPUVector, newlength::Int) v.size = (max(0, newlength),) return v end - resize!(v.buffer, grow_dimensions(v.real_length, length(v), newlength-length(v))) - v.size = (newlength,) - v.real_length = length(v.buffer) + resize!(v.buffer, grow_dimensions(v.real_length, length(v), newlength - length(v))) + v.size = (newlength,) + return v.real_length = length(v.buffer) end function grow_at(v::GPUVector, index::Int, amount::Int) - resize!(v, length(v)+amount) - copy!(v, index, v, index+amount, amount) + resize!(v, length(v) + amount) + return copy!(v, index, v, index + amount, amount) end -function splice!(v::GPUVector{T}, index::UnitRange, x::Vector=T[]) where T +function splice!(v::GPUVector{T}, index::UnitRange, x::Vector = T[]) where {T} lenv = length(v) - elements_to_grow = length(x)-length(index) # -1 - buffer = similar(v.buffer, length(v)+elements_to_grow) - copy!(v.buffer, 1, buffer, 1, first(index)-1) # copy first half - copy!(v.buffer, last(index)+1, buffer, first(index)+length(x), lenv-last(index)) # shift second half - v.buffer = buffer + elements_to_grow = length(x) - length(index) # -1 + buffer = similar(v.buffer, length(v) + elements_to_grow) + copy!(v.buffer, 1, buffer, 1, first(index) - 1) # copy first half + copy!(v.buffer, last(index) + 1, buffer, first(index) + length(x), lenv - last(index)) # shift second half + v.buffer = buffer v.real_length = length(buffer) - v.size = (v.real_length,) + v.size = (v.real_length,) copy!(x, 1, buffer, first(index), length(x)) # copy contents of insertion vector return end splice!(v::GPUVector{T}, index::Int, x::T) where {T} = v[index] = x -splice!(v::GPUVector{T}, index::Int, x::Vector=T[]) where {T} = splice!(v, index:index, map(T, x)) +splice!(v::GPUVector{T}, index::Int, x::Vector = T[]) where {T} = splice!(v, index:index, map(T, x)) -copy!(a::GPUVector, a_offset::Int, b::Vector, b_offset::Int, amount::Int) = copy!(a.buffer, a_offset, b, b_offset, amount) -copy!(a::GPUVector, a_offset::Int, b::GPUVector, b_offset::Int, amount::Int)= copy!(a.buffer, a_offset, b.buffer, b_offset, amount) +copy!(a::GPUVector, a_offset::Int, b::Vector, b_offset::Int, amount::Int) = copy!(a.buffer, a_offset, b, b_offset, amount) +copy!(a::GPUVector, a_offset::Int, b::GPUVector, b_offset::Int, amount::Int) = copy!(a.buffer, a_offset, b.buffer, b_offset, amount) -copy!(a::GPUArray, a_offset::Int, b::Vector, b_offset::Int, amount::Int) = _copy!(a, a_offset, b, b_offset, amount) -copy!(a::Vector, a_offset::Int, b::GPUArray, b_offset::Int, amount::Int) = _copy!(a, a_offset, b, b_offset, amount) +copy!(a::GPUArray, a_offset::Int, b::Vector, b_offset::Int, amount::Int) = _copy!(a, a_offset, b, b_offset, amount) +copy!(a::Vector, a_offset::Int, b::GPUArray, b_offset::Int, amount::Int) = _copy!(a, a_offset, b, b_offset, amount) copy!(a::GPUArray, a_offset::Int, b::GPUArray, b_offset::Int, amount::Int) = _copy!(a, a_offset, b, b_offset, amount) #don't overwrite Base.copy! with a::Vector, b::Vector function _copy!(a::Union{Vector, GPUArray}, a_offset::Int, b::Union{Vector, GPUArray}, b_offset::Int, amount::Int) (amount <= 0) && return nothing - @assert a_offset > 0 && (a_offset-1) + amount <= length(a) "a_offset $a_offset, amount $amount, lengtha $(length(a))" - @assert b_offset > 0 && (b_offset-1) + amount <= length(b) "b_offset $b_offset, amount $amount, lengthb $(length(b))" + @assert a_offset > 0 && (a_offset - 1) + amount <= length(a) "a_offset $a_offset, amount $amount, lengtha $(length(a))" + @assert b_offset > 0 && (b_offset - 1) + amount <= length(b) "b_offset $b_offset, amount $amount, lengthb $(length(b))" unsafe_copy!(a, a_offset, b, b_offset, amount) return nothing end # Interface: -gpu_data(t) = error("gpu_data not implemented for: $(typeof(t)). This happens, when you call data on an array, without implementing the GPUArray interface") -gpu_resize!(t) = error("gpu_resize! not implemented for: $(typeof(t)). This happens, when you call resize! on an array, without implementing the GPUArray interface") -gpu_getindex(t) = error("gpu_getindex not implemented for: $(typeof(t)). This happens, when you call getindex on an array, without implementing the GPUArray interface") +gpu_data(t) = error("gpu_data not implemented for: $(typeof(t)). This happens, when you call data on an array, without implementing the GPUArray interface") +gpu_resize!(t) = error("gpu_resize! not implemented for: $(typeof(t)). This happens, when you call resize! on an array, without implementing the GPUArray interface") +gpu_getindex(t) = error("gpu_getindex not implemented for: $(typeof(t)). This happens, when you call getindex on an array, without implementing the GPUArray interface") gpu_setindex!(t) = error("gpu_setindex! not implemented for: $(typeof(t)). This happens, when you call setindex! on an array, without implementing the GPUArray interface") -max_dim(t) = error("max_dim not implemented for: $(typeof(t)). This happens, when you call setindex! on an array, without implementing the GPUArray interface") +max_dim(t) = error("max_dim not implemented for: $(typeof(t)). This happens, when you call setindex! on an array, without implementing the GPUArray interface") -function (::Type{GPUArrayType})(data::Observable; kw...) where GPUArrayType <: GPUArray +function (::Type{GPUArrayType})(data::Observable; kw...) where {GPUArrayType <: GPUArray} gpu_mem = GPUArrayType(data[]; kw...) # TODO merge these and handle update tracking during construction obs2 = on(new_data -> update!(gpu_mem, new_data), data) diff --git a/GLMakie/src/GLAbstraction/GLBuffer.jl b/GLMakie/src/GLAbstraction/GLBuffer.jl index a19d789af23..ab91ca94a15 100644 --- a/GLMakie/src/GLAbstraction/GLBuffer.jl +++ b/GLMakie/src/GLAbstraction/GLBuffer.jl @@ -7,7 +7,7 @@ mutable struct GLBuffer{T} <: GPUArray{T, 1} # TODO maybe also delay upload to when render happens? observers::Vector{Observables.ObserverFunction} - function GLBuffer{T}(ptr::Ptr{T}, buff_length::Int, buffertype::GLenum, usage::GLenum) where T + function GLBuffer{T}(ptr::Ptr{T}, buff_length::Int, buffertype::GLenum, usage::GLenum) where {T} id = glGenBuffers() glBindBuffer(buffertype, id) # size of 0 can segfault it seems @@ -17,9 +17,10 @@ mutable struct GLBuffer{T} <: GPUArray{T, 1} obj = new( id, (buff_length,), buffertype, usage, current_context(), - Observables.ObserverFunction[]) + Observables.ObserverFunction[] + ) finalizer(free, obj) - obj + return obj end end @@ -27,14 +28,14 @@ function bind(buffer::GLBuffer) if buffer.id == 0 error("Binding freed GLBuffer{$(eltype(buffer))}") end - glBindBuffer(buffer.buffertype, buffer.id) + return glBindBuffer(buffer.buffertype, buffer.id) end #used to reset buffer target bind(buffer::GLBuffer, other_target) = glBindBuffer(buffer.buffertype, other_target) -function similar(x::GLBuffer{T}, buff_length::Int) where T - GLBuffer{T}(Ptr{T}(C_NULL), buff_length, x.buffertype, x.usage) +function similar(x::GLBuffer{T}, buff_length::Int) where {T} + return GLBuffer{T}(Ptr{T}(C_NULL), buff_length, x.buffertype, x.usage) end cardinality(::GLBuffer{T}) where {T} = cardinality(T) @@ -43,7 +44,7 @@ cardinality(::GLBuffer{T}) where {T} = cardinality(T) function GLBuffer( buffer::Union{Base.ReinterpretArray{T, 1}, DenseVector{T}}; buffertype::GLenum = GL_ARRAY_BUFFER, usage::GLenum = GL_STATIC_DRAW - ) where T <: GLArrayEltypes + ) where {T <: GLArrayEltypes} GC.@preserve buffer begin return GLBuffer{T}(pointer(buffer), length(buffer), buffertype, usage) end @@ -52,7 +53,7 @@ end function GLBuffer( buffer::DenseVector{T}; buffertype::GLenum = GL_ARRAY_BUFFER, usage::GLenum = GL_STATIC_DRAW - ) where T <: GLArrayEltypes + ) where {T <: GLArrayEltypes} GC.@preserve buffer begin return GLBuffer{T}(pointer(buffer), length(buffer), buffertype, usage) end @@ -61,8 +62,8 @@ end function GLBuffer( buffer::ShaderAbstractions.Buffer{T}; buffertype::GLenum = GL_ARRAY_BUFFER, usage::GLenum = GL_STATIC_DRAW - ) where T <: GLArrayEltypes - b = GLBuffer(ShaderAbstractions.data(buffer); buffertype=buffertype, usage=usage) + ) where {T <: GLArrayEltypes} + b = GLBuffer(ShaderAbstractions.data(buffer); buffertype = buffertype, usage = usage) au = ShaderAbstractions.updater(buffer) obsfunc = on(au.update) do (f, args) f(b, args...) # forward setindex! etc @@ -79,54 +80,54 @@ GLBuffer{T}(buffer::GLBuffer{T}) where {T} = buffer function GLBuffer( buffer::AbstractVector{T}; kw_args... - ) where T <: GLArrayEltypes - GLBuffer(collect(buffer); kw_args...) + ) where {T <: GLArrayEltypes} + return GLBuffer(collect(buffer); kw_args...) end function GLBuffer{T}( buffer::AbstractVector; kw_args... - ) where T <: GLArrayEltypes - GLBuffer(convert(Vector{T}, buffer); kw_args...) + ) where {T <: GLArrayEltypes} + return GLBuffer(convert(Vector{T}, buffer); kw_args...) end function GLBuffer( ::Type{T}, len::Int; buffertype::GLenum = GL_ARRAY_BUFFER, usage::GLenum = GL_STATIC_DRAW - ) where T <: GLArrayEltypes - GLBuffer{T}(Ptr{T}(C_NULL), len, buffertype, usage) + ) where {T <: GLArrayEltypes} + return GLBuffer{T}(Ptr{T}(C_NULL), len, buffertype, usage) end function indexbuffer( buffer::VectorTypes{T}; usage::GLenum = GL_STATIC_DRAW - ) where T <: GLArrayEltypes - GLBuffer(buffer, buffertype = GL_ELEMENT_ARRAY_BUFFER, usage=usage) + ) where {T <: GLArrayEltypes} + return GLBuffer(buffer, buffertype = GL_ELEMENT_ARRAY_BUFFER, usage = usage) end # GPUArray interface -function gpu_data(b::GLBuffer{T}) where T +function gpu_data(b::GLBuffer{T}) where {T} data = Vector{T}(undef, length(b)) bind(b) glGetBufferSubData(b.buffertype, 0, sizeof(data), data) bind(b, 0) - data + return data end # Resize buffer -function gpu_resize!(buffer::GLBuffer{T}, newdims::NTuple{1, Int}) where T +function gpu_resize!(buffer::GLBuffer{T}, newdims::NTuple{1, Int}) where {T} #TODO make this safe! newlength = newdims[1] - oldlen = length(buffer) + oldlen = length(buffer) if oldlen > 0 old_data = gpu_data(buffer) end bind(buffer) - glBufferData(buffer.buffertype, newlength*sizeof(T), C_NULL, buffer.usage) + glBufferData(buffer.buffertype, newlength * sizeof(T), C_NULL, buffer.usage) bind(buffer, 0) buffer.size = newdims - if oldlen>0 + if oldlen > 0 max_len = min(length(old_data), newlength) #might also shrink buffer[1:max_len] = old_data[1:max_len] end @@ -135,86 +136,86 @@ function gpu_resize!(buffer::GLBuffer{T}, newdims::NTuple{1, Int}) where T # unsafe_copy!(buffer, 1, newbuff, 1, length(buffer)) # buffer.id = newbuff.id # buffer.size = newbuff.size - nothing + return nothing end -function gpu_setindex!(b::GLBuffer{T}, value::Vector{T}, offset::Integer) where T +function gpu_setindex!(b::GLBuffer{T}, value::Vector{T}, offset::Integer) where {T} multiplicator = sizeof(T) bind(b) - glBufferSubData(b.buffertype, multiplicator*(offset-1), sizeof(value), value) - bind(b, 0) + glBufferSubData(b.buffertype, multiplicator * (offset - 1), sizeof(value), value) + return bind(b, 0) end -function gpu_setindex!(b::GLBuffer{T}, value::Vector{T}, offset::UnitRange{Int}) where T +function gpu_setindex!(b::GLBuffer{T}, value::Vector{T}, offset::UnitRange{Int}) where {T} multiplicator = sizeof(T) bind(b) - glBufferSubData(b.buffertype, multiplicator*(first(offset)-1), sizeof(value), value) + glBufferSubData(b.buffertype, multiplicator * (first(offset) - 1), sizeof(value), value) bind(b, 0) return nothing end # copy between two buffers # could be a setindex! operation, with subarrays for buffers -function unsafe_copy!(a::GLBuffer{T}, readoffset::Int, b::GLBuffer{T}, writeoffset::Int, len::Int) where T +function unsafe_copy!(a::GLBuffer{T}, readoffset::Int, b::GLBuffer{T}, writeoffset::Int, len::Int) where {T} multiplicator = sizeof(T) @assert a.id != 0 & b.id != 0 glBindBuffer(GL_COPY_READ_BUFFER, a.id) glBindBuffer(GL_COPY_WRITE_BUFFER, b.id) glCopyBufferSubData( GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, - multiplicator*(readoffset-1), - multiplicator*(writeoffset-1), - multiplicator*len + multiplicator * (readoffset - 1), + multiplicator * (writeoffset - 1), + multiplicator * len ) glBindBuffer(GL_COPY_READ_BUFFER, 0) glBindBuffer(GL_COPY_WRITE_BUFFER, 0) return nothing end -function Base.iterate(buffer::GLBuffer{T}, i=1) where T +function Base.iterate(buffer::GLBuffer{T}, i = 1) where {T} i > length(buffer) && return nothing - return gpu_getindex(buffer, i:i)[], i+1 + return gpu_getindex(buffer, i:i)[], i + 1 end #copy inside one buffer -function unsafe_copy!(buffer::GLBuffer{T}, readoffset::Int, writeoffset::Int, len::Int) where T +function unsafe_copy!(buffer::GLBuffer{T}, readoffset::Int, writeoffset::Int, len::Int) where {T} len <= 0 && return nothing bind(buffer) ptr = Ptr{T}(glMapBuffer(buffer.buffertype, GL_READ_WRITE)) - for i=1:len+1 - unsafe_store!(ptr, unsafe_load(ptr, i+readoffset-1), i+writeoffset-1) + for i in 1:(len + 1) + unsafe_store!(ptr, unsafe_load(ptr, i + readoffset - 1), i + writeoffset - 1) end glUnmapBuffer(buffer.buffertype) - bind(buffer,0) + bind(buffer, 0) return nothing end -function unsafe_copy!(a::Vector{T}, readoffset::Int, b::GLBuffer{T}, writeoffset::Int, len::Int) where T +function unsafe_copy!(a::Vector{T}, readoffset::Int, b::GLBuffer{T}, writeoffset::Int, len::Int) where {T} bind(b) ptr = Ptr{T}(glMapBuffer(b.buffertype, GL_WRITE_ONLY)) - for i=1:len - unsafe_store!(ptr, a[i+readoffset-1], i+writeoffset-1) + for i in 1:len + unsafe_store!(ptr, a[i + readoffset - 1], i + writeoffset - 1) end glUnmapBuffer(b.buffertype) - bind(b,0) + return bind(b, 0) end -function unsafe_copy!(a::GLBuffer{T}, readoffset::Int, b::Vector{T}, writeoffset::Int, len::Int) where T +function unsafe_copy!(a::GLBuffer{T}, readoffset::Int, b::Vector{T}, writeoffset::Int, len::Int) where {T} bind(a) ptr = Ptr{T}(glMapBuffer(a.buffertype, GL_READ_ONLY)) for i in 1:len - b[i+writeoffset-1] = unsafe_load(ptr, i+readoffset-2) #-2 => -1 to zero offset, -1 gl indexing starts at 0 + b[i + writeoffset - 1] = unsafe_load(ptr, i + readoffset - 2) #-2 => -1 to zero offset, -1 gl indexing starts at 0 end glUnmapBuffer(a.buffertype) - bind(a,0) + return bind(a, 0) end -function gpu_getindex(b::GLBuffer{T}, range::UnitRange) where T +function gpu_getindex(b::GLBuffer{T}, range::UnitRange) where {T} multiplicator = sizeof(T) - offset = first(range)-1 + offset = first(range) - 1 value = Vector{T}(undef, length(range)) bind(b) - glGetBufferSubData(b.buffertype, multiplicator*offset, sizeof(value), value) + glGetBufferSubData(b.buffertype, multiplicator * offset, sizeof(value), value) bind(b, 0) return value end diff --git a/GLMakie/src/GLAbstraction/GLExtendedFunctions.jl b/GLMakie/src/GLAbstraction/GLExtendedFunctions.jl index 15b7fa6d0d0..c6d3436238b 100644 --- a/GLMakie/src/GLAbstraction/GLExtendedFunctions.jl +++ b/GLMakie/src/GLAbstraction/GLExtendedFunctions.jl @@ -6,21 +6,21 @@ Its also to do some more complex error handling, not handled by the debug callba function glGetShaderiv(shaderID::GLuint, variable::GLenum) result = Ref{GLint}(-1) glGetShaderiv(shaderID, variable, result) - result[] + return result[] end function glShaderSource(shaderID::GLuint, shadercode::Vector{UInt8}) shader_code_ptrs = Ptr{UInt8}[pointer(shadercode)] - len = Ref{GLint}(length(shadercode)) - glShaderSource(shaderID, 1, shader_code_ptrs, len) + len = Ref{GLint}(length(shadercode)) + return glShaderSource(shaderID, 1, shader_code_ptrs, len) end glShaderSource(shaderID::GLuint, shadercode::String) = glShaderSource(shaderID, Vector{UInt8}(shadercode)) function glGetAttachedShaders(program::GLuint) - shader_count = glGetProgramiv(program, GL_ATTACHED_SHADERS) + shader_count = glGetProgramiv(program, GL_ATTACHED_SHADERS) length_written = GLsizei[0] - shaders = zeros(GLuint, shader_count) + shaders = zeros(GLuint, shader_count) glGetAttachedShaders(program, shader_count, length_written, shaders) - shaders[1:first(length_written)] + return shaders[1:first(length_written)] end get_attribute_location(program::GLuint, name) = get_attribute_location(program, ascii(name)) @@ -39,7 +39,7 @@ function get_attribute_location(program::GLuint, name::String) program has not been successfully linked" ) end - location + return location end @@ -52,20 +52,21 @@ function get_uniform_location(program::GLuint, name::String) the name starts with the reserved prefix gl_""" ) elseif location == GL_INVALID_OPERATION - error("""program is not a value generated by OpenGL or + error( + """program is not a value generated by OpenGL or program is not a program object or program has not been successfully linked""" ) end - location + return location end function glGetActiveUniform(programID::GLuint, index::Integer) - actualLength = GLsizei[1] - uniformSize = GLint[1] - typ = GLenum[1] - maxcharsize = glGetProgramiv(programID, GL_ACTIVE_UNIFORM_MAX_LENGTH) - name = Vector{GLchar}(undef, maxcharsize) + actualLength = GLsizei[1] + uniformSize = GLint[1] + typ = GLenum[1] + maxcharsize = glGetProgramiv(programID, GL_ACTIVE_UNIFORM_MAX_LENGTH) + name = Vector{GLchar}(undef, maxcharsize) glGetActiveUniform(programID, index, maxcharsize, actualLength, uniformSize, typ, name) @@ -77,11 +78,11 @@ function glGetActiveUniform(programID::GLuint, index::Integer) end function glGetActiveAttrib(programID::GLuint, index::Integer) - actualLength = GLsizei[1] - attributeSize = GLint[1] - typ = GLenum[1] - maxcharsize = glGetProgramiv(programID, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH) - name = Vector{GLchar}(undef, maxcharsize) + actualLength = GLsizei[1] + attributeSize = GLint[1] + typ = GLenum[1] + maxcharsize = glGetProgramiv(programID, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH) + name = Vector{GLchar}(undef, maxcharsize) glGetActiveAttrib(programID, index, maxcharsize, actualLength, attributeSize, typ, name) @@ -104,7 +105,7 @@ function glGetIntegerv(variable::GLenum) return result[] end -function glGenBuffers(n=1) +function glGenBuffers(n = 1) result = GLuint[0] glGenBuffers(1, result) id = result[] @@ -118,7 +119,7 @@ function glGenVertexArrays() result = GLuint[0] glGenVertexArrays(1, result) id = result[1] - if id <=0 + if id <= 0 error("glGenVertexArrays returned invalid id. OpenGL Context active?") end return id @@ -146,23 +147,23 @@ end function glDeleteTextures(id::GLuint) arr = [id] - glDeleteTextures(1, arr) + return glDeleteTextures(1, arr) end function glDeleteVertexArrays(id::GLuint) arr = [id] - glDeleteVertexArrays(1, arr) + return glDeleteVertexArrays(1, arr) end function glDeleteBuffers(id::GLuint) arr = [id] - glDeleteBuffers(1, arr) + return glDeleteBuffers(1, arr) end function glGetTexLevelParameteriv(target::GLenum, level, name::GLenum) result = GLint[0] glGetTexLevelParameteriv(target, level, name, result) - result[1] + return result[1] end glViewport(x::Rect2) = glViewport(minimum(x)..., widths(x)...) @@ -177,16 +178,18 @@ function glGenRenderbuffers(format::GLenum, attachment::GLenum, dimensions) return renderbuffer[1] end -Makie.@noconstprop function glTexImage(ttype::GLenum, level::Integer, internalFormat::GLenum, w::Integer, - h::Integer, d::Integer, border::Integer, format::GLenum, - datatype::GLenum, data) +Makie.@noconstprop function glTexImage( + ttype::GLenum, level::Integer, internalFormat::GLenum, w::Integer, + h::Integer, d::Integer, border::Integer, format::GLenum, + datatype::GLenum, data + ) glTexImage3D(GL_PROXY_TEXTURE_3D, level, internalFormat, w, h, d, border, format, datatype, C_NULL) - for l in 0:level + for l in 0:level result = glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, l, GL_TEXTURE_WIDTH) if result == 0 error("glTexImage 3D: width too large. Width: ", w) end - result = glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, l,GL_TEXTURE_HEIGHT) + result = glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, l, GL_TEXTURE_HEIGHT) if result == 0 error("glTexImage 3D: height too large. height: ", h) end @@ -202,8 +205,10 @@ Makie.@noconstprop function glTexImage(ttype::GLenum, level::Integer, internalFo glTexImage3D(ttype, level, internalFormat, w, h, d, border, format, datatype, data) end -Makie.@noconstprop function glTexImage(ttype::GLenum, level::Integer, internalFormat::GLenum, w::Integer, - h::Integer, border::Integer, format::GLenum, datatype::GLenum, data) +Makie.@noconstprop function glTexImage( + ttype::GLenum, level::Integer, internalFormat::GLenum, w::Integer, + h::Integer, border::Integer, format::GLenum, datatype::GLenum, data + ) maxsize = glGetIntegerv(GL_MAX_TEXTURE_SIZE) glTexImage2D(GL_PROXY_TEXTURE_2D, level, internalFormat, w, h, border, format, datatype, C_NULL) for l in 0:level @@ -223,8 +228,10 @@ Makie.@noconstprop function glTexImage(ttype::GLenum, level::Integer, internalFo glTexImage2D(ttype, level, internalFormat, w, h, border, format, datatype, data) end -Makie.@noconstprop function glTexImage(ttype::GLenum, level::Integer, internalFormat::GLenum, w::Integer, - border::Integer, format::GLenum, datatype::GLenum, data) +Makie.@noconstprop function glTexImage( + ttype::GLenum, level::Integer, internalFormat::GLenum, w::Integer, + border::Integer, format::GLenum, datatype::GLenum, data + ) glTexImage1D(GL_PROXY_TEXTURE_1D, level, internalFormat, w, border, format, datatype, C_NULL) for l in 0:level result = glGetTexLevelParameteriv(GL_PROXY_TEXTURE_1D, l, GL_TEXTURE_WIDTH) diff --git a/GLMakie/src/GLAbstraction/GLInfo.jl b/GLMakie/src/GLAbstraction/GLInfo.jl index c72c677807f..0cfdc28fa17 100644 --- a/GLMakie/src/GLAbstraction/GLInfo.jl +++ b/GLMakie/src/GLAbstraction/GLInfo.jl @@ -1,8 +1,8 @@ getnames(check_function::Function) = filter(check_function, uint32(0:65534)) # gets all the names currently boundo to programs -getProgramNames() = getnames(glIsProgram) -getShaderNames() = getnames(glIsShader) +getProgramNames() = getnames(glIsProgram) +getShaderNames() = getnames(glIsShader) getVertexArrayNames() = getnames(glIsVertexArray) # display info for all active uniforms in a program @@ -16,10 +16,11 @@ function getUniformsInfo(p::GLProgram) size = Ref{GLint}(0) type = Ref{GLenum}() - for i=0:activeUnif-1 + for i in 0:(activeUnif - 1) glGetActiveUniform(program, i, bufSize, buflen, size, type, name) - println(String(name), " ", buflen[], " ", size[], " ", GLENUM(type[]).name) + println(String(name), " ", buflen[], " ", size[], " ", GLENUM(type[]).name) end + return end function uniform_name_type(p::GLProgram, location) @@ -29,7 +30,7 @@ function uniform_name_type(p::GLProgram, location) size = Ref{GLint}(0) type = Ref{GLenum}() glGetActiveUniform(p.id, location, bufSize, buflen, size, type, name) - println(String(name), " ", buflen[], " ", size[], " ", GLENUM(type[]).name) + return println(String(name), " ", buflen[], " ", size[], " ", GLENUM(type[]).name) end # display the values for uniforms in the default block @@ -37,7 +38,7 @@ function getUniformInfo(p::GLProgram, uniName::Symbol) # is it a program ? @show program = p.id @show loc = glGetUniformLocation(program, uniName) - @show name, typ, uniform_size = glGetActiveUniform(program, loc) + return @show name, typ, uniform_size = glGetActiveUniform(program, loc) end @@ -57,7 +58,7 @@ function getUniformInBlockInfo(p::GLProgram, blockName, uniName) @show uniOffset = glGetActiveUniformsiv(program, uniIndex, GL_UNIFORM_OFFSET) @show uniSize = glGetActiveUniformsiv(program, uniIndex, GL_UNIFORM_SIZE) @show uniArrayStride = glGetActiveUniformsiv(program, uniIndex, GL_UNIFORM_ARRAY_STRIDE) - @show uniMatStride = glGetActiveUniformsiv(program, uniIndex, GL_UNIFORM_MATRIX_STRIDE) + return @show uniMatStride = glGetActiveUniformsiv(program, uniIndex, GL_UNIFORM_MATRIX_STRIDE) end @@ -68,10 +69,11 @@ function getAttributesInfo(p::GLProgram) # how many attribs? @show activeAttr = glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES) # get location and type for each attrib - for i=0:activeAttr-1 - @show name, typ, siz = glGetActiveAttrib(program, i) + for i in 0:(activeAttr - 1) + @show name, typ, siz = glGetActiveAttrib(program, i) @show loc = glGetAttribLocation(program, name) end + return end @@ -95,5 +97,5 @@ function getProgramInfo(p::GLProgram) @show info = glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS) @show info = glGetProgramiv(program, GL_ACTIVE_ATOMIC_COUNTER_BUFFERS) @show info = glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_BUFFER_MODE) - @show info = glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYINGS) + return @show info = glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYINGS) end diff --git a/GLMakie/src/GLAbstraction/GLRender.jl b/GLMakie/src/GLAbstraction/GLRender.jl index 44bb5b5a59b..c342daa0ee2 100644 --- a/GLMakie/src/GLAbstraction/GLRender.jl +++ b/GLMakie/src/GLAbstraction/GLRender.jl @@ -6,19 +6,20 @@ function render(list::Tuple) end function setup_clip_planes(N::Integer) - for i in 0:min(7, N-1) + for i in 0:min(7, N - 1) glEnable(GL_CLIP_DISTANCE0 + UInt32(i)) end for i in max(0, N):7 glDisable(GL_CLIP_DISTANCE0 + UInt32(i)) end + return end """ When rendering a specialised list of Renderables, we can do some optimizations """ -function render(list::Vector{RenderObject{Pre}}) where Pre +function render(list::Vector{RenderObject{Pre}}) where {Pre} isempty(list) && return nothing first(list).prerenderfunction() vertexarray = first(list).vertexarray @@ -66,7 +67,7 @@ It uses dictionaries and doesn't care about OpenGL call optimizations. So rewriting this function could get us a lot of performance for scenes with a lot of objects. """ -function render(renderobject::RenderObject, vertexarray=renderobject.vertexarray) +function render(renderobject::RenderObject, vertexarray = renderobject.vertexarray) if renderobject.visible renderobject.prerenderfunction() setup_clip_planes(to_value(get(renderobject.uniforms, :num_clip_planes, 0))) @@ -84,7 +85,7 @@ function render(renderobject::RenderObject, vertexarray=renderobject.vertexarray error("Uniform tuple too long: $(length(value))") end catch e - @warn error("uniform $key doesn't work with value $(renderobject.uniforms[key])") exception=(e, Base.catch_backtrace()) + @warn error("uniform $key doesn't work with value $(renderobject.uniforms[key])") exception = (e, Base.catch_backtrace()) end end end @@ -100,14 +101,14 @@ end Renders a vertexarray, which consists of the usual buffers plus a vector of unitranges which defines the segments of the buffers to be rendered """ -function render(vao::GLVertexArray{T}, mode::GLenum=GL_TRIANGLES) where T <: VecOrSignal{UnitRange{Int}} +function render(vao::GLVertexArray{T}, mode::GLenum = GL_TRIANGLES) where {T <: VecOrSignal{UnitRange{Int}}} for elem in to_value(vao.indices) glDrawArrays(mode, max(first(elem) - 1, 0), length(elem) + 1) end return nothing end -function render(vao::GLVertexArray{T}, mode::GLenum=GL_TRIANGLES) where T <: TOrSignal{UnitRange{Int}} +function render(vao::GLVertexArray{T}, mode::GLenum = GL_TRIANGLES) where {T <: TOrSignal{UnitRange{Int}}} r = to_value(vao.indices) offset = first(r) - 1 # 1 based -> 0 based ndraw = length(r) @@ -119,7 +120,7 @@ function render(vao::GLVertexArray{T}, mode::GLenum=GL_TRIANGLES) where T <: TOr return nothing end -function render(vao::GLVertexArray{T}, mode::GLenum=GL_TRIANGLES) where T <: TOrSignal{Int} +function render(vao::GLVertexArray{T}, mode::GLenum = GL_TRIANGLES) where {T <: TOrSignal{Int}} r = to_value(vao.indices) glDrawArrays(mode, 0, r) return nothing @@ -128,7 +129,7 @@ end """ Renders a vertex array which supplies an indexbuffer """ -function render(vao::GLVertexArray{GLBuffer{T}}, mode::GLenum=GL_TRIANGLES) where T <: Union{Integer,AbstractFace} +function render(vao::GLVertexArray{GLBuffer{T}}, mode::GLenum = GL_TRIANGLES) where {T <: Union{Integer, AbstractFace}} glDrawElements( mode, length(vao.indices) * cardinality(vao.indices), @@ -140,7 +141,7 @@ end """ Renders a normal vertex array only containing the usual buffers buffers. """ -function render(vao::GLVertexArray, mode::GLenum=GL_TRIANGLES) +function render(vao::GLVertexArray, mode::GLenum = GL_TRIANGLES) glDrawArrays(mode, 0, length(vao)) return end @@ -148,12 +149,12 @@ end """ Render instanced geometry """ -renderinstanced(vao::GLVertexArray, a, primitive=GL_TRIANGLES) = renderinstanced(vao, length(a), primitive) +renderinstanced(vao::GLVertexArray, a, primitive = GL_TRIANGLES) = renderinstanced(vao, length(a), primitive) """ Renders `amount` instances of an indexed geometry """ -function renderinstanced(vao::GLVertexArray{GLBuffer{T}}, amount::Integer, primitive=GL_TRIANGLES) where T <: Union{Integer,AbstractFace} +function renderinstanced(vao::GLVertexArray{GLBuffer{T}}, amount::Integer, primitive = GL_TRIANGLES) where {T <: Union{Integer, AbstractFace}} glDrawElementsInstanced(primitive, length(vao.indices) * cardinality(vao.indices), julia2glenum(T), C_NULL, amount) return end @@ -161,7 +162,7 @@ end """ Renders `amount` instances of an not indexed geometry geometry """ -function renderinstanced(vao::GLVertexArray, amount::Integer, primitive=GL_TRIANGLES) +function renderinstanced(vao::GLVertexArray, amount::Integer, primitive = GL_TRIANGLES) glDrawElementsInstanced(primitive, length(vao), GL_UNSIGNED_INT, C_NULL, amount) return end diff --git a/GLMakie/src/GLAbstraction/GLRenderObject.jl b/GLMakie/src/GLAbstraction/GLRenderObject.jl index e7f333f3d87..6779771967a 100644 --- a/GLMakie/src/GLAbstraction/GLRenderObject.jl +++ b/GLMakie/src/GLAbstraction/GLRenderObject.jl @@ -1,5 +1,5 @@ function Base.show(io::IO, obj::RenderObject) - println(io, "RenderObject with ID: ", obj.id) + return println(io, "RenderObject with ID: ", obj.id) end Base.getindex(obj::RenderObject, symbol::Symbol) = obj.uniforms[symbol] @@ -9,8 +9,8 @@ Base.getindex(obj::RenderObject, symbol::Symbol, x::Function) = getindex(obj, Va Base.getindex(obj::RenderObject, ::Val{:prerender}, x::Function) = obj.prerenderfunctions[x] Base.getindex(obj::RenderObject, ::Val{:postrender}, x::Function) = obj.postrenderfunctions[x] -Base.setindex!(obj::RenderObject, value, symbol::Symbol, x::Function) = setindex!(obj, value, Val(symbol), x) -Base.setindex!(obj::RenderObject, value, ::Val{:prerender}, x::Function) = obj.prerenderfunctions[x] = value +Base.setindex!(obj::RenderObject, value, symbol::Symbol, x::Function) = setindex!(obj, value, Val(symbol), x) +Base.setindex!(obj::RenderObject, value, ::Val{:prerender}, x::Function) = obj.prerenderfunctions[x] = value Base.setindex!(obj::RenderObject, value, ::Val{:postrender}, x::Function) = obj.postrenderfunctions[x] = value """ @@ -34,7 +34,7 @@ function (sp::StandardPrerender)() glDisable(GL_CULL_FACE) # glCullFace(GL_BACK) - if sp.transparency[] + return if sp.transparency[] # disable depth buffer writing glDepthMask(GL_FALSE) @@ -65,7 +65,7 @@ struct StandardPostrender end function (sp::StandardPostrender)() - render(sp.vao, sp.primitive) + return render(sp.vao, sp.primitive) end struct StandardPostrenderInstanced diff --git a/GLMakie/src/GLAbstraction/GLShader.jl b/GLMakie/src/GLAbstraction/GLShader.jl index 8e8ab99061c..27930eaf23d 100644 --- a/GLMakie/src/GLAbstraction/GLShader.jl +++ b/GLMakie/src/GLAbstraction/GLShader.jl @@ -1,30 +1,30 @@ # Different shader string literals- usage: e.g. frag" my shader code" macro frag_str(source::AbstractString) - quote + return quote ($source, GL_FRAGMENT_SHADER) end end macro vert_str(source::AbstractString) - quote + return quote ($source, GL_VERTEX_SHADER) end end macro geom_str(source::AbstractString) - quote + return quote ($source, GL_GEOMETRY_SHADER) end end macro comp_str(source::AbstractString) - quote + return quote ($source, GL_COMPUTE_SHADER) end end function getinfolog(obj::GLuint) # Return the info log for obj, whether it be a shader or a program. - isShader = glIsShader(obj) - getiv = isShader == GL_TRUE ? glGetShaderiv : glGetProgramiv - get_log = isShader == GL_TRUE ? glGetShaderInfoLog : glGetProgramInfoLog + isShader = glIsShader(obj) + getiv = isShader == GL_TRUE ? glGetShaderiv : glGetProgramiv + get_log = isShader == GL_TRUE ? glGetShaderInfoLog : glGetProgramInfoLog # Get the maximum possible length for the descriptive error message maxlength = GLint[0] @@ -52,12 +52,12 @@ islinked(program::GLuint) = glGetProgramiv(program, GL_LINK_STATUS) == GL_TRUE function createshader(shadertype::GLenum) shaderid = glCreateShader(shadertype) @assert shaderid > 0 "opengl context is not active or shader type not accepted. Shadertype: $(GLENUM(shadertype).name)" - shaderid::GLuint + return shaderid::GLuint end function createprogram() program = glCreateProgram() @assert program > 0 "couldn't create program. Most likely, opengl context is not active" - program::GLuint + return program::GLuint end shadertype(s::Shader) = s.typ @@ -95,7 +95,7 @@ struct ShaderCache end function ShaderCache(context) - ShaderCache( + return ShaderCache( context, Dict{String, Vector{String}}(), Dict{String, Dict{Any, Shader}}(), @@ -112,7 +112,7 @@ struct LazyShader <: AbstractLazyShader function LazyShader(cache::ShaderCache, paths::ShaderSource...; kw_args...) args = Dict{Symbol, Any}(kw_args) get!(args, :view, Dict{String, String}()) - new(cache, [paths...], args) + return new(cache, [paths...], args) end end @@ -171,7 +171,7 @@ function compile_program(shaders::Vector{Shader}, fragdatalocation) if !GLAbstraction.islinked(program) error( "program $program not linked. Error in: \n", - join(map(x-> string(x.name), shaders), " or "), "\n", getinfolog(program) + join(map(x -> string(x.name), shaders), " or "), "\n", getinfolog(program) ) end # Can be deleted, as they will still be linked to Program and released after program gets released @@ -179,20 +179,20 @@ function compile_program(shaders::Vector{Shader}, fragdatalocation) # generate the link locations nametypedict = uniform_name_type(program) uniformlocationdict = uniformlocations(nametypedict, program) - GLProgram(program, shaders, nametypedict, uniformlocationdict) + return GLProgram(program, shaders, nametypedict, uniformlocationdict) end function get_view(kw_dict) _view = kw_dict[:view] extension = Sys.isapple() ? "" : "#extension GL_ARB_draw_instanced : enable\n" - _view["GLSL_EXTENSION"] = extension*get(_view, "GLSL_EXTENSIONS", "") + _view["GLSL_EXTENSION"] = extension * get(_view, "GLSL_EXTENSIONS", "") _view["GLSL_VERSION"] = glsl_version_string() - _view + return _view end gl_convert(lazyshader::AbstractLazyShader, data) = error("gl_convert shader") function gl_convert(lazyshader::LazyShader, data) - gl_convert(lazyshader.shader_cache, lazyshader, data) + return gl_convert(lazyshader.shader_cache, lazyshader, data) end function gl_convert(cache::ShaderCache, lazyshader::AbstractLazyShader, data) @@ -226,14 +226,14 @@ end function insert_from_view(io, replace_view::Function, keyword::AbstractString) print(io, replace_view(keyword)) - nothing + return nothing end function insert_from_view(io, replace_view::Dict, keyword::AbstractString) if haskey(replace_view, keyword) print(io, replace_view[keyword]) end - nothing + return nothing end """ Replaces @@ -258,7 +258,7 @@ function mustache_replace(replace_view::Union{Dict, Function}, string) if char == '}' closed_mustaches += 1 if closed_mustaches == 2 # we found a complete mustache! - insert_from_view(io, replace_view, SubString(string, replace_begin+1, i-2)) + insert_from_view(io, replace_view, SubString(string, replace_begin + 1, i - 2)) open_mustaches = 0 closed_mustaches = 0 replace_started = false @@ -283,7 +283,7 @@ function mustache_replace(replace_view::Union{Dict, Function}, string) end last_char = char end - String(take!(io)) + return String(take!(io)) end @@ -297,7 +297,8 @@ function mustache2replacement(mustache_key, view, attributes) if !isa(val, AbstractString) if postfix == "_type" return toglsltype_string(val)::String - else postfix == "_calculation" + else + postfix == "_calculation" return glsl_variable_access(keystring, val) end end diff --git a/GLMakie/src/GLAbstraction/GLTexture.jl b/GLMakie/src/GLAbstraction/GLTexture.jl index 8fb657124eb..dcb54328215 100644 --- a/GLMakie/src/GLAbstraction/GLTexture.jl +++ b/GLMakie/src/GLAbstraction/GLTexture.jl @@ -1,7 +1,7 @@ struct TextureParameters{NDim} minfilter::Symbol magfilter::Symbol # magnification - repeat ::NTuple{NDim, Symbol} + repeat::NTuple{NDim, Symbol} anisotropic::Float32 swizzle_mask::Vector{GLenum} end @@ -9,24 +9,24 @@ end abstract type OpenglTexture{T, NDIM} <: GPUArray{T, NDIM} end mutable struct Texture{T <: GLArrayEltypes, NDIM} <: OpenglTexture{T, NDIM} - id ::GLuint - texturetype ::GLenum - pixeltype ::GLenum - internalformat ::GLenum - format ::GLenum - parameters ::TextureParameters{NDIM} - size ::NTuple{NDIM, Int} - context ::GLContext - observers ::Vector{Observables.ObserverFunction} + id::GLuint + texturetype::GLenum + pixeltype::GLenum + internalformat::GLenum + format::GLenum + parameters::TextureParameters{NDIM} + size::NTuple{NDIM, Int} + context::GLContext + observers::Vector{Observables.ObserverFunction} function Texture{T, NDIM}( - id ::GLuint, - texturetype ::GLenum, - pixeltype ::GLenum, - internalformat ::GLenum, - format ::GLenum, - parameters ::TextureParameters{NDIM}, - size ::NTuple{NDIM, Int} - ) where {T, NDIM} + id::GLuint, + texturetype::GLenum, + pixeltype::GLenum, + internalformat::GLenum, + format::GLenum, + parameters::TextureParameters{NDIM}, + size::NTuple{NDIM, Int} + ) where {T, NDIM} tex = new( id, texturetype, @@ -39,7 +39,7 @@ mutable struct Texture{T <: GLArrayEltypes, NDIM} <: OpenglTexture{T, NDIM} Observables.ObserverFunction[] ) finalizer(free, tex) - tex + return tex end end @@ -47,8 +47,8 @@ end mutable struct TextureBuffer{T <: GLArrayEltypes} <: OpenglTexture{T, 1} texture::Texture{T, 1} buffer::GLBuffer{T} - function TextureBuffer(texture::Texture{T, 1}, buffer::GLBuffer{T}) where T - new{T}(texture, buffer) + function TextureBuffer(texture::Texture{T, 1}, buffer::GLBuffer{T}) where {T} + return new{T}(texture, buffer) end end Base.size(t::TextureBuffer) = size(t.buffer) @@ -58,7 +58,7 @@ function bind(t::Texture) if t.id == 0 error("Binding freed Texture{$(eltype(t))}") end - glBindTexture(t.texturetype, t.id) + return glBindTexture(t.texturetype, t.id) end bind(t::Texture, id) = glBindTexture(t.texturetype, id) @@ -66,7 +66,7 @@ ShaderAbstractions.switch_context!(t::TextureBuffer) = switch_context!(t.texture function unsafe_free(tb::TextureBuffer) unsafe_free(tb.texture) - unsafe_free(tb.buffer) + return unsafe_free(tb.buffer) end is_texturearray(t::Texture) = t.texturetype == GL_TEXTURE_2D_ARRAY @@ -79,14 +79,14 @@ function set_packing_alignment(a) # at some point we should specialize to array/ glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0) glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0) - glPixelStorei(GL_UNPACK_SKIP_ROWS, 0) + return glPixelStorei(GL_UNPACK_SKIP_ROWS, 0) end Makie.@noconstprop function Texture( data::Ptr{T}, dims::NTuple{NDim, Int}; internalformat::GLenum = default_internalcolorformat(T), - texturetype ::GLenum = default_texturetype(NDim), - format ::GLenum = default_colorformat(T), + texturetype::GLenum = default_texturetype(NDim), + format::GLenum = default_colorformat(T), mipmap = false, parameters... # rest should be texture parameters ) where {T, NDim} @@ -111,7 +111,7 @@ function resize_nocopy!(t::Texture{T, ND}, newdims::NTuple{ND, Int}) where {T, N glTexImage(t.texturetype, 0, t.internalformat, newdims..., 0, t.format, t.pixeltype, C_NULL) t.size = newdims bind(t, 0) - t + return t end """ @@ -152,10 +152,10 @@ Constructor for Array Texture function Texture( data::Vector{Array{T, 2}}; internalformat::GLenum = default_internalcolorformat(T), - texturetype::GLenum = GL_TEXTURE_2D_ARRAY, - format::GLenum = default_colorformat(T), + texturetype::GLenum = GL_TEXTURE_2D_ARRAY, + format::GLenum = default_colorformat(T), parameters... - ) where T <: GLArrayEltypes + ) where {T <: GLArrayEltypes} texparams = TextureParameters(T, 2; parameters...) id = glGenTextures() @@ -163,18 +163,18 @@ function Texture( numbertype = julia2glenum(eltype(T)) - layers = length(data) - dims = map(size, data) - maxdims = foldl(dims, init = (0,0)) do v0, x + layers = length(data) + dims = map(size, data) + maxdims = foldl(dims, init = (0, 0)) do v0, x a = max(v0[1], x[1]) b = max(v0[2], x[2]) - (a,b) + (a, b) end set_packing_alignment(data) glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, internalformat, maxdims..., layers) for (layer, texel) in enumerate(data) width, height = size(texel) - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layer-1, width, height, 1, format, numbertype, texel) + glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layer - 1, width, height, 1, format, numbertype, texel) end texture = Texture{T, 2}( @@ -183,12 +183,11 @@ function Texture( tuple(maxdims...) ) set_parameters(texture) - texture + return texture end - -function TextureBuffer(buffer::GLBuffer{T}) where T <: GLArrayEltypes +function TextureBuffer(buffer::GLBuffer{T}) where {T <: GLArrayEltypes} texture_type = GL_TEXTURE_BUFFER id = glGenTextures() glBindTexture(texture_type, id) @@ -199,11 +198,11 @@ function TextureBuffer(buffer::GLBuffer{T}) where T <: GLArrayEltypes default_colorformat(T), TextureParameters(T, 1), size(buffer) ) - TextureBuffer(tex, buffer) + return TextureBuffer(tex, buffer) end -function TextureBuffer(buffer::Vector{T}) where T <: GLArrayEltypes +function TextureBuffer(buffer::Vector{T}) where {T <: GLArrayEltypes} buff = GLBuffer(buffer, buffertype = GL_TEXTURE_BUFFER, usage = GL_DYNAMIC_DRAW) - TextureBuffer(buff) + return TextureBuffer(buff) end #= @@ -230,41 +229,43 @@ Creates a texture from an Image Base.show(io::IO, t::Texture) = show(IOContext(io), MIME"text/plain"(), t) -function Base.show(io::IOContext, mime::MIME"text/plain", t::Texture{T,D}) where {T,D} - if get(io, :compact, false) +function Base.show(io::IOContext, mime::MIME"text/plain", t::Texture{T, D}) where {T, D} + return if get(io, :compact, false) println(io, "Texture$(D)D, ID: $(t.id), Size: $(size(t))") else show(io.io, mime, t) end end -function Base.show(io::IO, ::MIME"text/plain", t::Texture{T,D}) where {T,D} +function Base.show(io::IO, ::MIME"text/plain", t::Texture{T, D}) where {T, D} println(io, "Texture$(D)D: ") println(io, " ID: ", t.id) - println(io, " Size: ", reduce(size(t), init = "Dimensions: ") do v0, v1 - v0*"x"*string(v1) - end) + println( + io, " Size: ", reduce(size(t), init = "Dimensions: ") do v0, v1 + v0 * "x" * string(v1) + end + ) println(io, " Julia pixel type: ", T) println(io, " OpenGL pixel type: ", GLENUM(t.pixeltype).name) println(io, " Format: ", GLENUM(t.format).name) println(io, " Internal format: ", GLENUM(t.internalformat).name) - println(io, " Parameters: ", t.parameters) + return println(io, " Parameters: ", t.parameters) end # GPUArray interface: -function unsafe_copy!(a::Vector{T}, readoffset::Int, b::TextureBuffer{T}, writeoffset::Int, len::Int) where T +function unsafe_copy!(a::Vector{T}, readoffset::Int, b::TextureBuffer{T}, writeoffset::Int, len::Int) where {T} copy!(a, readoffset, b.buffer, writeoffset, len) bind(b.texture) - glTexBuffer(b.texture.texturetype, b.texture.internalformat, b.buffer.id) # update texture + return glTexBuffer(b.texture.texturetype, b.texture.internalformat, b.buffer.id) # update texture end -function unsafe_copy!(a::TextureBuffer{T}, readoffset::Int, b::Vector{T}, writeoffset::Int, len::Int) where T +function unsafe_copy!(a::TextureBuffer{T}, readoffset::Int, b::Vector{T}, writeoffset::Int, len::Int) where {T} copy!(a.buffer, readoffset, b, writeoffset, len) bind(a.texture) - glTexBuffer(a.texture.texturetype, a.texture.internalformat, a.buffer.id) # update texture + return glTexBuffer(a.texture.texturetype, a.texture.internalformat, a.buffer.id) # update texture end -function unsafe_copy!(a::TextureBuffer{T}, readoffset::Int, b::TextureBuffer{T}, writeoffset::Int, len::Int) where T +function unsafe_copy!(a::TextureBuffer{T}, readoffset::Int, b::TextureBuffer{T}, writeoffset::Int, len::Int) where {T} unsafe_copy!(a.buffer, readoffset, b.buffer, writeoffset, len) bind(a.texture) @@ -272,29 +273,29 @@ function unsafe_copy!(a::TextureBuffer{T}, readoffset::Int, b::TextureBuffer{T}, bind(b.texture) glTexBuffer(b.texture.texturetype, b.texture.internalformat, b.buffer.id) # update texture - bind(t.texture, 0) + return bind(t.texture, 0) end function gpu_setindex!(t::TextureBuffer{T}, newvalue::Vector{T}, indexes::UnitRange{I}) where {T, I <: Integer} bind(t.texture) t.buffer[indexes] = newvalue # set buffer indexes glTexBuffer(t.texture.texturetype, t.texture.internalformat, t.buffer.id) # update texture - bind(t.texture, 0) + return bind(t.texture, 0) end function gpu_setindex!(t::Texture{T, 1}, newvalue::Array{T, 1}, indexes::UnitRange{I}) where {T, I <: Integer} bind(t) texsubimage(t, newvalue, indexes) - bind(t, 0) + return bind(t, 0) end -function gpu_setindex!(t::Texture{T, N}, newvalue::Array{T, N}, indexes::Union{UnitRange,Integer}...) where {T, N} +function gpu_setindex!(t::Texture{T, N}, newvalue::Array{T, N}, indexes::Union{UnitRange, Integer}...) where {T, N} bind(t) texsubimage(t, newvalue, indexes...) - bind(t, 0) + return bind(t, 0) end -function gpu_setindex!(target::Texture{T, 2}, source::Texture{T, 2}, fbo=glGenFramebuffers()) where T +function gpu_setindex!(target::Texture{T, 2}, source::Texture{T, 2}, fbo = glGenFramebuffers()) where {T} glBindFramebuffer(GL_FRAMEBUFFER, fbo) glFramebufferTexture2D( GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, @@ -304,16 +305,15 @@ function gpu_setindex!(target::Texture{T, 2}, source::Texture{T, 2}, fbo=glGenFr GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, target.id, 0 ) - glDrawBuffer(GL_COLOR_ATTACHMENT1); + glDrawBuffer(GL_COLOR_ATTACHMENT1) w, h = map(minimum, zip(size(target), size(source))) - glBlitFramebuffer( + return glBlitFramebuffer( 0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST ) end - #= function gpu_setindex!{T}(target::Texture{T, 2}, source::Texture{T, 2}, fbo=glGenFramebuffers()) w, h = map(minimum, zip(size(target), size(source))) @@ -330,18 +330,18 @@ function gpu_data(t::Texture{T, ND}) where {T, ND} return result end -function unsafe_copy!(dest::Array{T, N}, source::Texture{T, N}) where {T,N} +function unsafe_copy!(dest::Array{T, N}, source::Texture{T, N}) where {T, N} bind(source) glGetTexImage(source.texturetype, 0, source.format, source.pixeltype, dest) bind(source, 0) - nothing + return nothing end gpu_data(t::TextureBuffer{T}) where {T} = gpu_data(t.buffer) gpu_getindex(t::TextureBuffer{T}, i::UnitRange{Int64}) where {T} = t.buffer[i] similar(t::Texture{T, NDim}, newdims::Int...) where {T, NDim} = similar(t, newdims) -function similar(t::TextureBuffer{T}, newdims::NTuple{1, Int}) where T +function similar(t::TextureBuffer{T}, newdims::NTuple{1, Int}) where {T} buff = similar(t.buffer, newdims...) return TextureBuffer(buff) end @@ -361,13 +361,13 @@ function similar(t::Texture{T, NDim}, newdims::NTuple{NDim, Int}) where {T, NDim ) end # Resize Texture -function gpu_resize!(t::TextureBuffer{T}, newdims::NTuple{1, Int}) where T +function gpu_resize!(t::TextureBuffer{T}, newdims::NTuple{1, Int}) where {T} resize!(t.buffer, newdims) bind(t.texture) glTexBuffer(t.texture.texturetype, t.texture.internalformat, t.buffer.id) #update data in texture - t.texture.size = newdims + t.texture.size = newdims bind(t.texture, 0) - t + return t end # Resize Texture function gpu_resize!(t::Texture{T, ND}, newdims::NTuple{ND, Int}) where {T, ND} @@ -381,35 +381,35 @@ function gpu_resize!(t::Texture{T, ND}, newdims::NTuple{ND, Int}) where {T, ND} return t end -function texsubimage(t::Texture{T, 1}, newvalue::Array{T}, xrange::UnitRange, level=0) where {T} - glTexSubImage1D( - t.texturetype, level, first(xrange)-1, length(xrange), t.format, t.pixeltype, newvalue +function texsubimage(t::Texture{T, 1}, newvalue::Array{T}, xrange::UnitRange, level = 0) where {T} + return glTexSubImage1D( + t.texturetype, level, first(xrange) - 1, length(xrange), t.format, t.pixeltype, newvalue ) end -function texsubimage(t::Texture{T, 2}, newvalue::Array{T}, xrange::UnitRange, yrange::UnitRange, level=0) where T - glTexSubImage2D( +function texsubimage(t::Texture{T, 2}, newvalue::Array{T}, xrange::UnitRange, yrange::UnitRange, level = 0) where {T} + return glTexSubImage2D( t.texturetype, level, - first(xrange)-1, first(yrange)-1, length(xrange), length(yrange), + first(xrange) - 1, first(yrange) - 1, length(xrange), length(yrange), t.format, t.pixeltype, newvalue ) end -function texsubimage(t::Texture{T, 3}, newvalue::Array{T}, xrange::UnitRange, yrange::UnitRange, zrange::UnitRange, level=0) where {T} - glTexSubImage3D( +function texsubimage(t::Texture{T, 3}, newvalue::Array{T}, xrange::UnitRange, yrange::UnitRange, zrange::UnitRange, level = 0) where {T} + return glTexSubImage3D( t.texturetype, level, - first(xrange)-1, first(yrange)-1, first(zrange)-1, length(xrange), length(yrange), length(zrange), + first(xrange) - 1, first(yrange) - 1, first(zrange) - 1, length(xrange), length(yrange), length(zrange), t.format, t.pixeltype, newvalue ) end Base.iterate(t::TextureBuffer{T}) where {T} = iterate(t.buffer) -function Base.iterate(t::TextureBuffer{T}, state::Tuple{Ptr{T}, Int}) where T +function Base.iterate(t::TextureBuffer{T}, state::Tuple{Ptr{T}, Int}) where {T} v_idx = iterate(t.buffer, state) if v_idx === nothing bind(t) glTexBuffer(t.texturetype, t.internalformat, t.buffer.id) bind(t, 0) end - v_idx + return v_idx end function default_colorformat_sym(colordim::Integer, isinteger::Bool, colororder::AbstractString) colordim > 4 && error("no colors with dimension > 4 allowed. Dimension given: ", colordim) @@ -427,15 +427,15 @@ default_colorformat_sym(::Type{T}) where {T <: AbstractArray} = default_colorfor default_colorformat_sym(::Type{T}) where {T <: StaticVector} = default_colorformat_sym(cardinality(T), eltype(T) <: Integer, "RGBA") default_colorformat_sym(::Type{T}) where {T <: Colorant} = default_colorformat_sym(cardinality(T), eltype(T) <: Integer, string(Base.typename(T).name)) -@generated function default_colorformat(::Type{T}) where T +@generated function default_colorformat(::Type{T}) where {T} sym = default_colorformat_sym(T) if !isdefined(ModernGL, sym) error("$T doesn't have a proper mapping to an OpenGL format") end - :($sym) + return :($sym) end -function default_internalcolorformat_sym(::Type{T}) where T +function default_internalcolorformat_sym(::Type{T}) where {T} cdim = colordim(T) if cdim > 4 || cdim < 1 error("$(cdim)-dimensional colors not supported") @@ -454,17 +454,17 @@ function default_internalcolorformat_sym(::Type{T}) where T elseif eltyp <: Unsigned sym *= "UI" end - Symbol(sym) + return Symbol(sym) end # for I = 1:4 # for -@generated function default_internalcolorformat(::Type{T}) where T +@generated function default_internalcolorformat(::Type{T}) where {T} sym = default_internalcolorformat_sym(T) if !isdefined(ModernGL, sym) error("$T doesn't have a proper mapping to an OpenGL format") end - :($sym) + return :($sym) end @@ -495,13 +495,14 @@ function map_texture_paramers(s::Symbol) error("$s is not a valid texture parameter") end -function TextureParameters(T, NDim; +function TextureParameters( + T, NDim; minfilter = T <: Integer ? :nearest : :linear, magfilter = minfilter, # magnification - x_repeat = :clamp_to_edge, #wrap_s - y_repeat = x_repeat, #wrap_t - z_repeat = x_repeat, #wrap_r - anisotropic = 1f0 + x_repeat = :clamp_to_edge, #wrap_s + y_repeat = x_repeat, #wrap_t + z_repeat = x_repeat, #wrap_r + anisotropic = 1.0f0 ) T <: Integer && (minfilter === :linear || magfilter === :linear) && error("Wrong Texture Parameter: Integer texture can't interpolate. Try :nearest") repeat = (x_repeat, y_repeat, z_repeat) @@ -512,18 +513,18 @@ function TextureParameters(T, NDim; else GLenum[] end - TextureParameters( - minfilter, magfilter, ntuple(i->repeat[i], NDim), + return TextureParameters( + minfilter, magfilter, ntuple(i -> repeat[i], NDim), anisotropic, swizzle_mask ) end function TextureParameters(t::Texture{T, NDim}; kw_args...) where {T, NDim} - TextureParameters(T, NDim; kw_args...) + return TextureParameters(T, NDim; kw_args...) end const GL_TEXTURE_MAX_ANISOTROPY_EXT = GLenum(0x84FE) -function set_parameters(t::Texture{T, N}, params::TextureParameters=t.parameters) where {T, N} +function set_parameters(t::Texture{T, N}, params::TextureParameters = t.parameters) where {T, N} fnames = (:minfilter, :magfilter, :repeat) data = Dict([(name, map_texture_paramers(getfield(params, name))) for name in fnames]) result = Tuple{GLenum, Any}[] @@ -545,21 +546,21 @@ function set_parameters(t::Texture{T, N}, params::TextureParameters=t.parameters e.code == GLFW.NO_CURRENT_CONTEXT || rethrow(e) end t.parameters = params - set_parameters(t, result) + return set_parameters(t, result) end function texparameter(t::Texture, key::GLenum, val::GLenum) - glTexParameteri(t.texturetype, key, val) + return glTexParameteri(t.texturetype, key, val) end function texparameter(t::Texture, key::GLenum, val::Vector) - glTexParameteriv(t.texturetype, key, val) + return glTexParameteriv(t.texturetype, key, val) end function texparameter(t::Texture, key::GLenum, val::Float32) - glTexParameterf(t.texturetype, key, val) + return glTexParameterf(t.texturetype, key, val) end function set_parameters(t::Texture, parameters::Vector{Tuple{GLenum, Any}}) bind(t) for elem in parameters texparameter(t, elem...) end - bind(t, 0) + return bind(t, 0) end diff --git a/GLMakie/src/GLAbstraction/GLTypes.jl b/GLMakie/src/GLAbstraction/GLTypes.jl index 2d661b87835..fba3ea6b4a1 100644 --- a/GLMakie/src/GLAbstraction/GLTypes.jl +++ b/GLMakie/src/GLAbstraction/GLTypes.jl @@ -1,15 +1,15 @@ ############################################################################ -const TOrSignal{T} = Union{Observable{T},T} +const TOrSignal{T} = Union{Observable{T}, T} -const ArrayOrSignal{T,N} = TOrSignal{X} where X <: AbstractArray{T,N} -const VecOrSignal{T} = ArrayOrSignal{T,1} -const MatOrSignal{T} = ArrayOrSignal{T,2} -const VolumeOrSignal{T} = ArrayOrSignal{T,3} +const ArrayOrSignal{T, N} = TOrSignal{X} where {X <: AbstractArray{T, N}} +const VecOrSignal{T} = ArrayOrSignal{T, 1} +const MatOrSignal{T} = ArrayOrSignal{T, 2} +const VolumeOrSignal{T} = ArrayOrSignal{T, 3} -const ArrayTypes{T,N} = Union{GPUArray{T,N},ArrayOrSignal{T,N}} -const VectorTypes{T} = ArrayTypes{T,1} -const MatTypes{T} = ArrayTypes{T,2} -const VolumeTypes{T} = ArrayTypes{T,3} +const ArrayTypes{T, N} = Union{GPUArray{T, N}, ArrayOrSignal{T, N}} +const VectorTypes{T} = ArrayTypes{T, 1} +const MatTypes{T} = ArrayTypes{T, 2} +const VolumeTypes{T} = ArrayTypes{T, 3} @enum Projection PERSPECTIVE ORTHOGRAPHIC @enum MouseButton MOUSE_LEFT MOUSE_MIDDLE MOUSE_RIGHT @@ -28,12 +28,12 @@ struct Shader id::GLuint context::GLContext function Shader(name, source, typ, id) - new(Symbol(name), source, typ, id, current_context()) + return new(Symbol(name), source, typ, id, current_context()) end end function Shader(name, source::Vector{UInt8}, typ) - compile_shader(source, typ, name) + return compile_shader(source, typ, name) end name(s::Shader) = s.name @@ -41,30 +41,30 @@ name(s::Shader) = s.name import Base: == function (==)(a::Shader, b::Shader) - a.source == b.source && a.typ == b.typ && a.id == b.id && a.context == b.context + return a.source == b.source && a.typ == b.typ && a.id == b.id && a.context == b.context end function Base.hash(s::Shader, h::UInt64) - hash((s.source, s.typ, s.id, s.context), h) + return hash((s.source, s.typ, s.id, s.context), h) end function Base.show(io::IO, shader::Shader) println(io, GLENUM(shader.typ).name, " shader: $(shader.name))") println(io, "source:") - print_with_lines(io, String(shader.source)) + return print_with_lines(io, String(shader.source)) end mutable struct GLProgram id::GLuint shader::Vector{Shader} - nametype::Dict{Symbol,GLenum} - uniformloc::Dict{Symbol,Tuple} + nametype::Dict{Symbol, GLenum} + uniformloc::Dict{Symbol, Tuple} context::GLContext - function GLProgram(id::GLuint, shader::Vector{Shader}, nametype::Dict{Symbol,GLenum}, uniformloc::Dict{Symbol,Tuple}) + function GLProgram(id::GLuint, shader::Vector{Shader}, nametype::Dict{Symbol, GLenum}, uniformloc::Dict{Symbol, Tuple}) obj = new(id, shader, nametype, uniformloc, current_context()) finalizer(free, obj) - obj + return obj end end @@ -78,6 +78,7 @@ function Base.show(io::IO, p::GLProgram) for (name, typ) in p.nametype println(io, " ", name, "::", GLENUM(typ).name) end + return end ############################################ @@ -93,7 +94,7 @@ struct RenderBuffer glGenRenderbuffers(1, id) glBindRenderbuffer(GL_RENDERBUFFER, id[1]) glRenderbufferStorage(GL_RENDERBUFFER, format, dimension...) - new(id, format, current_context()) + return new(id, format, current_context()) end end @@ -102,17 +103,17 @@ function resize!(rb::RenderBuffer, newsize::AbstractArray) error("RenderBuffer needs to be 2 dimensional. Dimension found: ", newsize) end glBindRenderbuffer(GL_RENDERBUFFER, rb.id) - glRenderbufferStorage(GL_RENDERBUFFER, rb.format, newsize...) + return glRenderbufferStorage(GL_RENDERBUFFER, rb.format, newsize...) end struct FrameBuffer{T} id::GLuint attachments::Vector{Any} context::GLContext - function FrameBuffer{T}(dimensions::Observable) where T + function FrameBuffer{T}(dimensions::Observable) where {T} fb = glGenFramebuffers() glBindFramebuffer(GL_FRAMEBUFFER, fb) - new(id, attachments, current_context()) + return new(id, attachments, current_context()) end end @@ -123,36 +124,37 @@ function resize!(fbo::FrameBuffer, newsize::AbstractArray) for elem in fbo.attachments resize!(elem) end + return end ######################################################################################## # OpenGL Arrays -const GLArrayEltypes = Union{StaticVector,Real,Colorant} +const GLArrayEltypes = Union{StaticVector, Real, Colorant} """ Transform julia datatypes to opengl enum type """ julia2glenum(x::Type{T}) where {T <: FixedPoint} = julia2glenum(FixedPointNumbers.rawtype(x)) -julia2glenum(x::Union{Type{T},T}) where {T <: Union{StaticVector,Colorant}} = julia2glenum(eltype(x)) -julia2glenum(::Type{OffsetInteger{O,T}}) where {O,T} = julia2glenum(T) -julia2glenum(::Type{GLubyte}) = GL_UNSIGNED_BYTE -julia2glenum(::Type{GLbyte}) = GL_BYTE -julia2glenum(::Type{GLuint}) = GL_UNSIGNED_INT +julia2glenum(x::Union{Type{T}, T}) where {T <: Union{StaticVector, Colorant}} = julia2glenum(eltype(x)) +julia2glenum(::Type{OffsetInteger{O, T}}) where {O, T} = julia2glenum(T) +julia2glenum(::Type{GLubyte}) = GL_UNSIGNED_BYTE +julia2glenum(::Type{GLbyte}) = GL_BYTE +julia2glenum(::Type{GLuint}) = GL_UNSIGNED_INT julia2glenum(::Type{GLushort}) = GL_UNSIGNED_SHORT -julia2glenum(::Type{GLshort}) = GL_SHORT -julia2glenum(::Type{GLint}) = GL_INT -julia2glenum(::Type{GLfloat}) = GL_FLOAT +julia2glenum(::Type{GLshort}) = GL_SHORT +julia2glenum(::Type{GLint}) = GL_INT +julia2glenum(::Type{GLfloat}) = GL_FLOAT julia2glenum(::Type{GLdouble}) = GL_DOUBLE -julia2glenum(::Type{Float16}) = GL_HALF_FLOAT +julia2glenum(::Type{Float16}) = GL_HALF_FLOAT struct DepthStencil_24_8 <: Real - data::NTuple{4,UInt8} + data::NTuple{4, UInt8} end -Base.eltype(::Type{<: DepthStencil_24_8}) = DepthStencil_24_8 +Base.eltype(::Type{<:DepthStencil_24_8}) = DepthStencil_24_8 julia2glenum(x::Type{DepthStencil_24_8}) = GL_UNSIGNED_INT_24_8 -function julia2glenum(::Type{T}) where T +function julia2glenum(::Type{T}) where {T} error("Type: $T not supported as opengl number datatype") end @@ -171,10 +173,10 @@ mutable struct GLVertexArray{T} program::GLProgram id::GLuint bufferlength::Int - buffers::Dict{String,GLBuffer} + buffers::Dict{String, GLBuffer} indices::T context::GLContext - function GLVertexArray{T}(program, id, bufferlength, buffers, indices) where T + function GLVertexArray{T}(program, id, bufferlength, buffers, indices) where {T} va = new(program, id, bufferlength, buffers, indices, current_context()) return va end @@ -196,7 +198,7 @@ function GLVertexArray(bufferdict::Dict, program::GLProgram) id = glGenVertexArrays() glBindVertexArray(id) lenbuffer = 0 - buffers = Dict{String,GLBuffer}() + buffers = Dict{String, GLBuffer}() for (name, buffer) in bufferdict if isa(buffer, GLBuffer) && buffer.buffertype == GL_ELEMENT_ARRAY_BUFFER bind(buffer) @@ -219,7 +221,7 @@ function GLVertexArray(bufferdict::Dict, program::GLProgram) end error( "Buffer $attribute does not have the same length as the other buffers." * - bufferlengths + bufferlengths ) end bind(buffer) @@ -247,7 +249,7 @@ function GLVertexArray(bufferdict::Dict, program::GLProgram) return obj end using ShaderAbstractions: Buffer -function GLVertexArray(program::GLProgram, buffers::Buffer, triangles::AbstractVector{<: GLTriangleFace}) +function GLVertexArray(program::GLProgram, buffers::Buffer, triangles::AbstractVector{<:GLTriangleFace}) # get the size of the first array, to assert later, that all have the same size id = glGenVertexArrays() glBindVertexArray(id) @@ -276,7 +278,7 @@ function bind(va::GLVertexArray) if va.id == 0 error("Binding freed VertexArray") end - glBindVertexArray(va.id) + return glBindVertexArray(va.id) end @@ -285,7 +287,7 @@ function Base.show(io::IO, vao::GLVertexArray) println(io, "GLVertexArray $(vao.id):") print(io, "GLVertexArray $(vao.id) buffers: ") writemime(io, MIME("text/plain"), vao.buffers) - println(io, "\nGLVertexArray $(vao.id) indices: ", vao.indices) + return println(io, "\nGLVertexArray $(vao.id) indices: ", vao.indices) end ################################################################################## @@ -299,7 +301,7 @@ end mutable struct RenderObject{Pre} context # OpenGL context - uniforms::Dict{Symbol,Any} + uniforms::Dict{Symbol, Any} observables::Vector{Observable} # for clean up vertexarray::GLVertexArray prerenderfunction::Pre @@ -309,11 +311,11 @@ mutable struct RenderObject{Pre} function RenderObject{Pre}( context, - uniforms::Dict{Symbol,Any}, observables::Vector{Observable}, + uniforms::Dict{Symbol, Any}, observables::Vector{Observable}, vertexarray::GLVertexArray, prerenderfunctions, postrenderfunctions, visible - ) where Pre + ) where {Pre} fxaa = Bool(to_value(get!(uniforms, :fxaa, true))) RENDER_OBJECT_ID_COUNTER[] += one(UInt32) # Store fxaa in ID, so we can access it in the shader to create a mask @@ -338,10 +340,10 @@ mutable struct RenderObject{Pre} end function RenderObject( - data::Dict{Symbol,Any}, program, + data::Dict{Symbol, Any}, program, pre::Pre, post, - context=current_context() - ) where Pre + context = current_context() + ) where {Pre} switch_context!(context) # This is a lazy workaround for disabling updates of `requires_update` when @@ -379,7 +381,7 @@ function RenderObject( merge!(data, gl_convert_struct(v, k)) delete!(data, k) - # try direct conversion + # try direct conversion elseif applicable(gl_convert, v) try data[k] = gl_convert(v) @@ -388,8 +390,8 @@ function RenderObject( rethrow(e) end - # Otherwise just let the value pass through - # TODO: Is this ok/ever not filtered? + # Otherwise just let the value pass through + # TODO: Is this ok/ever not filtered? else @debug "Passed on $k -> $(typeof(v)) without conversion." end @@ -430,7 +432,7 @@ include("GLRenderObject.jl") #################################################################################### # freeing function free(x) - try + return try unsafe_free(x) catch e isa(e, ContextNotAvailable) && return # if context got destroyed no need to worry! @@ -438,8 +440,8 @@ function free(x) end end -function clean_up_observables(x::T) where T - if hasfield(T, :observers) +function clean_up_observables(x::T) where {T} + return if hasfield(T, :observers) foreach(off, x.observers) empty!(x.observers) end diff --git a/GLMakie/src/GLAbstraction/GLUniforms.jl b/GLMakie/src/GLAbstraction/GLUniforms.jl index 934cd8c5485..fa8253539a5 100644 --- a/GLMakie/src/GLAbstraction/GLUniforms.jl +++ b/GLMakie/src/GLAbstraction/GLUniforms.jl @@ -7,10 +7,10 @@ const GLSL_COMPATIBLE_NUMBER_TYPES = (GLfloat, GLint, GLuint, GLdouble) const NATIVE_TYPES = Union{ StaticVector, Mat, GLSL_COMPATIBLE_NUMBER_TYPES..., ZeroIndex{GLint}, ZeroIndex{GLuint}, - GLBuffer, GPUArray, Shader, GLProgram + GLBuffer, GPUArray, Shader, GLProgram, } -opengl_prefix(T) = error("Object $T is not a supported uniform element type") +opengl_prefix(T) = error("Object $T is not a supported uniform element type") opengl_postfix(T) = error("Object $T is not a supported uniform element type") @@ -21,23 +21,23 @@ opengl_prefix(x::Type{T}) where {T <: Union{Cuint, UInt8, UInt16}} = "u" opengl_postfix(x::Type{Float64}) = "dv" opengl_postfix(x::Type{Float32}) = "fv" -opengl_postfix(x::Type{Cint}) = "iv" -opengl_postfix(x::Type{Cuint}) = "uiv" +opengl_postfix(x::Type{Cint}) = "iv" +opengl_postfix(x::Type{Cuint}) = "uiv" function uniformfunc(typ::DataType, dims::Tuple{Int}) - Symbol(string("glUniform", first(dims), opengl_postfix(typ))) + return Symbol(string("glUniform", first(dims), opengl_postfix(typ))) end function uniformfunc(typ::DataType, dims::Tuple{Int, Int}) M, N = dims - Symbol(string("glUniformMatrix", M == N ? "$M" : "$(N)x$(M)", opengl_postfix(typ))) + return Symbol(string("glUniformMatrix", M == N ? "$M" : "$(N)x$(M)", opengl_postfix(typ))) end gluniform(location::Integer, x::Nothing) = nothing function gluniform(location::Integer, x::Union{StaticVector, Mat, Colorant}) xref = [x] - gluniform(location, xref) + return gluniform(location, xref) end _size(p) = size(p) @@ -46,14 +46,14 @@ _size(p::Type{T}) where {T <: Colorant} = (length(p),) _ndims(p) = ndims(p) _ndims(p::Type{T}) where {T <: Colorant} = 1 -@generated function gluniform(location::Integer, x::Vector{FSA}) where FSA <: Union{Mat, Colorant, StaticVector} +@generated function gluniform(location::Integer, x::Vector{FSA}) where {FSA <: Union{Mat, Colorant, StaticVector}} func = uniformfunc(eltype(FSA), _size(FSA)) callexpr = if _ndims(FSA) == 2 :($func(location, length(x), GL_FALSE, x)) else :($func(location, length(x), x)) end - quote + return quote $callexpr end end @@ -68,23 +68,23 @@ function gluniform(location::GLint, target::GLint, t::Texture) activeTarget = GL_TEXTURE0 + UInt32(target) glActiveTexture(activeTarget) glBindTexture(t.texturetype, t.id) - gluniform(location, target) + return gluniform(location, target) end gluniform(location::Integer, x::Enum) = gluniform(GLint(location), GLint(x)) -function gluniform(loc::Integer, x::Observable{T}) where T - gluniform(GLint(loc), to_value(x)) +function gluniform(loc::Integer, x::Observable{T}) where {T} + return gluniform(GLint(loc), to_value(x)) end gluniform(location::Integer, x::Union{GLubyte, GLushort, GLuint}) = glUniform1ui(GLint(location), x) -gluniform(location::Integer, x::Union{GLbyte, GLshort, GLint, Bool}) = glUniform1i(GLint(location), x) -gluniform(location::Integer, x::GLfloat) = glUniform1f(GLint(location), x) -gluniform(location::Integer, x::GLdouble) = glUniform1d(GLint(location), x) +gluniform(location::Integer, x::Union{GLbyte, GLshort, GLint, Bool}) = glUniform1i(GLint(location), x) +gluniform(location::Integer, x::GLfloat) = glUniform1f(GLint(location), x) +gluniform(location::Integer, x::GLdouble) = glUniform1d(GLint(location), x) #Uniform upload functions for julia arrays... -gluniform(location::GLint, x::Vector{Float32}) = glUniform1fv(location, length(x), x) -gluniform(location::GLint, x::Vector{GLdouble}) = glUniform1dv(location, length(x), x) -gluniform(location::GLint, x::Vector{GLint}) = glUniform1iv(location, length(x), x) +gluniform(location::GLint, x::Vector{Float32}) = glUniform1fv(location, length(x), x) +gluniform(location::GLint, x::Vector{GLdouble}) = glUniform1dv(location, length(x), x) +gluniform(location::GLint, x::Vector{GLint}) = glUniform1iv(location, length(x), x) gluniform(location::GLint, x::Vector{GLuint}) = glUniform1uiv(location, length(x), x) glsl_typename(x::T) where {T} = glsl_typename(T) @@ -100,20 +100,20 @@ glsl_typename(t::Type{TextureBuffer{T}}) where {T} = string(opengl_prefix(eltype function glsl_typename(t::Texture{T, D}) where {T, D} str = string(opengl_prefix(eltype(T)), "sampler", D, "D") t.texturetype == GL_TEXTURE_2D_ARRAY && (str *= "Array") - str + return str end -function glsl_typename(t::Type{T}) where T <: Mat +function glsl_typename(t::Type{T}) where {T <: Mat} M, N = size(t) - string(opengl_prefix(eltype(t)), "mat", M==N ? M : string(N, "x", M)) + return string(opengl_prefix(eltype(t)), "mat", M == N ? M : string(N, "x", M)) end toglsltype_string(t::Observable) = toglsltype_string(to_value(t)) -function toglsltype_string(x::T) where {T<:Union{Real, Mat, StaticVector, Texture, Colorant, TextureBuffer, Nothing}} +function toglsltype_string(x::T) where {T <: Union{Real, Mat, StaticVector, Texture, Colorant, TextureBuffer, Nothing}} return "uniform $(glsl_typename(x))" end #Handle GLSL structs, which need to be addressed via single fields -function toglsltype_string(x::T) where T - if isa_gl_struct(x) +function toglsltype_string(x::T) where {T} + return if isa_gl_struct(x) string("uniform ", T.name.name) else error("can't splice $T into an OpenGL shader. Make sure all fields are of a concrete type and isbits(FieldType)-->true\n\n$x") @@ -121,7 +121,7 @@ function toglsltype_string(x::T) where T end toglsltype_string(t::Union{GLBuffer{T}, GPUVector{T}}) where {T} = string("in ", glsl_typename(T)) # Gets used to access a -function glsl_variable_access(keystring, t::Texture{T, D}) where {T,D} +function glsl_variable_access(keystring, t::Texture{T, D}) where {T, D} fields = SubString("rgba", 1, length(T)) if t.texturetype == GL_TEXTURE_BUFFER return string("texelFetch(", keystring, "index).", fields, ";") @@ -129,10 +129,10 @@ function glsl_variable_access(keystring, t::Texture{T, D}) where {T,D} return string("getindex(", keystring, "index).", fields, ";") end function glsl_variable_access(keystring, ::Union{Real, GLBuffer, GPUVector, Mat, Colorant}) - string(keystring, ";") + return string(keystring, ";") end function glsl_variable_access(keystring, s::Observable) - glsl_variable_access(keystring, to_value(s)) + return glsl_variable_access(keystring, to_value(s)) end function glsl_variable_access(keystring, t::Any) error("no glsl variable calculation available for : ", keystring, " of type ", typeof(t)) @@ -140,26 +140,30 @@ end function uniform_name_type(program::GLuint) uniformLength = glGetProgramiv(program, GL_ACTIVE_UNIFORMS) - Dict{Symbol, GLenum}(ntuple(uniformLength) do i # take size and name - name, typ = glGetActiveUniform(program, i-1) - end) + return Dict{Symbol, GLenum}( + ntuple(uniformLength) do i # take size and name + name, typ = glGetActiveUniform(program, i - 1) + end + ) end function attribute_name_type(program::GLuint) uniformLength = glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES) - Dict{Symbol, GLenum}(ntuple(uniformLength) do i - name, typ = glGetActiveAttrib(program, i-1) - end) + return Dict{Symbol, GLenum}( + ntuple(uniformLength) do i + name, typ = glGetActiveAttrib(program, i - 1) + end + ) end function istexturesampler(typ::GLenum) return ( typ == GL_SAMPLER_BUFFER || typ == GL_INT_SAMPLER_BUFFER || typ == GL_UNSIGNED_INT_SAMPLER_BUFFER || - typ == GL_IMAGE_2D || - typ == GL_SAMPLER_1D || typ == GL_SAMPLER_2D || typ == GL_SAMPLER_3D || - typ == GL_UNSIGNED_INT_SAMPLER_1D || typ == GL_UNSIGNED_INT_SAMPLER_2D || typ == GL_UNSIGNED_INT_SAMPLER_3D || - typ == GL_INT_SAMPLER_1D || typ == GL_INT_SAMPLER_2D || typ == GL_INT_SAMPLER_3D || - typ == GL_SAMPLER_1D_ARRAY || typ == GL_SAMPLER_2D_ARRAY || - typ == GL_UNSIGNED_INT_SAMPLER_1D_ARRAY || typ == GL_UNSIGNED_INT_SAMPLER_2D_ARRAY || - typ == GL_INT_SAMPLER_1D_ARRAY || typ == GL_INT_SAMPLER_2D_ARRAY + typ == GL_IMAGE_2D || + typ == GL_SAMPLER_1D || typ == GL_SAMPLER_2D || typ == GL_SAMPLER_3D || + typ == GL_UNSIGNED_INT_SAMPLER_1D || typ == GL_UNSIGNED_INT_SAMPLER_2D || typ == GL_UNSIGNED_INT_SAMPLER_3D || + typ == GL_INT_SAMPLER_1D || typ == GL_INT_SAMPLER_2D || typ == GL_INT_SAMPLER_3D || + typ == GL_SAMPLER_1D_ARRAY || typ == GL_SAMPLER_2D_ARRAY || + typ == GL_UNSIGNED_INT_SAMPLER_1D_ARRAY || typ == GL_UNSIGNED_INT_SAMPLER_2D_ARRAY || + typ == GL_INT_SAMPLER_1D_ARRAY || typ == GL_INT_SAMPLER_2D_ARRAY ) end @@ -180,7 +184,7 @@ gl_promote(x::Type{N0f8}) = x const Color3{T} = Colorant{T, 3} const Color4{T} = Colorant{T, 4} -gl_promote(x::Type{Bool}) = GLboolean +gl_promote(x::Type{Bool}) = GLboolean gl_promote(x::Type{T}) where {T <: Gray} = Gray{gl_promote(eltype(T))} gl_promote(x::Type{T}) where {T <: Color3} = RGB{gl_promote(eltype(T))} gl_promote(x::Type{T}) where {T <: Color4} = RGBA{gl_promote(eltype(T))} @@ -198,7 +202,7 @@ gl_convert(x::T) where {T <: AbstractMesh} = gl_convert(x) gl_convert(x::T) where {T <: GeometryBasics.Mesh} = gl_promote(T)(x) gl_convert(x::Observable{T}) where {T <: GeometryBasics.Mesh} = gl_promote(T)(x) -gl_convert(s::Vector{Matrix{T}}) where {T<:Colorant} = Texture(s) +gl_convert(s::Vector{Matrix{T}}) where {T <: Colorant} = Texture(s) gl_convert(s::Nothing) = s @@ -206,28 +210,32 @@ isa_gl_struct(x::Observable) = isa_gl_struct(to_value(x)) isa_gl_struct(x::AbstractArray) = false isa_gl_struct(x::NATIVE_TYPES) = false isa_gl_struct(x::Colorant) = false -function isa_gl_struct(x::T) where T +function isa_gl_struct(x::T) where {T} !isconcretetype(T) && return false if T <: Tuple return false end fnames = fieldnames(T) - !isempty(fnames) && all(name -> isconcretetype(fieldtype(T, name)) && isbits(getfield(x, name)), fnames) + return !isempty(fnames) && all(name -> isconcretetype(fieldtype(T, name)) && isbits(getfield(x, name)), fnames) end -function gl_convert_struct(obs::Observable{T}, uniform_name::Symbol) where T +function gl_convert_struct(obs::Observable{T}, uniform_name::Symbol) where {T} if isa_gl_struct(obs) - return Dict{Symbol, Any}(map(fieldnames(T)) do name - Symbol("$uniform_name.$name") => map(x -> gl_convert(getfield(x, name)), obs) - end) + return Dict{Symbol, Any}( + map(fieldnames(T)) do name + Symbol("$uniform_name.$name") => map(x -> gl_convert(getfield(x, name)), obs) + end + ) else error("can't convert $obs to a OpenGL type. Make sure all fields are of a concrete type and isbits(FieldType)-->true") end end -function gl_convert_struct(x::T, uniform_name::Symbol) where T +function gl_convert_struct(x::T, uniform_name::Symbol) where {T} if isa_gl_struct(x) - return Dict{Symbol, Any}(map(fieldnames(T)) do name - Symbol("$uniform_name.$name") => gl_convert(getfield(x, name)) - end) + return Dict{Symbol, Any}( + map(fieldnames(T)) do name + Symbol("$uniform_name.$name") => gl_convert(getfield(x, name)) + end + ) else error("can't convert $x to a OpenGL type. Make sure all fields are of a concrete type and isbits(FieldType)-->true") end @@ -237,31 +245,31 @@ end # native types don't need convert! gl_convert(a::T) where {T <: NATIVE_TYPES} = a gl_convert(s::Observable{T}) where {T <: NATIVE_TYPES} = s -gl_convert(s::Observable{T}) where T = const_lift(gl_convert, s) +gl_convert(s::Observable{T}) where {T} = const_lift(gl_convert, s) gl_convert(x::StaticVector{N, T}) where {N, T} = map(gl_promote(T), x) gl_convert(x::Mat{N, M, T}) where {N, M, T} = Mat{N, M, gl_promote(T)}(x) -gl_convert(a::AbstractVector{<: AbstractFace}) = indexbuffer(s) -gl_convert(t::Type{T}, a::T; kw_args...) where T <: NATIVE_TYPES = a -gl_convert(::Type{<: GPUArray}, a::StaticVector) = gl_convert(a) +gl_convert(a::AbstractVector{<:AbstractFace}) = indexbuffer(s) +gl_convert(t::Type{T}, a::T; kw_args...) where {T <: NATIVE_TYPES} = a +gl_convert(::Type{<:GPUArray}, a::StaticVector) = gl_convert(a) gl_convert(x::Vector) = x -function gl_convert(T::Type{<: GPUArray}, a::AbstractArray{X, N}; kw_args...) where {X, N} - T(convert(AbstractArray{gl_promote(X), N}, a); kw_args...) +function gl_convert(T::Type{<:GPUArray}, a::AbstractArray{X, N}; kw_args...) where {X, N} + return T(convert(AbstractArray{gl_promote(X), N}, a); kw_args...) end -gl_convert(::Type{<: GLBuffer}, x::GLBuffer; kw_args...) = x +gl_convert(::Type{<:GLBuffer}, x::GLBuffer; kw_args...) = x gl_convert(::Type{Texture}, x::Texture) = x -gl_convert(::Type{<: GPUArray}, x::GPUArray) = x +gl_convert(::Type{<:GPUArray}, x::GPUArray) = x function gl_convert(::Type{T}, a::Vector{Array{X, 2}}; kw_args...) where {T <: Texture, X} - T(a; kw_args...) + return T(a; kw_args...) end -gl_convert(::Type{<: GPUArray}, a::Observable{<: StaticVector}) = gl_convert(a) +gl_convert(::Type{<:GPUArray}, a::Observable{<:StaticVector}) = gl_convert(a) -function gl_convert(::Type{T}, a::Observable{<: AbstractArray{X, N}}; kw_args...) where {T <: GPUArray, X, N} +function gl_convert(::Type{T}, a::Observable{<:AbstractArray{X, N}}; kw_args...) where {T <: GPUArray, X, N} TGL = gl_promote(X) - s = (X == TGL) ? a : lift(x-> convert(Array{TGL, N}, x), a) - T(s; kw_args...) + s = (X == TGL) ? a : lift(x -> convert(Array{TGL, N}, x), a) + return T(s; kw_args...) end gl_convert(f::Function, a) = f(a) diff --git a/GLMakie/src/GLAbstraction/GLUtils.jl b/GLMakie/src/GLAbstraction/GLUtils.jl index 5fe35eda5c7..812fe3ab302 100644 --- a/GLMakie/src/GLAbstraction/GLUtils.jl +++ b/GLMakie/src/GLAbstraction/GLUtils.jl @@ -1,9 +1,9 @@ function print_with_lines(out::IO, text::AbstractString) io = IOBuffer() - for (i,line) in enumerate(split(text, "\n")) + for (i, line) in enumerate(split(text, "\n")) println(io, @sprintf("%-4d: %s", i, line)) end - write(out, take!(io)) + return write(out, take!(io)) end print_with_lines(text::AbstractString) = print_with_lines(stdout, text) @@ -18,7 +18,7 @@ matches_target(::Type{Target}, x::Observable{T}) where {Target, T} = applicable( matches_target(::Function, x) = true matches_target(::Function, x::Nothing) = false -signal_convert(T1, y::T2) where {T2<:Observable} = lift(convert, Observable(T1), y) +signal_convert(T1, y::T2) where {T2 <: Observable} = lift(convert, Observable(T1), y) """ @@ -50,8 +50,8 @@ macro gen_defaults!(dict, args) # @gen_defaults can be used multiple times, so we need to reuse gl_convert_targets if already in here for (i, elem) in enumerate(tuple_list) opengl_convert_target = :() # is optional, so first is an empty expression - convert_target = :() # is optional, so first is an empty expression - doc_strings = :() + convert_target = :() # is optional, so first is an empty expression + doc_strings = :() if Meta.isexpr(elem, :(=)) key_name, value_expr = elem.args if isa(key_name, Expr) && key_name.head === :(::) # we need to convert to a julia type @@ -97,7 +97,7 @@ macro gen_defaults!(dict, args) end #push!(return_expression.args, :($dictsym[:gl_convert_targets] = gl_convert_targets)) #just pass the targets via the dict push!(return_expression.args, :($dictsym)) #return dict - esc(return_expression) + return esc(return_expression) end export @gen_defaults! diff --git a/GLMakie/src/GLAbstraction/shaderabstraction.jl b/GLMakie/src/GLAbstraction/shaderabstraction.jl index e88c2e77e7d..31bfe9b8585 100644 --- a/GLMakie/src/GLAbstraction/shaderabstraction.jl +++ b/GLMakie/src/GLAbstraction/shaderabstraction.jl @@ -1,4 +1,3 @@ - const GLContext = Any # struct GLContext{T} <: ShaderAbstractions.AbstractContext # context::T diff --git a/GLMakie/src/GLMakie.jl b/GLMakie/src/GLMakie.jl index 40642e1c077..45334da42dc 100644 --- a/GLMakie/src/GLMakie.jl +++ b/GLMakie/src/GLMakie.jl @@ -32,7 +32,7 @@ using Base.Iterators: repeated, drop using LinearAlgebra # re-export Makie, including deprecated names -for name in names(Makie, all=true) +for name in names(Makie, all = true) if Base.isexported(Makie, name) @eval using Makie: $(name) @eval export $(name) @@ -78,6 +78,7 @@ function load_all_shaders(folder) loadshader(replace(path, "\\" => "/")) end end + return end @@ -92,7 +93,7 @@ load_all_shaders(SHADER_DIR) WARN_ON_LOAD[] = true function __init__() - activate!() + return activate!() end include("precompiles.jl") diff --git a/GLMakie/src/display.jl b/GLMakie/src/display.jl index e477f0f42c1..e1eb10e1a81 100644 --- a/GLMakie/src/display.jl +++ b/GLMakie/src/display.jl @@ -1,4 +1,4 @@ -function Base.display(screen::Screen, scene::Scene; connect=true) +function Base.display(screen::Screen, scene::Scene; connect = true) # So, the GLFW window events are not guarantee to fire # when we close a window, so we ensure this here! if !Makie.is_displayed(screen, scene) diff --git a/GLMakie/src/drawing_primitives.jl b/GLMakie/src/drawing_primitives.jl index 3a0d8a58f44..0755dee6db0 100644 --- a/GLMakie/src/drawing_primitives.jl +++ b/GLMakie/src/drawing_primitives.jl @@ -19,9 +19,9 @@ function handle_lights(attr::Dict, screen::Screen, lights::Vector{Makie.Abstract # Other parameters like position, direction, etc differe between light types. # To avoid wasting a bunch of memory we squash all of them into one vector of # size MAX_PARAMS. - attr[:N_lights] = Observable(0) - attr[:light_types] = Observable(sizehint!(Int32[], MAX_LIGHTS)) - attr[:light_colors] = Observable(sizehint!(RGBf[], MAX_LIGHTS)) + attr[:N_lights] = Observable(0) + attr[:light_types] = Observable(sizehint!(Int32[], MAX_LIGHTS)) + attr[:light_colors] = Observable(sizehint!(RGBf[], MAX_LIGHTS)) attr[:light_parameters] = Observable(sizehint!(Float32[], MAX_PARAMS)) on(screen.render_tick, priority = -1000) do _ @@ -79,7 +79,7 @@ function handle_lights(attr::Dict, screen::Screen, lights::Vector{Makie.Abstract idx = push_inplace!(parameters, idx, light.attenuation[]) elseif light isa DirectionalLight if light.camera_relative - T = inv(attr[:view][][Vec(1,2,3), Vec(1,2,3)]) + T = inv(attr[:view][][Vec(1, 2, 3), Vec(1, 2, 3)]) dir = normalize(T * light.direction[]) else dir = normalize(light.direction[]) @@ -115,7 +115,7 @@ to_range(x::AbstractRange) = (minimum(x), maximum(x)) to_range(x::AbstractVector) = (minimum(x), maximum(x)) function to_range(x::AbstractArray) - if length(x) in size(x) # assert that just one dim != 1 + return if length(x) in size(x) # assert that just one dim != 1 to_range(vec(x)) else error("Can't convert to a range. Please supply a range/vector/interval or a tuple (min, max)") @@ -144,9 +144,9 @@ function connect_camera!(plot, gl_attributes, cam, space = gl_attributes[:space] get!(gl_attributes, :view) do # get!(cam.calculated_values, Symbol("view_$(space[])")) do - return lift(plot, cam.view, space) do view, space - return is_data_space(space) ? Mat4f(view) : Mat4f(I) - end + return lift(plot, cam.view, space) do view, space + return is_data_space(space) ? Mat4f(view) : Mat4f(I) + end # end end @@ -167,22 +167,22 @@ function connect_camera!(plot, gl_attributes, cam, space = gl_attributes[:space] end get!(gl_attributes, :projection) do # return get!(cam.calculated_values, Symbol("projection_$(space[])")) do - return lift(plot, cam.projection, cam.pixel_space, space) do _, _, space - return Mat4f(Makie.space_to_clip(cam, space, false)) - end + return lift(plot, cam.projection, cam.pixel_space, space) do _, _, space + return Mat4f(Makie.space_to_clip(cam, space, false)) + end # end end get!(gl_attributes, :projectionview) do # get!(cam.calculated_values, Symbol("projectionview_$(space[])")) do - return lift(plot, cam.projectionview, cam.pixel_space, space) do _, _, space - return Mat4f(Makie.space_to_clip(cam, space, true)) - end + return lift(plot, cam.projectionview, cam.pixel_space, space) do _, _, space + return Mat4f(Makie.space_to_clip(cam, space, true)) + end # end end # resolution in real hardware pixels, not scaled pixels/units get!(gl_attributes, :resolution) do # get!(cam.calculated_values, :resolution) do - return lift(*, plot, gl_attributes[:px_per_unit], cam.resolution) + return lift(*, plot, gl_attributes[:px_per_unit], cam.resolution) # end end @@ -199,7 +199,7 @@ function handle_intensities!(screen, attributes, plot) end attributes[:intensity] = color[].color_scaled interp = color[].color_mapping_type[] === Makie.continuous ? :linear : :nearest - attributes[:color_map] = Texture(color[].colormap; minfilter=interp) + attributes[:color_map] = Texture(color[].colormap; minfilter = interp) attributes[:color_norm] = color[].colorrange_scaled attributes[:nan_color] = color[].nan_color attributes[:highclip] = Makie.highclip(color[]) @@ -221,11 +221,15 @@ function get_space(x) return haskey(x, :markerspace) ? x.markerspace : x.space end -const EXCLUDE_KEYS = Set([:transformation, :tickranges, :ticklabels, :raw, :SSAO, - :lightposition, :material, :axis_cycler, - :inspector_label, :inspector_hover, :inspector_clear, :inspectable, - :colorrange, :colormap, :colorscale, :highclip, :lowclip, :nan_color, - :calculated_colors, :space, :markerspace, :model, :dim_conversions, :material]) +const EXCLUDE_KEYS = Set( + [ + :transformation, :tickranges, :ticklabels, :raw, :SSAO, + :lightposition, :material, :axis_cycler, + :inspector_label, :inspector_hover, :inspector_clear, :inspectable, + :colorrange, :colormap, :colorscale, :highclip, :lowclip, :nan_color, + :calculated_colors, :space, :markerspace, :model, :dim_conversions, :material, + ] +) function cached_robj!(robj_func, screen, scene, plot::AbstractPlot) @@ -254,12 +258,14 @@ function cached_robj!(robj_func, screen, scene, plot::AbstractPlot) end # Pass along attributes - gl_attributes = Dict{Symbol, Any}(map(filtered) do key_value - key, value = key_value - gl_key = to_glvisualize_key(key) - gl_value = lift_convert(key, value, plot, screen) - gl_key => gl_value - end) + gl_attributes = Dict{Symbol, Any}( + map(filtered) do key_value + key, value = key_value + gl_key = to_glvisualize_key(key) + gl_value = lift_convert(key, value, plot, screen) + gl_key => gl_value + end + ) # :f32c should get passed to apply_transform_and_f32_conversion but not # make it to uniforms @@ -278,7 +284,7 @@ function cached_robj!(robj_func, screen, scene, plot::AbstractPlot) return Makie.is_data_space(space) ? min(8, length(planes)) : 0 end gl_attributes[:clip_planes] = map(plot, clip_planes, gl_attributes[:space]) do planes, space - Makie.is_data_space(space) || return [Vec4f(0, 0, 0, -1e9) for _ in 1:8] + Makie.is_data_space(space) || return [Vec4f(0, 0, 0, -1.0e9) for _ in 1:8] if length(planes) > 8 @warn("Only up to 8 clip planes are supported. The rest are ignored!", maxlog = 1) @@ -288,8 +294,8 @@ function cached_robj!(robj_func, screen, scene, plot::AbstractPlot) for i in 1:min(length(planes), 8) output[i] = Makie.gl_plane_format(planes[i]) end - for i in min(length(planes), 8)+1:8 - output[i] = Vec4f(0, 0, 0, -1e9) + for i in (min(length(planes), 8) + 1):8 + output[i] = Vec4f(0, 0, 0, -1.0e9) end return output end @@ -312,7 +318,7 @@ function cached_robj!(robj_func, screen, scene, plot::AbstractPlot) if !isnothing(dirlight) gl_attributes[:light_direction] = if dirlight.camera_relative map(gl_attributes[:view], dirlight.direction) do view, dir - return normalize(inv(view[Vec(1,2,3), Vec(1,2,3)]) * dir) + return normalize(inv(view[Vec(1, 2, 3), Vec(1, 2, 3)]) * dir) end else map(normalize, dirlight.direction) @@ -321,14 +327,14 @@ function cached_robj!(robj_func, screen, scene, plot::AbstractPlot) gl_attributes[:light_color] = dirlight.color else gl_attributes[:light_direction] = Observable(Vec3f(0)) - gl_attributes[:light_color] = Observable(RGBf(0,0,0)) + gl_attributes[:light_color] = Observable(RGBf(0, 0, 0)) end ambientlight = Makie.get_ambient_light(scene) if !isnothing(ambientlight) gl_attributes[:ambient] = ambientlight.color else - gl_attributes[:ambient] = Observable(RGBf(0,0,0)) + gl_attributes[:ambient] = Observable(RGBf(0, 0, 0)) end elseif shading == MultiLightShading handle_lights(gl_attributes, screen, scene.lights) @@ -348,7 +354,7 @@ function Base.insert!(screen::Screen, scene::Scene, @nospecialize(x::Plot)) add_scene!(screen, scene) # poll inside functions to make wait on compile less prominent pollevents(screen, Makie.BackendTick) - if isempty(x.plots) # if no plots inserted, this truly is an atomic + return if isempty(x.plots) # if no plots inserted, this truly is an atomic draw_atomic(screen, scene, x) else foreach(x.plots) do x @@ -371,7 +377,7 @@ function handle_view(array::SubArray, attributes) return A end -function handle_view(array::Observable{T}, attributes) where T <: SubArray +function handle_view(array::Observable{T}, attributes) where {T <: SubArray} A = lift(parent, array) indices = lift(index1D, array) attributes[:indices] = indices @@ -418,8 +424,10 @@ function draw_atomic(screen::Screen, scene::Scene, @nospecialize(plot::Union{Sca if plot isa Scatter mspace = plot.markerspace - gl_attributes[:preprojection] = lift(plot, space, mspace, cam.projectionview, - cam.resolution) do space, mspace, _, _ + gl_attributes[:preprojection] = lift( + plot, space, mspace, cam.projectionview, + cam.resolution + ) do space, mspace, _, _ return Mat4f(Makie.clip_to_space(cam, mspace) * Makie.space_to_clip(cam, space)) end # fast pixel does its own setup @@ -451,9 +459,13 @@ function draw_atomic(screen::Screen, scene::Scene, @nospecialize(plot::Union{Sca if haskey(gl_attributes, :intensity) gl_attributes[:color] = pop!(gl_attributes, :intensity) end - to_keep = Set([:color_map, :color, :color_norm, :px_per_unit, :scale, :model, :marker_offset, - :projectionview, :projection, :view, :visible, :resolution, :transparency]) - filter!(gl_attributes) do (k, v,) + to_keep = Set( + [ + :color_map, :color, :color_norm, :px_per_unit, :scale, :model, :marker_offset, + :projectionview, :projection, :view, :visible, :resolution, :transparency, + ] + ) + filter!(gl_attributes) do (k, v) return (k in to_keep) end gl_attributes[:markerspace] = lift(plot.markerspace) do space @@ -462,7 +474,7 @@ function draw_atomic(screen::Screen, scene::Scene, @nospecialize(plot::Union{Sca return error("Unsupported markerspace for FastPixel marker: $space") end gl_attributes[:marker_shape] = lift(x -> x.marker_type, plot.marker) - gl_attributes[:upvector] = lift(x-> Vec3f(normalize(x)), cam.upvector) + gl_attributes[:upvector] = lift(x -> Vec3f(normalize(x)), cam.upvector) return draw_pixel_scatter(screen, positions, gl_attributes) else if plot isa MeshScatter @@ -483,7 +495,7 @@ function draw_atomic(screen::Screen, scene::Scene, @nospecialize(plot::Union{Sca end end - if haskey(gl_attributes, :color) && to_value(gl_attributes[:color]) isa AbstractMatrix{<: Colorant} + if haskey(gl_attributes, :color) && to_value(gl_attributes[:color]) isa AbstractMatrix{<:Colorant} gl_attributes[:image] = gl_attributes[:color] end return draw_mesh_particle(screen, (marker, positions), gl_attributes) @@ -511,7 +523,7 @@ function draw_atomic(screen::Screen, scene::Scene, @nospecialize(plot::Lines)) data[:num_clip_planes] = Observable(0) pop!(data, :clip_planes) data[:clip_planes] = map(plot, data[:projectionview], plot.clip_planes, space) do pv, planes, space - Makie.is_data_space(space) || return [Vec4f(0, 0, 0, -1e9) for _ in 1:8] + Makie.is_data_space(space) || return [Vec4f(0, 0, 0, -1.0e9) for _ in 1:8] clip_planes = Makie.to_clip_space(pv, planes) @@ -519,8 +531,8 @@ function draw_atomic(screen::Screen, scene::Scene, @nospecialize(plot::Lines)) for i in 1:min(length(planes), 8) output[i] = Makie.gl_plane_format(clip_planes[i]) end - for i in min(length(planes), 8)+1:8 - output[i] = Vec4f(0, 0, 0, -1e9) + for i in (min(length(planes), 8) + 1):8 + output[i] = Vec4f(0, 0, 0, -1.0e9) end return output end @@ -581,8 +593,10 @@ function draw_atomic(screen::Screen, scene::Scene, @nospecialize(plot::LineSegme end end -function draw_atomic(screen::Screen, scene::Scene, - plot::Text{<:Tuple{<:Union{<:Makie.GlyphCollection, <:AbstractVector{<:Makie.GlyphCollection}}}}) +function draw_atomic( + screen::Screen, scene::Scene, + plot::Text{<:Tuple{<:Union{<:Makie.GlyphCollection, <:AbstractVector{<:Makie.GlyphCollection}}}} + ) return cached_robj!(screen, scene, plot) do gl_attributes glyphcollection = plot[1] @@ -605,24 +619,30 @@ function draw_atomic(screen::Screen, scene::Scene, filter!(gl_attributes) do (k, v) # These are liftkeys without model - !(k in ( - :position, :space, :markerspace, :font, - :fontsize, :rotation, :justification - )) # space, + !( + k in ( + :position, :space, :markerspace, :font, + :fontsize, :rotation, :justification, + ) + ) # space, end gl_attributes[:color] = lift(plot, glyphcollection) do gc if gc isa AbstractArray - reduce(vcat, (Makie.collect_vector(g.colors, length(g.glyphs)) for g in gc), - init = RGBAf[]) + reduce( + vcat, (Makie.collect_vector(g.colors, length(g.glyphs)) for g in gc), + init = RGBAf[] + ) else Makie.collect_vector(gc.colors, length(gc.glyphs)) end end gl_attributes[:stroke_color] = lift(plot, glyphcollection) do gc if gc isa AbstractArray - reduce(vcat, (Makie.collect_vector(g.strokecolors, length(g.glyphs)) for g in gc), - init = RGBAf[]) + reduce( + vcat, (Makie.collect_vector(g.strokecolors, length(g.glyphs)) for g in gc), + init = RGBAf[] + ) else Makie.collect_vector(gc.strokecolors, length(gc.glyphs)) end @@ -630,8 +650,10 @@ function draw_atomic(screen::Screen, scene::Scene, gl_attributes[:rotation] = lift(plot, glyphcollection) do gc if gc isa AbstractArray - reduce(vcat, (Makie.collect_vector(g.rotations, length(g.glyphs)) for g in gc), - init = Quaternionf[]) + reduce( + vcat, (Makie.collect_vector(g.rotations, length(g.glyphs)) for g in gc), + init = Quaternionf[] + ) else Makie.collect_vector(gc.rotations, length(gc.glyphs)) end @@ -689,7 +711,7 @@ function draw_atomic(screen::Screen, scene::Scene, plot::Heatmap) gl_attributes[:position_y] = Texture(ypos, minfilter = :nearest) # number of planes used to render the heatmap gl_attributes[:instances] = lift(plot, xpos, ypos) do x, y - (length(x)-1) * (length(y)-1) + (length(x) - 1) * (length(y) - 1) end interp = to_value(pop!(gl_attributes, :interpolate)) interp = interp ? :linear : :nearest @@ -697,7 +719,7 @@ function draw_atomic(screen::Screen, scene::Scene, plot::Heatmap) if intensity isa ShaderAbstractions.Sampler gl_attributes[:intensity] = to_value(intensity) else - gl_attributes[:intensity] = Texture(el32convert(intensity); minfilter=interp) + gl_attributes[:intensity] = Texture(el32convert(intensity); minfilter = interp) end return draw_heatmap(screen, gl_attributes) @@ -720,9 +742,9 @@ function draw_image(screen::Screen, scene::Scene, plot::Union{Heatmap, Image}) _interp = to_value(pop!(gl_attributes, :interpolate, true)) interp = _interp ? :linear : :nearest if haskey(gl_attributes, :intensity) - gl_attributes[:image] = Texture(pop!(gl_attributes, :intensity); minfilter=interp) + gl_attributes[:image] = Texture(pop!(gl_attributes, :intensity); minfilter = interp) else - gl_attributes[:image] = Texture(pop!(gl_attributes, :color); minfilter=interp) + gl_attributes[:image] = Texture(pop!(gl_attributes, :color); minfilter = interp) end gl_attributes[:picking_mode] = "#define PICKING_INDEX_FROM_UV" return draw_mesh(screen, gl_attributes) @@ -733,26 +755,26 @@ function draw_atomic(screen::Screen, scene::Scene, plot::Image) return draw_image(screen, scene, plot) end -function mesh_inner(screen::Screen, mesh, transfunc, gl_attributes, plot, space=:data) +function mesh_inner(screen::Screen, mesh, transfunc, gl_attributes, plot, space = :data) # signals not supported for shading yet shading = to_value(gl_attributes[:shading])::Makie.MakieCore.ShadingAlgorithm matcap_active = !isnothing(to_value(get(gl_attributes, :matcap, nothing))) color = pop!(gl_attributes, :color) interp = to_value(pop!(gl_attributes, :interpolate, true)) interp = interp ? :linear : :nearest - + if to_value(color) isa Colorant gl_attributes[:vertex_color] = color delete!(gl_attributes, :color_map) delete!(gl_attributes, :color_norm) elseif to_value(color) isa Makie.AbstractPattern img = lift(x -> el32convert(Makie.to_image(x)), plot, color) - gl_attributes[:image] = ShaderAbstractions.Sampler(img, x_repeat=:repeat, minfilter=:nearest) + gl_attributes[:image] = ShaderAbstractions.Sampler(img, x_repeat = :repeat, minfilter = :nearest) get!(gl_attributes, :fetch_pixel, true) # different default with Patterns (no swapping and flipping of axes) gl_attributes[:uv_transform] = map(plot, plot.attributes[:uv_transform]) do uv_transform if uv_transform === Makie.automatic - return Mat{2,3,Float32}(1,0,0,1,0,0) + return Mat{2, 3, Float32}(1, 0, 0, 1, 0, 0) else return convert_attribute(uv_transform, key"uv_transform"()) end @@ -760,15 +782,15 @@ function mesh_inner(screen::Screen, mesh, transfunc, gl_attributes, plot, space= elseif to_value(color) isa ShaderAbstractions.Sampler gl_attributes[:image] = Texture(lift(el32convert, plot, color)) delete!(gl_attributes, :color_map) - delete!(gl_attributes, :color_norm) + delete!(gl_attributes, :color_norm) elseif to_value(color) isa AbstractMatrix{<:Colorant} gl_attributes[:image] = Texture(lift(el32convert, plot, color), minfilter = interp) delete!(gl_attributes, :color_map) delete!(gl_attributes, :color_norm) - elseif to_value(color) isa AbstractMatrix{<: Number} + elseif to_value(color) isa AbstractMatrix{<:Number} gl_attributes[:image] = Texture(lift(el32convert, plot, color), minfilter = interp) gl_attributes[:color] = nothing - elseif to_value(color) isa AbstractVector{<: Union{Number, Colorant}} + elseif to_value(color) isa AbstractVector{<:Union{Number, Colorant}} gl_attributes[:vertex_color] = lift(el32convert, plot, color) else # error("Unsupported color type: $(typeof(to_value(color)))") @@ -788,7 +810,7 @@ function mesh_inner(screen::Screen, mesh, transfunc, gl_attributes, plot, space= # TODO: Should these use direct getters? (faces, normals, texturecoordinates) positions = map(coordinates, mesh) gl_attributes[:vertices] = apply_transform_and_f32_conversion(plot, pop!(gl_attributes, :f32c), positions) - gl_attributes[:faces] = lift(x-> decompose(GLTriangleFace, x), mesh) + gl_attributes[:faces] = lift(x -> decompose(GLTriangleFace, x), mesh) if hasproperty(to_value(mesh), :uv) gl_attributes[:texturecoordinates] = lift(decompose_uv, mesh) end @@ -818,12 +840,12 @@ function draw_atomic(screen::Screen, scene::Scene, plot::Surface) img = pop!(gl_attributes, :intensity) elseif to_value(color) isa Makie.AbstractPattern pattern_img = lift(x -> el32convert(Makie.to_image(x)), plot, color) - img = ShaderAbstractions.Sampler(pattern_img, x_repeat=:repeat, minfilter=:nearest) + img = ShaderAbstractions.Sampler(pattern_img, x_repeat = :repeat, minfilter = :nearest) haskey(gl_attributes, :fetch_pixel) || (gl_attributes[:fetch_pixel] = true) gl_attributes[:color_map] = nothing gl_attributes[:color] = nothing gl_attributes[:color_norm] = nothing - elseif isa(to_value(color), AbstractMatrix{<: Colorant}) + elseif isa(to_value(color), AbstractMatrix{<:Colorant}) img = color gl_attributes[:color_map] = nothing gl_attributes[:color] = nothing @@ -833,10 +855,10 @@ function draw_atomic(screen::Screen, scene::Scene, plot::Surface) space = plot.space interp = to_value(pop!(gl_attributes, :interpolate, true)) interp = interp ? :linear : :nearest - gl_attributes[:image] = Texture(img; minfilter=interp) + gl_attributes[:image] = Texture(img; minfilter = interp) @assert to_value(plot[3]) isa AbstractMatrix - gl_attributes[:instances] = map(z -> (size(z,1)-1) * (size(z,2)-1), plot[3]) + gl_attributes[:instances] = map(z -> (size(z, 1) - 1) * (size(z, 2) - 1), plot[3]) types = map(v -> typeof(to_value(v)), plot[1:2]) if all(T -> T <: Union{AbstractMatrix, AbstractVector}, types) @@ -869,7 +891,7 @@ function draw_atomic(screen::Screen, scene::Scene, plot::Surface) xpos = lift(first, plot, xypos) ypos = lift(last, plot, xypos) args = map((xpos, ypos, mat)) do arg - Texture(lift(x-> convert(Array, el32convert(x)), plot, arg); minfilter=:linear) + Texture(lift(x -> convert(Array, el32convert(x)), plot, arg); minfilter = :linear) end if isnothing(img) gl_attributes[:image] = args[3] @@ -877,7 +899,7 @@ function draw_atomic(screen::Screen, scene::Scene, plot::Surface) return draw_surface(screen, args, gl_attributes) else gl_attributes[:ranges] = to_range.(to_value.(plot[1:2])) - z_data = Texture(lift(el32convert, plot, plot[3]); minfilter=:linear) + z_data = Texture(lift(el32convert, plot, plot[3]); minfilter = :linear) if isnothing(img) gl_attributes[:image] = z_data end @@ -910,23 +932,25 @@ function draw_atomic(screen::Screen, scene::Scene, plot::Volume) gl_attributes[:num_clip_planes] = Observable(0) pop!(gl_attributes, :clip_planes) gl_attributes[:clip_planes] = map(plot, gl_attributes[:modelinv], plot.clip_planes, plot.space) do modelinv, planes, space - Makie.is_data_space(space) || return [Vec4f(0, 0, 0, -1e9) for _ in 1:8] + Makie.is_data_space(space) || return [Vec4f(0, 0, 0, -1.0e9) for _ in 1:8] # model/modelinv has no perspective projection so we should be fine # with just applying it to the plane origin and transpose(inv(modelinv)) # to plane.normal - @assert (length(planes) == 0) || isapprox(modelinv[4, 4], 1, atol = 1e-6) + @assert (length(planes) == 0) || isapprox(modelinv[4, 4], 1, atol = 1.0e-6) output = Vector{Vec4f}(undef, 8) for i in 1:min(length(planes), 8) origin = modelinv * to_ndim(Point4f, planes[i].distance * planes[i].normal, 1) normal = transpose(gl_attributes[:model][]) * to_ndim(Vec4f, planes[i].normal, 0) - distance = dot(Vec3f(origin[1], origin[2], origin[3]) / origin[4], - Vec3f(normal[1], normal[2], normal[3])) + distance = dot( + Vec3f(origin[1], origin[2], origin[3]) / origin[4], + Vec3f(normal[1], normal[2], normal[3]) + ) output[i] = Vec4f(normal[1], normal[2], normal[3], distance) end - for i in min(length(planes), 8)+1:8 - output[i] = Vec4f(0, 0, 0, -1e9) + for i in (min(length(planes), 8) + 1):8 + output[i] = Vec4f(0, 0, 0, -1.0e9) end return output @@ -934,7 +958,7 @@ function draw_atomic(screen::Screen, scene::Scene, plot::Volume) interp = to_value(pop!(gl_attributes, :interpolate)) interp = interp ? :linear : :nearest - Tex(x) = Texture(x; minfilter=interp) + Tex(x) = Texture(x; minfilter = interp) if haskey(gl_attributes, :intensity) intensity = pop!(gl_attributes, :intensity) return draw_volume(screen, Tex(intensity), gl_attributes) @@ -969,12 +993,13 @@ function draw_atomic(screen::Screen, scene::Scene, plot::Voxels) # adjust model matrix according to x/y/z limits gl_attributes[:model] = map( - plot, plot.converted..., pop!(gl_attributes, :model) - ) do xs, ys, zs, chunk, model + plot, plot.converted..., pop!(gl_attributes, :model) + ) do xs, ys, zs, chunk, model mini = minimum.((xs, ys, zs)) width = maximum.((xs, ys, zs)) .- mini - return Mat4f(model * - Makie.transformationmatrix(Vec3f(mini), Vec3f(width ./ size(chunk))) + return Mat4f( + model * + Makie.transformationmatrix(Vec3f(mini), Vec3f(width ./ size(chunk))) ) end @@ -983,24 +1008,26 @@ function draw_atomic(screen::Screen, scene::Scene, plot::Voxels) gl_attributes[:num_clip_planes] = Observable(0) pop!(gl_attributes, :clip_planes) gl_attributes[:clip_planes] = map(plot, gl_attributes[:model], plot.clip_planes, plot.space) do model, planes, space - Makie.is_data_space(space) || return [Vec4f(0, 0, 0, -1e9) for _ in 1:8] + Makie.is_data_space(space) || return [Vec4f(0, 0, 0, -1.0e9) for _ in 1:8] # model/modelinv has no perspective projection so we should be fine # with just applying it to the plane origin and transpose(inv(modelinv)) # to plane.normal modelinv = inv(model) - @assert (length(planes) == 0) || isapprox(modelinv[4, 4], 1, atol = 1e-6) + @assert (length(planes) == 0) || isapprox(modelinv[4, 4], 1, atol = 1.0e-6) output = Vector{Vec4f}(undef, 8) for i in 1:min(length(planes), 8) origin = modelinv * to_ndim(Point4f, planes[i].distance * planes[i].normal, 1) normal = transpose(model) * to_ndim(Vec4f, planes[i].normal, 0) - distance = dot(Vec3f(origin[1], origin[2], origin[3]) / origin[4], - Vec3f(normal[1], normal[2], normal[3])) + distance = dot( + Vec3f(origin[1], origin[2], origin[3]) / origin[4], + Vec3f(normal[1], normal[2], normal[3]) + ) output[i] = Vec4f(normal[1], normal[2], normal[3], distance) end - for i in min(length(planes), 8)+1:8 - output[i] = Vec4f(0, 0, 0, -1e9) + for i in (min(length(planes), 8) + 1):8 + output[i] = Vec4f(0, 0, 0, -1.0e9) end return output diff --git a/GLMakie/src/events.jl b/GLMakie/src/events.jl index 365c7a702ec..4d09ffdb58b 100644 --- a/GLMakie/src/events.jl +++ b/GLMakie/src/events.jl @@ -23,18 +23,18 @@ Makie.window_open(scene::Scene, screen) = window_open(scene, to_native(screen)) function Makie.window_open(scene::Scene, window::GLFW.Window) event = scene.events.window_open function windowclose(win) - @print_error begin + return @print_error begin @debug("Closing event from GLFW") event[] = false end end disconnect!(window, window_open) event[] = isopen(window) - GLFW.SetWindowCloseCallback(window, windowclose) + return GLFW.SetWindowCloseCallback(window, windowclose) end function Makie.disconnect!(window::GLFW.Window, ::typeof(window_open)) - GLFW.SetWindowCloseCallback(window, nothing) + return GLFW.SetWindowCloseCallback(window, nothing) end function Makie.window_area(scene::Scene, screen::Screen) @@ -100,30 +100,30 @@ Makie.mouse_buttons(scene::Scene, screen) = mouse_buttons(scene, to_native(scree function Makie.mouse_buttons(scene::Scene, window::GLFW.Window) event = scene.events.mousebutton function mousebuttons(window, button, action, mods) - @print_error begin + return @print_error begin event[] = MouseButtonEvent(Mouse.Button(Int(button)), Mouse.Action(Int(action))) end end disconnect!(window, mouse_buttons) - GLFW.SetMouseButtonCallback(window, mousebuttons) + return GLFW.SetMouseButtonCallback(window, mousebuttons) end function Makie.disconnect!(window::GLFW.Window, ::typeof(mouse_buttons)) - GLFW.SetMouseButtonCallback(window, nothing) + return GLFW.SetMouseButtonCallback(window, nothing) end Makie.keyboard_buttons(scene::Scene, screen) = keyboard_buttons(scene, to_native(screen)) function Makie.keyboard_buttons(scene::Scene, window::GLFW.Window) event = scene.events.keyboardbutton function keyoardbuttons(window, button, scancode::Cint, action, mods::Cint) - @print_error begin + return @print_error begin event[] = KeyEvent(Keyboard.Button(Int(button)), Keyboard.Action(Int(action))) end end disconnect!(window, keyboard_buttons) - GLFW.SetKeyCallback(window, keyoardbuttons) + return GLFW.SetKeyCallback(window, keyoardbuttons) end function Makie.disconnect!(window::GLFW.Window, ::typeof(keyboard_buttons)) - GLFW.SetKeyCallback(window, nothing) + return GLFW.SetKeyCallback(window, nothing) end """ @@ -135,16 +135,16 @@ Makie.dropped_files(scene::Scene, screen) = dropped_files(scene, to_native(scree function Makie.dropped_files(scene::Scene, window::GLFW.Window) event = scene.events.dropped_files function droppedfiles(window, files) - @print_error begin + return @print_error begin event[] = String.(files) end end disconnect!(window, dropped_files) event[] = String[] - GLFW.SetDropCallback(window, droppedfiles) + return GLFW.SetDropCallback(window, droppedfiles) end function Makie.disconnect!(window::GLFW.Window, ::typeof(dropped_files)) - GLFW.SetDropCallback(window, nothing) + return GLFW.SetDropCallback(window, nothing) end """ @@ -157,17 +157,17 @@ Makie.unicode_input(scene::Scene, screen) = unicode_input(scene, to_native(scree function Makie.unicode_input(scene::Scene, window::GLFW.Window) event = scene.events.unicode_input function unicodeinput(window, c::Char) - @print_error begin + return @print_error begin event[] = c end end disconnect!(window, unicode_input) # x = Char[]; sizehint!(x, 1) # event[] = x - GLFW.SetCharCallback(window, unicodeinput) + return GLFW.SetCharCallback(window, unicodeinput) end function Makie.disconnect!(window::GLFW.Window, ::typeof(unicode_input)) - GLFW.SetCharCallback(window, nothing) + return GLFW.SetCharCallback(window, nothing) end function correct_mouse(screen::Screen, w, h) @@ -218,7 +218,7 @@ function Makie.disconnect!(screen::Screen, ::typeof(mouse_position)) end function Makie.disconnect!(window::GLFW.Window, ::typeof(mouse_position)) error("disconnect!(::Screen, ::mouse_position) should be called instead of disconnect!(::GLFW.Window, ::mouseposition)!") - nothing + return nothing end """ @@ -245,10 +245,10 @@ end function Makie.scroll(scene::Scene, window::GLFW.Window) updater = ScrollUpdater(scene.events.scroll, true) disconnect!(window, scroll) - GLFW.SetScrollCallback(window, updater) + return GLFW.SetScrollCallback(window, updater) end function Makie.disconnect!(window::GLFW.Window, ::typeof(scroll)) - GLFW.SetScrollCallback(window, nothing) + return GLFW.SetScrollCallback(window, nothing) end """ @@ -261,17 +261,17 @@ Makie.hasfocus(scene::Scene, screen) = hasfocus(scene, to_native(screen)) function Makie.hasfocus(scene::Scene, window::GLFW.Window) event = scene.events.hasfocus function hasfocuscb(window, focus::Bool) - @print_error begin + return @print_error begin event[] = focus end end disconnect!(window, hasfocus) GLFW.SetWindowFocusCallback(window, hasfocuscb) event[] = GLFW.GetWindowAttrib(window, GLFW.FOCUSED) - nothing + return nothing end function Makie.disconnect!(window::GLFW.Window, ::typeof(hasfocus)) - GLFW.SetWindowFocusCallback(window, nothing) + return GLFW.SetWindowFocusCallback(window, nothing) end """ @@ -284,26 +284,26 @@ Makie.entered_window(scene::Scene, screen) = entered_window(scene, to_native(scr function Makie.entered_window(scene::Scene, window::GLFW.Window) event = scene.events.entered_window function enteredwindowcb(window, entered::Bool) - @print_error begin + return @print_error begin event[] = entered end end disconnect!(window, entered_window) - GLFW.SetCursorEnterCallback(window, enteredwindowcb) + return GLFW.SetCursorEnterCallback(window, enteredwindowcb) end function Makie.disconnect!(window::GLFW.Window, ::typeof(entered_window)) - GLFW.SetCursorEnterCallback(window, nothing) + return GLFW.SetCursorEnterCallback(window, nothing) end function Makie.frame_tick(scene::Scene, screen::Screen) # Separating screen ticks from event ticks allows us to sanitize: - # Internal on-tick event updates happen first (mouseposition), + # Internal on-tick event updates happen first (mouseposition), # consuming in event.tick listeners doesn't affect backend ticks, # more control/consistent order - on(Makie.TickCallback(scene), scene, screen.render_tick, priority = typemin(Int)) + return on(Makie.TickCallback(scene), scene, screen.render_tick, priority = typemin(Int)) end function Makie.disconnect!(screen::Screen, ::typeof(Makie.frame_tick)) connections = filter(x -> x[2] isa Makie.TickCallback, screen.render_tick.listeners) - foreach(x -> off(screen.render_tick, x[2]), connections) -end \ No newline at end of file + return foreach(x -> off(screen.render_tick, x[2]), connections) +end diff --git a/GLMakie/src/gl_backend.jl b/GLMakie/src/gl_backend.jl index ee4bffe3402..84ae781ec8e 100644 --- a/GLMakie/src/gl_backend.jl +++ b/GLMakie/src/gl_backend.jl @@ -1,12 +1,14 @@ try using GLFW catch e - @warn(""" - OpenGL/GLFW wasn't loaded correctly or couldn't be initialized. - This likely means, you're on a headless server without having OpenGL support setup correctly. - Have a look at the troubleshooting section in the readme: - https://github.com/MakieOrg/Makie.jl/tree/master/GLMakie#troubleshooting-opengl. - """) + @warn( + """ + OpenGL/GLFW wasn't loaded correctly or couldn't be initialized. + This likely means, you're on a headless server without having OpenGL support setup correctly. + Have a look at the troubleshooting section in the readme: + https://github.com/MakieOrg/Makie.jl/tree/master/GLMakie#troubleshooting-opengl. + """ + ) rethrow(e) end @@ -34,20 +36,20 @@ function get_texture!(atlas::Makie.TextureAtlas) tex, func = get!(atlas_texture_cache, (pointer(atlas.data), current_ctx)) do tex = Texture( - atlas.data, - minfilter = :linear, - magfilter = :linear, - # TODO: Consider alternatives to using the builtin anisotropic - # samplers for signed distance fields; the anisotropic - # filtering should happen *after* the SDF thresholding, but - # with the builtin sampler it happens before. - anisotropic = 16f0, - mipmap = true + atlas.data, + minfilter = :linear, + magfilter = :linear, + # TODO: Consider alternatives to using the builtin anisotropic + # samplers for signed distance fields; the anisotropic + # filtering should happen *after* the SDF thresholding, but + # with the builtin sampler it happens before. + anisotropic = 16.0f0, + mipmap = true ) # update the texture, whenever a new font is added to the atlas function callback(distance_field, rectangle) ctx = tex.context - if GLAbstraction.context_alive(ctx) + return if GLAbstraction.context_alive(ctx) prev_ctx = GLAbstraction.current_context() ShaderAbstractions.switch_context!(ctx) tex[rectangle] = distance_field diff --git a/GLMakie/src/glshaders/image_like.jl b/GLMakie/src/glshaders/image_like.jl index 21a1eed4081..09645bf598e 100644 --- a/GLMakie/src/glshaders/image_like.jl +++ b/GLMakie/src/glshaders/image_like.jl @@ -8,23 +8,27 @@ VolumePrerender(a, b) = VolumePrerender(StandardPrerender(a, b)) function (x::VolumePrerender)() x.sp() glEnable(GL_CULL_FACE) - glCullFace(GL_FRONT) + return glCullFace(GL_FRONT) end vol_depth_init(enable) = enable ? "float depth = 100000.0;" : "" vol_depth_default(enable) = enable ? "gl_FragDepth = gl_FragCoord.z;" : "" function vol_depth_main(enable) - if enable + return if enable """ vec4 frag_coord = projectionview * model * vec4(pos, 1); depth = min(depth, frag_coord.z / frag_coord.w); """ - else "" end + else + "" + end end function vol_depth_write(enable) - if enable + return if enable "gl_FragDepth = depth == 100000.0 ? gl_FragDepth : 0.5 * depth + 0.5;" - else "" end + else + "" + end end @nospecialize @@ -32,7 +36,7 @@ end A matrix of Intensities will result in a contourf kind of plot """ function draw_heatmap(screen, data::Dict) - primitive = triangle_mesh(Rect2(0f0,0f0,1f0,1f0)) + primitive = triangle_mesh(Rect2(0.0f0, 0.0f0, 1.0f0, 1.0f0)) to_opengl_mesh!(data, primitive) pop!(data, :shading, FastShading) @gen_defaults! data begin @@ -57,7 +61,7 @@ function draw_volume(screen, main::VolumeTypes, data::Dict) geom = Rect3f(Vec3f(0), Vec3f(1)) to_opengl_mesh!(data, const_lift(GeometryBasics.triangle_mesh, geom)) shading = pop!(data, :shading, FastShading) - pop!(data, :backlight, 0f0) # We overwrite this + pop!(data, :backlight, 0.0f0) # We overwrite this @gen_defaults! data begin volumedata = main => Texture model = Mat4f(I) @@ -67,10 +71,10 @@ function draw_volume(screen, main::VolumeTypes, data::Dict) color = color_map === nothing ? default(RGBA, s) : nothing algorithm = MaximumIntensityProjection - absorption = 1f0 + absorption = 1.0f0 isovalue = 0.5f0 isorange = 0.01f0 - backlight = 1f0 + backlight = 1.0f0 enable_depth = true transparency = false shader = GLVisualizeShader( @@ -81,9 +85,9 @@ function draw_volume(screen, main::VolumeTypes, data::Dict) "shading" => light_calc(shading), "MAX_LIGHTS" => "#define MAX_LIGHTS $(screen.config.max_lights)", "MAX_LIGHT_PARAMETERS" => "#define MAX_LIGHT_PARAMETERS $(screen.config.max_light_parameters)", - "depth_init" => vol_depth_init(to_value(enable_depth)), - "depth_default" => vol_depth_default(to_value(enable_depth)), - "depth_main" => vol_depth_main(to_value(enable_depth)), + "depth_init" => vol_depth_init(to_value(enable_depth)), + "depth_default" => vol_depth_default(to_value(enable_depth)), + "depth_main" => vol_depth_main(to_value(enable_depth)), "depth_write" => vol_depth_write(to_value(enable_depth)), "buffers" => output_buffers(screen, to_value(transparency)), "buffer_writes" => output_buffer_writes(screen, to_value(transparency)) diff --git a/GLMakie/src/glshaders/lines.jl b/GLMakie/src/glshaders/lines.jl index 9f29d47d8b7..3fe036471e8 100644 --- a/GLMakie/src/glshaders/lines.jl +++ b/GLMakie/src/glshaders/lines.jl @@ -3,21 +3,21 @@ function sumlengths(points, resolution) f(p::VecTypes{4}) = p[Vec(1, 2)] / p[4] f(p::VecTypes) = p[Vec(1, 2)] - invalid(p::VecTypes{4}) = p[4] <= 1e-6 + invalid(p::VecTypes{4}) = p[4] <= 1.0e-6 invalid(p::VecTypes) = false T = eltype(eltype(typeof(points))) result = zeros(T, length(points)) for (i, idx) in enumerate(eachindex(points)) - idx0 = max(idx-1, 1) + idx0 = max(idx - 1, 1) p1, p2 = points[idx0], points[idx] if any(map(isnan, p1)) || any(map(isnan, p2)) || invalid(p1) || invalid(p2) - result[i] = 0f0 + result[i] = 0.0f0 else - result[i] = result[max(i-1, 1)] + 0.5 * norm(resolution .* (f(p1) - f(p2))) + result[i] = result[max(i - 1, 1)] + 0.5 * norm(resolution .* (f(p1) - f(p2))) end end - result + return result end # because the "color_type" generated in GLAbstraction also include "uniform" @@ -37,7 +37,7 @@ function generate_indices(positions) resize!(valid, length(ps)) indices = Cuint[] - sizehint!(indices, length(ps)+2) + sizehint!(indices, length(ps) + 2) # This loop identifies sections of line points A B C D E F bounded by # the start/end of the list ps or by NaN and generates indices for them: @@ -61,31 +61,31 @@ function generate_indices(positions) if last_start_idx == -1 # place nan before section of line vertices # (or duplicate ps[1]) - push!(indices, i-1) + push!(indices, i - 1) last_start_idx = length(indices) + 1 last_start_pos = p end # add line vertex push!(indices, i) - # case loop (loop index set, loop contains at least 3 segments, start == end) + # case loop (loop index set, loop contains at least 3 segments, start == end) elseif (last_start_idx != -1) && (length(indices) - last_start_idx > 2) && - (ps[max(1, i-1)] ≈ last_start_pos) + (ps[max(1, i - 1)] ≈ last_start_pos) # add ghost vertices before an after the loop to cleanly connect line - indices[last_start_idx-1] = max(1, i-2) - push!(indices, indices[last_start_idx+1], i) + indices[last_start_idx - 1] = max(1, i - 2) + push!(indices, indices[last_start_idx + 1], i) # mark the ghost vertices - valid[i-2] = 2 - valid[indices[last_start_idx+1]] = 2 + valid[i - 2] = 2 + valid[indices[last_start_idx + 1]] = 2 # not in loop anymore last_start_idx = -1 - # non-looping line end + # non-looping line end elseif (last_start_idx != -1) # effective "last index not NaN" push!(indices, i) last_start_idx = -1 - # else: we don't need to push repeated NaNs + # else: we don't need to push repeated NaNs end end @@ -93,10 +93,10 @@ function generate_indices(positions) if (last_start_idx != -1) && (length(indices) - last_start_idx > 2) && (ps[end] ≈ last_start_pos) - indices[last_start_idx-1] = length(ps) - 1 - push!(indices, indices[last_start_idx+1]) - valid[end-1] = 2 - valid[indices[last_start_idx+1]] = 2 + indices[last_start_idx - 1] = length(ps) - 1 + push!(indices, indices[last_start_idx + 1]) + valid[end - 1] = 2 + valid[indices[last_start_idx + 1]] = 2 elseif last_start_idx != -1 push!(indices, length(ps)) end @@ -109,7 +109,7 @@ function generate_indices(positions) end @nospecialize -function draw_lines(screen, position::Union{VectorTypes{T}, MatTypes{T}}, data::Dict) where T<:Point +function draw_lines(screen, position::Union{VectorTypes{T}, MatTypes{T}}, data::Dict) where {T <: Point} p_vec = if isa(position, GPUArray) position else @@ -123,21 +123,21 @@ function draw_lines(screen, position::Union{VectorTypes{T}, MatTypes{T}}, data:: @gen_defaults! data begin total_length::Int32 = const_lift(x -> Int32(length(x) - 2), indices) - vertex = p_vec => GLBuffer - color = nothing => GLBuffer - color_map = nothing => Texture - color_norm = nothing - thickness = 2f0 => GLBuffer - pattern = nothing - pattern_sections = pattern => Texture - fxaa = false + vertex = p_vec => GLBuffer + color = nothing => GLBuffer + color_map = nothing => Texture + color_norm = nothing + thickness = 2.0f0 => GLBuffer + pattern = nothing + pattern_sections = pattern => Texture + fxaa = false # Duplicate the vertex indices on the ends of the line, as our geometry # shader in `layout(lines_adjacency)` mode requires each rendered # segment to have neighbouring vertices. - indices = indices => to_index_buffer + indices = indices => to_index_buffer transparency = false - fast = false - shader = GLVisualizeShader( + fast = false + shader = GLVisualizeShader( screen, "fragment_output.frag", "lines.vert", "lines.geom", "lines.frag", view = Dict( @@ -147,18 +147,18 @@ function draw_lines(screen, position::Union{VectorTypes{T}, MatTypes{T}}, data:: "stripped_color_type" => color_type ) ) - gl_primitive = GL_LINE_STRIP_ADJACENCY - valid_vertex = valid_vertex => GLBuffer - lastlen = const_lift(sumlengths, p_vec, resolution) => GLBuffer - pattern_length = 1f0 # we divide by pattern_length a lot. - debug = false + gl_primitive = GL_LINE_STRIP_ADJACENCY + valid_vertex = valid_vertex => GLBuffer + lastlen = const_lift(sumlengths, p_vec, resolution) => GLBuffer + pattern_length = 1.0f0 # we divide by pattern_length a lot. + debug = false end if to_value(pattern) !== nothing if !isa(pattern, Texture) if !isa(to_value(pattern), Vector) error("Pattern needs to be a Vector of floats. Found: $(typeof(pattern))") end - tex = GLAbstraction.Texture(lift(Makie.linestyle_to_sdf, pattern); x_repeat=:repeat) + tex = GLAbstraction.Texture(lift(Makie.linestyle_to_sdf, pattern); x_repeat = :repeat) data[:pattern] = tex end data[:pattern_length] = lift(pt -> Float32(last(pt) - first(pt)), pattern) @@ -167,23 +167,23 @@ function draw_lines(screen, position::Union{VectorTypes{T}, MatTypes{T}}, data:: return assemble_shader(data) end -function draw_linesegments(screen, positions::VectorTypes{T}, data::Dict) where T <: Point +function draw_linesegments(screen, positions::VectorTypes{T}, data::Dict) where {T <: Point} color_type = gl_color_type_annotation(data[:color]) @gen_defaults! data begin - vertex = positions => GLBuffer - color = nothing => GLBuffer - color_map = nothing => Texture - color_norm = nothing - thickness = 2f0 => GLBuffer - shape = RECTANGLE - pattern = nothing - fxaa = false - fast = false - indices = const_lift(length, positions) => to_index_buffer + vertex = positions => GLBuffer + color = nothing => GLBuffer + color_map = nothing => Texture + color_norm = nothing + thickness = 2.0f0 => GLBuffer + shape = RECTANGLE + pattern = nothing + fxaa = false + fast = false + indices = const_lift(length, positions) => to_index_buffer # TODO update boundingbox - transparency = false - shader = GLVisualizeShader( + transparency = false + shader = GLVisualizeShader( screen, "fragment_output.frag", "line_segment.vert", "line_segment.geom", "lines.frag", @@ -193,15 +193,15 @@ function draw_linesegments(screen, positions::VectorTypes{T}, data::Dict) where "stripped_color_type" => color_type ) ) - gl_primitive = GL_LINES - pattern_length = 1f0 - debug = false + gl_primitive = GL_LINES + pattern_length = 1.0f0 + debug = false end if !isa(pattern, Texture) && to_value(pattern) !== nothing if !isa(to_value(pattern), Vector) error("Pattern needs to be a Vector of floats. Found: $(typeof(pattern))") end - tex = GLAbstraction.Texture(lift(Makie.linestyle_to_sdf, pattern); x_repeat=:repeat) + tex = GLAbstraction.Texture(lift(Makie.linestyle_to_sdf, pattern); x_repeat = :repeat) data[:pattern] = tex data[:pattern_length] = lift(pt -> Float32(last(pt) - first(pt)), pattern) end diff --git a/GLMakie/src/glshaders/mesh.jl b/GLMakie/src/glshaders/mesh.jl index 07229a3faf3..e31ecaf9363 100644 --- a/GLMakie/src/glshaders/mesh.jl +++ b/GLMakie/src/glshaders/mesh.jl @@ -1,11 +1,11 @@ -function to_opengl_mesh!(result, mesh_obs::TOrSignal{<: GeometryBasics.Mesh}) +function to_opengl_mesh!(result, mesh_obs::TOrSignal{<:GeometryBasics.Mesh}) m = convert(Observable, mesh_obs) - - result[:faces] = indexbuffer(map(faces, m)) + + result[:faces] = indexbuffer(map(faces, m)) result[:vertices] = GLBuffer(map(coordinates, m)) function to_buffer(name, target) - if hasproperty(m[], name) + return if hasproperty(m[], name) val = getproperty(m[], name) if mesh_obs isa Observable val = map(m -> getproperty(m, name), m) @@ -31,7 +31,7 @@ function to_opengl_mesh!(result, mesh_obs::TOrSignal{<: GeometryBasics.Mesh}) to_buffer(:normal, :normals) end to_buffer(:attribute_id, :attribute_id) - + return result end @@ -41,7 +41,7 @@ function draw_mesh(screen, data::Dict) vertices = nothing => GLBuffer faces = nothing => indexbuffer normals = nothing => GLBuffer - backlight = 0f0 + backlight = 0.0f0 vertex_color = nothing => GLBuffer image = nothing => Texture matcap = nothing => Texture @@ -49,7 +49,7 @@ function draw_mesh(screen, data::Dict) color_norm = nothing fetch_pixel = false texturecoordinates = Vec2f(0) => GLBuffer - uv_transform = Mat{2,3,Float32}(1, 0, 0, -1, 0, 1) + uv_transform = Mat{2, 3, Float32}(1, 0, 0, -1, 0, 1) transparency = false interpolate_in_fragment_shader = true shader = GLVisualizeShader( diff --git a/GLMakie/src/glshaders/particles.jl b/GLMakie/src/glshaders/particles.jl index 6355f267486..8fdd4dd8625 100644 --- a/GLMakie/src/glshaders/particles.jl +++ b/GLMakie/src/glshaders/particles.jl @@ -1,31 +1,31 @@ using Makie: RectanglePacker -function to_meshcolor(color::TOrSignal{Vector{T}}) where T <: Colorant - TextureBuffer(color) +function to_meshcolor(color::TOrSignal{Vector{T}}) where {T <: Colorant} + return TextureBuffer(color) end -function to_meshcolor(color::TOrSignal{Matrix{T}}) where T <: Colorant - Texture(color) +function to_meshcolor(color::TOrSignal{Matrix{T}}) where {T <: Colorant} + return Texture(color) end function to_meshcolor(color) - color + return color end vec2quaternion(rotation::StaticVector{4}) = rotation function vec2quaternion(r::StaticVector{2}) - vec2quaternion(Vec3f(r[1], r[2], 0)) + return vec2quaternion(Vec3f(r[1], r[2], 0)) end function vec2quaternion(rotation::StaticVector{3}) - Makie.rotation_between(Vec3f(0, 0, 1), Vec3f(rotation)) + return Makie.rotation_between(Vec3f(0, 0, 1), Vec3f(rotation)) end vec2quaternion(rotation::Vec4f) = rotation -vec2quaternion(rotation::VectorTypes) = const_lift(x-> vec2quaternion.(x), rotation) +vec2quaternion(rotation::VectorTypes) = const_lift(x -> vec2quaternion.(x), rotation) vec2quaternion(rotation::Observable) = lift(vec2quaternion, rotation) -vec2quaternion(rotation::Makie.Quaternion)= Vec4f(rotation.data) -vec2quaternion(rotation)= vec2quaternion(to_rotation(rotation)) -GLAbstraction.gl_convert(rotation::Makie.Quaternion)= Vec4f(rotation.data) +vec2quaternion(rotation::Makie.Quaternion) = Vec4f(rotation.data) +vec2quaternion(rotation) = vec2quaternion(to_rotation(rotation)) +GLAbstraction.gl_convert(rotation::Makie.Quaternion) = Vec4f(rotation.data) to_pointsize(x::Number) = Float32(x) to_pointsize(x) = Float32(x[1]) struct PointSizeRender @@ -42,15 +42,15 @@ is_all_equal_scale(vs::Vector{Vec2f}) = all(is_all_equal_scale, vs) intensity_convert(intensity, verts) = intensity -function intensity_convert(intensity::VecOrSignal{T}, verts) where T - if length(to_value(intensity)) == length(to_value(verts)) +function intensity_convert(intensity::VecOrSignal{T}, verts) where {T} + return if length(to_value(intensity)) == length(to_value(verts)) GLBuffer(intensity) else Texture(intensity) end end -function intensity_convert_tex(intensity::VecOrSignal{T}, verts) where T - if length(to_value(intensity)) == length(to_value(verts)) +function intensity_convert_tex(intensity::VecOrSignal{T}, verts) where {T} + return if length(to_value(intensity)) == length(to_value(verts)) TextureBuffer(intensity) else Texture(intensity) @@ -58,7 +58,6 @@ function intensity_convert_tex(intensity::VecOrSignal{T}, verts) where T end - @nospecialize """ This is the main function to assemble particles with a GLNormalMesh as a primitive @@ -84,9 +83,9 @@ function draw_mesh_particle(screen, p, data) # 3x Vec2 should match the element order of glsl mat3x2 output = Vector{Vec2f}(undef, 3 * length(transforms)) for i in eachindex(transforms) - output[3 * (i-1) + 1] = transforms[i][Vec(1, 2)] - output[3 * (i-1) + 2] = transforms[i][Vec(3, 4)] - output[3 * (i-1) + 3] = transforms[i][Vec(5, 6)] + output[3 * (i - 1) + 1] = transforms[i][Vec(1, 2)] + output[3 * (i - 1) + 2] = transforms[i][Vec(3, 4)] + output[3 * (i - 1) + 3] = transforms[i][Vec(5, 6)] end return output end => TextureBuffer @@ -107,7 +106,7 @@ function draw_mesh_particle(screen, p, data) fetch_pixel = false scale_primitive = false interpolate_in_fragment_shader = false - backlight = 0f0 + backlight = 0.0f0 instances = const_lift(length, position) transparency = false @@ -139,14 +138,14 @@ This is supposed to be the fastest way of displaying particles! """ function draw_pixel_scatter(screen, position::VectorTypes, data::Dict) @gen_defaults! data begin - vertex = position => GLBuffer - color_map = nothing => Texture - color = nothing => GLBuffer + vertex = position => GLBuffer + color_map = nothing => Texture + color = nothing => GLBuffer marker_offset = Vec3f(0) => GLBuffer - color_norm = nothing - scale = 2f0 + color_norm = nothing + scale = 2.0f0 transparency = false - shader = GLVisualizeShader( + shader = GLVisualizeShader( screen, "fragment_output.frag", "dots.vert", "dots.frag", view = Dict( @@ -156,19 +155,19 @@ function draw_pixel_scatter(screen, position::VectorTypes, data::Dict) ) gl_primitive = GL_POINTS end - data[:prerender] = ()-> glEnable(GL_VERTEX_PROGRAM_POINT_SIZE) + data[:prerender] = () -> glEnable(GL_VERTEX_PROGRAM_POINT_SIZE) return assemble_shader(data) end function draw_scatter( - screen, p::Tuple{TOrSignal{Matrix{C}}, VectorTypes{P}}, data::Dict + screen, p::Tuple{TOrSignal{Matrix{C}}, VectorTypes{P}}, data::Dict ) where {C <: Colorant, P <: Point} data[:image] = p[1] # we don't want this to be overwritten by user @gen_defaults! data begin - scale = lift(x-> Vec2f(size(x)), p[1]) + scale = lift(x -> Vec2f(size(x)), p[1]) offset = Vec2f(0) end - draw_scatter(screen, (RECTANGLE, p[2]), data) + return draw_scatter(screen, (RECTANGLE, p[2]), data) end function draw_scatter( @@ -177,13 +176,13 @@ function draw_scatter( images = map(el32convert, to_value(p[1])) isempty(images) && error("Can not display empty vector of images as primitive") sizes = map(size, images) - if !all(x-> x == sizes[1], sizes) # if differently sized + if !all(x -> x == sizes[1], sizes) # if differently sized # create texture atlas maxdims = sum(map(Vec{2, Int}, sizes)) - rectangles = map(x->Rect2(0, 0, x...), sizes) + rectangles = map(x -> Rect2(0, 0, x...), sizes) rpack = RectanglePacker(Rect2(0, 0, maxdims...)) uv_coordinates = [push!(rpack, rect).area for rect in rectangles] - max_xy = mapreduce(maximum, (a,b)-> max.(a, b), uv_coordinates) + max_xy = mapreduce(maximum, (a, b) -> max.(a, b), uv_coordinates) texture_atlas = Texture(eltype(images[1]), (max_xy...,)) for (area, img) in zip(uv_coordinates, images) texture_atlas[area] = img #transfer to texture atlas @@ -220,7 +219,7 @@ function draw_scatter(screen, (marker, position), data) ) do pv, pp, m, pos T = pv * pp * m depth_vals = map(pos) do p - p4d = T * to_ndim(Point4f, to_ndim(Point3f, p, 0f0), 1f0) + p4d = T * to_ndim(Point4f, to_ndim(Point3f, p, 0.0f0), 1.0f0) p4d[3] / p4d[4] end UInt32.(sortperm(depth_vals, rev = true) .- 1) @@ -228,17 +227,17 @@ function draw_scatter(screen, (marker, position), data) end @gen_defaults! data begin - shape = Cint(0) - position = position => GLBuffer + shape = Cint(0) + position = position => GLBuffer marker_offset = Vec3f(0) => GLBuffer - scale = Vec2f(0) => GLBuffer - rotation = rot => GLBuffer - image = nothing => Texture + scale = Vec2f(0) => GLBuffer + rotation = rot => GLBuffer + image = nothing => Texture end data[:shape] = map( - convert(Observable{Int}, pop!(data, :shape)), data[:scale] - ) do shape, scale + convert(Observable{Int}, pop!(data, :shape)), data[:scale] + ) do shape, scale if shape == 0 && !is_all_equal_scale(scale) return Cint(5) # scaled CIRCLE -> ELLIPSE else @@ -247,25 +246,25 @@ function draw_scatter(screen, (marker, position), data) end @gen_defaults! data begin - quad_offset = Vec2f(0) => GLBuffer - intensity = nothing => GLBuffer - color_map = nothing => Texture - color_norm = nothing - color = nothing => GLBuffer + quad_offset = Vec2f(0) => GLBuffer + intensity = nothing => GLBuffer + color_map = nothing => Texture + color_norm = nothing + color = nothing => GLBuffer - glow_color = RGBA{Float32}(0,0,0,0) => GLBuffer - stroke_color = RGBA{Float32}(0,0,0,0) => GLBuffer - stroke_width = 0f0 - glow_width = 0f0 + glow_color = RGBA{Float32}(0, 0, 0, 0) => GLBuffer + stroke_color = RGBA{Float32}(0, 0, 0, 0) => GLBuffer + stroke_width = 0.0f0 + glow_width = 0.0f0 uv_offset_width = Vec4f(0) => GLBuffer - distancefield = nothing => Texture - indices = const_lift(length, position) => to_index_buffer + distancefield = nothing => Texture + indices = const_lift(length, position) => to_index_buffer # rotation and billboard don't go along - billboard = rotation == Vec4f(0,0,0,1) => "if `billboard` == true, particles will always face camera" - fxaa = false - transparency = false - shader = GLVisualizeShader( + billboard = rotation == Vec4f(0, 0, 0, 1) => "if `billboard` == true, particles will always face camera" + fxaa = false + transparency = false + shader = GLVisualizeShader( screen, "fragment_output.frag", "util.vert", "sprites.geom", "sprites.vert", "distance_shape.frag", diff --git a/GLMakie/src/glshaders/surface.jl b/GLMakie/src/glshaders/surface.jl index a868b48bd39..128fc61c786 100644 --- a/GLMakie/src/glshaders/surface.jl +++ b/GLMakie/src/glshaders/surface.jl @@ -1,6 +1,5 @@ - function position_calc(x...) - _position_calc(Iterators.filter(x->!isa(x, Nothing), x)...) + return _position_calc(Iterators.filter(x -> !isa(x, Nothing), x)...) end function normal_calc(x::Bool, invert_normals::Bool = false) @@ -25,7 +24,7 @@ function light_calc(x::Makie.MakieCore.ShadingAlgorithm) return "#define FAST_SHADING" elseif x === MultiLightShading return "#define MULTI_LIGHT_SHADING" - # elseif x === :PBR # TODO? + # elseif x === :PBR # TODO? else @warn "Did not recognize shading value :$x. Defaulting to FastShading." return "#define FAST_SHADING" @@ -34,8 +33,8 @@ end function _position_calc( position_x::MatTypes{T}, position_y::MatTypes{T}, position_z::MatTypes{T}, target::Type{Texture} - ) where T<:AbstractFloat - """ + ) where {T <: AbstractFloat} + return """ int index1D = index + offseti.x + offseti.y * dims.x + (index/(dims.x-1)); ivec2 index2D = ind2sub(dims, index1D); vec2 index01 = (vec2(index2D) + 0.5) / (vec2(dims)); @@ -51,8 +50,8 @@ end function _position_calc( position_x::VectorTypes{T}, position_y::VectorTypes{T}, position_z::MatTypes{T}, target::Type{Texture} - ) where T<:AbstractFloat - """ + ) where {T <: AbstractFloat} + return """ int index1D = index + offseti.x + offseti.y * dims.x + (index/(dims.x-1)); ivec2 index2D = ind2sub(dims, index1D); vec2 index01 = (vec2(index2D) + 0.5) / (vec2(dims)); @@ -67,23 +66,23 @@ end function _position_calc( position_xyz::VectorTypes{T}, target::Type{TextureBuffer} - ) where T <: StaticVector - "pos = texelFetch(position, index).xyz;" + ) where {T <: StaticVector} + return "pos = texelFetch(position, index).xyz;" end function _position_calc( position_xyz::VectorTypes{T}, target::Type{GLBuffer} - ) where T <: StaticVector + ) where {T <: StaticVector} len = length(T) - filler = join(ntuple(x->0, 3-len), ", ") + filler = join(ntuple(x -> 0, 3 - len), ", ") needs_comma = len != 3 ? ", " : "" - "pos = vec3(position $needs_comma $filler);" + return "pos = vec3(position $needs_comma $filler);" end function _position_calc( grid::Grid{2}, position_z::MatTypes{T}, target::Type{Texture} - ) where T<:AbstractFloat - """ + ) where {T <: AbstractFloat} + return """ int index1D = index + offseti.x + offseti.y * dims.x; // + (index/(dims.x-1)); ivec2 index2D = ind2sub(dims, index1D); vec2 index01 = (vec2(index2D) + 0.5) / (vec2(dims)); @@ -95,7 +94,7 @@ end @nospecialize # surface(::Matrix, ::Matrix, ::Matrix) -function draw_surface(screen, main::Tuple{MatTypes{T}, MatTypes{T}, MatTypes{T}}, data::Dict) where T <: AbstractFloat +function draw_surface(screen, main::Tuple{MatTypes{T}, MatTypes{T}, MatTypes{T}}, data::Dict) where {T <: AbstractFloat} @gen_defaults! data begin position_x = main[1] => (Texture, "x position, must be a `Matrix{Float}`") position_y = main[2] => (Texture, "y position, must be a `Matrix{Float}`") @@ -106,7 +105,7 @@ function draw_surface(screen, main::Tuple{MatTypes{T}, MatTypes{T}, MatTypes{T}} end # surface(Vector or Range, Vector or Range, ::Matrix) -function draw_surface(screen, main::Tuple{VectorTypes{T}, VectorTypes{T}, MatTypes{T}}, data::Dict) where T <: AbstractFloat +function draw_surface(screen, main::Tuple{VectorTypes{T}, VectorTypes{T}, MatTypes{T}}, data::Dict) where {T <: AbstractFloat} @gen_defaults! data begin position_x = main[1] => (Texture, "x position, must be a `Vector{Float}`") position_y = main[2] => (Texture, "y position, must be a `Vector{Float}`") @@ -117,7 +116,7 @@ function draw_surface(screen, main::Tuple{VectorTypes{T}, VectorTypes{T}, MatTyp end function draw_surface(screen, main, data::Dict) - primitive = triangle_mesh(Rect2(0f0,0f0,1f0,1f0)) + primitive = triangle_mesh(Rect2(0.0f0, 0.0f0, 1.0f0, 1.0f0)) to_opengl_mesh!(data, primitive) shading = pop!(data, :shading, FastShading)::Makie.MakieCore.ShadingAlgorithm @gen_defaults! data begin @@ -129,7 +128,7 @@ function draw_surface(screen, main, data::Dict) image = nothing => Texture normal = shading != NoShading invert_normals = false - backlight = 0f0 + backlight = 0.0f0 end @gen_defaults! data begin color = nothing => Texture @@ -142,8 +141,8 @@ function draw_surface(screen, main, data::Dict) highclip = RGBAf(0, 0, 0, 0) lowclip = RGBAf(0, 0, 0, 0) - uv_transform = Mat{2,3,Float32}(1, 0, 0, -1, 0, 1) - instances = const_lift(x->(size(x,1)-1) * (size(x,2)-1), main) => "number of planes used to render the surface" + uv_transform = Mat{2, 3, Float32}(1, 0, 0, -1, 0, 1) + instances = const_lift(x -> (size(x, 1) - 1) * (size(x, 2) - 1), main) => "number of planes used to render the surface" transparency = false shader = GLVisualizeShader( screen, diff --git a/GLMakie/src/glshaders/visualize_interface.jl b/GLMakie/src/glshaders/visualize_interface.jl index d9236e4f61c..6ca93906091 100644 --- a/GLMakie/src/glshaders/visualize_interface.jl +++ b/GLMakie/src/glshaders/visualize_interface.jl @@ -1,18 +1,20 @@ @enum CubeSides TOP BOTTOM FRONT BACK RIGHT LEFT -struct Grid{N,T <: AbstractRange} - dims::NTuple{N,T} +struct Grid{N, T <: AbstractRange} + dims::NTuple{N, T} end -Base.ndims(::Grid{N,T}) where {N,T} = N +Base.ndims(::Grid{N, T}) where {N, T} = N Grid(ranges::AbstractRange...) = Grid(ranges) -function Grid(a::Array{T,N}) where {N,T} - s = Vec{N,Float32}(size(a)) +function Grid(a::Array{T, N}) where {N, T} + s = Vec{N, Float32}(size(a)) smax = maximum(s) s = s ./ smax - Grid(ntuple(Val{N}) do i - range(0, stop=s[i], length=size(a, i)) - end) + return Grid( + ntuple(Val{N}) do i + range(0, stop = s[i], length = size(a, i)) + end + ) end Grid(a::AbstractArray, ranges...) = Grid(a, ranges) @@ -23,40 +25,46 @@ Due to the approach, the tuple `ranges` can consist of NTuple(2, T) and all kind of range types. The constructor will make sure that all ranges match the size of the dimension of the array `a`. """ -function Grid(a::AbstractArray{T,N}, ranges::Tuple) where {T,N} - length(ranges) = ! N && throw(ArgumentError( - "You need to supply a range for every dimension of the array. Given: $ranges +function Grid(a::AbstractArray{T, N}, ranges::Tuple) where {T, N} + length(ranges) = ! N && throw( + ArgumentError( + "You need to supply a range for every dimension of the array. Given: $ranges given Array: $(typeof(a))" - )) - Grid(ntuple(Val(N)) do i - range(first(ranges[i]), stop=last(ranges[i]), length=size(a, i)) - end) + ) + ) + return Grid( + ntuple(Val(N)) do i + range(first(ranges[i]), stop = last(ranges[i]), length = size(a, i)) + end + ) end Base.length(p::Grid) = prod(size(p)) Base.size(p::Grid) = map(length, p.dims) -function Base.getindex(p::Grid{N,T}, i) where {N,T} +function Base.getindex(p::Grid{N, T}, i) where {N, T} inds = ind2sub(size(p), i) - return Point{N,eltype(T)}(ntuple(Val(N)) do i - p.dims[i][inds[i]] - end) + return Point{N, eltype(T)}( + ntuple(Val(N)) do i + p.dims[i][inds[i]] + end + ) end -Base.iterate(g::Grid, i=1) = i <= length(g) ? (g[i], i + 1) : nothing +Base.iterate(g::Grid, i = 1) = i <= length(g) ? (g[i], i + 1) : nothing GLAbstraction.isa_gl_struct(x::Grid) = true -GLAbstraction.toglsltype_string(t::Grid{N,T}) where {N,T} = "uniform Grid$(N)D" -function GLAbstraction.gl_convert_struct(g::Grid{N,T}, uniform_name::Symbol) where {N,T} - return Dict{Symbol,Any}( - Symbol("$uniform_name.start") => Vec{N,Float32}(minimum.(g.dims)), - Symbol("$uniform_name.stop") => Vec{N,Float32}(maximum.(g.dims)), - Symbol("$uniform_name.lendiv") => Vec{N,Cint}(length.(g.dims) .- 1), - Symbol("$uniform_name.dims") => Vec{N,Cint}(map(length, g.dims)) +GLAbstraction.toglsltype_string(t::Grid{N, T}) where {N, T} = "uniform Grid$(N)D" +function GLAbstraction.gl_convert_struct(g::Grid{N, T}, uniform_name::Symbol) where {N, T} + return Dict{Symbol, Any}( + Symbol("$uniform_name.start") => Vec{N, Float32}(minimum.(g.dims)), + Symbol("$uniform_name.stop") => Vec{N, Float32}(maximum.(g.dims)), + Symbol("$uniform_name.lendiv") => Vec{N, Cint}(length.(g.dims) .- 1), + Symbol("$uniform_name.dims") => Vec{N, Cint}(map(length, g.dims)) ) end -function GLAbstraction.gl_convert_struct(g::Grid{1,T}, uniform_name::Symbol) where T +function GLAbstraction.gl_convert_struct(g::Grid{1, T}, uniform_name::Symbol) where {T} x = g.dims[1] - return Dict{Symbol,Any}( + return Dict{Symbol, Any}( Symbol("$uniform_name.start") => Float32(minimum(x)), Symbol("$uniform_name.stop") => Float32(maximum(x)), Symbol("$uniform_name.lendiv") => Cint(length(x) - 1), @@ -67,10 +75,10 @@ end struct GLVisualizeShader <: AbstractLazyShader screen::Screen paths::Tuple - kw_args::Dict{Symbol,Any} + kw_args::Dict{Symbol, Any} function GLVisualizeShader( screen::Screen, paths::String...; - view = Dict{String,String}(), kw_args... + view = Dict{String, String}(), kw_args... ) # TODO properly check what extensions are available @static if !Sys.isapple() @@ -80,12 +88,12 @@ struct GLVisualizeShader <: AbstractLazyShader args = Dict{Symbol, Any}(kw_args) args[:view] = view args[:fragdatalocation] = [(0, "fragment_color"), (1, "fragment_groupid")] - new(screen, map(x -> loadshader(x), paths), args) + return new(screen, map(x -> loadshader(x), paths), args) end end function GLAbstraction.gl_convert(shader::GLVisualizeShader, data) - GLAbstraction.gl_convert(shader.screen.shader_cache, shader, data) + return GLAbstraction.gl_convert(shader.screen.shader_cache, shader, data) end function assemble_shader(data) @@ -100,7 +108,7 @@ function assemble_shader(data) pre = if !isnothing(pre_fun) _pre_fun = GLAbstraction.StandardPrerender(transp, overdraw) - ()->(_pre_fun(); pre_fun()) + () -> (_pre_fun(); pre_fun()) else GLAbstraction.StandardPrerender(transp, overdraw) end @@ -132,15 +140,15 @@ to_index_buffer(x::TOrSignal{UnitRange{Int}}) = x For integers, we transform it to 0 based indices """ to_index_buffer(x::AbstractVector{I}) where {I <: Integer} = indexbuffer(Cuint.(x .- 1)) -function to_index_buffer(x::Observable{<: AbstractVector{I}}) where I <: Integer - indexbuffer(lift(x -> Cuint.(x .- 1), x)) +function to_index_buffer(x::Observable{<:AbstractVector{I}}) where {I <: Integer} + return indexbuffer(lift(x -> Cuint.(x .- 1), x)) end """ If already GLuint, we assume its 0 based (bad heuristic, should better be solved with some Index type) """ -function to_index_buffer(x::VectorTypes{I}) where I <: Union{GLuint,LineFace{GLIndex}} - indexbuffer(x) +function to_index_buffer(x::VectorTypes{I}) where {I <: Union{GLuint, LineFace{GLIndex}}} + return indexbuffer(x) end to_index_buffer(x) = error( @@ -149,7 +157,7 @@ to_index_buffer(x) = error( ) function output_buffers(screen::Screen, transparency = false) - if transparency + return if transparency """ layout(location=2) out float coverage; """ @@ -164,7 +172,7 @@ function output_buffers(screen::Screen, transparency = false) end function output_buffer_writes(screen::Screen, transparency = false) - if transparency + return if transparency scale = screen.config.transparency_weight_scale """ float weight = color.a * max(0.01, $scale * pow((1 - gl_FragCoord.z), 3)); diff --git a/GLMakie/src/glshaders/voxel.jl b/GLMakie/src/glshaders/voxel.jl index f0a3c679405..bd0f7763ffc 100644 --- a/GLMakie/src/glshaders/voxel.jl +++ b/GLMakie/src/glshaders/voxel.jl @@ -5,14 +5,14 @@ function draw_voxels(screen, main::VolumeTypes, data::Dict) shading = pop!(data, :shading, FastShading) @gen_defaults! data begin voxel_id = main => Texture - gap = 0f0 + gap = 0.0f0 instances = const_lift(gap, voxel_id) do gap, chunk N = sum(size(chunk)) ifelse(gap > 0.01, 2 * N, N + 3) end model = Mat4f(I) transparency = false - backlight = 0f0 + backlight = 0.0f0 color = nothing => Texture color_map = nothing => Texture uv_map = nothing => Texture @@ -32,4 +32,4 @@ function draw_voxels(screen, main::VolumeTypes, data::Dict) return assemble_shader(data) end -@specialize \ No newline at end of file +@specialize diff --git a/GLMakie/src/glwindow.jl b/GLMakie/src/glwindow.jl index c40d6a23f93..2dbeaf6ce7b 100644 --- a/GLMakie/src/glwindow.jl +++ b/GLMakie/src/glwindow.jl @@ -7,8 +7,8 @@ struct SelectionID{T <: Integer} id::T index::T end -Base.convert(::Type{SelectionID{T}}, s::SelectionID) where T = SelectionID{T}(T(s.id), T(s.index)) -Base.zero(::Type{GLMakie.SelectionID{T}}) where T = SelectionID{T}(T(0), T(0)) +Base.convert(::Type{SelectionID{T}}, s::SelectionID) where {T} = SelectionID{T}(T(s.id), T(s.index)) +Base.zero(::Type{GLMakie.SelectionID{T}}) where {T} = SelectionID{T}(T(0), T(0)) mutable struct GLFramebuffer resolution::Observable{NTuple{2, Int}} @@ -25,16 +25,16 @@ Base.haskey(fb::GLFramebuffer, key::Symbol) = haskey(fb.buffers, key) Base.getindex(fb::GLFramebuffer, key::Symbol) = fb.buffer_ids[key] => fb.buffers[key] function getfallback(fb::GLFramebuffer, key::Symbol, fallback_key::Symbol) - haskey(fb, key) ? fb[key] : fb[fallback_key] + return haskey(fb, key) ? fb[key] : fb[fallback_key] end -function attach_framebuffer(t::Texture{T, 2}, attachment) where T - glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, t.id, 0) +function attach_framebuffer(t::Texture{T, 2}, attachment) where {T} + return glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, t.id, 0) end # attach texture as color attachment with automatic id picking -function attach_colorbuffer!(fb::GLFramebuffer, key::Symbol, t::Texture{T, 2}) where T +function attach_colorbuffer!(fb::GLFramebuffer, key::Symbol, t::Texture{T, 2}) where {T} if haskey(fb.buffer_ids, key) || haskey(fb.buffers, key) error("Key $key already exists.") end @@ -45,7 +45,7 @@ function attach_colorbuffer!(fb::GLFramebuffer, key::Symbol, t::Texture{T, 2}) w max_color_id = id end end - next_color_id = max_color_id + 0x1 + next_color_id = max_color_id + 0x01 if next_color_id > GL_COLOR_ATTACHMENT15 error("Ran out of color buffers.") end @@ -129,13 +129,13 @@ Makie.@noconstprop function GLFramebuffer(fb_size::NTuple{2, Int}) # To allow adding postprocessors in various combinations we need to keep # track of the buffer ids that are already in use. We may also want to reuse # buffers so we give them names for easy fetching. - buffer_ids = Dict{Symbol,GLuint}( - :color => GL_COLOR_ATTACHMENT0, + buffer_ids = Dict{Symbol, GLuint}( + :color => GL_COLOR_ATTACHMENT0, :objectid => GL_COLOR_ATTACHMENT1, :HDR_color => GL_COLOR_ATTACHMENT2, :OIT_weight => GL_COLOR_ATTACHMENT3, - :depth => GL_DEPTH_ATTACHMENT, - :stencil => GL_STENCIL_ATTACHMENT, + :depth => GL_DEPTH_ATTACHMENT, + :stencil => GL_STENCIL_ATTACHMENT, ) buffers = Dict{Symbol, Texture}( :color => color_buffer, @@ -184,7 +184,7 @@ function MonitorProperties(monitor::GLFW.Monitor) dpi = Vec(videomode.width * 25.4, videomode.height * 25.4) * sfactor ./ Vec{2, Float64}(physicalsize) videomode_supported = GLFW.GetVideoModes(monitor) - MonitorProperties(name, isprimary, position, physicalsize, videomode, videomode_supported, dpi, monitor) + return MonitorProperties(name, isprimary, position, physicalsize, videomode, videomode_supported, dpi, monitor) end was_destroyed(nw::GLFW.Window) = nw.handle == C_NULL @@ -197,11 +197,11 @@ function GLContext() end function ShaderAbstractions.native_switch_context!(x::GLFW.Window) - GLFW.MakeContextCurrent(x) + return GLFW.MakeContextCurrent(x) end function ShaderAbstractions.native_context_alive(x::GLFW.Window) - GLFW.is_initialized() && !was_destroyed(x) + return GLFW.is_initialized() && !was_destroyed(x) end function destroy!(nw::GLFW.Window) @@ -212,7 +212,7 @@ function destroy!(nw::GLFW.Window) GLFW.DestroyWindow(nw) nw.handle = C_NULL end - was_current && ShaderAbstractions.switch_context!() + return was_current && ShaderAbstractions.switch_context!() end function window_size(nw::GLFW.Window) @@ -228,7 +228,7 @@ function framebuffer_size(nw::GLFW.Window) return Tuple(GLFW.GetFramebufferSize(nw)) end function scale_factor(nw::GLFW.Window) - was_destroyed(nw) && return 1f0 + was_destroyed(nw) && return 1.0f0 return minimum(GLFW.GetWindowContentScale(nw)) end diff --git a/GLMakie/src/picking.jl b/GLMakie/src/picking.jl index cde1cd4d59f..f77c355fca7 100644 --- a/GLMakie/src/picking.jl +++ b/GLMakie/src/picking.jl @@ -1,4 +1,3 @@ - ################################################################################ ### Point picking ################################################################################ @@ -54,7 +53,7 @@ function Makie.pick(scene::Scene, screen::Screen, xy::Vec{2, Float64}) end function Makie.pick(scene::Scene, screen::Screen, rect::Rect2i) - map(pick_native(screen, rect)) do sid + return map(pick_native(screen, rect)) do sid if haskey(screen.cache2plot, sid.id) (screen.cache2plot[sid.id], sid.index) else @@ -88,7 +87,7 @@ function Makie.pick_closest(scene::Scene, screen::Screen, xy, range) id = SelectionID{Int}(0, 0) x, y = xy .* ppu .+ 1 .- Vec2f(x0, y0) for i in 1:dx, j in 1:dy - d = (x-i)^2 + (y-j)^2 + d = (x - i)^2 + (y - j)^2 sid = sids[i, j] if (d < min_dist) && (sid.id > 0) && haskey(screen.cache2plot, sid.id) min_dist = d @@ -130,7 +129,7 @@ function Makie.pick_sorted(scene::Scene, screen::Screen, xy, range) x, y = xy .* ppu .+ 1 .- Vec2f(x0, y0) for i in 1:dx, j in 1:dy if picks[i, j].id > 0 - d = (x-i)^2 + (y-j)^2 + d = (x - i)^2 + (y - j)^2 idx = findfirst(isequal(picks[i, j]), selected) if idx === nothing continue diff --git a/GLMakie/src/postprocessing.jl b/GLMakie/src/postprocessing.jl index 0195b040ae3..cd072f9bacb 100644 --- a/GLMakie/src/postprocessing.jl +++ b/GLMakie/src/postprocessing.jl @@ -16,7 +16,7 @@ function (sp::PostprocessPrerender)() return end -rcpframe(x) = 1f0 ./ Vec2f(x[1], x[2]) +rcpframe(x) = 1.0f0 ./ Vec2f(x[1], x[2]) struct PostProcessor{F} robjs::Vector{RenderObject} @@ -25,7 +25,7 @@ struct PostProcessor{F} end function empty_postprocessor(args...; kwargs...) - PostProcessor(RenderObject[], screen -> nothing, empty_postprocessor) + return PostProcessor(RenderObject[], screen -> nothing, empty_postprocessor) end @@ -72,12 +72,10 @@ function OIT_postprocessor(framebuffer, shader_cache) GLAbstraction.render(pass) end - PostProcessor(RenderObject[pass], full_render, OIT_postprocessor) + return PostProcessor(RenderObject[pass], full_render, OIT_postprocessor) end - - function ssao_postprocessor(framebuffer, shader_cache) # Add missing buffers if !haskey(framebuffer, :position) @@ -194,7 +192,7 @@ function ssao_postprocessor(framebuffer, shader_cache) glDisable(GL_SCISSOR_TEST) end - PostProcessor(RenderObject[pass1, pass2], full_render, ssao_postprocessor) + return PostProcessor(RenderObject[pass1, pass2], full_render, ssao_postprocessor) end """ @@ -208,7 +206,7 @@ function fxaa_postprocessor(framebuffer, shader_cache) if !haskey(framebuffer, :HDR_color) glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.id[1]) color_luma_buffer = Texture( - RGBA{N0f8}, size(framebuffer), minfilter=:linear, x_repeat=:clamp_to_edge + RGBA{N0f8}, size(framebuffer), minfilter = :linear, x_repeat = :clamp_to_edge ) luma_id = attach_colorbuffer!(framebuffer, :color_luma, color_luma_buffer) else @@ -260,7 +258,7 @@ function fxaa_postprocessor(framebuffer, shader_cache) GLAbstraction.render(pass2) end - PostProcessor(RenderObject[pass1, pass2], full_render, fxaa_postprocessor) + return PostProcessor(RenderObject[pass1, pass2], full_render, fxaa_postprocessor) end @@ -295,7 +293,7 @@ function to_screen_postprocessor(framebuffer, shader_cache, screen_fb_id = nothi GLAbstraction.render(pass) # copy postprocess end - PostProcessor(RenderObject[pass], full_render, to_screen_postprocessor) + return PostProcessor(RenderObject[pass], full_render, to_screen_postprocessor) end function destroy!(pp::PostProcessor) diff --git a/GLMakie/src/precompiles.jl b/GLMakie/src/precompiles.jl index 32072bce182..daeafe2d686 100644 --- a/GLMakie/src/precompiles.jl +++ b/GLMakie/src/precompiles.jl @@ -4,14 +4,13 @@ macro compile(block) return quote let figlike = $(esc(block)) - Makie.colorbuffer(figlike; px_per_unit=1) + Makie.colorbuffer(figlike; px_per_unit = 1) return nothing end end end - let @setup_workload begin x = rand(5) @@ -26,7 +25,7 @@ let shared_precompile = joinpath(base_path, "shared-precompile.jl") include(shared_precompile) try - display(plot(x); visible=false) + display(plot(x); visible = false) catch end Makie.CURRENT_FIGURE[] = nothing @@ -41,16 +40,16 @@ let screen = empty_screen(false, false, nothing) destroy!(screen) config = Makie.merge_screen_config(ScreenConfig, Dict{Symbol, Any}()) - screen = Screen(Scene(), config, nothing, MIME"image/png"(); visible=false, start_renderloop=false) + screen = Screen(Scene(), config, nothing, MIME"image/png"(); visible = false, start_renderloop = false) close(screen) - config = Makie.merge_screen_config(ScreenConfig, Dict{Symbol,Any}()) - screen = Screen(Scene(), config; visible=false, start_renderloop=false) + config = Makie.merge_screen_config(ScreenConfig, Dict{Symbol, Any}()) + screen = Screen(Scene(), config; visible = false, start_renderloop = false) close(screen) empty!(atlas_texture_cache) - closeall(; empty_shader=false) + closeall(; empty_shader = false) @assert isempty(SCREEN_REUSE_POOL) @assert isempty(ALL_SCREENS) @assert isempty(SINGLETON_SCREEN) @@ -60,18 +59,20 @@ let end precompile(Screen, (Scene, ScreenConfig)) -precompile(GLFramebuffer, (NTuple{2,Int},)) +precompile(GLFramebuffer, (NTuple{2, Int},)) precompile(glTexImage, (GLenum, Int, GLenum, Int, Int, Int, GLenum, GLenum, Ptr{Float32})) precompile(glTexImage, (GLenum, Int, GLenum, Int, Int, Int, GLenum, GLenum, Ptr{RGBAf})) precompile(glTexImage, (GLenum, Int, GLenum, Int, Int, Int, GLenum, GLenum, Ptr{RGBf})) precompile(glTexImage, (GLenum, Int, GLenum, Int, Int, Int, GLenum, GLenum, Ptr{RGBA{N0f8}})) -precompile(glTexImage, - (GLenum, Int, GLenum, Int, Int, Int, GLenum, GLenum, Ptr{GLAbstraction.DepthStencil_24_8})) -precompile(glTexImage, (GLenum, Int, GLenum, Int, Int, Int, GLenum, GLenum, Ptr{Vec{2,GLuint}})) +precompile( + glTexImage, + (GLenum, Int, GLenum, Int, Int, Int, GLenum, GLenum, Ptr{GLAbstraction.DepthStencil_24_8}) +) +precompile(glTexImage, (GLenum, Int, GLenum, Int, Int, Int, GLenum, GLenum, Ptr{Vec{2, GLuint}})) precompile(glTexImage, (GLenum, Int, GLenum, Int, Int, Int, GLenum, GLenum, Ptr{RGBA{Float16}})) precompile(glTexImage, (GLenum, Int, GLenum, Int, Int, Int, GLenum, GLenum, Ptr{N0f8})) -precompile(setindex!, (GLMakie.GLAbstraction.Texture{Float16,2}, Matrix{Float32}, Rect2{Int32})) -precompile(getindex, (Makie.Text{Tuple{Vector{Point{2,Float32}}}}, Symbol)) -precompile(getproperty, (Makie.Text{Tuple{Vector{Point{2,Float32}}}}, Symbol)) -precompile(plot!, (Makie.Text{Tuple{Vector{Point{2,Float32}}}},)) +precompile(setindex!, (GLMakie.GLAbstraction.Texture{Float16, 2}, Matrix{Float32}, Rect2{Int32})) +precompile(getindex, (Makie.Text{Tuple{Vector{Point{2, Float32}}}}, Symbol)) +precompile(getproperty, (Makie.Text{Tuple{Vector{Point{2, Float32}}}}, Symbol)) +precompile(plot!, (Makie.Text{Tuple{Vector{Point{2, Float32}}}},)) precompile(Base.getindex, (Attributes, Symbol)) diff --git a/GLMakie/src/rendering.jl b/GLMakie/src/rendering.jl index 4e6f9f65caf..cc70b629e3f 100644 --- a/GLMakie/src/rendering.jl +++ b/GLMakie/src/rendering.jl @@ -26,7 +26,7 @@ end """ Renders a single frame of a `window` """ -function render_frame(screen::Screen; resize_buffers=true) +function render_frame(screen::Screen; resize_buffers = true) nw = to_native(screen) ShaderAbstractions.switch_context!(nw) @@ -39,7 +39,7 @@ function render_frame(screen::Screen; resize_buffers=true) # return Makie.zvalue2d(plot) end - sort!(screen.renderlist; by=sortby) + sort!(screen.renderlist; by = sortby) # NOTE # The transparent color buffer is reused by SSAO and FXAA. Changing the diff --git a/GLMakie/src/screen.jl b/GLMakie/src/screen.jl index 5d2012b1187..86a9d87eb36 100644 --- a/GLMakie/src/screen.jl +++ b/GLMakie/src/screen.jl @@ -92,7 +92,8 @@ mutable struct ScreenConfig ssao::Bool, transparency_weight_scale::Number, max_lights::Int, - max_light_parameters::Int) + max_light_parameters::Int + ) return new( # Renderloop renderloop isa Makie.Automatic ? GLMakie.renderloop : renderloop, @@ -118,7 +119,8 @@ mutable struct ScreenConfig ssao, transparency_weight_scale, max_lights, - max_light_parameters) + max_light_parameters + ) end end @@ -134,7 +136,7 @@ Note that the `screen_config` can also be set permanently via `Makie.set_theme!( $(Base.doc(ScreenConfig)) """ -function activate!(; inline=LAST_INLINE[], screen_config...) +function activate!(; inline = LAST_INLINE[], screen_config...) if haskey(screen_config, :pause_rendering) error("pause_rendering got renamed to pause_renderloop.") end @@ -208,10 +210,10 @@ mutable struct Screen{GLWindow} <: MakieScreen screen = new{GLWindow}( glscreen, owns_glscreen, shader_cache, framebuffer, config, Threads.Atomic{Bool}(stop_renderloop), rendertask, BudgetedTimer(1.0 / 30.0), - Observable(0f0), screen2scene, + Observable(0.0f0), screen2scene, screens, renderlist, postprocessors, cache, cache2plot, Matrix{RGB{N0f8}}(undef, s), Observable(Makie.UnknownTickState), - Observable(true), Observable(0f0), nothing, reuse, true, false + Observable(true), Observable(0.0f0), nothing, reuse, true, false ) push!(ALL_SCREENS, screen) # track all created screens return screen @@ -226,7 +228,7 @@ Makie.isvisible(screen::Screen) = screen.config.visible # gets removed in destroy!(screen) const ALL_SCREENS = Set{Screen}() -Makie.@noconstprop function empty_screen(debugging::Bool; reuse=true, window=nothing) +Makie.@noconstprop function empty_screen(debugging::Bool; reuse = true, window = nothing) return empty_screen(debugging, reuse, window) end @@ -236,18 +238,18 @@ Makie.@noconstprop function empty_screen(debugging::Bool, reuse::Bool, window) if isnothing(window) windowhints = [ - (GLFW.SAMPLES, 0), - (GLFW.DEPTH_BITS, 0), + (GLFW.SAMPLES, 0), + (GLFW.DEPTH_BITS, 0), # SETTING THE ALPHA BIT IS REALLY IMPORTANT ON OSX, SINCE IT WILL JUST KEEP SHOWING A BLACK SCREEN # WITHOUT ANY ERROR -.- - (GLFW.ALPHA_BITS, 8), - (GLFW.RED_BITS, 8), - (GLFW.GREEN_BITS, 8), - (GLFW.BLUE_BITS, 8), + (GLFW.ALPHA_BITS, 8), + (GLFW.RED_BITS, 8), + (GLFW.GREEN_BITS, 8), + (GLFW.BLUE_BITS, 8), (GLFW.STENCIL_BITS, 0), - (GLFW.AUX_BUFFERS, 0), + (GLFW.AUX_BUFFERS, 0), (GLFW.SCALE_TO_MONITOR, true), # Windows & X11 (GLFW.SCALE_FRAMEBUFFER, true), # OSX & Wayland @@ -262,13 +264,15 @@ Makie.@noconstprop function empty_screen(debugging::Bool, reuse::Bool, window) debugging = debugging, ) catch e - @warn(""" - GLFW couldn't create an OpenGL window. - This likely means, you don't have an OpenGL capable Graphic Card, - or you don't have an OpenGL 3.3 capable video driver installed. - Have a look at the troubleshooting section in the GLMakie readme: - https://github.com/MakieOrg/Makie.jl/tree/master/GLMakie#troubleshooting-opengl. - """) + @warn( + """ + GLFW couldn't create an OpenGL window. + This likely means, you don't have an OpenGL capable Graphic Card, + or you don't have an OpenGL 3.3 capable video driver installed. + Have a look at the troubleshooting section in the GLMakie readme: + https://github.com/MakieOrg/Makie.jl/tree/master/GLMakie#troubleshooting-opengl. + """ + ) rethrow(e) end @@ -285,7 +289,7 @@ Makie.@noconstprop function empty_screen(debugging::Bool, reuse::Bool, window) empty_postprocessor(), empty_postprocessor(), empty_postprocessor(), - to_screen_postprocessor(fb, shader_cache) + to_screen_postprocessor(fb, shader_cache), ] screen = Screen( @@ -329,7 +333,7 @@ function reopen!(screen::Screen) return screen end -function screen_from_pool(debugging; window=nothing) +function screen_from_pool(debugging; window = nothing) screen = if isempty(SCREEN_REUSE_POOL) @debug("create empty screen for pool") empty_screen(debugging; window) @@ -346,22 +350,22 @@ function singleton_screen(debugging::Bool) if !isempty(SINGLETON_SCREEN) @debug("reusing singleton screen") screen = SINGLETON_SCREEN[1] - stop_renderloop!(screen; close_after_renderloop=false) + stop_renderloop!(screen; close_after_renderloop = false) empty!(screen) else @debug("new singleton screen") # reuse=false, because we "manually" re-use the singleton screen! - screen = empty_screen(debugging; reuse=false) + screen = empty_screen(debugging; reuse = false) push!(SINGLETON_SCREEN, screen) end return reopen!(screen) end function Makie.apply_screen_config!(screen::Screen, config::ScreenConfig, scene::Scene, args...) - apply_config!(screen, config) + return apply_config!(screen, config) end -function apply_config!(screen::Screen, config::ScreenConfig; start_renderloop::Bool=true) +function apply_config!(screen::Screen, config::ScreenConfig; start_renderloop::Bool = true) @debug("Applying screen config! to existing screen") glw = screen.glscreen @@ -420,7 +424,7 @@ function Screen(; # Screen config is managed by the current active theme, so managed by Makie config = Makie.merge_screen_config(ScreenConfig, Dict{Symbol, Any}(screen_config)) screen = screen_from_pool(config.debugging; window) - apply_config!(screen, config; start_renderloop=start_renderloop) + apply_config!(screen, config; start_renderloop = start_renderloop) if !isnothing(resolution) resize!(screen, resolution...) end @@ -432,12 +436,12 @@ function set_screen_visibility!(screen::Screen, visible::Bool) error(unimplemented_error) end - set_screen_visibility!(screen.glscreen, visible) + return set_screen_visibility!(screen.glscreen, visible) end function set_screen_visibility!(nw::GLFW.Window, visible::Bool) @assert nw.handle !== C_NULL - GLFW.set_visibility!(nw, visible) + return GLFW.set_visibility!(nw, visible) end function display_scene!(screen::Screen, scene::Scene) @@ -450,37 +454,43 @@ function display_scene!(screen::Screen, scene::Scene) return end -Makie.@noconstprop function Screen(scene::Scene; start_renderloop=true, screen_config...) +Makie.@noconstprop function Screen(scene::Scene; start_renderloop = true, screen_config...) config = Makie.merge_screen_config(ScreenConfig, Dict{Symbol, Any}(screen_config)) - return Screen(scene, config; start_renderloop=start_renderloop) + return Screen(scene, config; start_renderloop = start_renderloop) end # Open an interactive window -Makie.@noconstprop function Screen(scene::Scene, config::ScreenConfig; visible=nothing, - start_renderloop=true) +Makie.@noconstprop function Screen( + scene::Scene, config::ScreenConfig; visible = nothing, + start_renderloop = true + ) screen = singleton_screen(config.debugging) !isnothing(visible) && (config.visible = visible) - apply_config!(screen, config; start_renderloop=start_renderloop) + apply_config!(screen, config; start_renderloop = start_renderloop) display_scene!(screen, scene) return screen end # Screen to save a png/jpeg to file or io -Makie.@noconstprop function Screen(scene::Scene, config::ScreenConfig, io::Union{Nothing,String,IO}, - typ::MIME; visible=nothing, start_renderloop=false) +Makie.@noconstprop function Screen( + scene::Scene, config::ScreenConfig, io::Union{Nothing, String, IO}, + typ::MIME; visible = nothing, start_renderloop = false + ) screen = singleton_screen(config.debugging) !isnothing(visible) && (config.visible = visible) - apply_config!(screen, config; start_renderloop=start_renderloop) + apply_config!(screen, config; start_renderloop = start_renderloop) display_scene!(screen, scene) return screen end # Screen that is efficient for `colorbuffer(screen)` -Makie.@noconstprop function Screen(scene::Scene, config::ScreenConfig, ::Makie.ImageStorageFormat; - start_renderloop=false) +Makie.@noconstprop function Screen( + scene::Scene, config::ScreenConfig, ::Makie.ImageStorageFormat; + start_renderloop = false + ) screen = singleton_screen(config.debugging) config.visible = false - apply_config!(screen, config; start_renderloop=start_renderloop) + apply_config!(screen, config; start_renderloop = start_renderloop) display_scene!(screen, scene) return screen end @@ -505,11 +515,13 @@ function add_scene!(screen::Screen, scene::Scene) id = length(screen.screens) + 1 push!(screen.screens, (id, scene)) screen.requires_update = true - onany((args...) -> screen.requires_update = true, - scene, - scene.visible, scene.backgroundcolor, scene.clear, - scene.ssao.bias, scene.ssao.blur, scene.ssao.radius, scene.camera.projectionview, - scene.camera.resolution) + onany( + (args...) -> screen.requires_update = true, + scene, + scene.visible, scene.backgroundcolor, scene.clear, + scene.ssao.bias, scene.ssao.blur, scene.ssao.radius, scene.camera.projectionview, + scene.camera.resolution + ) return id end return @@ -524,6 +536,7 @@ function Makie.insertplots!(screen::Screen, scene::Scene) for s in scene.children insertplots!(screen, s) end + return end function Base.delete!(screen::Screen, scene::Scene) @@ -586,7 +599,7 @@ function destroy!(rob::RenderObject) for obs in rob.observables Observables.clear(obs) end - GLAbstraction.free(rob.vertexarray) + return GLAbstraction.free(rob.vertexarray) end function Base.delete!(screen::Screen, scene::Scene, plot::AbstractPlot) @@ -601,7 +614,7 @@ function Base.delete!(screen::Screen, scene::Scene, plot::AbstractPlot) renderobject = get(screen.cache, objectid(plot), nothing) if !isnothing(renderobject) destroy!(renderobject) - filter!(x-> x[3] !== renderobject, screen.renderlist) + filter!(x -> x[3] !== renderobject, screen.renderlist) delete!(screen.cache2plot, renderobject.id) end delete!(screen.cache, objectid(plot)) @@ -641,7 +654,7 @@ end function destroy!(screen::Screen) @debug("Destroy screen!") - close(screen; reuse=false) + close(screen; reuse = false) # wait for rendertask to finish # otherwise, during rendertask clean up we may run into a destroyed window wait(screen) @@ -665,14 +678,14 @@ end Closes screen and empties it. Doesn't destroy the screen and instead frees it to be re-used again, if `reuse=true`. """ -function Base.close(screen::Screen; reuse=true) +function Base.close(screen::Screen; reuse = true) @debug("Close screen!") set_screen_visibility!(screen, false) if screen.window_open[] # otherwise we trigger an infinite loop of closing screen.window_open[] = false end empty!(screen) - stop_renderloop!(screen; close_after_renderloop=false) + stop_renderloop!(screen; close_after_renderloop = false) if reuse && screen.reuse @debug("reusing screen!") @@ -685,7 +698,7 @@ function Base.close(screen::Screen; reuse=true) return end -function closeall(; empty_shader=true) +function closeall(; empty_shader = true) # Since we call closeall to reload any shader # We empty the shader source cache here if empty_shader @@ -733,7 +746,7 @@ function Base.resize!(screen::Screen, w::Int, h::Int) return nothing end -function fast_color_data!(dest::Array{RGB{N0f8}, 2}, source::Texture{T, 2}) where T +function fast_color_data!(dest::Array{RGB{N0f8}, 2}, source::Texture{T, 2}) where {T} GLAbstraction.bind(source) glPixelStorei(GL_PACK_ALIGNMENT, 1) glGetTexImage(source.texturetype, 0, GL_RGB, GL_UNSIGNED_BYTE, dest) @@ -759,7 +772,7 @@ heatmap(depth_color, colormap=:grays) """ function depthbuffer(screen::Screen) ShaderAbstractions.switch_context!(screen.glscreen) - render_frame(screen, resize_buffers=false) # let it render + render_frame(screen, resize_buffers = false) # let it render glFinish() # block until opengl is done rendering source = screen.framebuffer.buffers[:depth] depth = Matrix{Float32}(undef, size(source)) @@ -779,7 +792,7 @@ function Makie.colorbuffer(screen::Screen, format::Makie.ImageStorageFormat = Ma # we still need to poll though, to get all the newest events! pollevents(screen, Makie.BackendTick) # keep current buffer size to allows larger-than-window renders - render_frame(screen, resize_buffers=false) # let it render + render_frame(screen, resize_buffers = false) # let it render if screen.config.visible GLFW.SwapBuffers(to_native(screen)) else @@ -838,10 +851,10 @@ function start_renderloop!(screen::Screen) end function pause_renderloop!(screen::Screen) - screen.config.pause_renderloop = true + return screen.config.pause_renderloop = true end -function stop_renderloop!(screen::Screen; close_after_renderloop=screen.close_after_renderloop) +function stop_renderloop!(screen::Screen; close_after_renderloop = screen.close_after_renderloop) # don't double close when stopping renderloop c = screen.close_after_renderloop screen.close_after_renderloop = close_after_renderloop @@ -858,8 +871,8 @@ function stop_renderloop!(screen::Screen; close_after_renderloop=screen.close_af return end -function set_framerate!(screen::Screen, fps=30) - screen.config.framerate = fps +function set_framerate!(screen::Screen, fps = 30) + return screen.config.framerate = fps end function refreshwindowcb(screen, window) @@ -901,6 +914,7 @@ function vsynced_renderloop(screen) GC.safepoint() GLFW.SwapBuffers(to_native(screen)) end + return end function fps_renderloop(screen::Screen) @@ -917,6 +931,7 @@ function fps_renderloop(screen::Screen) GC.safepoint() sleep(screen.timer) end + return end function requires_update(screen::Screen) @@ -954,7 +969,7 @@ function on_demand_renderloop(screen::Screen) # last_time = t end cause = screen.stop_renderloop[] ? "stopped renderloop" : "closing window" - @debug("Leaving renderloop, cause: $(cause)") + return @debug("Leaving renderloop, cause: $(cause)") end function renderloop(screen) @@ -973,7 +988,7 @@ function renderloop(screen) fps_renderloop(screen) end catch e - @warn "error in renderloop" exception=(e, Base.catch_backtrace()) + @warn "error in renderloop" exception = (e, Base.catch_backtrace()) rethrow(e) end if screen.close_after_renderloop @@ -981,7 +996,7 @@ function renderloop(screen) @debug("Closing screen after quitting renderloop!") close(screen) catch e - @warn "error closing screen" exception=(e, Base.catch_backtrace()) + @warn "error closing screen" exception = (e, Base.catch_backtrace()) end end screen.rendertask = nothing @@ -990,7 +1005,7 @@ end function plot2robjs(screen::Screen, plot) plots = Makie.collect_atomic_plots(plot) - return map(x-> screen.cache[objectid(x)], plots) + return map(x -> screen.cache[objectid(x)], plots) end export plot2robjs diff --git a/GLMakie/test/glmakie_refimages.jl b/GLMakie/test/glmakie_refimages.jl index afc81dd8c17..7d5f53c66d2 100644 --- a/GLMakie/test/glmakie_refimages.jl +++ b/GLMakie/test/glmakie_refimages.jl @@ -8,7 +8,7 @@ using ReferenceTests.RNG @reference_test "Sampler type" begin # Directly access texture parameters: - x = Sampler(fill(to_color(:yellow), 100, 100), minfilter=:nearest) + x = Sampler(fill(to_color(:yellow), 100, 100), minfilter = :nearest) scene = image(x) # indexing will go straight to the GPU, while only transferring the changes st = Stepper(scene) @@ -26,21 +26,22 @@ end pos = Observable(RNG.rand(Point3f, 2)) rot = Observable(RNG.rand(Vec3f, 2)) color = Observable(RNG.rand(RGBf, 2)) - size = Observable(0.1*RNG.rand(2)) + size = Observable(0.1 * RNG.rand(2)) makenew = Observable(1) on(makenew) do i pos[] = RNG.rand(Point3f, i) rot[] = RNG.rand(Vec3f, i) color[] = RNG.rand(RGBf, i) - size[] = 0.1*RNG.rand(i) + size[] = 0.1 * RNG.rand(i) end - fig, ax, p = meshscatter(pos, - rotation=rot, - color=color, - markersize=size, - axis = (; scenekw = (;limits=Rect3f(Point3(0), Point3(1)))) + fig, ax, p = meshscatter( + pos, + rotation = rot, + color = color, + markersize = size, + axis = (; scenekw = (; limits = Rect3f(Point3(0), Point3(1)))) ) Record(fig, [10, 5, 100, 60, 177]) do i makenew[] = i @@ -49,18 +50,18 @@ end @reference_test "Explicit frame rendering" begin function update_loop(m, buff, screen) - for i = 1:20 + for i in 1:20 GLFW.PollEvents() - buff .= RNG.rand.(Point3f) .* 20f0 + buff .= RNG.rand.(Point3f) .* 20.0f0 m[1] = buff GLMakie.render_frame(screen) GLFW.SwapBuffers(GLMakie.to_native(screen)) glFinish() end end - fig, ax, meshplot = meshscatter(RNG.rand(Point3f, 10^4) .* 20f0; color=:black) - screen = display(GLMakie.Screen(;renderloop=(screen) -> nothing, start_renderloop=false, visible=false), fig.scene) - buff = RNG.rand(Point3f, 10^4) .* 20f0; + fig, ax, meshplot = meshscatter(RNG.rand(Point3f, 10^4) .* 20.0f0; color = :black) + screen = display(GLMakie.Screen(; renderloop = (screen) -> nothing, start_renderloop = false, visible = false), fig.scene) + buff = RNG.rand(Point3f, 10^4) .* 20.0f0 update_loop(meshplot, buff, screen) @test isnothing(screen.rendertask) GLMakie.destroy!(screen) @@ -73,11 +74,11 @@ end fig = Figure() left = LScene(fig[1, 1]) - contour!(left, [sin(i+j) * sin(j+k) * sin(i+k) for i in 1:10, j in 1:10, k in 1:10], enable_depth = true) - mesh!(left, Sphere(Point3f(5), 6f0), color=:black) + contour!(left, [sin(i + j) * sin(j + k) * sin(i + k) for i in 1:10, j in 1:10, k in 1:10], enable_depth = true) + mesh!(left, Sphere(Point3f(5), 6.0f0), color = :black) right = LScene(fig[1, 2]) volume!(right, [sin(2i) * sin(2j) * sin(2k) for i in 1:10, j in 1:10, k in 1:10], algorithm = :iso, enable_depth = true) - mesh!(right, Sphere(Point3f(5), 6.0f0); color=:black) + mesh!(right, Sphere(Point3f(5), 6.0f0); color = :black) fig end @@ -85,13 +86,13 @@ end angle2pos(phi) = Point3f(cosd(phi), sind(phi), 0) lights = [ AmbientLight(RGBf(0.1, 0.1, 0.1)), - SpotLight(RGBf(2,0,0), angle2pos(0), Vec3f(0, 0, -1), Vec2f(pi/5, pi/4)), - SpotLight(RGBf(0,2,0), angle2pos(120), Vec3f(0, 0, -1), Vec2f(pi/5, pi/4)), - SpotLight(RGBf(0,0,2), angle2pos(240), Vec3f(0, 0, -1), Vec2f(pi/5, pi/4)), - PointLight(RGBf(1,1,1), Point3f(-4, -4, -2.5), 10.0), - PointLight(RGBf(1,1,0), Point3f(-4, 4, -2.5), 10.0), - PointLight(RGBf(1,0,1), Point3f( 4, 4, -2.5), 10.0), - PointLight(RGBf(0,1,1), Point3f( 4, -4, -2.5), 10.0), + SpotLight(RGBf(2, 0, 0), angle2pos(0), Vec3f(0, 0, -1), Vec2f(pi / 5, pi / 4)), + SpotLight(RGBf(0, 2, 0), angle2pos(120), Vec3f(0, 0, -1), Vec2f(pi / 5, pi / 4)), + SpotLight(RGBf(0, 0, 2), angle2pos(240), Vec3f(0, 0, -1), Vec2f(pi / 5, pi / 4)), + PointLight(RGBf(1, 1, 1), Point3f(-4, -4, -2.5), 10.0), + PointLight(RGBf(1, 1, 0), Point3f(-4, 4, -2.5), 10.0), + PointLight(RGBf(1, 0, 1), Point3f(4, 4, -2.5), 10.0), + PointLight(RGBf(0, 1, 1), Point3f(4, -4, -2.5), 10.0), ] scene = Scene(size = (400, 400), camera = cam3d!, lights = lights) @@ -109,15 +110,15 @@ end angle2dir(phi) = Vec3f(cosd(phi), sind(phi), -2) lights = [ AmbientLight(RGBf(0.1, 0.1, 0.1)), - DirectionalLight(RGBf(1,0,0), angle2dir(0)), - DirectionalLight(RGBf(0,1,0), angle2dir(120)), - DirectionalLight(RGBf(0,0,1), angle2dir(240)), + DirectionalLight(RGBf(1, 0, 0), angle2dir(0)), + DirectionalLight(RGBf(0, 1, 0), angle2dir(120)), + DirectionalLight(RGBf(0, 0, 1), angle2dir(240)), ] scene = Scene(size = (400, 400), camera = cam3d!, center = false, lights = lights, backgroundcolor = :black) mesh!( - scene, Sphere(Point3f(0), 1f0), color = :white, shading = MultiLightShading, - specular = Vec3f(1), shininess = 16f0 + scene, Sphere(Point3f(0), 1.0f0), color = :white, shading = MultiLightShading, + specular = Vec3f(1), shininess = 16.0f0 ) update_cam!(scene, Vec3f(0, 0, 3), Vec3f(0, 0, 0), Vec3f(0, 1, 0)) scene @@ -128,8 +129,8 @@ end lights = Makie.AbstractLight[ RectLight(RGBf(0.5, 0, 0), Point3f(-0.5, -1, 2), Vec3f(3, 0, 0), Vec3f(0, 3, 0)), RectLight(RGBf(0, 0.5, 0), Rect2f(-1, 1, 1, 3)), - RectLight(RGBf(0, 0, 0.5), Point3f( 1, 0.5, 2), Vec3f(3, 0, 0), Vec3f(0, 3, 0)), - RectLight(RGBf(0.5, 0.5, 0.5), Point3f( 1, -1, 2), Vec3f(3, 0, 0), Vec3f(0, 3, 0), Vec3f(-0.3, 0.3, -1)), + RectLight(RGBf(0, 0, 0.5), Point3f(1, 0.5, 2), Vec3f(3, 0, 0), Vec3f(0, 3, 0)), + RectLight(RGBf(0.5, 0.5, 0.5), Point3f(1, -1, 2), Vec3f(3, 0, 0), Vec3f(0, 3, 0), Vec3f(-0.3, 0.3, -1)), ] # Test transformations translate!(lights[2], Vec3f(-1, 1, 2)) # translate to by default @@ -148,7 +149,7 @@ end # scatter/text shader xs = 20:20:280 ys = fill(170, length(xs)) - zs = range(3, 1, length=length(xs)) + zs = range(3, 1, length = length(xs)) scatter!(scene, xs, ys, zs, color = :blue, markersize = 40, fxaa = false) ys = fill(130, length(xs)) scatter!(scene, xs, ys, zs, color = :blue, markersize = 40, fxaa = true) @@ -158,7 +159,7 @@ end # lines/linesegments shader xs = 20:10:270 ys = [50 + shift for _ in 1:13 for shift in (-10, 10)] - zs = range(3, 1, length=length(xs)) + zs = range(3, 1, length = length(xs)) lines!(scene, xs, ys, zs, color = :blue, linewidth = 4, fxaa = false) ys = [20 + shift for _ in 1:13 for shift in (-10, 10)] lines!(scene, xs, ys, zs, color = :blue, linewidth = 4, fxaa = true) @@ -167,4 +168,4 @@ end mesh!(scene, Rect2f(0, 0, 300, 200), color = :red) scene -end \ No newline at end of file +end diff --git a/GLMakie/test/runtests.jl b/GLMakie/test/runtests.jl index 2aa9d1d5765..c7ad6a8c36f 100644 --- a/GLMakie/test/runtests.jl +++ b/GLMakie/test/runtests.jl @@ -11,7 +11,7 @@ if !GLMakie.ModernGL.enable_opengl_debugging @warn("TESTING WITHOUT OPENGL DEBUGGING") end -GLMakie.activate!(framerate=1.0, scalefactor=1.0) +GLMakie.activate!(framerate = 1.0, scalefactor = 1.0) @testset "mimes" begin Makie.inline!(true) @@ -42,11 +42,11 @@ end function check_tick(tick, state, count) @test tick.state == state @test tick.count == count - @test tick.time > 1e-9 - @test tick.delta_time > 1e-9 + @test tick.time > 1.0e-9 + @test tick.delta_time > 1.0e-9 end - f, a, p = scatter(rand(10)); + f, a, p = scatter(rand(10)) @test events(f).tick[] == Makie.Tick() filename = "$(tempname()).png" @@ -61,7 +61,7 @@ end rm(filename) end - f, a, p = scatter(rand(10)); + f, a, p = scatter(rand(10)) filename = "$(tempname()).mp4" try tick_record = Makie.Tick[] @@ -73,8 +73,8 @@ end for (i, tick) in enumerate(tick_record[start:end]) @test tick.state == Makie.OneTimeRenderTick - @test tick.count == i-1 - @test tick.time ≈ dt * (i-1) + @test tick.count == i - 1 + @test tick.time ≈ dt * (i - 1) @test tick.delta_time ≈ dt end finally @@ -82,7 +82,7 @@ end end # test destruction of tick overwrite - f, a, p = scatter(rand(10)); + f, a, p = scatter(rand(10)) let io = VideoStream(f) @test events(f).tick[] == Makie.Tick(Makie.OneTimeRenderTick, 0, 0.0, 1.0 / io.options.framerate) @@ -92,8 +92,8 @@ end events(f).tick[] = tick @test events(f).tick[] == tick - - f, a, p = scatter(rand(10)); + + f, a, p = scatter(rand(10)) tick_record = Makie.Tick[] on(t -> push!(tick_record, t), events(f).tick) screen = GLMakie.Screen(render_on_demand = true, framerate = 30.0, pause_rendering = false, visible = false) @@ -103,7 +103,7 @@ end sleep(0.1) GLMakie.closeall() - # Why does it start with a skipped tick? + # Why does it start with a skipped tick? i = 1 while tick_record[i].state == Makie.SkippedRenderTick check_tick(tick_record[1], Makie.SkippedRenderTick, i) @@ -114,14 +114,14 @@ end i += 1 while tick_record[i].state == Makie.SkippedRenderTick - check_tick(tick_record[i], Makie.SkippedRenderTick, i) - i += 1 - end + check_tick(tick_record[i], Makie.SkippedRenderTick, i) + i += 1 + end while (i <= length(tick_record)) && (tick_record[i].state == Makie.PausedRenderTick) check_tick(tick_record[i], Makie.PausedRenderTick, i) i += 1 end - @test i == length(tick_record)+1 -end \ No newline at end of file + @test i == length(tick_record) + 1 +end diff --git a/GLMakie/test/unit_tests.jl b/GLMakie/test/unit_tests.jl index c14d1ba7504..7fb71a7c1f8 100644 --- a/GLMakie/test/unit_tests.jl +++ b/GLMakie/test/unit_tests.jl @@ -9,7 +9,7 @@ end @testset "shader cache" begin GLMakie.closeall() screen = display(GLMakie.Screen(visible = false), Figure()) - cache = screen.shader_cache; + cache = screen.shader_cache # Postprocessing shaders @test length(cache.shader_cache) == 5 @test length(cache.template_cache) == 5 @@ -34,13 +34,13 @@ end @test length(cache.program_cache) == 11 # heatmap hasn't been compiled so one new program should be added - display(screen, heatmap([1,2,2.5,3], [1,2,2.5,3], rand(4,4))) + display(screen, heatmap([1, 2, 2.5, 3], [1, 2, 2.5, 3], rand(4, 4))) @test length(cache.shader_cache) == 20 @test length(cache.template_cache) == 20 @test length(cache.program_cache) == 12 # For second time no new shaders should be added - display(screen, heatmap([1,2,2.5,3], [1,2,2.5,3], rand(4,4))) + display(screen, heatmap([1, 2, 2.5, 3], [1, 2, 2.5, 3], rand(4, 4))) @test length(cache.shader_cache) == 20 @test length(cache.template_cache) == 20 @test length(cache.program_cache) == 12 @@ -63,7 +63,7 @@ end # A displayed figure should create a singleton screen and leave other # screens untouched - fig, ax, splot = scatter(1:4); + fig, ax, splot = scatter(1:4) screen2 = display(fig) @test screen !== screen2 @test GLMakie.ALL_SCREENS == Set([screen, screen2]) @@ -95,11 +95,11 @@ end @test isempty(events(ax.scene).window_open.listeners) # Test singleton screen replacement - fig, ax, p = scatter(1:4); + fig, ax, p = scatter(1:4) screen = display(fig) ptr = deepcopy(screen.glscreen.handle) @test isopen(screen) && (screen === GLMakie.SINGLETON_SCREEN[1]) - fig2, ax2, p2 = scatter(4:-1:1); + fig2, ax2, p2 = scatter(4:-1:1) screen2 = display(fig2) @test isopen(screen2) && (screen2 === GLMakie.SINGLETON_SCREEN[]) @test screen === screen2 @@ -110,25 +110,25 @@ end @testset "Pick a plot element or plot elements inside a rectangle" begin N = 100000 fig, ax, splot = scatter(1:N, 1:N) - limits!(ax, 99990,100000, 99990,100000) + limits!(ax, 99990, 100000, 99990, 100000) screen = display(GLMakie.Screen(visible = false), fig) # we don't really need the color buffer here, but this should be the best way right now to really # force a full render to happen GLMakie.Makie.colorbuffer(screen) # test for pick a single data point (with idx > 65535) - point_px = project_sp(ax.scene, Point2f(N-1,N-1)) - plot,idx = pick(ax.scene, point_px) - @test idx == N-1 + point_px = project_sp(ax.scene, Point2f(N - 1, N - 1)) + plot, idx = pick(ax.scene, point_px) + @test idx == N - 1 # test for pick a rectangle of data points (also with some indices > 65535) - rect = Rect2f(99990.5,99990.5,8,8) + rect = Rect2f(99990.5, 99990.5, 8, 8) origin_px = project_sp(ax.scene, Point(origin(rect))) tip_px = project_sp(ax.scene, Point(origin(rect) .+ widths(rect))) rect_px = Rect2i(round.(origin_px), round.(tip_px .- origin_px)) picks = unique(pick(ax.scene, rect_px)) # objects returned in plot_idx should be either grid lines (i.e. LineSegments) or Scatter points - @test all(pi-> pi[1] isa Union{LineSegments,Scatter, Makie.Mesh}, picks) + @test all(pi -> pi[1] isa Union{LineSegments, Scatter, Makie.Mesh}, picks) # scatter points should have indices equal to those in 99991:99998 scatter_plot_idx = filter(pi -> pi[1] isa Scatter, picks) @test Set(last.(scatter_plot_idx)) == Set(99991:99998) @@ -139,10 +139,10 @@ end @testset "empty!(fig)" begin GLMakie.closeall() fig = Figure() - ax = Axis(fig[1,1]) + ax = Axis(fig[1, 1]) heatmap!(ax, rand(4, 4)) - lines!(ax, 1:5, rand(5); linewidth=3) - text!(ax, [Point2f(2)], text=["hi"]) + lines!(ax, 1:5, rand(5); linewidth = 3) + text!(ax, [Point2f(2)], text = ["hi"]) screen = display(GLMakie.Screen(visible = false), fig) empty!(fig) @test screen in fig.scene.current_screens @@ -157,10 +157,10 @@ end @test robj.vertexarray.id == 0 end end - ax = Axis(fig[1,1]) + ax = Axis(fig[1, 1]) heatmap!(ax, rand(4, 4)) - lines!(ax, 1:5, rand(5); linewidth=3) - text!(ax, [Point2f(2)], text=["hi"]) + lines!(ax, 1:5, rand(5); linewidth = 3) + text!(ax, [Point2f(2)], text = ["hi"]) @testset "no freed object after replotting" begin for (_, _, robj) in screen.renderlist for (k, v) in robj.uniforms @@ -178,15 +178,15 @@ end @testset "empty!(ax)" begin GLMakie.closeall() fig = Figure() - ax = Axis(fig[1,1]) + ax = Axis(fig[1, 1]) hmp = heatmap!(ax, rand(4, 4)) - lp = lines!(ax, 1:5, rand(5); linewidth=3) - tp = text!(ax, [Point2f(2)], text=["hi"]) + lp = lines!(ax, 1:5, rand(5); linewidth = 3) + tp = text!(ax, [Point2f(2)], text = ["hi"]) screen = display(GLMakie.Screen(visible = false), fig) @test ax.scene.plots == [hmp, lp, tp] - robjs = map(x-> screen.cache[objectid(x)], [hmp, lp, tp.plots...]) + robjs = map(x -> screen.cache[objectid(x)], [hmp, lp, tp.plots...]) empty!(ax) @@ -201,8 +201,8 @@ end end heatmap!(ax, rand(4, 4)) - lines!(ax, 1:5, rand(5); linewidth=3) - text!(ax, [Point2f(2)], text=["hi"]) + lines!(ax, 1:5, rand(5); linewidth = 3) + text!(ax, [Point2f(2)], text = ["hi"]) @testset "no freed object after replotting" begin for (_, _, robj) in screen.renderlist for (k, v) in robj.uniforms @@ -223,7 +223,7 @@ end @testset "closing and redisplaying" begin GLMakie.closeall() fig = Figure() - ax = Axis(fig[1,1]) # only happens with axis + ax = Axis(fig[1, 1]) # only happens with axis # lines!(ax, 1:5, rand(5); linewidth=5) # but doesn't need a plot screen = display(GLMakie.Screen(visible = false), fig) GLMakie.closeall() @@ -234,11 +234,11 @@ end @testset "closing and redisplaying + resizing" begin GLMakie.closeall() fig = Figure() - ax = Axis(fig[1,1]) # only happens with axis + ax = Axis(fig[1, 1]) # only happens with axis screen = display(GLMakie.Screen(visible = false), fig) close(screen) screen = display(GLMakie.Screen(visible = false), fig) - resize!(fig, 800,601) + resize!(fig, 800, 601) @test true # test for no errors for now # GLMakie.destroy!(screen) end @@ -256,23 +256,23 @@ end GLMakie.closeall() set_theme!() screens = map(1:10) do i - fig = Figure(size=(500, 500)) - rng = Random.MersenneTwister(0) - ax, pl = image(fig[1, 1], 0..1, 0..1, rand(rng, 1000, 1000)) - scatter!(ax, rand(rng, Point2f, 1000), color=:red) - lines!(ax, rand(rng, Point2f, 1000), transparency=true) + fig = Figure(size = (500, 500)) + rng = Random.MersenneTwister(0) + ax, pl = image(fig[1, 1], 0 .. 1, 0 .. 1, rand(rng, 1000, 1000)) + scatter!(ax, rand(rng, Point2f, 1000), color = :red) + lines!(ax, rand(rng, Point2f, 1000), transparency = true) ax3d, pl = mesh(fig[1, 2], Sphere(Point3f(0), 1)) - meshscatter!(ax3d, rand(rng, Point3f, 100), color=:red) + meshscatter!(ax3d, rand(rng, Point3f, 100), color = :red) heatmap(fig[2, 1], rand(rng, 100, 100)) - surface(fig[2, 2], 0..1, 0..1, rand(rng, 1000, 1000) ./ 2) + surface(fig[2, 2], 0 .. 1, 0 .. 1, rand(rng, 1000, 1000) ./ 2) - display(GLMakie.Screen(visible=false, scalefactor=1), fig) + display(GLMakie.Screen(visible = false, scalefactor = 1), fig) end images = map(Makie.colorbuffer, screens) - @test all(x-> x ≈ first(images), images) + @test all(x -> x ≈ first(images), images) @test Base.summarysize(screens) / 10^6 > 60 foreach(close, screens) @@ -296,7 +296,7 @@ end @test (Base.summarysize(screen) / 10^6) < 1.4 end # All should go to pool after close - @test all(x-> x in GLMakie.SCREEN_REUSE_POOL, screens) + @test all(x -> x in GLMakie.SCREEN_REUSE_POOL, screens) GLMakie.closeall() # now every screen should be gone @@ -310,9 +310,9 @@ end W, H = 400, 400 N = 51 - x = collect(range(0.0, 2π, length=N)) + x = collect(range(0.0, 2π, length = N)) y = sin.(x) - fig, ax, pl = scatter(x, y, figure = (; size = (W, H))); + fig, ax, pl = scatter(x, y, figure = (; size = (W, H))) hidedecorations!(ax) # On OSX, the native window size has an underlying scale factor that we need to account @@ -324,15 +324,15 @@ end end screen = display(GLMakie.Screen(visible = true, scalefactor = 2), fig) - @test screen.scalefactor[] === 2f0 - @test screen.px_per_unit[] === 2f0 # inherited from scale factor + @test screen.scalefactor[] === 2.0f0 + @test screen.px_per_unit[] === 2.0f0 # inherited from scale factor @test size(screen.framebuffer) == (2W, 2H) @test GLMakie.window_size(screen.glscreen) == scaled(screen, (W, H)) # check that picking works through the resized GL buffers GLMakie.Makie.colorbuffer(screen) # force render # - point pick - point_px = project_sp(ax.scene, Point2f(x[end÷2], y[end÷2])) + point_px = project_sp(ax.scene, Point2f(x[end ÷ 2], y[end ÷ 2])) elem, idx = pick(ax.scene, point_px) @test elem === pl @test idx == length(x) ÷ 2 @@ -342,7 +342,7 @@ end quadrant = Rect2i(round.(bottom_px)..., round.(right_px - bottom_px)...) picks = pick(ax.scene, quadrant) points = Set(Int(p[2]) for p in picks if p[1] isa Scatter) - @test points == Set(((N+1)÷2):N) + @test points == Set(((N + 1) ÷ 2):N) # - pick sorted xy_px = project_sp(ax.scene, Point2f(x[1], y[1])) picks = GLMakie.Makie.pick_sorted(ax.scene, screen, xy_px, 50) @@ -351,8 +351,8 @@ end # render at lower resolution screen = display(GLMakie.Screen(visible = false, scalefactor = 2, px_per_unit = 1), fig) - @test screen.scalefactor[] === 2f0 - @test screen.px_per_unit[] === 1f0 + @test screen.scalefactor[] === 2.0f0 + @test screen.px_per_unit[] === 1.0f0 @test size(screen.framebuffer) == (W, H) # decrease the scale factor after-the-fact @@ -367,7 +367,7 @@ end # save at current size @test screen.px_per_unit[] == 1 - save(file, fig; px_per_unit=1) + save(file, fig; px_per_unit = 1) img = load(file) @test size(img) == (W, H) # save with a different resolution @@ -377,7 +377,7 @@ end # writing to file should not effect the visible figure @test_broken screen.px_per_unit[] == 1 # Make sure switching back resizes the screen correctly! - save(file, fig; px_per_unit=1) + save(file, fig; px_per_unit = 1) img = load(file) @test size(img) == (W, H) end @@ -421,10 +421,10 @@ end print(Int(screen.scalefactor[])) """ cmd = ``` - $(Base.julia_cmd()) - --project=$(Base.active_project()) - --eval $jlscript - ``` + $(Base.julia_cmd()) + --project=$(Base.active_project()) + --eval $jlscript + ``` scalefactor = readchomp(cmd) @test scalefactor == "2" finally @@ -446,7 +446,7 @@ end height = 800 f = Figure(; size = (width, height)) - vio = Makie.VideoStream(f; format="mp4", px_per_unit=2.0, backend=GLMakie) + vio = Makie.VideoStream(f; format = "mp4", px_per_unit = 2.0, backend = GLMakie) @test size(vio.screen) == size(f.scene) .* 2 @@ -459,7 +459,7 @@ end @testset "image size changes" begin s = Scene() - im = image!(s, 0..10, 0..10, zeros(RGBf, 10, 20)) + im = image!(s, 0 .. 10, 0 .. 10, zeros(RGBf, 10, 20)) display(GLMakie.Screen(visible = false), s) im[3][] = zeros(RGBf, 20, 10) # same length, different size im[3][] = zeros(RGBf, 15, 5) # smaller size @@ -468,21 +468,21 @@ end end @testset "Verify camera uniforms after delete" begin - f=Figure(size=(200,200)) + f = Figure(size = (200, 200)) screen = display(f, visible = false) - ax=Axis(f[1,1]) - lines!(ax,sin.(0.0:0.1:2pi)) - text!(ax,10.0,0.0,text="sine wave") + ax = Axis(f[1, 1]) + lines!(ax, sin.(0.0:0.1:2pi)) + text!(ax, 10.0, 0.0, text = "sine wave") empty!(ax) ids = [robj.id for (_, _, robj) in screen.renderlist] lines!(ax, sin.(0.0:0.1:2pi)) - text!(ax,10.0,0.0,text="sine wave") + text!(ax, 10.0, 0.0, text = "sine wave") resize!(current_figure(), 800, 800) robj = filter(x -> !(x.id in ids), last.(screen.renderlist))[1] cam = ax.scene.camera - @test robj.uniforms[:resolution][] == screen.px_per_unit[] * cam.resolution[] + @test robj.uniforms[:resolution][] == screen.px_per_unit[] * cam.resolution[] @test robj.uniforms[:projectionview][] == cam.projectionview[] end diff --git a/MakieCore/src/attributes.jl b/MakieCore/src/attributes.jl index 3195f77ec40..96541a7b420 100644 --- a/MakieCore/src/attributes.jl +++ b/MakieCore/src/attributes.jl @@ -1,4 +1,3 @@ - const Theme = Attributes Base.broadcastable(x::AbstractScene) = Ref(x) @@ -10,9 +9,9 @@ value_convert(x::Observables.AbstractObservable) = Observables.observe(x) value_convert(@nospecialize(x)) = x # We transform a tuple of observables into a Observable(tuple(values...)) -function value_convert(x::NTuple{N, Union{Any, Observables.AbstractObservable}}) where N +function value_convert(x::NTuple{N, Union{Any, Observables.AbstractObservable}}) where {N} result = Observable(to_value.(x)) - onany((args...)-> args, x...) + onany((args...) -> args, x...) return result end @@ -20,7 +19,7 @@ value_convert(x::NamedTuple) = Attributes(x) # Version of `convert(Observable{Any}, obj)` that doesn't require runtime dispatch node_any(@nospecialize(obj)) = isa(obj, Observable{Any}) ? obj : - isa(obj, Observable) ? convert(Observable{Any}, obj) : Observable{Any}(obj) + isa(obj, Observable) ? convert(Observable{Any}, obj) : Observable{Any}(obj) node_pairs(pair::Union{Pair, Tuple{Any, Any}}) = (pair[1] => node_any(value_convert(pair[2]))) node_pairs(pairs) = (node_pairs(pair) for pair in pairs) @@ -80,22 +79,22 @@ end Base.merge(target::Attributes, args::Attributes...) = merge!(deepcopy(target), args...) function Base.getproperty(x::Union{Attributes, AbstractPlot}, key::Symbol) - if hasfield(typeof(x), key) + return if hasfield(typeof(x), key) getfield(x, key) else getindex(x, key) end end -function Base.setproperty!(x::Union{Attributes,AbstractPlot}, key::Symbol, value::NamedTuple) - x[key] = Attributes(value) +function Base.setproperty!(x::Union{Attributes, AbstractPlot}, key::Symbol, value::NamedTuple) + return x[key] = Attributes(value) end function Base.setindex!(x::Attributes, value::NamedTuple, key::Symbol) return x[key] = Attributes(value) end function Base.setproperty!(x::Union{Attributes, AbstractPlot}, key::Symbol, value) - if hasfield(typeof(x), key) + return if hasfield(typeof(x), key) setfield!(x, key, value) else setindex!(x, value, key) @@ -110,7 +109,7 @@ function Base.getindex(x::Attributes, key::Symbol) end function Base.setindex!(x::Attributes, value, key::Symbol) - if haskey(x, key) + return if haskey(x, key) x.attributes[key][] = value else x.attributes[key] = node_any(value) @@ -123,7 +122,7 @@ end _indent_attrs(s, n) = join(split(s, '\n'), "\n" * " "^n) -function Base.show(io::IO,::MIME"text/plain", attr::Attributes) +function Base.show(io::IO, ::MIME"text/plain", attr::Attributes) io = IOContext(io, :compact => true) @@ -150,6 +149,7 @@ function Base.show(io::IO,::MIME"text/plain", attr::Attributes) print(io, to_value(attr[k])) end end + return end Base.show(io::IO, attr::Attributes) = show(io, MIME"text/plain"(), attr) @@ -170,9 +170,9 @@ function Base.get!(f::Function, x::AttributeOrPlot, key::Symbol) return x[key] end end -Base.get!(x::AttributeOrPlot, key::Symbol, default) = get!(()-> default, x, key) +Base.get!(x::AttributeOrPlot, key::Symbol, default) = get!(() -> default, x, key) Base.get(f::Function, x::AttributeOrPlot, key::Symbol) = haskey(x, key) ? x[key] : f() -Base.get(x::AttributeOrPlot, key::Symbol, default) = get(()-> default, x, key) +Base.get(x::AttributeOrPlot, key::Symbol, default) = get(() -> default, x, key) # This is a bit confusing, since for a plot it returns the attribute from the arguments # and not a plot for integer indexing. But, we want to treat plots as "atomic" @@ -198,13 +198,13 @@ end function Base.getindex(x::AttributeOrPlot, key::Symbol, key2::Symbol, rest::Symbol...) dict = to_value(x[key]) dict isa Attributes || error("Trying to access $(typeof(dict)) with multiple keys: $key, $key2, $(rest)") - dict[key2, rest...] + return dict[key2, rest...] end function Base.setindex!(x::AttributeOrPlot, value, key::Symbol, key2::Symbol, rest::Symbol...) dict = to_value(x[key]) dict isa Attributes || error("Trying to access $(typeof(dict)) with multiple keys: $key, $key2, $(rest)") - dict[key2, rest...] = value + return dict[key2, rest...] = value end function Base.setindex!(x::AbstractPlot, value, key::Symbol) @@ -230,7 +230,7 @@ function Base.setindex!(x::AbstractPlot, value::Observable, key::Symbol) end # a few shortcut functions to make attribute conversion easier -function get_attribute(dict, key, default=nothing) +function get_attribute(dict, key, default = nothing) if haskey(dict, key) value = to_value(dict[key]) value isa Automatic && return default diff --git a/MakieCore/src/basic_plots.jl b/MakieCore/src/basic_plots.jl index fe973814e00..2b698368b28 100644 --- a/MakieCore/src/basic_plots.jl +++ b/MakieCore/src/basic_plots.jl @@ -45,13 +45,13 @@ function generic_plot_attributes(attr) inspector_label = attr[:inspector_label], inspector_clear = attr[:inspector_clear], inspector_hover = attr[:inspector_hover], - clip_planes = attr[:clip_planes] + clip_planes = attr[:clip_planes], ) end function mixin_generic_plot_attributes() - @DocumentedAttributes begin + return @DocumentedAttributes begin transformation = automatic "Sets a model matrix for the plot. This overrides adjustments made with `translate!`, `rotate!` and `scale!`." model = automatic @@ -118,12 +118,12 @@ function colormap_attributes(attr) lowclip = attr[:lowclip], highclip = attr[:highclip], nan_color = attr[:nan_color], - alpha = attr[:alpha] + alpha = attr[:alpha], ) end function mixin_colormap_attributes() - @DocumentedAttributes begin + return @DocumentedAttributes begin """ Sets the colormap that is sampled for numeric `color`s. `PlotUtils.cgrad(...)`, `Makie.Reverse(any_colormap)` can be used as well, or any symbol from ColorBrewer or PlotUtils. @@ -162,8 +162,8 @@ function shading_attributes!(attr) attr[:diffuse] = 1.0 attr[:specular] = 0.2 attr[:shininess] = 32.0f0 - attr[:backlight] = 0f0 - attr[:ssao] = false + attr[:backlight] = 0.0f0 + return attr[:ssao] = false end function shading_attributes(attr) @@ -173,12 +173,12 @@ function shading_attributes(attr) specular = attr[:specular], shininess = attr[:shininess], backlight = attr[:backlight], - ssao = attr[:ssao] + ssao = attr[:ssao], ) end function mixin_shading_attributes() - @DocumentedAttributes begin + return @DocumentedAttributes begin "Sets the lighting algorithm used. Options are `NoShading` (no lighting), `FastShading` (AmbientLight + PointLight) or `MultiLightShading` (Multiple lights, GLMakie only). Note that this does not affect RPRMakie." shading = automatic "Sets how strongly the red, green and blue channel react to diffuse (scattered) light." @@ -188,7 +188,7 @@ function mixin_shading_attributes() "Sets how sharp the reflection is." shininess = 32.0f0 "Sets a weight for secondary light calculation with inverted normals." - backlight = 0f0 + backlight = 0.0f0 "RPRMakie only attribute to set complex RadeonProRender materials. *Warning*, how to set an RPR material may change and other backends will ignore this attribute" material = nothing @@ -205,7 +205,7 @@ calculated_attributes!(trait, plot) = nothing `calculated_attributes!(plot::AbstractPlot)` Fill in values that can only be calculated when we have all other attributes filled """ -calculated_attributes!(plot::T) where T = calculated_attributes!(T, plot) +calculated_attributes!(plot::T) where {T} = calculated_attributes!(T, plot) """ image(x, y, image) @@ -214,9 +214,10 @@ calculated_attributes!(plot::T) where T = calculated_attributes!(T, plot) Plots an image on a rectangle bounded by `x` and `y` (defaults to size of image). """ @recipe Image ( - x::EndPoints, - y::EndPoints, - image::AbstractMatrix{<:Union{FloatType,Colorant}}) begin + x::EndPoints, + y::EndPoints, + image::AbstractMatrix{<:Union{FloatType, Colorant}}, +) begin "Sets whether colors should be interpolated between pixels." interpolate = true mixin_generic_plot_attributes()... @@ -262,9 +263,11 @@ If `x` and `y` are omitted with a matrix argument, they default to `x, y = axes( Note that `heatmap` is slower to render than `image` so `image` should be preferred for large, regularly spaced grids. """ -@recipe Heatmap (x::Union{EndPoints,RealVector, RealMatrix}, - y::Union{EndPoints,RealVector, RealMatrix}, - values::AbstractMatrix{<:Union{FloatType,Colorant}}) begin +@recipe Heatmap ( + x::Union{EndPoints, RealVector, RealMatrix}, + y::Union{EndPoints, RealVector, RealMatrix}, + values::AbstractMatrix{<:Union{FloatType, Colorant}}, +) begin "Sets whether colors should be interpolated" interpolate = false mixin_generic_plot_attributes()... @@ -285,11 +288,11 @@ Available algorithms are: * `:indexedabsorption` => IndexedAbsorptionRGBA """ @recipe Volume ( - x::EndPoints, - y::EndPoints, - z::EndPoints, - volume::AbstractArray{Float32,3} - ) begin + x::EndPoints, + y::EndPoints, + z::EndPoints, + volume::AbstractArray{Float32, 3}, +) begin "Sets the volume algorithm that is used." algorithm = :mip "Sets the target value for the IsoValue algorithm." @@ -301,7 +304,7 @@ Available algorithms are: "Enables depth write for Volume, so that volume correctly occludes other objects." enable_depth = true "Absorption multiplier for algorithm=:absorption. This changes how much light each voxel absorbs." - absorption = 1f0 + absorption = 1.0f0 mixin_generic_plot_attributes()... mixin_shading_attributes()... mixin_colormap_attributes()... @@ -417,7 +420,7 @@ end Plots a 3D or 2D mesh. Supported `mesh_object`s include `Mesh` types from [GeometryBasics.jl](https://github.com/JuliaGeometry/GeometryBasics.jl). """ -@recipe Mesh (mesh::Union{AbstractVector{<:GeometryBasics.Mesh},GeometryBasics.Mesh,GeometryBasics.MetaMesh},) begin +@recipe Mesh (mesh::Union{AbstractVector{<:GeometryBasics.Mesh}, GeometryBasics.Mesh, GeometryBasics.MetaMesh},) begin "Sets the color of the mesh. Can be a `Vector{<:Colorant}` for per vertex colors or a single `Colorant`. A `Matrix{<:Colorant}` can be used to color the mesh with a texture, which requires the mesh to contain texture coordinates." color = @inherit patchcolor "sets whether colors should be interpolated" @@ -488,7 +491,7 @@ Plots a marker for each element in `(x, y, z)`, `(x, y)`, or `positions`. end function deprecated_attributes(::Type{<:Scatter}) - ( + return ( (; attribute = :rotations, message = "`rotations` has been renamed to `rotation` for consistency in Makie v0.21.", error = true), ) end @@ -530,7 +533,7 @@ Plots a mesh for each element in `(x, y, z)`, `(x, y)`, or `positions` (similar end function deprecated_attributes(::Type{<:MeshScatter}) - ( + return ( (; attribute = :rotations, message = "`rotations` has been renamed to `rotation` for consistency in Makie v0.21.", error = true), ) end @@ -586,7 +589,7 @@ Plots one or multiple texts passed via the `text` keyword. end function deprecated_attributes(::Type{<:Text}) - ( + return ( (; attribute = :textsize, message = "`textsize` has been renamed to `fontsize` in Makie v0.19. Please change all occurrences of `textsize` to `fontsize` or revert back to an earlier version.", error = true), ) end @@ -699,7 +702,7 @@ Draws a wireframe, either interpreted as a surface or as a mesh. """ @recipe Wireframe begin documented_attributes(LineSegments)... - depth_shift = -1f-5 + depth_shift = -1.0f-5 end """ @@ -760,7 +763,7 @@ or other array-like output. true the directions are normalized, skipping this scaling.""" normalize = false """Scales the length of the arrow tail.""" - lengthscale = 1f0 + lengthscale = 1.0f0 """Defines the number of angle subdivisions used when generating the arrow head and tail meshes. Consider lowering this if you have performance diff --git a/MakieCore/src/conversion.jl b/MakieCore/src/conversion.jl index 09d91fd9f9b..04058f8f613 100644 --- a/MakieCore/src/conversion.jl +++ b/MakieCore/src/conversion.jl @@ -1,5 +1,3 @@ - - """ convert_attribute(value, attribute::Key[, plottype::Key]) @@ -37,7 +35,7 @@ Plots with the `PointBased` trait convert their input data to a `Vector{Point{D, Float32}}`. """ struct PointBased <: ConversionTrait end -conversion_trait(::Type{<: XYBased}) = PointBased() +conversion_trait(::Type{<:XYBased}) = PointBased() """ GridBased <: ConversionTrait @@ -63,7 +61,7 @@ See also: [`CellGrid`](@ref), [`ImageLike`](@ref) Used for: Surface """ struct VertexGrid <: GridBased end -conversion_trait(::Type{<: Surface}) = VertexGrid() +conversion_trait(::Type{<:Surface}) = VertexGrid() """ CellGrid() <: GridBased <: ConversionTrait @@ -77,7 +75,7 @@ See also: [`VertexGrid`](@ref), [`ImageLike`](@ref) Used for: Heatmap """ struct CellGrid <: GridBased end -conversion_trait(::Type{<: Heatmap}) = CellGrid() +conversion_trait(::Type{<:Heatmap}) = CellGrid() """ ImageLike() <: ConversionTrait @@ -90,12 +88,12 @@ See also: [`CellGrid`](@ref), [`VertexGrid`](@ref) Used for: Image """ struct ImageLike <: ConversionTrait end -conversion_trait(::Type{<: Image}) = ImageLike() +conversion_trait(::Type{<:Image}) = ImageLike() # Rect2f(xmin, ymin, xmax, ymax) struct VolumeLike <: ConversionTrait end -conversion_trait(::Type{<: Volume}) = VolumeLike() +conversion_trait(::Type{<:Volume}) = VolumeLike() function convert_arguments end diff --git a/MakieCore/src/recipes.jl b/MakieCore/src/recipes.jl index 8f396c12538..5cc409df8bc 100644 --- a/MakieCore/src/recipes.jl +++ b/MakieCore/src/recipes.jl @@ -5,16 +5,16 @@ to_func_name(x::Symbol) = Symbol(lowercase(string(x))) # Will get overloaded by recipe Macro plotsym(x) = :plot -function func2string(func::F) where F <: Function - string(F.name.mt.name) +function func2string(func::F) where {F <: Function} + return string(F.name.mt.name) end -plotfunc(::Plot{F}) where F = F -plotfunc(::Type{<: AbstractPlot{Func}}) where Func = Func -plotfunc(::T) where T <: AbstractPlot = plotfunc(T) +plotfunc(::Plot{F}) where {F} = F +plotfunc(::Type{<:AbstractPlot{Func}}) where {Func} = Func +plotfunc(::T) where {T <: AbstractPlot} = plotfunc(T) function plotfunc(f::Function) if endswith(string(nameof(f)), "!") - name = Symbol(string(nameof(f))[begin:end-1]) + name = Symbol(string(nameof(f))[begin:(end - 1)]) return getproperty(parentmodule(f), name) else return f @@ -33,12 +33,12 @@ function plotfunc!(x) return getproperty(parentmodule(F), name) end -func2type(x::T) where T = func2type(T) -func2type(x::Type{<: AbstractPlot}) = x +func2type(x::T) where {T} = func2type(T) +func2type(x::Type{<:AbstractPlot}) = x func2type(f::Function) = Plot{plotfunc(f)} -plotkey(::Type{<: AbstractPlot{Typ}}) where Typ = Symbol(lowercase(func2string(Typ))) -plotkey(::T) where T <: AbstractPlot = plotkey(T) +plotkey(::Type{<:AbstractPlot{Typ}}) where {Typ} = Symbol(lowercase(func2string(Typ))) +plotkey(::T) where {T <: AbstractPlot} = plotkey(T) plotkey(::Nothing) = :scatter plotkey(any) = nothing @@ -54,27 +54,26 @@ function _create_plot end function _create_plot! end - plot(args...; kw...) = _create_plot(plot, Dict{Symbol, Any}(kw), args...) plot!(args...; kw...) = _create_plot!(plot, Dict{Symbol, Any}(kw), args...) """ Each argument can be named for a certain plot type `P`. Falls back to `arg1`, `arg2`, etc. """ -function argument_names(plot::P) where {P<:AbstractPlot} - argument_names(P, length(plot.converted)) +function argument_names(plot::P) where {P <: AbstractPlot} + return argument_names(P, length(plot.converted)) end function argument_names(::Type{<:AbstractPlot}, num_args::Integer) # this is called in the indexing function, so let's be a bit efficient - ntuple(i -> Symbol("arg$i"), num_args) + return ntuple(i -> Symbol("arg$i"), num_args) end # Since we can use Plot like a scene in some circumstances, we define this alias theme(x::SceneLike, args...) = theme(x.parent, args...) theme(x::AbstractScene) = x.theme -theme(x::AbstractScene, key; default=nothing) = deepcopy(get(x.theme, key, default)) -theme(x::AbstractPlot, key; default=nothing) = deepcopy(get(x.attributes, key, default)) +theme(x::AbstractScene, key; default = nothing) = deepcopy(get(x.theme, key, default)) +theme(x::AbstractPlot, key; default = nothing) = deepcopy(get(x.attributes, key, default)) Attributes(x::AbstractPlot) = x.attributes @@ -189,7 +188,7 @@ macro recipe(theme_func, Tsym::Symbol, args::Symbol...) funcname = esc(funcname_sym) expr = quote $(funcname)() = not_implemented_for($funcname) - const $(PlotType){$(esc(:ArgType))} = Plot{$funcname,$(esc(:ArgType))} + const $(PlotType){$(esc(:ArgType))} = Plot{$funcname, $(esc(:ArgType))} $(MakieCore).plotsym(::Type{<:$(PlotType)}) = $(QuoteNode(Tsym)) Core.@__doc__ ($funcname)(args...; kw...) = _create_plot($funcname, Dict{Symbol, Any}(kw), args...) ($funcname!)(args...; kw...) = _create_plot!($funcname, Dict{Symbol, Any}(kw), args...) @@ -206,7 +205,7 @@ macro recipe(theme_func, Tsym::Symbol, args::Symbol...) ), ) end - expr + return expr end function attribute_names end @@ -215,7 +214,7 @@ function documented_attributes end # this can be used for inheriting from other attribute_names(_) = nothing Base.@kwdef struct AttributeMetadata - docstring::Union{Nothing,String} + docstring::Union{Nothing, String} default_value::Any default_expr::String # stringified expression, just needed for docs purposes end @@ -227,7 +226,7 @@ update_metadata(am1::AttributeMetadata, am2::AttributeMetadata) = AttributeMetad ) struct DocumentedAttributes - d::Dict{Symbol,AttributeMetadata} + d::Dict{Symbol, AttributeMetadata} end struct Inherit @@ -323,12 +322,14 @@ macro DocumentedAttributes(expr::Expr) # and is inserted at the start of the final code block gsym = gensym("mixin") mixin = only(attr.args) - push!(mixin_exprs, quote - $gsym = $(esc(mixin)) - if !($gsym isa DocumentedAttributes) - error("Mixin was not a DocumentedAttributes but $($gsym)") + push!( + mixin_exprs, quote + $gsym = $(esc(mixin)) + if !($gsym isa DocumentedAttributes) + error("Mixin was not a DocumentedAttributes but $($gsym)") + end end - end) + ) # docstrings and default expressions of the mixed in # DocumentedAttributes are inserted @@ -346,24 +347,24 @@ macro DocumentedAttributes(expr::Expr) end end - quote + return quote $(mixin_exprs...) - d = Dict{Symbol,AttributeMetadata}() + d = Dict{Symbol, AttributeMetadata}() $(metadata_exprs...) DocumentedAttributes(d) end end function is_attribute(T::Type{<:Plot}, sym::Symbol) - sym in attribute_names(T) + return sym in attribute_names(T) end function attribute_default_expressions(T::Type{<:Plot}) - Dict(k => v.default_expr for (k, v) in documented_attributes(T).d) + return Dict(k => v.default_expr for (k, v) in documented_attributes(T).d) end function _attribute_docs(T::Type{<:Plot}) - Dict(k => v.docstring for (k, v) in documented_attributes(T).d) + return Dict(k => v.docstring for (k, v) in documented_attributes(T).d) end @@ -380,11 +381,11 @@ function create_args_type_expr(PlotType, args) throw(ArgumentError("All fields need to be of type `name::Type` or `name`. Found: $(all_fields)")) end types = []; names = Symbol[] - if all(x-> x isa Symbol, all_fields) + if all(x -> x isa Symbol, all_fields) return all_fields, :() end for field in all_fields - if field isa Symbol + if field isa Symbol error("All fields need to be typed if one is. Please either type all fields or none. Found: $(all_fields)") end push!(names, field.args[1]) @@ -414,7 +415,7 @@ function attribute_names(T::Type{<:Plot}) return keys(attr.d) end -function lookup_default(::Type{T}, scene, attribute::Symbol) where {T<:Plot} +function lookup_default(::Type{T}, scene, attribute::Symbol) where {T <: Plot} thm = theme(scene) metas = documented_attributes(T).d psym = plotsym(T) @@ -431,7 +432,7 @@ function lookup_default(::Type{T}, scene, attribute::Symbol) where {T<:Plot} end end -function default_theme(scene, T::Type{<: Plot}) +function default_theme(scene, T::Type{<:Plot}) metas = documented_attributes(T) attr = Attributes() isnothing(metas) && return attr @@ -489,7 +490,7 @@ function create_recipe_expr(Tsym, args, attrblock) $(funcname)() = not_implemented_for($funcname) - const $(PlotType){$(esc(:ArgType))} = Plot{$funcname,$(esc(:ArgType))} + const $(PlotType){$(esc(:ArgType))} = Plot{$funcname, $(esc(:ArgType))} # This weird syntax is so that the output of the macrocall can be escaped because it # contains user expressions, without escaping what's passed to the macro because that @@ -507,11 +508,11 @@ function create_recipe_expr(Tsym, args, attrblock) function ($funcname)(args...; kw...) kwdict = Dict{Symbol, Any}(kw) - _create_plot($funcname, kwdict, args...) + return _create_plot($funcname, kwdict, args...) end function ($funcname!)(args...; kw...) kwdict = Dict{Symbol, Any}(kw) - _create_plot!($funcname, kwdict, args...) + return _create_plot!($funcname, kwdict, args...) end $(arg_type_func) @@ -537,7 +538,6 @@ function create_recipe_expr(Tsym, args, attrblock) end - function make_recipe_docstring(P::Type{<:Plot}, Tsym, funcname_sym, docstring) io = IOBuffer() @@ -567,13 +567,13 @@ end isline(ex) = (ex isa Expr && ex.head === :line) || isa(ex, LineNumberNode) rmlines(x) = x function rmlines(x::Expr) - # Do not strip the first argument to a macrocall, which is - # required. - if x.head === :macrocall && length(x.args) >= 2 - Expr(x.head, x.args[1], nothing, filter(x->!isline(x), x.args[3:end])...) - else - Expr(x.head, filter(x->!isline(x), x.args)...) - end + # Do not strip the first argument to a macrocall, which is + # required. + return if x.head === :macrocall && length(x.args) >= 2 + Expr(x.head, x.args[1], nothing, filter(x -> !isline(x), x.args[3:end])...) + else + Expr(x.head, filter(x -> !isline(x), x.args)...) + end end default_expr_string(x) = string(rmlines(x)) @@ -606,11 +606,11 @@ function extract_attribute_metadata(arg) type = left.args[2] end - (docs = docs, symbol = attr_symbol, type = type, default = default) + return (docs = docs, symbol = attr_symbol, type = type, default = default) end function expand_mixins(attrblock::Expr) - Expr(:block, mapreduce(expand_mixin, vcat, attrblock.args)...) + return Expr(:block, mapreduce(expand_mixin, vcat, attrblock.args)...) end expand_mixin(x) = x @@ -650,16 +650,16 @@ end plot(MyType(...)) ``` """ -function Plot(args::Vararg{DataType,N}) where {N} - Plot{plot, <:Tuple{args...}} +function Plot(args::Vararg{DataType, N}) where {N} + return Plot{plot, <:Tuple{args...}} end function Plot(::Type{T}) where {T} - Plot{plot, <:Tuple{T}} + return Plot{plot, <:Tuple{T}} end -function Plot(::Type{T1}, ::Type{T2}) where {T1,T2} - Plot{plot, <:Tuple{T1,T2}} +function Plot(::Type{T1}, ::Type{T2}) where {T1, T2} + return Plot{plot, <:Tuple{T1, T2}} end """ @@ -702,9 +702,9 @@ function print_columns(io::IO, v::Vector{String}; gapsize = 2, rows_first = true ncols = 1 while true widths = col_widths(ncols; rows_first) - aggregated_width = (sum(widths) + (ncols-1) * gapsize) + aggregated_width = (sum(widths) + (ncols - 1) * gapsize) if aggregated_width > cols - ncols = max(1, ncols-1) + ncols = max(1, ncols - 1) break end ncols += 1 @@ -723,7 +723,7 @@ function print_columns(io::IO, v::Vector{String}; gapsize = 2, rows_first = true remaining = widths[icol] end remaining += !(icol == ncols) * gapsize - print(io, ' ' ^ remaining) + print(io, ' '^remaining) end println(io) end @@ -736,11 +736,11 @@ function _levenshtein_matrix(s1, s2) a, b = collect(s1), collect(s2) m, n = length(a), length(b) d = Matrix{Int}(undef, m + 1, n + 1) - d[1:m+1, 1] = 0:m - d[1, 1:n+1] = 0:n + d[1:(m + 1), 1] = 0:m + d[1, 1:(n + 1)] = 0:n for i in 1:m for j in 1:n - d[i+1, j+1] = min(d[i, j+1] + 1, d[i+1, j] + 1, d[i, j] + (a[i] != b[j])) + d[i + 1, j + 1] = min(d[i, j + 1] + 1, d[i + 1, j] + 1, d[i, j] + (a[i] != b[j])) end end return d @@ -756,8 +756,8 @@ function _fuzzyscore(needle, haystack) is, acro = _bestmatch(needle, haystack) score += (acro ? 2 : 1) * length(is) # Matched characters score -= 2(length(needle) - length(is)) # Missing characters - !acro && (score -= _avgdistance(is)/10) # Contiguous - !isempty(is) && (score -= sum(is)/length(is)/100) # Closer to beginning + !acro && (score -= _avgdistance(is) / 10) # Contiguous + return !isempty(is) && (score -= sum(is) / length(is) / 100) # Closer to beginning end function _matchinds(needle, haystack; acronym::Bool = false) # https://github.com/JuliaLang/julia/blob/6f3fdf7b36250fb95f512a2b927ad2518c07d2b5/stdlib/REPL/src/docview.jl#L602 @@ -829,16 +829,16 @@ function textdiff(X::String, Y::String) push!(results, (b[j], :normal)) i -= 1 j -= 1 - elseif i > 0 && j > 0 && d[i+1, j+1] == d[i, j] + 1 + elseif i > 0 && j > 0 && d[i + 1, j + 1] == d[i, j] + 1 # Substitution (different characters between `X` and `Y`) push!(results, (b[j], :orange)) # Highlighting the new character. Not showing the old one i -= 1 j -= 1 - elseif j > 0 && d[i+1, j+1] == d[i+1, j] + 1 + elseif j > 0 && d[i + 1, j + 1] == d[i + 1, j] + 1 # Insertion in `Y` (character in `Y` but not in `X`) push!(results, (b[j], :red)) # Highlighting the added character j -= 1 - elseif i > 0 && d[i+1, j+1] == d[i, j+1] + 1 + elseif i > 0 && d[i + 1, j + 1] == d[i, j + 1] + 1 # Deletion in `X` (character in `X` but not in `Y`) i -= 1 # Just move the index for X. Not showing the deletion here. end @@ -867,7 +867,7 @@ function Base.showerror(io::IO, err::InvalidAttributeError) printstyled(io, att; color = :red, bold = true) end print(io, " for $(err.object_name) type ") - printstyled(io, err.type; color=:blue, bold=true) + printstyled(io, err.type; color = :blue, bold = true) println(io, ".") nameset = sort(string.(collect(attribute_names(err.type)))) attrs = string.(collect(err.attributes)) @@ -880,7 +880,7 @@ function Base.showerror(io::IO, err::InvalidAttributeError) print(io, "Did you mean:") for (id, (passed, (suggestion, close))) in enumerate(zip(attrs, possible_cands)) close || continue - any_next = any(x -> x[2], view(possible_cands, id+1:length(possible_cands))) + any_next = any(x -> x[2], view(possible_cands, (id + 1):length(possible_cands))) if (id == length(err.attributes)) || (id < length(err.attributes) && !any_next) print(io, " and") end @@ -904,15 +904,17 @@ function Base.showerror(io::IO, err::InvalidAttributeError) println(io) print_columns(io, sort([string(a) for a in allowlist]); cols = displaysize(stderr)[2], rows_first = true) end - println(io) + return println(io) end function attribute_name_allowlist() - return (:xautolimits, :yautolimits, :zautolimits, :label, :rasterize, :model, :transformation, - :dim_conversions, :cycle, :clip_planes) + return ( + :xautolimits, :yautolimits, :zautolimits, :label, :rasterize, :model, :transformation, + :dim_conversions, :cycle, :clip_planes, + ) end -function validate_attribute_keys(plot::P) where {P<:Plot} +function validate_attribute_keys(plot::P) where {P <: Plot} nameset = attribute_names(P) nameset === nothing && return allowlist = attribute_name_allowlist() diff --git a/MakieCore/src/types.jl b/MakieCore/src/types.jl index ffb6b10139c..cd0420829a1 100644 --- a/MakieCore/src/types.jl +++ b/MakieCore/src/types.jl @@ -1,4 +1,3 @@ - """ abstract type Transformable This is a bit of a weird name, but all scenes and plots are transformable, @@ -68,8 +67,8 @@ mutable struct Plot{PlotFunc, T} <: ScenePlot{PlotFunc} transformation::Union{Nothing, Transformable} # Unprocessed arguments directly from the user command e.g. `plot(args...; kw...)`` - kw::Dict{Symbol,Any} - kw_obs::Observable{Vector{Pair{Symbol,Any}}} + kw::Dict{Symbol, Any} + kw_obs::Observable{Vector{Pair{Symbol, Any}}} args::Vector{Any} converted::Vector{Observable} @@ -78,26 +77,26 @@ mutable struct Plot{PlotFunc, T} <: ScenePlot{PlotFunc} plots::Vector{Plot} deregister_callbacks::Vector{Observables.ObserverFunction} - parent::Union{AbstractScene,Plot} - - function Plot{Typ,T}( - kw::Dict{Symbol,Any}, kw_obs::Observable{Vector{Pair{Symbol,Any}}}, - args::Vector{Any}, converted::Vector{Observable}, - deregister_callbacks::Vector{Observables.ObserverFunction}=Observables.ObserverFunction[] - ) where {Typ,T} - return new{Typ,T}(nothing, kw, kw_obs, args, converted, Attributes(), Plot[], deregister_callbacks) + parent::Union{AbstractScene, Plot} + + function Plot{Typ, T}( + kw::Dict{Symbol, Any}, kw_obs::Observable{Vector{Pair{Symbol, Any}}}, + args::Vector{Any}, converted::Vector{Observable}, + deregister_callbacks::Vector{Observables.ObserverFunction} = Observables.ObserverFunction[] + ) where {Typ, T} + return new{Typ, T}(nothing, kw, kw_obs, args, converted, Attributes(), Plot[], deregister_callbacks) end end function Base.show(io::IO, plot::Plot) - print(io, typeof(plot)) + return print(io, typeof(plot)) end Base.parent(x::AbstractPlot) = x.parent struct Key{K} end macro key_str(arg) - :(Key{$(QuoteNode(Symbol(arg)))}) + return :(Key{$(QuoteNode(Symbol(arg)))}) end Base.broadcastable(x::Key) = (x,) @@ -137,7 +136,7 @@ Can be used for rotation. struct Billboard{T <: Union{Float32, Vector{Float32}}} rotation::T end -Billboard() = Billboard(0f0) +Billboard() = Billboard(0.0f0) Billboard(angle::Real) = Billboard(Float32(angle)) Billboard(angles::Vector) = Billboard(Float32.(angles)) @@ -147,10 +146,10 @@ Billboard(angles::Vector) = Billboard(Float32.(angles)) MultiLightShading end -const RealArray{T,N} = AbstractArray{T,N} where {T<:Real} +const RealArray{T, N} = AbstractArray{T, N} where {T <: Real} const RealVector{T} = RealArray{1} const RealMatrix{T} = RealArray{2} -const FloatType = Union{Float32,Float64} +const FloatType = Union{Float32, Float64} # This could be simply a tuple or ClosedInterval # But ClosedInterval doesn't support all operations/constructions we need @@ -158,7 +157,7 @@ const FloatType = Union{Float32,Float64} # E.g. (0, 3) becomes (-0.5, 3.5) for a 3x3 heatmap, so if we have a tuple as input we need to do this calculation # And only if it's an EndPoint type, we can be sure its already in the correct format. struct EndPoints{T} <: AbstractVector{T} - data::NTuple{2,T} + data::NTuple{2, T} end EndPoints(a::Number, b::Number) = EndPoints((a, b)) EndPoints{T}(a::Number, b::Number) where {T} = EndPoints{T}((T(a), T(b))) @@ -169,4 +168,4 @@ Base.broadcasted(f, a::EndPoints, b) = EndPoints(f.(a.data, b)) Base.broadcasted(f, a, b::EndPoints) = EndPoints(f.(a, b.data)) Base.:(==)(a::EndPoints, b::NTuple{2}) = a.data == b # Something we can convert to an EndPoints type -const EndPointsLike = Union{ClosedInterval,Tuple{Real,Real}} +const EndPointsLike = Union{ClosedInterval, Tuple{Real, Real}} diff --git a/MakieCore/test/runtests.jl b/MakieCore/test/runtests.jl index 600ac535987..13b76fbdf29 100644 --- a/MakieCore/test/runtests.jl +++ b/MakieCore/test/runtests.jl @@ -12,7 +12,7 @@ end function plot!(plot::Plot(AbstractTimeseriesSolution)) # plot contains any keyword arguments that you pass to plot(series; kw...) var = get(plot, :var, Observable(5)) - density!(plot, map((v, r)-> v .* r.results, var, plot[1])) + return density!(plot, map((v, r) -> v .* r.results, var, plot[1])) end struct Test2 @@ -29,7 +29,7 @@ function plot!(plot::Plot(Test2)) ser = AbstractTimeseriesSolution(arg1[].series) sol = Solution(arg1[].series) plot!(plot, ser, var = 10) - scatter!(plot, sol, attribute = 3, color=:red) + return scatter!(plot, sol, attribute = 3, color = :red) end used_attributes(::Any, x::Solution) = (:attribute,) diff --git a/MakieRecipes/src/attribute_table.jl b/MakieRecipes/src/attribute_table.jl index 5909ceeaff0..177c7d9612a 100644 --- a/MakieRecipes/src/attribute_table.jl +++ b/MakieRecipes/src/attribute_table.jl @@ -11,7 +11,7 @@ function makie_color(c) if color === :match return Colors.colorant"blue" end - convert(RGBA, c) + return convert(RGBA, c) end makie_seriestype_map = Dict{Symbol, Type}( diff --git a/MakieRecipes/src/bezier.jl b/MakieRecipes/src/bezier.jl index c3c0afd2324..7f819e0b881 100644 --- a/MakieRecipes/src/bezier.jl +++ b/MakieRecipes/src/bezier.jl @@ -1,4 +1,3 @@ - @recipe(Bezier) do scene merge( default_theme(scene, Lines), @@ -9,15 +8,15 @@ ) end -conversion_trait(::Type{<: Bezier}) = PointBased() +conversion_trait(::Type{<:Bezier}) = PointBased() -function calculated_attributes!(::Type{<: Bezier}, plot) +function calculated_attributes!(::Type{<:Bezier}, plot) pos = plot[1][] # extend one color per linesegment to be one (the same) color per vertex # taken from @edljk in PR #77 if haskey(plot, :color) && isa(plot.color[], AbstractVector) && iseven(length(pos)) && (length(pos) ÷ 2) == length(plot.color[]) plot[:color] = lift(plot.color) do cols - map(i-> cols[(i + 1) ÷ 2], 1:(length(cols) * 2)) + map(i -> cols[(i + 1) ÷ 2], 1:(length(cols) * 2)) end end color_and_colormap!(plot) @@ -25,7 +24,7 @@ function calculated_attributes!(::Type{<: Bezier}, plot) end # used in the pipeline too (for poly) -function from_nansep_vec(v::Vector{T}) where T +function from_nansep_vec(v::Vector{T}) where {T} idxs = findall(isnan, v) if isempty(idxs) @@ -35,7 +34,7 @@ function from_nansep_vec(v::Vector{T}) where T prev = 1 num = 1 for i in idxs - vs[num] = v[prev:i-1] + vs[num] = v[prev:(i - 1)] prev = i + 1 num += 1 @@ -50,7 +49,7 @@ function bezier_value(pts::AbstractVector, t::Real) for (i, p) in enumerate(pts) val += p * binomial(n, i - 1) * (1 - t)^(n - i + 1) * t^(i - 1) end - val + return val end @@ -79,7 +78,7 @@ function plot!(plot::Bezier) curves = lift(to_bezier, positions, npoints) - lines!( + return lines!( plot, curves; linestyle = plot.linestyle, diff --git a/MakieRecipes/src/layout_integration.jl b/MakieRecipes/src/layout_integration.jl index 6cf6ad5206f..55f001d294c 100644 --- a/MakieRecipes/src/layout_integration.jl +++ b/MakieRecipes/src/layout_integration.jl @@ -1,4 +1,4 @@ function tomakie!(sc::AbstractScene, layout::Makie.GridLayout, args...; attrs...) # TODO create a finalizer for a Tuple{Scene, Layout, Vector{LAxis}} - RecipesPipeline.recipe_pipeline!(sc, Dict{Symbol, Any}(attrs), args) + return RecipesPipeline.recipe_pipeline!(sc, Dict{Symbol, Any}(attrs), args) end diff --git a/MakieRecipes/src/pipeline_integration.jl b/MakieRecipes/src/pipeline_integration.jl index c9bba8d60eb..727bb8d4896 100644 --- a/MakieRecipes/src/pipeline_integration.jl +++ b/MakieRecipes/src/pipeline_integration.jl @@ -3,21 +3,21 @@ # ## Types and aliases const PlotContext = Union{ - AbstractScene, - AbstractPlot, - MakieLayout.LAxis - } + AbstractScene, + AbstractPlot, + MakieLayout.LAxis, +} # ## API implementation # Define overrides for RecipesPipeline hooks. -RecipesBase.apply_recipe(plotattributes, ::Type{T}, ::PlotContext) where T = throw(MethodError("Unmatched plot type: $T")) +RecipesBase.apply_recipe(plotattributes, ::Type{T}, ::PlotContext) where {T} = throw(MethodError("Unmatched plot type: $T")) # Preprocessing involves resetting the palette for now. # Later, it may involve setting up a layouting context, among other things. function RecipesPipeline.preprocess_attributes!(plt::PlotContext, plotattributes) - plt.palette[].i[] = zero(UInt8) + return plt.palette[].i[] = zero(UInt8) end @@ -41,21 +41,21 @@ function RecipesPipeline.process_userrecipe!(sc::PlotContext, kw_list, kw) map(kw[:line_z], kw[:x], kw[:y], kw[:z]) end - push!(kw_list, kw) + return push!(kw_list, kw) end # Determine axis limits function RecipesPipeline.get_axis_limits(sc::PlotContext, f, letter) lims = to_value(data_limits(sc)) i = if letter === :x - 1 - elseif letter === :y - 2 - elseif letter === :z - 3 - else - throw(ArgumentError("Letter $letter does not correspond to an axis.")) - end + 1 + elseif letter === :y + 2 + elseif letter === :z + 3 + else + throw(ArgumentError("Letter $letter does not correspond to an axis.")) + end o = origin(lims) return (o[i], o[i] + widths(lims)[i]) @@ -66,9 +66,9 @@ end ######################################## function slice_arg(v::AbstractMatrix, idx::Int) - c = mod1(idx, size(v,2)) - m,n = axes(v) - size(v,1) == 1 ? v[first(m),n[c]] : v[:,n[c]] + c = mod1(idx, size(v, 2)) + m, n = axes(v) + return size(v, 1) == 1 ? v[first(m), n[c]] : v[:, n[c]] end # slice_arg(wrapper::Plots.InputWrapper, idx) = wrapper.obj slice_arg(v, idx) = v @@ -94,7 +94,7 @@ function makie_plottype(st::Symbol) return get(makie_seriestype_map, st, Lines) end -makie_args(::Type{T}, plotattributes) where T <: AbstractPlot = makie_args(conversion_trait(T), plotattributes) +makie_args(::Type{T}, plotattributes) where {T <: AbstractPlot} = makie_args(conversion_trait(T), plotattributes) function makie_args(::PointBased, plotattributes) @@ -115,9 +115,9 @@ end # TODO use Makie.plottype makie_args(::SurfaceLike, plotattributes) = (plotattributes[:x], plotattributes[:y], plotattributes[:z].surf) -makie_args(::Type{<: Contour}, plotattributes) = (plotattributes[:x], plotattributes[:y], plotattributes[:z].surf) +makie_args(::Type{<:Contour}, plotattributes) = (plotattributes[:x], plotattributes[:y], plotattributes[:z].surf) -function makie_args(::Type{<: Poly}, plotattributes) +function makie_args(::Type{<:Poly}, plotattributes) return (from_nansep_vec(Point2f.(plotattributes[:x], plotattributes[:y])),) end @@ -141,7 +141,7 @@ function translate_to_makie!(st, pa) end # series color - if st ∈ (:path, :path3d, :curves) + return if st ∈ (:path, :path3d, :curves) if !isnothing(get(pa, :line_z, nothing)) pa[:color] = pa[:line_z] @@ -287,9 +287,9 @@ end function set_palette!(plt, plotattributes) pt = get!(plotattributes, :palette, default_palette) - if pt isa Palette + return if pt isa Palette # nothing - elseif pt isa Vector{<: Colorant} + elseif pt isa Vector{<:Colorant} plotattributes[:palette] = Palette(pt) else @warn "Palette was unrecognizable!" @@ -310,7 +310,7 @@ function plot_series_annotations!(plt, args, pt, plotattributes) @debug("Series annotations say hi") - annotations!(plt, strs, positions; fontsize = fontsize/30, align = (:center, :center), color = get(plotattributes, :textcolor, :black)) + return annotations!(plt, strs, positions; fontsize = fontsize / 30, align = (:center, :center), color = get(plotattributes, :textcolor, :black)) end @@ -326,7 +326,7 @@ function plot_annotations!(plt, args, pt, plotattributes) @debug("Annotations say hi") - annotations!(plt, strs, positions; fontsize = fontsizes ./ 80, align = (:center, :center), color = get(plotattributes, :textcolor, :black)) + return annotations!(plt, strs, positions; fontsize = fontsizes ./ 80, align = (:center, :center), color = get(plotattributes, :textcolor, :black)) end @@ -340,7 +340,7 @@ function plot_fill!(plt, args, pt, plotattributes) c = to_color(color) bandcolor = RGBA(red(c), green(c), blue(c), alpha(c) * opacity) - band!(plt, x, upper, lower; color = bandcolor) + return band!(plt, x, upper, lower; color = bandcolor) end # Add the "series" to the Scene. diff --git a/MakieRecipes/src/recipeplot.jl b/MakieRecipes/src/recipeplot.jl index c2ad9918bf6..13d7416937e 100644 --- a/MakieRecipes/src/recipeplot.jl +++ b/MakieRecipes/src/recipeplot.jl @@ -1,4 +1,3 @@ - @recipe(RecipePlot) do scene th = merge( default_theme(scene), @@ -8,7 +7,7 @@ return th end -function plot!(p::T) where T <: RecipePlot +function plot!(p::T) where {T <: RecipePlot} # What happens here is that I want to lift on every available observable, # so they need to be splatted. This also means that nested attributes diff --git a/RPRMakie/examples/bars.jl b/RPRMakie/examples/bars.jl index 43f7c9faf3e..3fe7f98c822 100644 --- a/RPRMakie/examples/bars.jl +++ b/RPRMakie/examples/bars.jl @@ -2,20 +2,22 @@ using GeometryBasics, RPRMakie using Colors, FileIO, ImageShow using Colors: N0f8 -RPRMakie.activate!(plugin=RPR.Northstar, resource=RPR.GPU0) -fig = Figure(; size=(800, 600), fontsize=26) +RPRMakie.activate!(plugin = RPR.Northstar, resource = RPR.GPU0) +fig = Figure(; size = (800, 600), fontsize = 26) radiance = 10000 -lights = [EnvironmentLight(0.5, load(RPR.assetpath("studio026.exr"))), - PointLight(Vec3f(0, 0, 20), RGBf(radiance, radiance, radiance))] +lights = [ + EnvironmentLight(0.5, load(RPR.assetpath("studio026.exr"))), + PointLight(Vec3f(0, 0, 20), RGBf(radiance, radiance, radiance)), +] -ax = LScene(fig[1, 1]; scenekw=(lights=lights, showaxis=false)) +ax = LScene(fig[1, 1]; scenekw = (lights = lights, showaxis = false)) rectMesh = Rect(Vec3f(-0.5, -0.5, 0), Vec3f(1)) recmesh = GeometryBasics.normal_mesh(rectMesh) n = 100 pos = [Point3f(i, j, 0) ./ 10 for i in 1:n for j in 1:n] z = rand(n, n) -mat = (type=:Microfacet, color=:gray, roughness=0.2, ior=1.390) -meshscatter!(ax, pos; marker=recmesh, markersize=Vec3f.(0.1, 0.1, z[:]), material=mat, color=vec(z)) +mat = (type = :Microfacet, color = :gray, roughness = 0.2, ior = 1.39) +meshscatter!(ax, pos; marker = recmesh, markersize = Vec3f.(0.1, 0.1, z[:]), material = mat, color = vec(z)) cam = cameracontrols(ax.scene) cam.eyeposition[] = Float32[5, 22, 12] diff --git a/RPRMakie/examples/datashader-rpr.jl b/RPRMakie/examples/datashader-rpr.jl index dce5f7c845e..da7dd2076aa 100644 --- a/RPRMakie/examples/datashader-rpr.jl +++ b/RPRMakie/examples/datashader-rpr.jl @@ -1,12 +1,12 @@ using DelimitedFiles, GLMakie GLMakie.activate!() # hide # For saving/showing/inlining into documentation we need to disable async calculation. -Makie.set_theme!(DataShader=(; async_latest=false)) +Makie.set_theme!(DataShader = (; async_latest = false)) airports = Point2f.(eachrow(readdlm(assetpath("airportlocations.csv")))) (xmin, ymin), (xmax, ymax) = extrema(xx) xx = Rect2f(points) -all(x-> x in xx, points) +all(x -> x in xx, points) canvas = Canvas(Rect2f(points)) @@ -14,39 +14,41 @@ aggregate!(canvas, points); m = collect(Makie.get_aggregation(canvas)) -(xmin, ymin), (xmax, ymax) = map(x-> x./widths(canvas.bounds), extrema(canvas.bounds)) +(xmin, ymin), (xmax, ymax) = map(x -> x ./ widths(canvas.bounds), extrema(canvas.bounds)) xw, yw = 1 ./ size(m) maxi = maximum(mscaled) GLMakie.activate!() radiance = 50 -lights = [EnvironmentLight(0.5, load(RPR.assetpath("studio026.exr"))), - PointLight(Vec3f(0, 0, 2), RGBf(radiance, radiance, radiance))] +lights = [ + EnvironmentLight(0.5, load(RPR.assetpath("studio026.exr"))), + PointLight(Vec3f(0, 0, 2), RGBf(radiance, radiance, radiance)), +] mscaled = m ./ widths(canvas.bounds)[1] recmesh = GeometryBasics.normal_mesh(Rect3f(Vec3f(-0.5), Vec3f(1))) -RPRMakie.activate!(plugin=RPR.Northstar, iterations=1, resource=RPR.RPR_CREATION_FLAGS_ENABLE_GPU1) +RPRMakie.activate!(plugin = RPR.Northstar, iterations = 1, resource = RPR.RPR_CREATION_FLAGS_ENABLE_GPU1) f, ax, pl = meshscatter( xmin .. xmax, ymin .. ymax, mscaled; - axis=(; type=LScene, show_axis=false, scenekw=(; lights=lights)), - marker=recmesh, - color=mscaled, - colorrange=Vec2f(0.000001, maxi), - lowclip=(:blue, 0.1), - colormap=[:white, :red], - material=(; type=:Microfacet, color=:gray, roughness=0.2, ior=1.390), - markersize=Vec3f.(xw, yw, vec(mscaled)) + axis = (; type = LScene, show_axis = false, scenekw = (; lights = lights)), + marker = recmesh, + color = mscaled, + colorrange = Vec2f(0.000001, maxi), + lowclip = (:blue, 0.1), + colormap = [:white, :red], + material = (; type = :Microfacet, color = :gray, roughness = 0.2, ior = 1.39), + markersize = Vec3f.(xw, yw, vec(mscaled)) ) ax.scene |> display -display(f; backend=GLMakie) +display(f; backend = GLMakie) using RPRMakie, FileIO -RPRMakie.activate!(plugin=RPR.Tahoe, iterations=1, resource=RPR.RPR_CREATION_FLAGS_ENABLE_GPU1) +RPRMakie.activate!(plugin = RPR.Tahoe, iterations = 1, resource = RPR.RPR_CREATION_FLAGS_ENABLE_GPU1) RPRMakie.replace_scene_rpr!(ax.scene) l = lights[2] -l.position[] = Vec3f(xmin + xmax/2, ymin + ymax / 2, widths(canvas.bounds)[1]) +l.position[] = Vec3f(xmin + xmax / 2, ymin + ymax / 2, widths(canvas.bounds)[1]) l.radiance[] = RGBf(500, 500, 500) pl.colorrange[] = Vec2f(0.000001, maxi) diff --git a/RPRMakie/examples/eart_topographie_sphere.jl b/RPRMakie/examples/eart_topographie_sphere.jl index e02ee0a2fc9..7fcc83998c4 100644 --- a/RPRMakie/examples/eart_topographie_sphere.jl +++ b/RPRMakie/examples/eart_topographie_sphere.jl @@ -7,7 +7,7 @@ lon = dataset["lon"][:] lat = dataset["lat"][:] data = Float32.(dataset["ETOPO1avg"][:, :]) -function toCartesian(lon, lat; r=1, cxyz=(0, 0, 0)) +function toCartesian(lon, lat; r = 1, cxyz = (0, 0, 0)) lat, lon = lat * π / 180, lon * π / 180 x = cxyz[1] + (r + 80_000) * cos(lat) * cos(lon) y = cxyz[2] + (r + 80_000) * cos(lat) * sin(lon) @@ -15,10 +15,10 @@ function toCartesian(lon, lat; r=1, cxyz=(0, 0, 0)) return (x, y, z) ./ 80_000 end -function lonlat3D(lon, lat, data; cxyz=(0, 0, 0)) +function lonlat3D(lon, lat, data; cxyz = (0, 0, 0)) xyzw = zeros(size(data)..., 3) for (i, lon) in enumerate(lon), (j, lat) in enumerate(lat) - x, y, z = toCartesian(lon, lat; r=data[i, j], cxyz=cxyz) + x, y, z = toCartesian(lon, lat; r = data[i, j], cxyz = cxyz) xyzw[i, j, 1] = x xyzw[i, j, 2] = y xyzw[i, j, 3] = z @@ -26,7 +26,7 @@ function lonlat3D(lon, lat, data; cxyz=(0, 0, 0)) return xyzw[:, :, 1], xyzw[:, :, 2], xyzw[:, :, 3] end # this is needed in order to have a closed surface -lonext = cat(collect(lon), lon[1]; dims=1) +lonext = cat(collect(lon), lon[1]; dims = 1) dataext = begin tmpdata = zeros(size(lon)[1] + 1, size(lat)[1]) tmpdata[1:size(lon)[1], :] = data @@ -39,15 +39,15 @@ xetopo, yetopo, zetopo = lonlat3D(lonext, lat, dataext) begin r = 30 lights = [PointLight(Vec3f(2, 1, 3), RGBf(r, r, r))] - fig = Figure(; size=(1200, 1200), backgroundcolor=:black) - ax = LScene(fig[1, 1]; show_axis=false)#, scenekw=(lights=lights,)) - pltobj = surface!(ax, xetopo, yetopo, zetopo; color=dataext, colormap=:hot, colorrange=(-6000, 5000)) + fig = Figure(; size = (1200, 1200), backgroundcolor = :black) + ax = LScene(fig[1, 1]; show_axis = false) #, scenekw=(lights=lights,)) + pltobj = surface!(ax, xetopo, yetopo, zetopo; color = dataext, colormap = :hot, colorrange = (-6000, 5000)) cam = cameracontrols(ax.scene) cam.fov[] = 10 cam.eyeposition[] = Vec3f(3, 1, 1) cam.lookat[] = Vec3f(0) cam.upvector[] = Vec3f(0, 0, 1) Makie.update_cam!(ax.scene, cam) - RPRMakie.activate!(; iterations=32, plugin=RPR.Tahoe) + RPRMakie.activate!(; iterations = 32, plugin = RPR.Tahoe) display(ax.scene) end diff --git a/RPRMakie/examples/earth_topography.jl b/RPRMakie/examples/earth_topography.jl index ceaf99ef70a..e89c43cbd82 100644 --- a/RPRMakie/examples/earth_topography.jl +++ b/RPRMakie/examples/earth_topography.jl @@ -27,22 +27,26 @@ function glow_material(data_normed) ) end -RPRMakie.activate!(iterations=32, plugin=RPR.Northstar) -fig = Figure(; size=(2000, 800)) +RPRMakie.activate!(iterations = 32, plugin = RPR.Northstar) +fig = Figure(; size = (2000, 800)) radiance = 30000 -lights = [EnvironmentLight(1.0, load(RPR.assetpath("studio026.exr"))), - PointLight(Vec3f(0, 100, 100), RGBf(radiance, radiance, radiance))] +lights = [ + EnvironmentLight(1.0, load(RPR.assetpath("studio026.exr"))), + PointLight(Vec3f(0, 100, 100), RGBf(radiance, radiance, radiance)), +] -ax = LScene(fig[1, 1]; show_axis=false, scenekw=(lights=lights,)) +ax = LScene(fig[1, 1]; show_axis = false, scenekw = (lights = lights,)) mini, maxi = extrema(data) data_normed = ((data .- mini) ./ (maxi - mini)) material = glow_material(data_normed) -pltobj = surface!(ax, lon, lat, data_normed .* 20; - material=material, colormap=[:black, :white, :brown], - colorrange=(0.2, 0.8) .* 20) +pltobj = surface!( + ax, lon, lat, data_normed .* 20; + material = material, colormap = [:black, :white, :brown], + colorrange = (0.2, 0.8) .* 20 +) # Set the camera to a nice angle cam = cameracontrols(ax.scene) cam.eyeposition[] = Vec3f(3, -300, 300) diff --git a/RPRMakie/examples/lego.jl b/RPRMakie/examples/lego.jl index fa9956c947d..3062819aa17 100644 --- a/RPRMakie/examples/lego.jl +++ b/RPRMakie/examples/lego.jl @@ -20,8 +20,8 @@ origins = Dict( ) rotation_axes = Dict( - "arm_right" => Vec3f(0.0000, -0.9828, 0.1848), - "arm_left" => Vec3f(0.0000, 0.9828, 0.1848), + "arm_right" => Vec3f(0.0, -0.9828, 0.1848), + "arm_left" => Vec3f(0.0, 0.9828, 0.1848), "leg_right" => Vec3f(0, -1, 0), "leg_left" => Vec3f(0, 1, 0), ) @@ -34,42 +34,42 @@ function plot_part!(scene, parent, name::String) origin = get(origins, name, nothing) if !isnothing(origin) centered = m.position .- origin - m = GeometryBasics.Mesh(meta(centered; normals=m.normals), faces(m)) + m = GeometryBasics.Mesh(meta(centered; normals = m.normals), faces(m)) translate!(trans, origin) else translate!(trans, -ptrans.translation[]) end - return mesh!(scene, m; color=color, transformation=trans) + return mesh!(scene, m; color = color, transformation = trans) end -function plot_lego_figure(s, floor=true) +function plot_lego_figure(s, floor = true) # Plot hierarchical mesh! figure = Dict() # Plot hierarchical mesh! figure["torso"] = plot_part!(s, s, "torso") - figure["head"] = plot_part!(s, figure["torso"], "head") - figure["eyes_mouth"] = plot_part!(s, figure["head"], "eyes_mouth") - figure["arm_right"] = plot_part!(s, figure["torso"], "arm_right") - figure["hand_right"] = plot_part!(s, figure["arm_right"], "hand_right") - figure["arm_left"] = plot_part!(s, figure["torso"], "arm_left") - figure["hand_left"] = plot_part!(s, figure["arm_left"], "hand_left") - figure["belt"] = plot_part!(s, figure["torso"], "belt") - figure["leg_right"] = plot_part!(s, figure["belt"], "leg_right") - figure["leg_left"] = plot_part!(s, figure["belt"], "leg_left") + figure["head"] = plot_part!(s, figure["torso"], "head") + figure["eyes_mouth"] = plot_part!(s, figure["head"], "eyes_mouth") + figure["arm_right"] = plot_part!(s, figure["torso"], "arm_right") + figure["hand_right"] = plot_part!(s, figure["arm_right"], "hand_right") + figure["arm_left"] = plot_part!(s, figure["torso"], "arm_left") + figure["hand_left"] = plot_part!(s, figure["arm_left"], "hand_left") + figure["belt"] = plot_part!(s, figure["torso"], "belt") + figure["leg_right"] = plot_part!(s, figure["belt"], "leg_right") + figure["leg_left"] = plot_part!(s, figure["belt"], "leg_left") # lift the little guy up translate!(figure["torso"], 0, 0, 20) # add some floor - floor && mesh!(s, Rect3f(Vec3f(-400, -400, -2), Vec3f(800, 800, 2)), color=:white) + floor && mesh!(s, Rect3f(Vec3f(-400, -400, -2), Vec3f(800, 800, 2)), color = :white) return figure end -RPRMakie.activate!(iterations=200, plugin=RPR.Northstar) +RPRMakie.activate!(iterations = 200, plugin = RPR.Northstar) radiance = 50000 lights = [ EnvironmentLight(1.5, rotl90(load(assetpath("sunflowers_1k.hdr"))')), - PointLight(Vec3f(50, 0, 200), RGBf(radiance, radiance, radiance*1.1)), + PointLight(Vec3f(50, 0, 200), RGBf(radiance, radiance, radiance * 1.1)), ] -s = Scene(size=(500, 500), lights=lights) +s = Scene(size = (500, 500), lights = lights) cam3d!(s) c = cameracontrols(s) @@ -78,12 +78,12 @@ c.far[] = 1000 update_cam!(s, c, Vec3f(100, 30, 80), Vec3f(0, 0, -10)) figure = plot_lego_figure(s) -rot_joints_by = 0.25*pi +rot_joints_by = 0.25 * pi total_translation = 50 animation_strides = 10 a1 = LinRange(0, rot_joints_by, animation_strides) -angles = [a1; reverse(a1[1:end-1]); -a1[2:end]; reverse(-a1[1:end-1]);] +angles = [a1; reverse(a1[1:(end - 1)]); -a1[2:end]; reverse(-a1[1:(end - 1)]);] nsteps = length(angles); #Number of animation steps translations = LinRange(0, total_translation, nsteps) s diff --git a/RPRMakie/examples/lines.jl b/RPRMakie/examples/lines.jl index 2fed509dc2d..5a7265ddd68 100644 --- a/RPRMakie/examples/lines.jl +++ b/RPRMakie/examples/lines.jl @@ -4,29 +4,31 @@ using Colors: N0f8 function box!(ax, size) orig = Vec3f(-2, -2, 0) - mesh!(ax, Rect3f(orig, Vec3f(size, size, 0.1)); color=:white, - material=(reflection_color=Vec4f(1), reflection_weight=10f0)) - mesh!(ax, Rect3f(orig, Vec3f(0.1, size, size)); color=:white) - mesh!(ax, Rect3f(orig, Vec3f(size, 0.1, size)); color=:white) + mesh!( + ax, Rect3f(orig, Vec3f(size, size, 0.1)); color = :white, + material = (reflection_color = Vec4f(1), reflection_weight = 10.0f0) + ) + mesh!(ax, Rect3f(orig, Vec3f(0.1, size, size)); color = :white) + mesh!(ax, Rect3f(orig, Vec3f(size, 0.1, size)); color = :white) return end begin - fig = Figure(; size=(1000, 1000)) + fig = Figure(; size = (1000, 1000)) radiance = 100 lights = Makie.AbstractLight[PointLight(Vec3f(10), RGBf(radiance, radiance, radiance * 1.1))] - ax = LScene(fig[1, 1]; scenekw=(; lights=lights), show_axis=false) + ax = LScene(fig[1, 1]; scenekw = (; lights = lights), show_axis = false) points = Point3f[] for i in 4:10 n = i + 1 y = LinRange(0, i, n) y2 = (y ./ 2) .- 2 xyz = Point3f.((i - 5) ./ 2, y2, sin.(y) .+ 1) - lp = lines!(ax, xyz; linewidth=10, color=:white) + lp = lines!(ax, xyz; linewidth = 10, color = :white) append!(points, xyz) end - mat = (; emission_color=:red, emission_weight=Vec3f(5.0f0)) - meshscatter!(ax, points; material=mat) + mat = (; emission_color = :red, emission_weight = Vec3f(5.0f0)) + meshscatter!(ax, points; material = mat) box!(ax, 5) RPRMakie.activate!(plugin = RPR.Northstar, iterations = 500, resource = RPR.GPU0) ax.scene |> display diff --git a/RPRMakie/examples/makie_example.jl b/RPRMakie/examples/makie_example.jl index 32a099ba9cd..1eb52f78bd3 100644 --- a/RPRMakie/examples/makie_example.jl +++ b/RPRMakie/examples/makie_example.jl @@ -1,11 +1,11 @@ using GeometryBasics, Makie using FileIO, Colors using RPRMakie -RPRMakie.activate!(iterations=200) +RPRMakie.activate!(iterations = 200) earth = load(Makie.assetpath("earth.png")) m = uv_mesh(Tessellation(Sphere(Point3f(0), 1.0f0), 60)) -f, ax, mplot = Makie.mesh(m; color=earth) -Makie.mesh!(ax, Sphere(Point3f(2, 0, 0), 0.1f0); color=:red) +f, ax, mplot = Makie.mesh(m; color = earth) +Makie.mesh!(ax, Sphere(Point3f(2, 0, 0), 0.1f0); color = :red) x, y = collect(-8:0.5:8), collect(-8:0.5:8) z = [sinc(√(X^2 + Y^2) / π) for X in x, Y in y] wireframe!(ax, -2 .. 2, -2 .. 2, z) diff --git a/RPRMakie/examples/material_x.jl b/RPRMakie/examples/material_x.jl index 757fd825c90..636aea0d4e7 100644 --- a/RPRMakie/examples/material_x.jl +++ b/RPRMakie/examples/material_x.jl @@ -5,16 +5,18 @@ material = "Pinwheel_Pattern_Marble_Tiles_4k_16b" # folder you downloaded & extr img = begin radiance = 1000 - lights = [EnvironmentLight(0.5, load(RPR.assetpath("studio026.exr"))), - PointLight(Vec3f(5), RGBf(radiance, radiance, radiance * 1.1))] - fig = Figure(; size=(1500, 700)) - ax = LScene(fig[1, 1]; show_axis=false, scenekw=(lights=lights,)) - screen = RPRMakie.Screen(ax.scene; plugin=RPR.Northstar, iterations=500, resource=RPR.GPU0) + lights = [ + EnvironmentLight(0.5, load(RPR.assetpath("studio026.exr"))), + PointLight(Vec3f(5), RGBf(radiance, radiance, radiance * 1.1)), + ] + fig = Figure(; size = (1500, 700)) + ax = LScene(fig[1, 1]; show_axis = false, scenekw = (lights = lights,)) + screen = RPRMakie.Screen(ax.scene; plugin = RPR.Northstar, iterations = 500, resource = RPR.GPU0) matsys = screen.matsys marble_tiles = RPR.Matx(matsys, joinpath(material, "Pinwheel_Pattern_Marble_Tiles.mtlx")) - mesh!(ax, load(Makie.assetpath("matball_floor.obj")); color=:white) - matball!(ax, marble_tiles; color=nothing) + mesh!(ax, load(Makie.assetpath("matball_floor.obj")); color = :white) + matball!(ax, marble_tiles; color = nothing) cam = cameracontrols(ax.scene) cam.eyeposition[] = Vec3f(0.0, -2, 1) cam.lookat[] = Vec3f(0) diff --git a/RPRMakie/examples/materials.jl b/RPRMakie/examples/materials.jl index 80f7d9a0f2e..d3b3ef7f427 100644 --- a/RPRMakie/examples/materials.jl +++ b/RPRMakie/examples/materials.jl @@ -4,11 +4,13 @@ using Colors: N0f8 img = begin radiance = 500 - lights = [EnvironmentLight(1.0, load(RPR.assetpath("studio026.exr"))), - PointLight(Vec3f(10), RGBf(radiance, radiance, radiance * 1.1))] - fig = Figure(; size=(1500, 700)) - ax = LScene(fig[1, 1]; show_axis=false, scenekw=(lights=lights,)) - screen = RPRMakie.Screen(ax.scene; plugin=RPR.Northstar, iterations=1000) + lights = [ + EnvironmentLight(1.0, load(RPR.assetpath("studio026.exr"))), + PointLight(Vec3f(10), RGBf(radiance, radiance, radiance * 1.1)), + ] + fig = Figure(; size = (1500, 700)) + ax = LScene(fig[1, 1]; show_axis = false, scenekw = (lights = lights,)) + screen = RPRMakie.Screen(ax.scene; plugin = RPR.Northstar, iterations = 1000) matsys = screen.matsys emissive = RPR.EmissiveMaterial(matsys) @@ -19,20 +21,22 @@ img = begin dielectric = RPR.DielectricBrdfX(matsys) gold = RPR.SurfaceGoldX(matsys) - materials = [glass chrome; - gold dielectric; - emissive plastic] + materials = [ + glass chrome; + gold dielectric; + emissive plastic + ] - mesh!(ax, load(Makie.assetpath("matball_floor.obj")); color=:white) + mesh!(ax, load(Makie.assetpath("matball_floor.obj")); color = :white) palette = reshape(Makie.DEFAULT_PALETTES.color[][1:6], size(materials)) for i in CartesianIndices(materials) x, y = Tuple(i) mat = materials[i] mplot = if mat === emissive - matball!(ax, diffuse; inner=emissive, color=nothing) + matball!(ax, diffuse; inner = emissive, color = nothing) else - matball!(ax, mat; color=nothing) + matball!(ax, mat; color = nothing) end v = Vec3f(((x, y) .- (0.5 .* size(materials)) .- 0.5)..., 0) translate!(mplot, 0.9 .* (v .- Vec3f(0, 3, 0))) diff --git a/RPRMakie/examples/opengl_interop.jl b/RPRMakie/examples/opengl_interop.jl index 5c0d4a54ad5..66158a7a406 100644 --- a/RPRMakie/examples/opengl_interop.jl +++ b/RPRMakie/examples/opengl_interop.jl @@ -5,25 +5,29 @@ using Colors: N0f8 f = (u, v) -> cos(v) * (6 - (5 / 4 + sin(3 * u)) * sin(u - 3 * v)) g = (u, v) -> sin(v) * (6 - (5 / 4 + sin(3 * u)) * sin(u - 3 * v)) h = (u, v) -> -cos(u - 3 * v) * (5 / 4 + sin(3 * u)); -u = range(0; stop=2π, length=150) -v = range(0; stop=2π, length=150) +u = range(0; stop = 2π, length = 150) +v = range(0; stop = 2π, length = 150) radiance = 500 -lights = [EnvironmentLight(1.0, load(RPR.assetpath("studio026.exr"))), - PointLight(Vec3f(10), RGBf(radiance, radiance, radiance * 1.1)), - AmbientLight(RGBf(0.5, 0.5, 0.5))] +lights = [ + EnvironmentLight(1.0, load(RPR.assetpath("studio026.exr"))), + PointLight(Vec3f(10), RGBf(radiance, radiance, radiance * 1.1)), + AmbientLight(RGBf(0.5, 0.5, 0.5)), +] -fig = Figure(; size=(1500, 1000)) -ax = LScene(fig[1, 1]; show_axis=false, scenekw=(lights=lights,)) -screen = RPRMakie.Screen(size(ax.scene); plugin=RPR.Northstar, resource=RPR.RPR_CREATION_FLAGS_ENABLE_GPU0) +fig = Figure(; size = (1500, 1000)) +ax = LScene(fig[1, 1]; show_axis = false, scenekw = (lights = lights,)) +screen = RPRMakie.Screen(size(ax.scene); plugin = RPR.Northstar, resource = RPR.RPR_CREATION_FLAGS_ENABLE_GPU0) material = RPR.UberMaterial(screen.matsys) -surface!(ax, f.(u, v'), g.(u, v'), h.(u, v'); diffuse=Vec3f(1), specular=0.5, - colormap=:balance, material=material) +surface!( + ax, f.(u, v'), g.(u, v'), h.(u, v'); diffuse = Vec3f(1), specular = 0.5, + colormap = :balance, material = material +) function Input(fig, val::RGB) - hue = Slider(fig; range=1:380, width=200) - lightness = Slider(fig; range=LinRange(0, 1, 100), width=200) - labels = [Label(fig, "hue"; halign=:left), Label(fig, "light"; halign=:left)] + hue = Slider(fig; range = 1:380, width = 200) + lightness = Slider(fig; range = LinRange(0, 1, 100), width = 200) + labels = [Label(fig, "hue"; halign = :left), Label(fig, "light"; halign = :left)] layout = grid!(hcat(labels, [hue, lightness])) hsl = HSL(val) set_close_to!(hue, hsl.h) @@ -33,34 +37,36 @@ function Input(fig, val::RGB) end function Input(fig, val::Vec4) - s = Slider(fig; range=LinRange(0, 1, 100), width=200) + s = Slider(fig; range = LinRange(0, 1, 100), width = 200) set_close_to!(s, first(val)) return map(x -> Vec4f(x), s.value), s end function Input(fig, val::Bool) - toggle = Toggle(fig; active=val) + toggle = Toggle(fig; active = val) return toggle.active, toggle end -sliders = (reflection_color=Input(fig, RGB(0, 0, 0)), reflection_weight=Input(fig, Vec4(0)), - reflection_roughness=Input(fig, Vec4(0)), reflection_anisotropy=Input(fig, Vec4(0)), - reflection_anisotropy_rotation=Input(fig, Vec4(0)), reflection_mode=Input(fig, Vec4(0)), - reflection_ior=Input(fig, Vec4(0)), reflection_metalness=Input(fig, Vec4(0)), - refraction_color=Input(fig, RGB(0, 0, 0)), refraction_weight=Input(fig, Vec4(0)), - refraction_roughness=Input(fig, Vec4(0)), refraction_ior=Input(fig, Vec4(0)), - refraction_absorption_color=Input(fig, RGB(0, 0, 0)), - refraction_absorption_distance=Input(fig, Vec4(0)), refraction_caustics=Input(fig, true), - sss_scatter_color=Input(fig, RGB(0, 0, 0)), sss_scatter_distance=Input(fig, Vec4(0)), - sss_scatter_direction=Input(fig, Vec4(0)), sss_weight=Input(fig, Vec4(0)), - sss_multiscatter=Input(fig, false), backscatter_weight=Input(fig, Vec4(0)), - backscatter_color=Input(fig, RGB(0, 0, 0))) +sliders = ( + reflection_color = Input(fig, RGB(0, 0, 0)), reflection_weight = Input(fig, Vec4(0)), + reflection_roughness = Input(fig, Vec4(0)), reflection_anisotropy = Input(fig, Vec4(0)), + reflection_anisotropy_rotation = Input(fig, Vec4(0)), reflection_mode = Input(fig, Vec4(0)), + reflection_ior = Input(fig, Vec4(0)), reflection_metalness = Input(fig, Vec4(0)), + refraction_color = Input(fig, RGB(0, 0, 0)), refraction_weight = Input(fig, Vec4(0)), + refraction_roughness = Input(fig, Vec4(0)), refraction_ior = Input(fig, Vec4(0)), + refraction_absorption_color = Input(fig, RGB(0, 0, 0)), + refraction_absorption_distance = Input(fig, Vec4(0)), refraction_caustics = Input(fig, true), + sss_scatter_color = Input(fig, RGB(0, 0, 0)), sss_scatter_distance = Input(fig, Vec4(0)), + sss_scatter_direction = Input(fig, Vec4(0)), sss_weight = Input(fig, Vec4(0)), + sss_multiscatter = Input(fig, false), backscatter_weight = Input(fig, Vec4(0)), + backscatter_color = Input(fig, RGB(0, 0, 0)), +) labels = [] inputs = [] refresh = Observable(nothing) for (key, (obs, input)) in pairs(sliders) - push!(labels, Label(fig, string(key); justification=:left)) + push!(labels, Label(fig, string(key); justification = :left)) push!(inputs, input) on(obs) do value @show key value @@ -69,7 +75,7 @@ for (key, (obs, input)) in pairs(sliders) end end -fig[1, 2] = grid!(hcat(labels, inputs); width=500) +fig[1, 2] = grid!(hcat(labels, inputs); width = 500) GLMakie.activate!() cam = cameracontrols(ax.scene) @@ -78,10 +84,10 @@ cam.lookat[] = Vec3f(0, 0, -1) cam.upvector[] = Vec3f(0, 0, 1) cam.fov[] = 30 -GLMakie.activate!(inline=false) -display(fig; inline=false, backend=GLMakie) -RPRMakie.activate!(iterations=1, plugin=RPR.Northstar, resource=RPR.GPU0) -context, task = RPRMakie.replace_scene_rpr!(ax.scene, screen; refresh=refresh); +GLMakie.activate!(inline = false) +display(fig; inline = false, backend = GLMakie) +RPRMakie.activate!(iterations = 1, plugin = RPR.Northstar, resource = RPR.GPU0) +context, task = RPRMakie.replace_scene_rpr!(ax.scene, screen; refresh = refresh); nothing # Change light parameters interactively diff --git a/RPRMakie/examples/sea_cables.jl b/RPRMakie/examples/sea_cables.jl index 0f78515347f..afb47bb9b7a 100644 --- a/RPRMakie/examples/sea_cables.jl +++ b/RPRMakie/examples/sea_cables.jl @@ -48,24 +48,26 @@ end earth_img = load(Downloads.download("https://upload.wikimedia.org/wikipedia/commons/5/56/Blue_Marble_Next_Generation_%2B_topography_%2B_bathymetry.jpg")) # the actual plot ! -RPRMakie.activate!(; iterations=100) +RPRMakie.activate!(; iterations = 100) scene = with_theme(theme_dark()) do - fig = Figure(; size=(1000, 1000)) + fig = Figure(; size = (1000, 1000)) radiance = 30 - lights = [EnvironmentLight(0.5, load(RPR.assetpath("starmap_4k.tif"))), - PointLight(Vec3f(1, 1, 3), RGBf(radiance, radiance, radiance))] - ax = LScene(fig[1, 1]; show_axis=false, scenekw=(lights=lights,)) + lights = [ + EnvironmentLight(0.5, load(RPR.assetpath("starmap_4k.tif"))), + PointLight(Vec3f(1, 1, 3), RGBf(radiance, radiance, radiance)), + ] + ax = LScene(fig[1, 1]; show_axis = false, scenekw = (lights = lights,)) n = 1024 ÷ 4 # 2048 θ = LinRange(0, pi, n) φ = LinRange(-pi, pi, 2 * n) xe = [cos(φ) * sin(θ) for θ in θ, φ in φ] ye = [sin(φ) * sin(θ) for θ in θ, φ in φ] ze = [cos(θ) for θ in θ, φ in φ] - surface!(ax, xe, ye, ze; color=earth_img) - meshscatter!(toPoints3D; color=1:length(toPoints3D), markersize=0.005, colormap=:plasma) + surface!(ax, xe, ye, ze; color = earth_img) + meshscatter!(toPoints3D; color = 1:length(toPoints3D), markersize = 0.005, colormap = :plasma) colors = Makie.DEFAULT_PALETTES.color[] c = Iterators.cycle(colors) - foreach(((l, c),) -> lines!(ax, l; linewidth=2, color=c), zip(splitLines3D, c)) + foreach(((l, c),) -> lines!(ax, l; linewidth = 2, color = c), zip(splitLines3D, c)) ax.scene.camera_controls.eyeposition[] = Vec3f(1.5) return ax.scene end diff --git a/RPRMakie/examples/volume.jl b/RPRMakie/examples/volume.jl index c44b59b7dc1..7a3f38ad044 100644 --- a/RPRMakie/examples/volume.jl +++ b/RPRMakie/examples/volume.jl @@ -2,13 +2,15 @@ using RPRMakie using Makie, NIfTI, FileIO using GLMakie r = LinRange(-1, 1, 100) -cube = [(x .^ 2 + y .^ 2 + z .^ 2) for x = r, y = r, z = r] +cube = [(x .^ 2 + y .^ 2 + z .^ 2) for x in r, y in r, z in r] brain = Float32.(niread(Makie.assetpath("brain.nii.gz")).raw) radiance = 5000 -lights = [EnvironmentLight(1.0, load(RPR.assetpath("studio026.exr"))), - PointLight(Vec3f(10), RGBf(radiance, radiance, radiance * 1.1))] -fig = Figure(; size=(1000, 1000)) -ax = LScene(fig[1, 1]; show_axis=false, scenekw=(lights=lights,)) -Makie.volume!(ax, 0..3, 0..3.78, 0..3.18, brain, algorithm=:absorption, absorption=0.3) -display(ax.scene; iterations=5000) +lights = [ + EnvironmentLight(1.0, load(RPR.assetpath("studio026.exr"))), + PointLight(Vec3f(10), RGBf(radiance, radiance, radiance * 1.1)), +] +fig = Figure(; size = (1000, 1000)) +ax = LScene(fig[1, 1]; show_axis = false, scenekw = (lights = lights,)) +Makie.volume!(ax, 0 .. 3, 0 .. 3.78, 0 .. 3.18, brain, algorithm = :absorption, absorption = 0.3) +display(ax.scene; iterations = 5000) diff --git a/RPRMakie/src/RPRMakie.jl b/RPRMakie/src/RPRMakie.jl index b83ae20599e..c6e4de0d27f 100644 --- a/RPRMakie/src/RPRMakie.jl +++ b/RPRMakie/src/RPRMakie.jl @@ -35,7 +35,6 @@ function ScreenConfig(iterations::Int, max_recursion::Int, render_resource, rend end - include("scene.jl") include("lines.jl") include("meshes.jl") @@ -66,7 +65,7 @@ function __init__() return end -for name in names(Makie; all=true) +for name in names(Makie; all = true) if Base.isexported(Makie, name) @eval using Makie: $(name) @eval export $(name) diff --git a/RPRMakie/src/lines.jl b/RPRMakie/src/lines.jl index 5f85f8db0c3..e1944e85285 100644 --- a/RPRMakie/src/lines.jl +++ b/RPRMakie/src/lines.jl @@ -3,7 +3,7 @@ function line2segments(points) indices = RPR.rpr_int[] count = 0 for i in 1:npoints - push!(indices, i - 1) + push!(indices, i - 1) count += 1 if count == 4 && !(i == npoints) push!(indices, i - 1) @@ -34,7 +34,7 @@ function to_rpr_object(context, matsys, scene, plot::Makie.LineSegments) arg1 = to_value(plot[1]) isempty(arg1) && return nothing points = decompose(Point3f, arg1) - segments = TupleView{2,2}(RPR.rpr_int(0):RPR.rpr_int(length(points) - 1)) + segments = TupleView{2, 2}(RPR.rpr_int(0):RPR.rpr_int(length(points) - 1)) indices = RPR.rpr_int[] for (a, b) in segments @@ -57,8 +57,10 @@ function to_rpr_object(context, matsys, scene, plot::Makie.LineSegments) fill(Float32(plot.linewidth[] / 1000), nsegments) end - curve = RPR.Curve(context, points, indices, radius, Vec2f.(0.0, LinRange(0, 1, nsegments)), - fill(1, nsegments)) + curve = RPR.Curve( + context, points, indices, radius, Vec2f.(0.0, LinRange(0, 1, nsegments)), + fill(1, nsegments) + ) material = extract_material(matsys, plot) color = to_color(plot.color[]) @@ -75,7 +77,7 @@ function to_rpr_object(context, matsys, scene, plot::Makie.LineSegments) if color isa AbstractVector{<:Colorant} set_color!(copy(color)) elseif color isa AbstractVector{<:Number} - sampler = Makie.sampler(to_colormap(plot.colormap[]), color; scaling=Makie.Scaling(identity, plot.colorrange[])) + sampler = Makie.sampler(to_colormap(plot.colormap[]), color; scaling = Makie.Scaling(identity, plot.colorrange[])) set_color!(collect(sampler)) else material.color = to_color(color) diff --git a/RPRMakie/src/meshes.jl b/RPRMakie/src/meshes.jl index 976eec45db5..5c962fae0c7 100644 --- a/RPRMakie/src/meshes.jl +++ b/RPRMakie/src/meshes.jl @@ -1,7 +1,7 @@ function extract_material(matsys, plot) if haskey(plot, :material) && !isnothing(to_value(plot.material)) if plot.material isa Attributes - return RPR.Material(matsys, Dict(map(((k,v),)-> k => to_value(v), plot.material))) + return RPR.Material(matsys, Dict(map(((k, v),) -> k => to_value(v), plot.material))) else return plot.material[] end @@ -28,7 +28,7 @@ function mesh_material(context, matsys, plot, color_obs = plot.color) tex.data = img return tex end - elseif color isa Colorant || color isa Union{String,Symbol} + elseif color isa Colorant || color isa Union{String, Symbol} lift(to_color, plot, color_obs) elseif color isa Nothing # ignore! @@ -38,7 +38,7 @@ function mesh_material(context, matsys, plot, color_obs = plot.color) end material = extract_material(matsys, plot) - on(plot, color_signal; update=true) do color + on(plot, color_signal; update = true) do color if !isnothing(color) && hasproperty(material, :color) material.color = color end @@ -70,19 +70,19 @@ function to_rpr_object(context, matsys, scene, plot::Makie.MeshScatter) RPR.rprShapeSetObjectID(marker, 0) material = extract_material(matsys, plot) set!(marker, material) - for i in 1:(n_instances-1) + for i in 1:(n_instances - 1) inst = RPR.Shape(context, marker) RPR.rprShapeSetObjectID(inst, i) push!(instances, inst) end color = plot.calculated_colors[] - if color isa AbstractVector{<:Union{Number,Colorant}} || color isa Makie.ColorMapping + if color isa AbstractVector{<:Union{Number, Colorant}} || color isa Makie.ColorMapping c_converted = to_color(color) object_id = RPR.InputLookupMaterial(matsys) object_id.value = RPR.RPR_MATERIAL_NODE_LOOKUP_OBJECT_ID - uv = object_id * Vec3f(0, 1 / (n_instances-1), 0) - tex = RPR.Texture(matsys, reverse(c_converted)'; uv=uv) + uv = object_id * Vec3f(0, 1 / (n_instances - 1), 0) + tex = RPR.Texture(matsys, reverse(c_converted)'; uv = uv) material.color = tex elseif color isa Union{Colorant, AbstractMatrix{<:Colorant}} material.color = color @@ -125,7 +125,7 @@ function to_rpr_object(context, matsys, scene, plot::Makie.Voxels) RPR.rprShapeSetObjectID(marker, 0) material = extract_material(matsys, plot) set!(marker, material) - for i in 1:(n_instances-1) + for i in 1:(n_instances - 1) inst = RPR.Shape(context, marker) RPR.rprShapeSetObjectID(inst, i) push!(instances, inst) @@ -134,7 +134,7 @@ function to_rpr_object(context, matsys, scene, plot::Makie.Voxels) color_from_num = Makie.voxel_colors(plot) object_id = RPR.InputLookupMaterial(matsys) object_id.value = RPR.RPR_MATERIAL_NODE_LOOKUP_OBJECT_ID - uv = object_id * Vec3f(0, 1/n_instances, 0) + uv = object_id * Vec3f(0, 1 / n_instances, 0) tex = RPR.Texture(matsys, collect(color_from_num'); uv = uv) material.color = tex @@ -196,7 +196,7 @@ function Makie.plot!(plot::Matball) mat = getproperty(plot, name)[] mat = mat isa Makie.Automatic ? base : mat mesh = load(assetpath("matball_$(name).obj")) - mesh!(plot, mesh, material=mat, color=plot.color) + mesh!(plot, mesh, material = mat, color = plot.color) end return plot end diff --git a/RPRMakie/src/scene.jl b/RPRMakie/src/scene.jl index b37e63339fa..36dc4d64b92 100644 --- a/RPRMakie/src/scene.jl +++ b/RPRMakie/src/scene.jl @@ -28,11 +28,11 @@ function to_rpr_object(context, matsys, scene, plot) end function insert_plots!(context, matsys, scene, mscene::Makie.Scene, @nospecialize(plot::Plot)) - if isempty(plot.plots) # if no plots inserted, this truly is an atomic + return if isempty(plot.plots) # if no plots inserted, this truly is an atomic object = to_rpr_object(context, matsys, mscene, plot) if !isnothing(object) if object isa AbstractVector - foreach(x-> push!(scene, x), object) + foreach(x -> push!(scene, x), object) else push!(scene, object) end @@ -69,12 +69,12 @@ function to_rpr_light(context::RPR.Context, rpr_scene, light::Makie.DirectionalL directionallight = RPR.DirectionalLight(context) map(light.direction) do dir if light.camera_relative - T = inv(scene.camera.view[][Vec(1,2,3), Vec(1,2,3)]) + T = inv(scene.camera.view[][Vec(1, 2, 3), Vec(1, 2, 3)]) dir = normalize(T * dir) else dir = normalize(dir) end - quart = Makie.rotation_between(Vec3f(dir), Vec3f(0,0,-1)) + quart = Makie.rotation_between(Vec3f(dir), Vec3f(0, 0, -1)) transform!(directionallight, Makie.rotationmatrix4(quart)) end map(light.color) do c @@ -104,7 +104,7 @@ end function to_rpr_light(context::RPR.Context, rpr_scene, light::Makie.SpotLight) spotlight = RPR.SpotLight(context) map(light.position, light.direction) do pos, dir - quart = Makie.rotation_between(dir, Vec3f(0,0,-1)) + quart = Makie.rotation_between(dir, Vec3f(0, 0, -1)) transform!(spotlight, Makie.translationmatrix(pos) * Makie.rotationmatrix4(quart)) end map(light.color) do c @@ -154,7 +154,7 @@ function to_rpr_scene(context::RPR.Context, matsys, mscene::Makie.Scene) set!(context, scene) # Only set background image if it isn't set by env light, since # background image takes precedence - if !any(x-> x isa Makie.EnvironmentLight, mscene.lights) + if !any(x -> x isa Makie.EnvironmentLight, mscene.lights) env_img = fill(to_color(mscene.backgroundcolor[]), 1, 1) img = RPR.Image(context, env_img) RPR.rprSceneSetBackgroundImage(scene, img) @@ -170,7 +170,7 @@ function to_rpr_scene(context::RPR.Context, matsys, mscene::Makie.Scene) return scene end -function replace_scene_rpr!(scene::Makie.Scene, screen=Screen(scene); refresh=Observable(nothing)) +function replace_scene_rpr!(scene::Makie.Scene, screen = Screen(scene); refresh = Observable(nothing)) context = screen.context matsys = screen.matsys screen.scene = scene @@ -202,14 +202,14 @@ function replace_scene_rpr!(scene::Makie.Scene, screen=Screen(scene); refresh=Ob task = @async while isopen(scene) t = time() cam_values = update_rpr_camera!(cam_values, camera, cam_controls, cam) - framebuffer2 = render(screen; clear=clear[], iterations=1) + framebuffer2 = render(screen; clear = clear[], iterations = 1) if clear[] clear[] = false end data = RPR.get_data(framebuffer2) - im[1] = reverse(reshape(data, screen.fb_size); dims=2) + im[1] = reverse(reshape(data, screen.fb_size); dims = 2) tframe = time() - t - to_sleep = (1/10) - tframe + to_sleep = (1 / 10) - tframe if to_sleep < 0.0 yield() else @@ -248,11 +248,11 @@ Base.size(screen::Screen) = screen.fb_size function Base.show(io::IO, ::MIME"image/png", screen::Screen) img = colorbuffer(screen) - FileIO.save(FileIO.Stream{FileIO.format"PNG"}(Makie.raw_io(io)), img) + return FileIO.save(FileIO.Stream{FileIO.format"PNG"}(Makie.raw_io(io)), img) end function Makie.apply_screen_config!(screen::Screen, config::ScreenConfig) - context = RPR.Context(; resource=config.resource, plugin=config.plugin) + context = RPR.Context(; resource = config.resource, plugin = config.plugin) screen.context = context screen.matsys = RPR.MaterialSystem(context, 0) set_standard_tonemapping!(context) @@ -261,7 +261,7 @@ function Makie.apply_screen_config!(screen::Screen, config::ScreenConfig) return screen end -function Screen(fb_size::NTuple{2,<:Integer}; screen_config...) +function Screen(fb_size::NTuple{2, <:Integer}; screen_config...) config = Makie.merge_screen_config(ScreenConfig, Dict{Symbol, Any}(screen_config)) return Screen(fb_size, config) end @@ -280,8 +280,8 @@ end Screen(scene::Scene, config::ScreenConfig, ::IO, ::MIME) = Screen(scene, config) Screen(scene::Scene, config::ScreenConfig, ::Makie.ImageStorageFormat) = Screen(scene, config) -function Screen(fb_size::NTuple{2,<:Integer}, config::ScreenConfig) - context = RPR.Context(; resource=config.resource, plugin=config.plugin) +function Screen(fb_size::NTuple{2, <:Integer}, config::ScreenConfig) + context = RPR.Context(; resource = config.resource, plugin = config.plugin) matsys = RPR.MaterialSystem(context, 0) set_standard_tonemapping!(context) set!(context, RPR.RPR_CONTEXT_MAX_RECURSION, UInt(config.max_recursion)) @@ -291,10 +291,11 @@ function Screen(fb_size::NTuple{2,<:Integer}, config::ScreenConfig) return Screen( context, matsys, framebuffer1, framebuffer2, fb_size, nothing, false, nothing, - config.iterations, false) + config.iterations, false + ) end -function render(screen; clear=true, iterations=screen.iterations) +function render(screen; clear = true, iterations = screen.iterations) context = screen.context fb_size = screen.fb_size framebuffer1 = screen.framebuffer1 @@ -323,10 +324,10 @@ function Makie.colorbuffer(screen::Screen) display(screen, screen.scene) end data_1d = RPR.get_data(render(screen)) - r = reverse(reshape(data_1d, screen.fb_size), dims=2) + r = reverse(reshape(data_1d, screen.fb_size), dims = 2) img = rotl90(r) return map(img) do color - RGB{Colors.N0f8}(mapc(x-> clamp(x, 0, 1), color)) + RGB{Colors.N0f8}(mapc(x -> clamp(x, 0, 1), color)) end end diff --git a/RPRMakie/src/volume.jl b/RPRMakie/src/volume.jl index 197c56ed1a0..05f269dc9bb 100644 --- a/RPRMakie/src/volume.jl +++ b/RPRMakie/src/volume.jl @@ -26,7 +26,7 @@ function to_rpr_object(context, matsys, scene, plot::Makie.Volume) color_sampler.uv = gridsampler volmat = RPR.VolumeMaterial(matsys) - on(plot.absorption; update=true) do absorption + on(plot.absorption; update = true) do absorption return volmat.density = Vec4f(absorption, 0.0, 0.0, 0.0) end volmat.densitygrid = gridsampler diff --git a/RPRMakie/test/lines.jl b/RPRMakie/test/lines.jl index 9dba114232c..16abe3ddb2a 100644 --- a/RPRMakie/test/lines.jl +++ b/RPRMakie/test/lines.jl @@ -2,7 +2,7 @@ using GLMakie, GeometryBasics, RPRMakie, RadeonProRender using Colors, FileIO using Colors: N0f8 RPR = RadeonProRender -GLMakie.activate!(float=true, focus_on_show=false) +GLMakie.activate!(float = true, focus_on_show = false) cat = load(GLMakie.assetpath("cat.obj")) begin @@ -12,16 +12,16 @@ begin emissive = RPR.EmissiveMaterial(matsys) diffuse = RPR.DiffuseMaterial(matsys) - fig = Figure(size=(1000, 1000)) - ax = LScene(fig[1, 1], show_axis=false) + fig = Figure(size = (1000, 1000)) + ax = LScene(fig[1, 1], show_axis = false) for i in 4:4:12 n = i + 1 y = LinRange(0, i, n) y2 = (y ./ 2) .- 2 - lines!(ax, fill((i-5) ./ 2, n), y2, sin.(y) .+ 1, linewidth=5) + lines!(ax, fill((i - 5) ./ 2, n), y2, sin.(y) .+ 1, linewidth = 5) end - mesh!(ax, Rect3f(Vec3f(-3, -3, -0.1), Vec3f(6, 6, 0.1)), color=:white) - mesh!(ax, Sphere(Point3f(0, 0, 2), 0.1), material=emissive) + mesh!(ax, Rect3f(Vec3f(-3, -3, -0.1), Vec3f(6, 6, 0.1)), color = :white) + mesh!(ax, Sphere(Point3f(0, 0, 2), 0.1), material = emissive) display(fig) end # fetch(task) @@ -32,41 +32,41 @@ end begin - uber1.color =Vec4f(1, 1, 1, 1) - uber1.diffuse_weight =Vec4f(0, 0, 0, 0) - uber1.diffuse_roughness =Vec4f(1, 1, 1, 1) - uber1.reflection_color =Vec4f(0.996078, 0.858824, 0.639216, 0) - uber1.reflection_weight =Vec4f(1, 1, 1, 1) - uber1.reflection_roughness =Vec4f(0, 0, 0, 0) - uber1.reflection_anisotropy =Vec4f(0, 0, 0, 0) - uber1.reflection_anisotropy_rotation =Vec4f(0, 0, 0, 0) - uber1.reflection_ior =Vec4f(1.36, 1.36, 1.36, 1.36) - uber1.refraction_color =Vec4f(0.996078, 0.858824, 0.639216, 0) - uber1.refraction_weight =Vec4f(1, 1, 1, 1) - uber1.refraction_roughness =Vec4f(0, 0, 0, 0) - uber1.refraction_ior =Vec4f(1.36, 1.36, 1.36, 1.36) - uber1.refraction_absorption_color =Vec4f(0.996078, 0.858824, 0.639216, 0) - uber1.refraction_absorption_distance =Vec4f(0, 0, 0, 0) - uber1.refraction_caustics =Vec4f(0) - uber1.coating_color =Vec4f(1, 1, 1, 1) - uber1.coating_weight =Vec4f(0, 0, 0, 0) - uber1.coating_roughness =Vec4f(0, 0, 0, 0) - uber1.coating_ior =Vec4f(3, 3, 3, 3) - uber1.coating_metalness =Vec4f(0, 0, 0, 0) - uber1.coating_transmission_color =Vec4f(1, 1, 1, 1) - uber1.coating_thickness =Vec4f(0, 0, 0, 0) - uber1.sheen =Vec4f(1, 1, 1, 1) - uber1.sheen_tint =Vec4f(0, 0, 0, 0) - uber1.sheen_weight =Vec4f(0, 0, 0, 0) - uber1.emission_color =Vec4f(1, 1, 1, 1) - uber1.emission_weight =Vec3f( 0, 0, 0) - uber1.transparency =Vec4f(0, 0, 0, 0) - uber1.sss_scatter_color =Vec4f(0, 0, 0, 0) - uber1.sss_scatter_distance =Vec4f(0, 0, 0, 0) - uber1.sss_scatter_direction =Vec4f(0, 0, 0, 0) - uber1.sss_weight =Vec4f(0, 0, 0, 0) - uber1.backscatter_weight =Vec4f(0, 0, 0, 0) - uber1.backscatter_color =Vec4f(1, 1, 1, 1) + uber1.color = Vec4f(1, 1, 1, 1) + uber1.diffuse_weight = Vec4f(0, 0, 0, 0) + uber1.diffuse_roughness = Vec4f(1, 1, 1, 1) + uber1.reflection_color = Vec4f(0.996078, 0.858824, 0.639216, 0) + uber1.reflection_weight = Vec4f(1, 1, 1, 1) + uber1.reflection_roughness = Vec4f(0, 0, 0, 0) + uber1.reflection_anisotropy = Vec4f(0, 0, 0, 0) + uber1.reflection_anisotropy_rotation = Vec4f(0, 0, 0, 0) + uber1.reflection_ior = Vec4f(1.36, 1.36, 1.36, 1.36) + uber1.refraction_color = Vec4f(0.996078, 0.858824, 0.639216, 0) + uber1.refraction_weight = Vec4f(1, 1, 1, 1) + uber1.refraction_roughness = Vec4f(0, 0, 0, 0) + uber1.refraction_ior = Vec4f(1.36, 1.36, 1.36, 1.36) + uber1.refraction_absorption_color = Vec4f(0.996078, 0.858824, 0.639216, 0) + uber1.refraction_absorption_distance = Vec4f(0, 0, 0, 0) + uber1.refraction_caustics = Vec4f(0) + uber1.coating_color = Vec4f(1, 1, 1, 1) + uber1.coating_weight = Vec4f(0, 0, 0, 0) + uber1.coating_roughness = Vec4f(0, 0, 0, 0) + uber1.coating_ior = Vec4f(3, 3, 3, 3) + uber1.coating_metalness = Vec4f(0, 0, 0, 0) + uber1.coating_transmission_color = Vec4f(1, 1, 1, 1) + uber1.coating_thickness = Vec4f(0, 0, 0, 0) + uber1.sheen = Vec4f(1, 1, 1, 1) + uber1.sheen_tint = Vec4f(0, 0, 0, 0) + uber1.sheen_weight = Vec4f(0, 0, 0, 0) + uber1.emission_color = Vec4f(1, 1, 1, 1) + uber1.emission_weight = Vec3f(0, 0, 0) + uber1.transparency = Vec4f(0, 0, 0, 0) + uber1.sss_scatter_color = Vec4f(0, 0, 0, 0) + uber1.sss_scatter_distance = Vec4f(0, 0, 0, 0) + uber1.sss_scatter_direction = Vec4f(0, 0, 0, 0) + uber1.sss_weight = Vec4f(0, 0, 0, 0) + uber1.backscatter_weight = Vec4f(0, 0, 0, 0) + uber1.backscatter_color = Vec4f(1, 1, 1, 1) uber1.reflection_mode = UInt(RPR.RPR_UBER_MATERIAL_IOR_MODE_PBR) uber1.emission_mode = UInt(RPR.RPR_UBER_MATERIAL_EMISSION_MODE_SINGLESIDED) @@ -77,131 +77,131 @@ end begin - uber2.color = Vec4f(0.501961f0,0.0f0,0.0f0,0.0f0) - uber2.diffuse_weight = Vec4f(1.0f0,1.0f0,1.0f0,1.0f0) - uber2.diffuse_roughness = Vec4f(0.500000f0,0.500000f0,0.500000f0,0.500000f0) - uber2.reflection_color = Vec4f(0.490196f0,0.490196f0,0.490196f0,0.0f0) - uber2.reflection_weight = Vec4f(0.990000f0,0.990000f0,0.990000f0,0.990000f0) - uber2.reflection_roughness = Vec4f(0.008000f0,0.008000f0,0.008000f0,0.008000f0) - uber2.reflection_anisotropy = Vec4f(0.0f0,0.0f0,0.0f0,0.0f0) - uber2.reflection_anisotropy_rotation = Vec4f(0.0f0,0.0f0,0.0f0,0.0f0) + uber2.color = Vec4f(0.501961f0, 0.0f0, 0.0f0, 0.0f0) + uber2.diffuse_weight = Vec4f(1.0f0, 1.0f0, 1.0f0, 1.0f0) + uber2.diffuse_roughness = Vec4f(0.5f0, 0.5f0, 0.5f0, 0.5f0) + uber2.reflection_color = Vec4f(0.490196f0, 0.490196f0, 0.490196f0, 0.0f0) + uber2.reflection_weight = Vec4f(0.99f0, 0.99f0, 0.99f0, 0.99f0) + uber2.reflection_roughness = Vec4f(0.008f0, 0.008f0, 0.008f0, 0.008f0) + uber2.reflection_anisotropy = Vec4f(0.0f0, 0.0f0, 0.0f0, 0.0f0) + uber2.reflection_anisotropy_rotation = Vec4f(0.0f0, 0.0f0, 0.0f0, 0.0f0) uber2.reflection_mode = 1 - uber2.reflection_ior = Vec4f(1.460000f0,1.460000f0,1.460000f0,1.460000f0) - uber2.refraction_color = Vec4f(1.0f0,1.0f0,1.0f0,1.0f0) - uber2.refraction_weight = Vec4f(0.0f0,0.0f0,0.0f0,0.0f0) - uber2.refraction_roughness = Vec4f(0.0f0,0.0f0,0.0f0,0.0f0) - uber2.refraction_ior = Vec4f(1.500000f0,1.500000f0,1.500000f0,1.500000f0) + uber2.reflection_ior = Vec4f(1.46f0, 1.46f0, 1.46f0, 1.46f0) + uber2.refraction_color = Vec4f(1.0f0, 1.0f0, 1.0f0, 1.0f0) + uber2.refraction_weight = Vec4f(0.0f0, 0.0f0, 0.0f0, 0.0f0) + uber2.refraction_roughness = Vec4f(0.0f0, 0.0f0, 0.0f0, 0.0f0) + uber2.refraction_ior = Vec4f(1.5f0, 1.5f0, 1.5f0, 1.5f0) uber2.refraction_thin_surface = Vec4f(0) - uber2.refraction_absorption_color = Vec4f(1.0f0,1.0f0,1.0f0,0.0f0) - uber2.refraction_absorption_distance = Vec4f(1.0f0,1.0f0,1.0f0,0.0f0) + uber2.refraction_absorption_color = Vec4f(1.0f0, 1.0f0, 1.0f0, 0.0f0) + uber2.refraction_absorption_distance = Vec4f(1.0f0, 1.0f0, 1.0f0, 0.0f0) uber2.refraction_caustics = 1 - uber2.coating_color = Vec4f(0.490196f0,0.490196f0,0.490196f0,0.0f0) - uber2.coating_weight = Vec4f(1.0f0,1.0f0,1.0f0,1.0f0) - uber2.coating_roughness = Vec4f(0.008000f0,0.008000f0,0.008000f0,0.008000f0) + uber2.coating_color = Vec4f(0.490196f0, 0.490196f0, 0.490196f0, 0.0f0) + uber2.coating_weight = Vec4f(1.0f0, 1.0f0, 1.0f0, 1.0f0) + uber2.coating_roughness = Vec4f(0.008f0, 0.008f0, 0.008f0, 0.008f0) uber2.coating_mode = 1 - uber2.coating_ior = Vec4f(1.460000f0,1.460000f0,1.460000f0,1.460000f0) - uber2.coating_metalness = Vec4f(0.0f0,0.0f0,0.0f0,0.0f0) - uber2.coating_transmission_color = Vec4f(0.0f0,0.0f0,0.0f0,1.0f0) - uber2.coating_thickness = Vec4f(0.0f0,0.0f0,0.0f0,0.0f0) - uber2.sheen = Vec4f(1.0f0,1.0f0,1.0f0,1.0f0) - uber2.sheen_tint = Vec4f(0.0f0,0.0f0,0.0f0,0.0f0) - uber2.sheen_weight = Vec4f(0.0f0,0.0f0,0.0f0,0.0f0) - uber2.emission_color = Vec4f(1.0f0,1.0f0,1.0f0,1.0f0) - uber2.emission_weight = Vec4f(0.0f0,0.0f0,0.0f0,0.0f0) + uber2.coating_ior = Vec4f(1.46f0, 1.46f0, 1.46f0, 1.46f0) + uber2.coating_metalness = Vec4f(0.0f0, 0.0f0, 0.0f0, 0.0f0) + uber2.coating_transmission_color = Vec4f(0.0f0, 0.0f0, 0.0f0, 1.0f0) + uber2.coating_thickness = Vec4f(0.0f0, 0.0f0, 0.0f0, 0.0f0) + uber2.sheen = Vec4f(1.0f0, 1.0f0, 1.0f0, 1.0f0) + uber2.sheen_tint = Vec4f(0.0f0, 0.0f0, 0.0f0, 0.0f0) + uber2.sheen_weight = Vec4f(0.0f0, 0.0f0, 0.0f0, 0.0f0) + uber2.emission_color = Vec4f(1.0f0, 1.0f0, 1.0f0, 1.0f0) + uber2.emission_weight = Vec4f(0.0f0, 0.0f0, 0.0f0, 0.0f0) uber2.emission_mode = 1 - uber2.transparency = Vec4f(0.0f0,0.0f0,0.0f0,0.0f0) - uber2.sss_scatter_color = Vec4f(0.0f0,0.0f0,0.0f0,0.0f0) - uber2.sss_scatter_distance = Vec4f(0.0f0,0.0f0,0.0f0,0.0f0) - uber2.sss_scatter_direction = Vec4f(0.0f0,0.0f0,0.0f0,0.0f0) - uber2.sss_weight = Vec4f(0.0f0,0.0f0,0.0f0,0.0f0) + uber2.transparency = Vec4f(0.0f0, 0.0f0, 0.0f0, 0.0f0) + uber2.sss_scatter_color = Vec4f(0.0f0, 0.0f0, 0.0f0, 0.0f0) + uber2.sss_scatter_distance = Vec4f(0.0f0, 0.0f0, 0.0f0, 0.0f0) + uber2.sss_scatter_direction = Vec4f(0.0f0, 0.0f0, 0.0f0, 0.0f0) + uber2.sss_weight = Vec4f(0.0f0, 0.0f0, 0.0f0, 0.0f0) uber2.sss_multiscatter = false - uber2.backscatter_weight = Vec4f(0.0f0,0.0f0,0.0f0,0.0f0) - uber2.backscatter_color = Vec4f(0.501961f0,0.0f0,0.0f0,0.0f0) + uber2.backscatter_weight = Vec4f(0.0f0, 0.0f0, 0.0f0, 0.0f0) + uber2.backscatter_color = Vec4f(0.501961f0, 0.0f0, 0.0f0, 0.0f0) end begin - uber3.color = Vec4(0.752941,0.596078,0.443137,0.0) - uber3.diffuse_weight = Vec4(1.0,1.0,1.0,1.0) - uber3.diffuse_roughness = Vec4(0.500000,0.500000,0.500000,0.500000) - uber3.reflection_color = Vec4(0.666667,0.490196,0.313726,0.0) - uber3.reflection_weight = Vec4(1.0,1.0,1.0,1.0) - uber3.reflection_roughness = Vec4(0.300000,0.300000,0.300000,0.300000) - uber3.reflection_anisotropy = Vec4(0.0,0.0,0.0,0.0) - uber3.reflection_anisotropy_rotation = Vec4(0.0,0.0,0.0,0.0) + uber3.color = Vec4(0.752941, 0.596078, 0.443137, 0.0) + uber3.diffuse_weight = Vec4(1.0, 1.0, 1.0, 1.0) + uber3.diffuse_roughness = Vec4(0.5, 0.5, 0.5, 0.5) + uber3.reflection_color = Vec4(0.666667, 0.490196, 0.313726, 0.0) + uber3.reflection_weight = Vec4(1.0, 1.0, 1.0, 1.0) + uber3.reflection_roughness = Vec4(0.3, 0.3, 0.3, 0.3) + uber3.reflection_anisotropy = Vec4(0.0, 0.0, 0.0, 0.0) + uber3.reflection_anisotropy_rotation = Vec4(0.0, 0.0, 0.0, 0.0) uber3.reflection_mode = 2 - uber3.reflection_ior = Vec4(1.0,1.0,1.0,1.0) - uber3.refraction_color = Vec4(1.0,1.0,1.0,1.0) - uber3.refraction_weight = Vec4(0.0,0.0,0.0,0.0) - uber3.refraction_roughness = Vec4(0.0,0.0,0.0,0.0) - uber3.refraction_ior = Vec4(1.500000,1.500000,1.500000,1.500000) + uber3.reflection_ior = Vec4(1.0, 1.0, 1.0, 1.0) + uber3.refraction_color = Vec4(1.0, 1.0, 1.0, 1.0) + uber3.refraction_weight = Vec4(0.0, 0.0, 0.0, 0.0) + uber3.refraction_roughness = Vec4(0.0, 0.0, 0.0, 0.0) + uber3.refraction_ior = Vec4(1.5, 1.5, 1.5, 1.5) uber3.refraction_thin_surface = 0 - uber3.refraction_absorption_color = Vec4(1.0,1.0,1.0,0.0) - uber3.refraction_absorption_distance = Vec4(1.0,1.0,1.0,0.0) + uber3.refraction_absorption_color = Vec4(1.0, 1.0, 1.0, 0.0) + uber3.refraction_absorption_distance = Vec4(1.0, 1.0, 1.0, 0.0) uber3.refraction_caustics = 1 - uber3.coating_color = Vec4(0.752941,0.596078,0.443137,0.0) - uber3.coating_weight = Vec4(1.0,1.0,1.0,1.0) - uber3.coating_roughness = Vec4(0.420000,0.420000,0.420000,0.420000) + uber3.coating_color = Vec4(0.752941, 0.596078, 0.443137, 0.0) + uber3.coating_weight = Vec4(1.0, 1.0, 1.0, 1.0) + uber3.coating_roughness = Vec4(0.42, 0.42, 0.42, 0.42) uber3.coating_mode = 1 - uber3.coating_ior = Vec4(1.700000,1.700000,1.700000,1.700000) - uber3.coating_metalness = Vec4(0.0,0.0,0.0,0.0) - uber3.coating_transmission_color = Vec4(0.0,0.0,0.0,1.0) - uber3.coating_thickness = Vec4(0.0,0.0,0.0,0.0) - uber3.sheen = Vec4(1.0,1.0,1.0,1.0) - uber3.sheen_tint = Vec4(0.0,0.0,0.0,0.0) - uber3.sheen_weight = Vec4(0.0,0.0,0.0,0.0) - uber3.emission_color = Vec4(1.0,1.0,1.0,1.0) - uber3.emission_weight = Vec4(0.0,0.0,0.0,0.0) + uber3.coating_ior = Vec4(1.7, 1.7, 1.7, 1.7) + uber3.coating_metalness = Vec4(0.0, 0.0, 0.0, 0.0) + uber3.coating_transmission_color = Vec4(0.0, 0.0, 0.0, 1.0) + uber3.coating_thickness = Vec4(0.0, 0.0, 0.0, 0.0) + uber3.sheen = Vec4(1.0, 1.0, 1.0, 1.0) + uber3.sheen_tint = Vec4(0.0, 0.0, 0.0, 0.0) + uber3.sheen_weight = Vec4(0.0, 0.0, 0.0, 0.0) + uber3.emission_color = Vec4(1.0, 1.0, 1.0, 1.0) + uber3.emission_weight = Vec4(0.0, 0.0, 0.0, 0.0) uber3.emission_mode = 1 - uber3.transparency = Vec4(0.0,0.0,0.0,0.0) - uber3.sss_scatter_color = Vec4(0.0,0.0,0.0,0.0) - uber3.sss_scatter_distance = Vec4(0.0,0.0,0.0,0.0) - uber3.sss_scatter_direction = Vec4(0.0,0.0,0.0,0.0) - uber3.sss_weight = Vec4(0.0,0.0,0.0,0.0) + uber3.transparency = Vec4(0.0, 0.0, 0.0, 0.0) + uber3.sss_scatter_color = Vec4(0.0, 0.0, 0.0, 0.0) + uber3.sss_scatter_distance = Vec4(0.0, 0.0, 0.0, 0.0) + uber3.sss_scatter_direction = Vec4(0.0, 0.0, 0.0, 0.0) + uber3.sss_weight = Vec4(0.0, 0.0, 0.0, 0.0) uber3.sss_multiscatter = 0 - uber3.backscatter_weight = Vec4(0.0,0.0,0.0,0.0) - uber3.backscatter_color = Vec4(0.752941,0.596078,0.443137,0.0) + uber3.backscatter_weight = Vec4(0.0, 0.0, 0.0, 0.0) + uber3.backscatter_color = Vec4(0.752941, 0.596078, 0.443137, 0.0) end begin - uber4.color = Vec4f(1.0,1.0,1.0,1.0) - uber4.diffuse_weight = Vec4f(0.0,0.0,0.0,0.0) - uber4.diffuse_roughness = Vec4f(1.0,1.0,1.0,1.0) - uber4.reflection_color = Vec4f(0.501961,0.501961,0.501961,0.0) - uber4.reflection_weight = Vec4f(1.0,1.0,1.0,1.0) - uber4.reflection_roughness = Vec4f(0.0,0.0,0.0,0.0) - uber4.reflection_anisotropy = Vec4f(0.0,0.0,0.0,0.0) - uber4.reflection_anisotropy_rotation = Vec4f(0.0,0.0,0.0,0.0) + uber4.color = Vec4f(1.0, 1.0, 1.0, 1.0) + uber4.diffuse_weight = Vec4f(0.0, 0.0, 0.0, 0.0) + uber4.diffuse_roughness = Vec4f(1.0, 1.0, 1.0, 1.0) + uber4.reflection_color = Vec4f(0.501961, 0.501961, 0.501961, 0.0) + uber4.reflection_weight = Vec4f(1.0, 1.0, 1.0, 1.0) + uber4.reflection_roughness = Vec4f(0.0, 0.0, 0.0, 0.0) + uber4.reflection_anisotropy = Vec4f(0.0, 0.0, 0.0, 0.0) + uber4.reflection_anisotropy_rotation = Vec4f(0.0, 0.0, 0.0, 0.0) uber4.reflection_mode = 1 - uber4.reflection_ior = Vec4f(1.330000,1.330000,1.330000,1.330000) - uber4.refraction_color = Vec4f(0.501961,0.898039,0.996078,0.0) - uber4.refraction_weight = Vec4f(1.0,1.0,1.0,1.0) - uber4.refraction_roughness = Vec4f(0.0,0.0,0.0,0.0) - uber4.refraction_ior = Vec4f(1.330000,1.330000,1.330000,1.330000) + uber4.reflection_ior = Vec4f(1.33, 1.33, 1.33, 1.33) + uber4.refraction_color = Vec4f(0.501961, 0.898039, 0.996078, 0.0) + uber4.refraction_weight = Vec4f(1.0, 1.0, 1.0, 1.0) + uber4.refraction_roughness = Vec4f(0.0, 0.0, 0.0, 0.0) + uber4.refraction_ior = Vec4f(1.33, 1.33, 1.33, 1.33) uber4.refraction_thin_surface = 0 - uber4.refraction_absorption_color = Vec4f(0.501961,0.898039,0.996078,0.0) - uber4.refraction_absorption_distance = Vec4f(0.0,0.0,0.0,0.0) + uber4.refraction_absorption_color = Vec4f(0.501961, 0.898039, 0.996078, 0.0) + uber4.refraction_absorption_distance = Vec4f(0.0, 0.0, 0.0, 0.0) uber4.refraction_caustics = 0 - uber4.coating_color = Vec4f(1.0,1.0,1.0,1.0) - uber4.coating_weight = Vec4f(0.0,0.0,0.0,0.0) - uber4.coating_roughness = Vec4f(0.0,0.0,0.0,0.0) + uber4.coating_color = Vec4f(1.0, 1.0, 1.0, 1.0) + uber4.coating_weight = Vec4f(0.0, 0.0, 0.0, 0.0) + uber4.coating_roughness = Vec4f(0.0, 0.0, 0.0, 0.0) uber4.coating_mode = 1 - uber4.coating_ior = Vec4f(3.0,3.0,3.0,3.0) - uber4.coating_metalness = Vec4f(0.0,0.0,0.0,0.0) - uber4.coating_transmission_color = Vec4f(1.0,1.0,1.0,1.0) - uber4.coating_thickness = Vec4f(0.0,0.0,0.0,0.0) - uber4.sheen = Vec4f(1.0,1.0,1.0,1.0) - uber4.sheen_tint = Vec4f(0.0,0.0,0.0,0.0) - uber4.sheen_weight = Vec4f(0.0,0.0,0.0,0.0) - uber4.emission_color = Vec4f(1.0,1.0,1.0,1.0) - uber4.emission_weight = Vec4f(0.0,0.0,0.0,0.0) + uber4.coating_ior = Vec4f(3.0, 3.0, 3.0, 3.0) + uber4.coating_metalness = Vec4f(0.0, 0.0, 0.0, 0.0) + uber4.coating_transmission_color = Vec4f(1.0, 1.0, 1.0, 1.0) + uber4.coating_thickness = Vec4f(0.0, 0.0, 0.0, 0.0) + uber4.sheen = Vec4f(1.0, 1.0, 1.0, 1.0) + uber4.sheen_tint = Vec4f(0.0, 0.0, 0.0, 0.0) + uber4.sheen_weight = Vec4f(0.0, 0.0, 0.0, 0.0) + uber4.emission_color = Vec4f(1.0, 1.0, 1.0, 1.0) + uber4.emission_weight = Vec4f(0.0, 0.0, 0.0, 0.0) uber4.emission_mode = 1 - uber4.transparency = Vec4f(0.0,0.0,0.0,0.0) - uber4.sss_scatter_color = Vec4f(0.0,0.0,0.0,0.0) - uber4.sss_scatter_distance = Vec4f(0.0,0.0,0.0,0.0) - uber4.sss_scatter_direction = Vec4f(0.0,0.0,0.0,0.0) - uber4.sss_weight = Vec4f(0.0,0.0,0.0,0.0) + uber4.transparency = Vec4f(0.0, 0.0, 0.0, 0.0) + uber4.sss_scatter_color = Vec4f(0.0, 0.0, 0.0, 0.0) + uber4.sss_scatter_distance = Vec4f(0.0, 0.0, 0.0, 0.0) + uber4.sss_scatter_direction = Vec4f(0.0, 0.0, 0.0, 0.0) + uber4.sss_weight = Vec4f(0.0, 0.0, 0.0, 0.0) uber4.sss_multiscatter = 0 - uber4.backscatter_weight = Vec4f(0.0,0.0,0.0,0.0) - uber4.backscatter_color = Vec4f(1.0,1.0,1.0,1.0) + uber4.backscatter_weight = Vec4f(0.0, 0.0, 0.0, 0.0) + uber4.backscatter_color = Vec4f(1.0, 1.0, 1.0, 1.0) end diff --git a/RPRMakie/test/runtests.jl b/RPRMakie/test/runtests.jl index 730e57ca3df..a6db591a777 100644 --- a/RPRMakie/test/runtests.jl +++ b/RPRMakie/test/runtests.jl @@ -1,9 +1,9 @@ using RPRMakie using Test -RPRMakie.activate!(iterations=50) -f, ax, pl = meshscatter(rand(Point3f, 100), color=:blue) +RPRMakie.activate!(iterations = 50) +f, ax, pl = meshscatter(rand(Point3f, 100), color = :blue) out = joinpath(@__DIR__, "recorded") -isdir(out) && rm(out; recursive=true, force=true) +isdir(out) && rm(out; recursive = true, force = true) mkdir(out) save(joinpath(out, "test.png"), ax.scene); diff --git a/ReferenceTests/src/database.jl b/ReferenceTests/src/database.jl index 6bb2b835fd7..20170be9895 100644 --- a/ReferenceTests/src/database.jl +++ b/ReferenceTests/src/database.jl @@ -4,7 +4,11 @@ function used_functions(code) if @capture(x, f_(xs__)) push!(used_functions, Symbol(string(f))) end - if @capture(x, f_(xs__) do; body__; end) + if @capture( + x, f_(xs__) do; + body__ + end + ) push!(used_functions, Symbol(string(f))) end return x @@ -28,7 +32,7 @@ Records `code` and saves the result to `joinpath(ReferenceTests.RECORDING_DIR[], macro reference_test(name, code) title = string(name) funcs = used_functions(code) - skip = (title in SKIP_TITLES) || any(x-> x in funcs, SKIP_FUNCTIONS) + skip = (title in SKIP_TITLES) || any(x -> x in funcs, SKIP_FUNCTIONS) return quote @testset $(title) begin if $skip @@ -40,21 +44,23 @@ macro reference_test(name, code) error("title must be unique. Duplicate title: $(title)") end println("running $(lpad(COUNTER[] += 1, 3)): $($title)") - Makie.set_theme!(; size=(500, 500), - CairoMakie=(; px_per_unit=1), - GLMakie=(; scalefactor=1, px_per_unit=1), - WGLMakie=(; scalefactor=1, px_per_unit=1)) + Makie.set_theme!(; + size = (500, 500), + CairoMakie = (; px_per_unit = 1), + GLMakie = (; scalefactor = 1, px_per_unit = 1), + WGLMakie = (; scalefactor = 1, px_per_unit = 1) + ) ReferenceTests.RNG.seed_rng!() result = let $(esc(code)) end @test save_result(joinpath(RECORDING_DIR[], $title), result) push!($REGISTERED_TESTS, $title) - elapsed = round(time() - t1; digits=5) + elapsed = round(time() - t1; digits = 5) total = Sys.total_memory() - mem = round((total - Sys.free_memory()) / 10^9; digits=3) + mem = round((total - Sys.free_memory()) / 10^9; digits = 3) # TODO, write to file and create an overview in the end, similar to the benchmark results! - println("Used $(mem)gb of $(round(total / 10^9; digits=3))gb RAM, time: $(elapsed)s") + println("Used $(mem)gb of $(round(total / 10^9; digits = 3))gb RAM, time: $(elapsed)s") end end end @@ -66,57 +72,59 @@ end Helper, to more easily save all kind of results from the test database """ function save_result(path::String, scene::Makie.FigureLike) - isfile(path * ".png") && rm(path * ".png"; force=true) + isfile(path * ".png") && rm(path * ".png"; force = true) FileIO.save(path * ".png", scene) return true end function save_result(path::String, stream::VideoStream) - isfile(path * ".mp4") && rm(path * ".mp4"; force=true) + isfile(path * ".mp4") && rm(path * ".mp4"; force = true) FileIO.save(path * ".mp4", stream) return true end function save_result(path::String, object) - isfile(path) && rm(path; force=true) + isfile(path) && rm(path; force = true) FileIO.save(path, object) return true end -function mark_broken_tests(title_excludes = []; functions=[]) +function mark_broken_tests(title_excludes = []; functions = []) empty!(SKIP_TITLES) empty!(SKIP_FUNCTIONS) empty!(SKIPPED_NAMES) union!(SKIP_TITLES, title_excludes) - union!(SKIP_FUNCTIONS, functions) + return union!(SKIP_FUNCTIONS, functions) end mark_skipped!(name::String) = push!(SKIPPED_NAMES, name) macro include_reference_tests(backend::Symbol, path, paths...) toplevel_folder = dirname(string(__source__.file)) - return esc(quote - using ReferenceTests: @reference_test - include_paths = map([$path, $(paths...)]) do p - isdir(p) ? p : joinpath(@__DIR__, "tests", p) - end - recording_dir = joinpath($toplevel_folder, "reference_images") - if isdir(recording_dir) - rm(recording_dir; force=true, recursive=true) - end - # prefix the recordings with the backend name so that each backend has its own versions - ReferenceTests.RECORDING_DIR[] = joinpath(recording_dir, "recorded", $(string(backend))) - mkpath(ReferenceTests.RECORDING_DIR[]) - @testset "Reference tests $($(string(backend)))" begin - empty!(ReferenceTests.REGISTERED_TESTS) - for include_path in include_paths - include(include_path) + return esc( + quote + using ReferenceTests: @reference_test + include_paths = map([$path, $(paths...)]) do p + isdir(p) ? p : joinpath(@__DIR__, "tests", p) end + recording_dir = joinpath($toplevel_folder, "reference_images") + if isdir(recording_dir) + rm(recording_dir; force = true, recursive = true) + end + # prefix the recordings with the backend name so that each backend has its own versions + ReferenceTests.RECORDING_DIR[] = joinpath(recording_dir, "recorded", $(string(backend))) + mkpath(ReferenceTests.RECORDING_DIR[]) + @testset "Reference tests $($(string(backend)))" begin + empty!(ReferenceTests.REGISTERED_TESTS) + for include_path in include_paths + include(include_path) + end + end + recorded_files = collect(ReferenceTests.REGISTERED_TESTS) + recording_dir = recording_dir + empty!(ReferenceTests.REGISTERED_TESTS) + ReferenceTests.COUNTER[] = 0 + (recorded_files, recording_dir) end - recorded_files = collect(ReferenceTests.REGISTERED_TESTS) - recording_dir = recording_dir - empty!(ReferenceTests.REGISTERED_TESTS) - ReferenceTests.COUNTER[] = 0 - (recorded_files, recording_dir) - end) + ) end diff --git a/ReferenceTests/src/image_download.jl b/ReferenceTests/src/image_download.jl index e1e72cb9cf2..4b890a8cd88 100644 --- a/ReferenceTests/src/image_download.jl +++ b/ReferenceTests/src/image_download.jl @@ -5,7 +5,7 @@ function last_major_version() return "v" * string(VersionNumber(version.major, version.minor)) end -function download_refimages(tag=last_major_version()) +function download_refimages(tag = last_major_version()) url = "https://github.com/MakieOrg/Makie.jl/releases/download/$(tag)/reference_images.tar" images_tar = basedir("reference_images.tar") images = basedir("reference_images") @@ -17,7 +17,7 @@ function download_refimages(tag=last_major_version()) end end !isfile(images_tar) && download(url, images_tar) - isdir(images) && rm(images, recursive=true, force=true) + isdir(images) && rm(images, recursive = true, force = true) Tar.extract(images_tar, images) return images end diff --git a/ReferenceTests/src/runtests.jl b/ReferenceTests/src/runtests.jl index 52a689289d0..02cff567bda 100644 --- a/ReferenceTests/src/runtests.jl +++ b/ReferenceTests/src/runtests.jl @@ -6,7 +6,7 @@ rgbf_convert(x::AbstractMatrix{<:RGB}) = convert(Matrix{RGBf}, x) rgbf_convert(x::AbstractMatrix{<:RGBA}) = convert(Matrix{RGBAf}, x) function get_frames(video::AbstractString) - mktempdir() do folder + return mktempdir() do folder afolder = joinpath(folder, "a") mkpath(afolder) Makie.extract_frames(video, afolder) @@ -14,7 +14,7 @@ function get_frames(video::AbstractString) if length(aframes) > 10 # we don't want to compare too many frames since it's time costly # so we just compare 10 random frames if more than 10 - samples = range(1, stop=length(aframes), length=10) + samples = range(1, stop = length(aframes), length = 10) istep = round(Int, length(aframes) / 10) samples = 1:istep:length(aframes) aframes = aframes[samples] @@ -23,7 +23,7 @@ function get_frames(video::AbstractString) end end -function compare_images(a::AbstractMatrix{<:Union{RGB,RGBA}}, b::AbstractMatrix{<:Union{RGB,RGBA}}) +function compare_images(a::AbstractMatrix{<:Union{RGB, RGBA}}, b::AbstractMatrix{<:Union{RGB, RGBA}}) a = rgbf_convert(a) b = rgbf_convert(b) @@ -38,7 +38,7 @@ function compare_images(a::AbstractMatrix{<:Union{RGB,RGBA}}, b::AbstractMatrix{ range_dim1 = round.(Int, range(0, size(a, 1), length = ceil(Int, size(a, 1) / approx_tile_size_px))) range_dim2 = round.(Int, range(0, size(a, 2), length = ceil(Int, size(a, 2) / approx_tile_size_px))) - boundary_iter(boundaries) = zip(boundaries[1:end-1] .+ 1, boundaries[2:end]) + boundary_iter(boundaries) = zip(boundaries[1:(end - 1)] .+ 1, boundaries[2:end]) _norm(rgb1::RGBf, rgb2::RGBf) = sqrt(sum(((rgb1.r - rgb2.r)^2, (rgb1.g - rgb2.g)^2, (rgb1.b - rgb2.b)^2))) _norm(rgba1::RGBAf, rgba2::RGBAf) = sqrt(sum(((rgba1.r - rgba2.r)^2, (rgba1.g - rgba2.g)^2, (rgba1.b - rgba2.b)^2, (rgba1.alpha - rgba2.alpha)^2))) @@ -76,12 +76,12 @@ function compare_media(a::AbstractString, b::AbstractString) end function get_all_relative_filepaths_recursively(dir) - mapreduce(vcat, walkdir(dir)) do (root, dirs, files) + return mapreduce(vcat, walkdir(dir)) do (root, dirs, files) relpath.(joinpath.(root, files), dir) end end -function record_comparison(base_folder::String, backend::String; record_folder_name="recorded", tag=last_major_version()) +function record_comparison(base_folder::String, backend::String; record_folder_name = "recorded", tag = last_major_version()) record_folder = joinpath(base_folder, record_folder_name) @info "Downloading reference images" reference_folder = download_refimages(tag) @@ -99,7 +99,7 @@ function record_comparison(base_folder::String, backend::String; record_folder_n println(file, path) end end - + open(joinpath(base_folder, "missing_files.txt"), "w") do file backend_ref_dir = joinpath(reference_folder, backend) recorded_paths = mapreduce(vcat, walkdir(backend_ref_dir)) do (root, dirs, files) @@ -124,7 +124,7 @@ function record_comparison(base_folder::String, backend::String; record_folder_n end function test_comparison(scores; threshold) - @testset "Comparison scores" begin + return @testset "Comparison scores" begin for (image, score) in pairs(scores) @testset "$image" begin @test score <= threshold @@ -134,9 +134,9 @@ function test_comparison(scores; threshold) end function compare( - relative_test_paths::Vector{String}, reference_dir::String, record_dir; - o_refdir = reference_dir, missing_refimages = String[], - scores = Dict{String,Float64}() + relative_test_paths::Vector{String}, reference_dir::String, record_dir; + o_refdir = reference_dir, missing_refimages = String[], + scores = Dict{String, Float64}() ) for relative_test_path in relative_test_paths diff --git a/ReferenceTests/src/stable_rng.jl b/ReferenceTests/src/stable_rng.jl index ba257b3dd6b..de0157bac13 100644 --- a/ReferenceTests/src/stable_rng.jl +++ b/ReferenceTests/src/stable_rng.jl @@ -1,23 +1,23 @@ module RNG -using StableRNGs -using Colors -using Random + using StableRNGs + using Colors + using Random -const STABLE_RNG = StableRNG(123) + const STABLE_RNG = StableRNG(123) -rand(args...) = Base.rand(STABLE_RNG, args...) -randn(args...) = Base.randn(STABLE_RNG, args...) + rand(args...) = Base.rand(STABLE_RNG, args...) + randn(args...) = Base.randn(STABLE_RNG, args...) -seed_rng!() = Random.seed!(STABLE_RNG, 123) + seed_rng!() = Random.seed!(STABLE_RNG, 123) -function Base.rand(r::StableRNGs.LehmerRNG, ::Random.SamplerType{T}) where T <: ColorAlpha - return T(Base.rand(r), Base.rand(r), Base.rand(r), Base.rand(r)) -end + function Base.rand(r::StableRNGs.LehmerRNG, ::Random.SamplerType{T}) where {T <: ColorAlpha} + return T(Base.rand(r), Base.rand(r), Base.rand(r), Base.rand(r)) + end -function Base.rand(r::StableRNGs.LehmerRNG, ::Random.SamplerType{T}) where T <: AbstractRGB - return T(Base.rand(r), Base.rand(r), Base.rand(r)) -end + function Base.rand(r::StableRNGs.LehmerRNG, ::Random.SamplerType{T}) where {T <: AbstractRGB} + return T(Base.rand(r), Base.rand(r), Base.rand(r)) + end end diff --git a/ReferenceTests/src/tests/attributes.jl b/ReferenceTests/src/tests/attributes.jl index fd5483748b9..b54469d5745 100644 --- a/ReferenceTests/src/tests/attributes.jl +++ b/ReferenceTests/src/tests/attributes.jl @@ -1,17 +1,17 @@ @reference_test "visible" begin fig = Figure() colors = Makie.resample(to_colormap(:deep), 20) - scatter(fig[1, 1], RNG.randn(20), color=colors, markersize=10, visible=true) - scatter(fig[1, 2], RNG.randn(20), color=colors, markersize=10, visible=false) + scatter(fig[1, 1], RNG.randn(20), color = colors, markersize = 10, visible = true) + scatter(fig[1, 2], RNG.randn(20), color = colors, markersize = 10, visible = false) fig end @reference_test "(mesh)scatter with NaN rotation and markersize" begin scene = Scene(size = (150, 300)) xs = [-0.6, 0.0, 0.6] - scatter!(scene, xs, fill( 0.75, 3), marker = :ltriangle, rotation = [0.5, NaN, -0.5], markersize = 50) - scatter!(scene, xs, fill( 0.25, 3), marker = :ltriangle, markersize = [50, NaN, 50]) - meshscatter!(scene, xs, fill(-0.25, 3), marker = Rect2f(-0.5,-0.5,1,1), rotation = [0.5, NaN, -0.5], markersize = 0.2) - meshscatter!(scene, xs, fill(-0.75, 3), marker = Rect2f(-0.5,-0.5,1,1), markersize = [0.2, NaN, 0.2]) + scatter!(scene, xs, fill(0.75, 3), marker = :ltriangle, rotation = [0.5, NaN, -0.5], markersize = 50) + scatter!(scene, xs, fill(0.25, 3), marker = :ltriangle, markersize = [50, NaN, 50]) + meshscatter!(scene, xs, fill(-0.25, 3), marker = Rect2f(-0.5, -0.5, 1, 1), rotation = [0.5, NaN, -0.5], markersize = 0.2) + meshscatter!(scene, xs, fill(-0.75, 3), marker = Rect2f(-0.5, -0.5, 1, 1), markersize = [0.2, NaN, 0.2]) scene -end \ No newline at end of file +end diff --git a/ReferenceTests/src/tests/categorical.jl b/ReferenceTests/src/tests/categorical.jl index 4740ac2a4a4..13b78a76886 100644 --- a/ReferenceTests/src/tests/categorical.jl +++ b/ReferenceTests/src/tests/categorical.jl @@ -3,8 +3,8 @@ using Test using Makie: Categorical @reference_test "multi plot, error with non categorical" begin - f, ax, p = scatter(1:4, Categorical(["a", "b", "c", "a"]), color=1:4, colormap=:viridis, markersize=20) - scatter!(ax, 1:4, Categorical(["b", "x", "a", "c"]), color=1:4, colormap=:reds, markersize=20) + f, ax, p = scatter(1:4, Categorical(["a", "b", "c", "a"]), color = 1:4, colormap = :viridis, markersize = 20) + scatter!(ax, 1:4, Categorical(["b", "x", "a", "c"]), color = 1:4, colormap = :reds, markersize = 20) # TODO, throw better error (not that easy since we need to check for sortability) @test_throws MethodError scatter!(ax, 1:4, 1:4) # error f @@ -14,21 +14,23 @@ end # If we set the ticks explicitly, with sortby defaulting to nothing, # we can combine all objects: f = Figure() - ax = Axis(f[1, 1]; - dim1_conversion=Makie.CategoricalConversion(; sortby=nothing), - dim2_conversion=Makie.CategoricalConversion(; sortby=nothing)) + ax = Axis( + f[1, 1]; + dim1_conversion = Makie.CategoricalConversion(; sortby = nothing), + dim2_conversion = Makie.CategoricalConversion(; sortby = nothing) + ) - p = scatter!(ax, 1:4, Categorical(["a", "b", "c", "a"]); color=1:4, colormap=:viridis, markersize=20) - sp = scatter!(ax, 1:4, 1:4; color=1:4, colormap=:reds, markersize=20) - scatter!(ax, [1im, 2im], 1:2, color=[:red, :black], markersize=20) + p = scatter!(ax, 1:4, Categorical(["a", "b", "c", "a"]); color = 1:4, colormap = :viridis, markersize = 20) + sp = scatter!(ax, 1:4, 1:4; color = 1:4, colormap = :reds, markersize = 20) + scatter!(ax, [1im, 2im], 1:2, color = [:red, :black], markersize = 20) f end @reference_test "new random categories, interactive" begin obs = Observable(Categorical(["o", "m", "d", "p", "p"])) obs2 = Observable(Categorical(["q", "f", "y", "e", "n"])) - f, ax, pl = scatter(1:5, obs, markersize=20, color=1:5, colormap=:viridis) - scatter!(1:5, obs2, markersize=20, color=1:5, colormap=:reds) + f, ax, pl = scatter(1:5, obs, markersize = 20, color = 1:5, colormap = :viridis) + scatter!(1:5, obs2, markersize = 20, color = 1:5, colormap = :reds) obs[] = Categorical(["f", "z", "a", "u", "z"]) obs2[] = Categorical(["i", "s", "n", "i", "o"]) autolimits!(ax) @@ -37,14 +39,14 @@ end @reference_test "changing order of categorical values" begin obs = Observable(Categorical(["a", "a", "b", "b"])) - f, ax, p = scatter(1:4, obs; markersize=20, color=1:4, colormap=:viridis) + f, ax, p = scatter(1:4, obs; markersize = 20, color = 1:4, colormap = :viridis) obs[] = Categorical(["a", "b", "a", "b"]) f end @reference_test "new categories, in between old values" begin obs = Observable(Categorical(["a", "c", "e", "g"])) - f, ax, p = scatter(1:4, obs, markersize=20, color=1:4, colormap=:viridis) + f, ax, p = scatter(1:4, obs, markersize = 20, color = 1:4, colormap = :viridis) obs[] = Categorical(["b", "d", "f", "h"]) f end @@ -55,15 +57,15 @@ end @reference_test "custom struct, with custom sorting function" begin f = Figure() - conversion = Makie.CategoricalConversion(sortby=x->x.value) - xtickformat = x-> string.(getfield.(x, :value)) .* " val" - ax = Axis(f[1, 1]; dim1_conversion=conversion, xtickformat=xtickformat) + conversion = Makie.CategoricalConversion(sortby = x -> x.value) + xtickformat = x -> string.(getfield.(x, :value)) .* " val" + ax = Axis(f[1, 1]; dim1_conversion = conversion, xtickformat = xtickformat) barplot!(ax, SomeStruct.([:a, :b, :c]), 1:3) f end @reference_test "Categorical xticks yticks" begin - f, ax, p = scatter(Categorical(["a", "b", "c", "d"]), Categorical(["a", "a", "c", "x"]), markersize=20) + f, ax, p = scatter(Categorical(["a", "b", "c", "d"]), Categorical(["a", "a", "c", "x"]), markersize = 20) ax.xticks = ["a", "d"] ax.yticks = ["a", "b", "d", "x"] f diff --git a/ReferenceTests/src/tests/dates.jl b/ReferenceTests/src/tests/dates.jl index 68ee8cae1e9..cf2df6e62b6 100644 --- a/ReferenceTests/src/tests/dates.jl +++ b/ReferenceTests/src/tests/dates.jl @@ -3,20 +3,20 @@ using Makie.Unitful, Makie.Dates, Test some_time = Time("11:11:55.914") date = Date("2021-10-27") date_time = DateTime("2021-10-27T11:11:55.914") -time_range = some_time .+ range(Second(0); step=Second(5), length=10) -date_range = range(date, step=Day(5), length=10) -date_time_range = range(date_time, step=Week(5), length=10) +time_range = some_time .+ range(Second(0); step = Second(5), length = 10) +date_range = range(date, step = Day(5), length = 10) +date_time_range = range(date_time, step = Week(5), length = 10) @reference_test "Time & Date ranges" begin f = Figure() - scatter(f[1, 1], time_range, 1:10, axis = (xticklabelrotation = pi/4, )) - scatter(f[1, 2], date_range, 1:10, axis = (xticklabelrotation = pi/4, )) - scatter(f[2, 1], date_time_range, 1:10, axis = (xticklabelrotation = pi/4, )) + scatter(f[1, 1], time_range, 1:10, axis = (xticklabelrotation = pi / 4,)) + scatter(f[1, 2], date_range, 1:10, axis = (xticklabelrotation = pi / 4,)) + scatter(f[2, 1], date_time_range, 1:10, axis = (xticklabelrotation = pi / 4,)) f end @reference_test "Don'some_time allow mixing units incorrectly" begin - date_time_range = range(date_time, step=Second(5), length=10) + date_time_range = range(date_time, step = Second(5), length = 10) f, ax, pl = scatter(date_time_range, 1:10) @test_throws ErrorException scatter!(time_range, 1:10) f @@ -24,13 +24,13 @@ end @reference_test "Force Unitful to be rendered as Time" begin yconversion = Makie.DateTimeConversion(Time) - scatter(1:4, (1:4) .* u"s"; axis=(dim2_conversion=yconversion,)) + scatter(1:4, (1:4) .* u"s"; axis = (dim2_conversion = yconversion,)) end @reference_test "Time Observable" begin obs = Observable(time_range) f, ax, pl = scatter(obs, 1:10) - obs[] = some_time .+ range(Second(0); step=Second(1), length=10) + obs[] = some_time .+ range(Second(0); step = Second(1), length = 10) autolimits!(ax) f end @@ -38,7 +38,7 @@ end @reference_test "Date Observable" begin obs = Observable(date_range) f, ax, pl = scatter(obs, 1:10) - obs[] = range(date, step=Day(1), length=10) + obs[] = range(date, step = Day(1), length = 10) autolimits!(ax) f end @@ -46,7 +46,7 @@ end @reference_test "DateTime Observable" begin obs = Observable(date_time_range) f, ax, pl = scatter(obs, 1:10) - obs[] = range(date_time, step=Week(3), length=10) + obs[] = range(date_time, step = Week(3), length = 10) autolimits!(ax) f end diff --git a/ReferenceTests/src/tests/examples2d.jl b/ReferenceTests/src/tests/examples2d.jl index 9183c9c091c..7f517e81bce 100644 --- a/ReferenceTests/src/tests/examples2d.jl +++ b/ReferenceTests/src/tests/examples2d.jl @@ -1,4 +1,3 @@ - @reference_test "RGB heatmap, heatmap + image overlap" begin fig = Figure() heatmap(fig[1, 1], RNG.rand(32, 32)) @@ -29,17 +28,17 @@ end @reference_test "poly and colormap" begin # example by @Paulms from MakieOrg/Makie.jl#310 points = Point2f[[0.0, 0.0], [0.1, 0.0], [0.1, 0.1], [0.0, 0.1]] - colors = [0.0 ,0.0, 0.5, 0.0] - fig, ax, polyplot = poly(points, color=colors, colorrange=(0.0, 1.0)) + colors = [0.0, 0.0, 0.5, 0.0] + fig, ax, polyplot = poly(points, color = colors, colorrange = (0.0, 1.0)) points = Point2f[[0.1, 0.1], [0.2, 0.1], [0.2, 0.2], [0.1, 0.2]] - colors = [0.5,0.5,1.0,0.3] - poly!(ax, points, color=colors, colorrange=(0.0, 1.0)) + colors = [0.5, 0.5, 1.0, 0.3] + poly!(ax, points, color = colors, colorrange = (0.0, 1.0)) fig end @reference_test "quiver" begin - x = range(-2, stop=2, length=21) - arrows(x, x, RNG.rand(21, 21), RNG.rand(21, 21), arrowsize=0.05) + x = range(-2, stop = 2, length = 21) + arrows(x, x, RNG.rand(21, 21), RNG.rand(21, 21), arrowsize = 0.05) end @reference_test "Arrows on hemisphere" begin @@ -47,13 +46,13 @@ end fig, ax, meshplot = mesh(s) pos = decompose(Point3f, s) dirs = decompose_normals(s) - arrows!(ax, pos, dirs, arrowcolor=:red, arrowsize=0.1, linecolor=:red) + arrows!(ax, pos, dirs, arrowcolor = :red, arrowsize = 0.1, linecolor = :red) fig end @reference_test "image" begin fig = Figure() - image(fig[1,1], Makie.logo(), axis = (; aspect = DataAspect())) + image(fig[1, 1], Makie.logo(), axis = (; aspect = DataAspect())) image(fig[1, 2], RNG.rand(100, 500), axis = (; aspect = DataAspect())) fig end @@ -83,19 +82,20 @@ end color = [0.0, 0.0, 0.0, 0.0, -0.375, 0.0, 0.0, 0.0, 0.0] f = Figure() - poly(f[1, 1], coordinates, connectivity, color=color, strokecolor=(:black, 0.6), strokewidth=4) + poly(f[1, 1], coordinates, connectivity, color = color, strokecolor = (:black, 0.6), strokewidth = 4) - a, meshplot = mesh(f[2, 1], coordinates, connectivity, color=color, shading=NoShading) - wireframe!(meshplot[1], color=(:black, 0.6), linewidth=3) + a, meshplot = mesh(f[2, 1], coordinates, connectivity, color = color, shading = NoShading) + wireframe!(meshplot[1], color = (:black, 0.6), linewidth = 3) cat = loadasset("cat.obj") vertices = decompose(Point3f, cat) faces = decompose(TriangleFace{Int}, cat) - coordinates = [vertices[i][j] for i = 1:length(vertices), j = 1:3] - connectivity = [faces[i][j] for i = 1:length(faces), j = 1:3] - mesh(f[1:2, 2], + coordinates = [vertices[i][j] for i in 1:length(vertices), j in 1:3] + connectivity = [faces[i][j] for i in 1:length(faces), j in 1:3] + mesh( + f[1:2, 2], coordinates, connectivity, - color=RNG.rand(length(vertices)) + color = RNG.rand(length(vertices)) ) f @@ -103,15 +103,17 @@ end @reference_test "colored triangle (mesh, poly, 3D) + poly stroke" begin f = Figure() - mesh(f[1, 1], - [(0.0, 0.0), (0.5, 1.0), (1.0, 0.0)], color=[:red, :green, :blue], - shading=NoShading + mesh( + f[1, 1], + [(0.0, 0.0), (0.5, 1.0), (1.0, 0.0)], color = [:red, :green, :blue], + shading = NoShading ) - poly(f[1, 2], + poly( + f[1, 2], [(0.0, 0.0), (0.5, 1.0), (1.0, 0.0)], - color=[:red, :green, :blue], - strokecolor=:black, strokewidth=2 + color = [:red, :green, :blue], + strokecolor = :black, strokewidth = 2 ) x = [0, 1, 2, 0] @@ -122,10 +124,10 @@ end j = [1, 2, 3, 2] k = [2, 3, 1, 3] # indices interpreted as triangles (every 3 sequential indices) - indices = [1, 2, 3, 1, 3, 4, 1, 4, 2, 2, 3, 4] - mesh(f[2, 1], x, y, z, indices, color=color) + indices = [1, 2, 3, 1, 3, 4, 1, 4, 2, 2, 3, 4] + mesh(f[2, 1], x, y, z, indices, color = color) - ax, p = poly(f[2, 2], [Rect2f(0, 0, 1, 1)], color=:green, strokewidth=50, strokecolor=:black) + ax, p = poly(f[2, 2], [Rect2f(0, 0, 1, 1)], color = :green, strokewidth = 50, strokecolor = :black) xlims!(ax, -0.5, 1.5) ylims!(ax, -0.5, 1.5) @@ -133,30 +135,35 @@ end end @reference_test "scale_plot" begin - t = range(0, stop=1, length=500) # time steps + t = range(0, stop = 1, length = 500) # time steps θ = (6π) .* t # angles x = # x coords of spiral - y = # y coords of spiral - lines(t .* cos.(θ), t .* sin.(θ); - color=t, colormap=:algae, linewidth=8, axis = (; aspect = DataAspect())) + y = # y coords of spiral + lines( + t .* cos.(θ), t .* sin.(θ); + color = t, colormap = :algae, linewidth = 8, axis = (; aspect = DataAspect()) + ) end @reference_test "Polygons" begin - points = decompose(Point2f, Circle(Point2f(50), 50f0)) - fig, ax, pol = poly(points, color=:gray, strokewidth=10, strokecolor=:red) + points = decompose(Point2f, Circle(Point2f(50), 50.0f0)) + fig, ax, pol = poly(points, color = :gray, strokewidth = 10, strokecolor = :red) # Optimized forms - poly!(ax, [Circle(Point2f(50 + 300), 50f0)], color=:gray, strokewidth=10, strokecolor=:red) - poly!(ax, [Circle(Point2f(50 + i, 50 + i), 10f0) for i = 1:100:400], color=:red) - poly!(ax, [Rect2f(50 + i, 50 + i, 20, 20) for i = 1:100:400], strokewidth=2, strokecolor=:green) - linesegments!(ax, - [Point2f(50 + i, 50 + i) => Point2f(i + 70, i + 70) for i = 1:100:400], linewidth=8, color=:purple + poly!(ax, [Circle(Point2f(50 + 300), 50.0f0)], color = :gray, strokewidth = 10, strokecolor = :red) + poly!(ax, [Circle(Point2f(50 + i, 50 + i), 10.0f0) for i in 1:100:400], color = :red) + poly!(ax, [Rect2f(50 + i, 50 + i, 20, 20) for i in 1:100:400], strokewidth = 2, strokecolor = :green) + linesegments!( + ax, + [Point2f(50 + i, 50 + i) => Point2f(i + 70, i + 70) for i in 1:100:400], linewidth = 8, color = :purple + ) + poly!( + ax, [Polygon(decompose(Point2f, Rect2f(150, 0, 100, 100))), Polygon(decompose(Point2f, Circle(Point2f(350, 200), 50)))], + color = :gray, strokewidth = 10, strokecolor = :red ) - poly!(ax, [Polygon(decompose(Point2f, Rect2f(150, 0, 100, 100))), Polygon(decompose(Point2f, Circle(Point2f(350, 200), 50)))], - color=:gray, strokewidth=10, strokecolor=:red) # single objects - poly!(ax, Circle(Point2f(50, 350), 50), color=:gray, strokewidth=10, strokecolor=:red) - poly!(ax, Rect2f(0, 150, 100, 100), color=:gray, strokewidth=10, strokecolor=:red) - poly!(ax, Polygon(decompose(Point2f, Rect2f(150, 300, 100, 100))), color=:gray, strokewidth=10, strokecolor=:red) + poly!(ax, Circle(Point2f(50, 350), 50), color = :gray, strokewidth = 10, strokecolor = :red) + poly!(ax, Rect2f(0, 150, 100, 100), color = :gray, strokewidth = 10, strokecolor = :red) + poly!(ax, Polygon(decompose(Point2f, Rect2f(150, 300, 100, 100))), color = :gray, strokewidth = 10, strokecolor = :red) fig end @@ -164,12 +171,12 @@ end # Sample 100 Brownian motion path and plot the mean trajectory together # with a ±1σ band (visualizing uncertainty as marginal standard deviation). n, m = 100, 101 - t = range(0, 1, length=m) - X = cumsum(RNG.randn(n, m), dims=2) + t = range(0, 1, length = m) + X = cumsum(RNG.randn(n, m), dims = 2) X = X .- X[:, 1] - μ = vec(mean(X, dims=1)) # mean + μ = vec(mean(X, dims = 1)) # mean lines(t, μ) # plot mean line - σ = vec(std(X, dims=1)) # stddev + σ = vec(std(X, dims = 1)) # stddev band!(t, μ + σ, μ - σ) # plot stddev band current_figure() end @@ -209,22 +216,24 @@ end end @reference_test "Streamplot animation" begin - v(x::Point2{T}, t) where T = Point2{T}(one(T) * x[2] * t, 4 * x[1]) + v(x::Point2{T}, t) where {T} = Point2{T}(one(T) * x[2] * t, 4 * x[1]) sf = Observable(Base.Fix2(v, 0.0)) title_str = Observable("t = 0.00") - sp = streamplot(sf, -2..2, -2..2; - linewidth=2, colormap=:magma, axis=(;title=title_str)) - Record(sp, LinRange(0, 20, 5); framerate=1) do i + sp = streamplot( + sf, -2 .. 2, -2 .. 2; + linewidth = 2, colormap = :magma, axis = (; title = title_str) + ) + Record(sp, LinRange(0, 20, 5); framerate = 1) do i sf[] = Base.Fix2(v, i) - title_str[] = "t = $(round(i; sigdigits=2))" + title_str[] = "t = $(round(i; sigdigits = 2))" end end @reference_test "Line changing colour" begin - fig, ax, lineplot = lines(RNG.rand(10); linewidth=10) + fig, ax, lineplot = lines(RNG.rand(10); linewidth = 10) N = 20 - Record(fig, 1:N; framerate=1) do i + Record(fig, 1:N; framerate = 1) do i lineplot.color = RGBf(i / N, (N - i) / N, 0) # animate scene end end @@ -243,7 +252,7 @@ let P.γ * x[1] - x[2] + P.β ) ff(x) = ff(x, P) - streamplot(ff, -1.5..1.5, -1.5..1.5, colormap=:magma) + streamplot(ff, -1.5 .. 1.5, -1.5 .. 1.5, colormap = :magma) end end @@ -251,17 +260,18 @@ end N = 7 # number of colours in default palette fig = Figure() ax = Axis(fig) - fig[1,1] = ax + fig[1, 1] = ax st = Stepper(fig) xs = 0:9 # data ys = zeros(10) colors = Makie.DEFAULT_PALETTES.color[] plots = map(1:N) do i # plot lines - lines!(ax, + lines!( + ax, xs, ys; - color=colors[i], - linewidth=5 + color = colors[i], + linewidth = 5 ) # plot lines with colors end @@ -269,14 +279,15 @@ end for (i, rot) in enumerate(LinRange(0, π / 2, N)) Makie.rotate!(plots[i], rot) - arc!(ax, + arc!( + ax, Point2f(0), (8 - i), pi / 2, (pi / 2 - rot); - color=plots[i].color, - linewidth=5, - linestyle=:dash + color = plots[i].color, + linewidth = 5, + linestyle = :dash ) end @@ -366,72 +377,74 @@ end highs = LinRange(0.1, 0.4, length(vals)) fig, ax, rbars = rangebars(vals, lows, highs, color = :red) - rangebars!(ax, vals, lows, highs, color = LinRange(0, 1, length(vals)), - whiskerwidth = 3, direction = :x) + rangebars!( + ax, vals, lows, highs, color = LinRange(0, 1, length(vals)), + whiskerwidth = 3, direction = :x + ) fig end @reference_test "Simple pie charts" begin fig = Figure() - pie(fig[1, 1], 1:5, color=collect(1:5), axis=(;aspect=DataAspect())) - pie(fig[1, 2], 1:5, color=collect(1.0:5), radius=2, inner_radius=1, axis=(;aspect=DataAspect())) - pie(fig[2, 1], 0.1:0.1:1.0, normalize=false, axis=(;aspect=DataAspect())) + pie(fig[1, 1], 1:5, color = collect(1:5), axis = (; aspect = DataAspect())) + pie(fig[1, 2], 1:5, color = collect(1.0:5), radius = 2, inner_radius = 1, axis = (; aspect = DataAspect())) + pie(fig[2, 1], 0.1:0.1:1.0, normalize = false, axis = (; aspect = DataAspect())) fig end @reference_test "Pie with Segment-specific Radius" begin fig = Figure() - ax = Axis(fig[1, 1]; autolimitaspect=1) + ax = Axis(fig[1, 1]; autolimitaspect = 1) - kw = (; offset_radius=0.4, strokecolor=:transparent, strokewidth=0) - pie!(ax, ones(7); radius=sqrt.(2:8) * 3, kw..., color=Makie.wong_colors(0.8)[1:7]) + kw = (; offset_radius = 0.4, strokecolor = :transparent, strokewidth = 0) + pie!(ax, ones(7); radius = sqrt.(2:8) * 3, kw..., color = Makie.wong_colors(0.8)[1:7]) vs = [2, 3, 4, 5, 6, 7, 8] vs_inner = [1, 1, 1, 1, 2, 2, 2] rs = 8 rs_inner = sqrt.(vs_inner ./ vs) * rs - lp = Makie.LinePattern(; direction=Makie.Vec2f(1, -1), width=2, tilesize=(12, 12), linecolor=:darkgrey, background_color=:transparent) + lp = Makie.LinePattern(; direction = Makie.Vec2f(1, -1), width = 2, tilesize = (12, 12), linecolor = :darkgrey, background_color = :transparent) # draw the inner pie twice since `color` can not be vector of `LinePattern` currently - pie!(ax, 20, 0, vs; radius=rs_inner, inner_radius=0, kw..., color=Makie.wong_colors(0.4)[eachindex(vs)]) - pie!(ax, 20, 0, vs; radius=rs_inner, inner_radius=0, kw..., color=lp) - pie!(ax, 20, 0, vs; radius=rs, inner_radius=rs_inner, kw..., color=Makie.wong_colors(0.8)[eachindex(vs)]) + pie!(ax, 20, 0, vs; radius = rs_inner, inner_radius = 0, kw..., color = Makie.wong_colors(0.4)[eachindex(vs)]) + pie!(ax, 20, 0, vs; radius = rs_inner, inner_radius = 0, kw..., color = lp) + pie!(ax, 20, 0, vs; radius = rs, inner_radius = rs_inner, kw..., color = Makie.wong_colors(0.8)[eachindex(vs)]) fig end @reference_test "Pie Position" begin fig = Figure() - ax = Axis(fig[1, 1]; autolimitaspect=1) + ax = Axis(fig[1, 1]; autolimitaspect = 1) vs = 0:6 |> Vector - vs_ = vs ./ sum(vs) .* (3/2*π) + vs_ = vs ./ sum(vs) .* (3 / 2 * π) cs = Makie.wong_colors() Δx = [1, 1, 1, -1, -1, -1, 1] ./ 10 Δy = [1, 1, 1, 1, 1, -1, -1] ./ 10 Δr1 = [0, 0, 0.2, 0, 0.2, 0, 0] Δr2 = [0, 0, 0.2, 0, 0, 0, 0] - pie!(ax, vs; color=cs) - pie!(ax, 3 .+ Δx, 0, vs; color=cs) - pie!(ax, 0, 3 .+ Δy, vs; color=cs) - pie!(ax, 3 .+ Δx, 3 .+ Δy, vs; color=cs) + pie!(ax, vs; color = cs) + pie!(ax, 3 .+ Δx, 0, vs; color = cs) + pie!(ax, 0, 3 .+ Δy, vs; color = cs) + pie!(ax, 3 .+ Δx, 3 .+ Δy, vs; color = cs) - pie!(ax, 7, 0, vs; color=cs, offset_radius=Δr1) - pie!(ax, 7, 3, vs; color=cs, offset_radius=0.2) - pie!(ax, 10 .+ Δx, 3 .+ Δy, vs; color=cs, offset_radius=0.2) - pie!(ax, 10, 0, vs_; color=cs, offset_radius=Δr1, normalize=false, offset=π/2) + pie!(ax, 7, 0, vs; color = cs, offset_radius = Δr1) + pie!(ax, 7, 3, vs; color = cs, offset_radius = 0.2) + pie!(ax, 10 .+ Δx, 3 .+ Δy, vs; color = cs, offset_radius = 0.2) + pie!(ax, 10, 0, vs_; color = cs, offset_radius = Δr1, normalize = false, offset = π / 2) - pie!(ax, Point2(0.5, -3), vs_; color=cs, offset_radius=Δr2, normalize=false, offset=π/2) - pie!(ax, Point2.(3.5, -3 .+ Δy), vs_; color=cs, offset_radius=Δr2, normalize=false, offset=π/2) - pie!(ax, Point2.(6.5 .+ Δx, -3), vs_; color=cs, offset_radius=Δr2, normalize=false, offset=π/2) - pie!(ax, Point2.(9.5 .+ Δx, -3 .+ Δy), vs_; color=cs, offset_radius=Δr2, normalize=false, offset=π/2) + pie!(ax, Point2(0.5, -3), vs_; color = cs, offset_radius = Δr2, normalize = false, offset = π / 2) + pie!(ax, Point2.(3.5, -3 .+ Δy), vs_; color = cs, offset_radius = Δr2, normalize = false, offset = π / 2) + pie!(ax, Point2.(6.5 .+ Δx, -3), vs_; color = cs, offset_radius = Δr2, normalize = false, offset = π / 2) + pie!(ax, Point2.(9.5 .+ Δx, -3 .+ Δy), vs_; color = cs, offset_radius = Δr2, normalize = false, offset = π / 2) - pie!(ax, 0.5, -6, vs_; inner_radius=0.2, color=cs, offset_radius=0.2, normalize=false, offset=π/2) - pie!(ax, 3.5, -6 .+ Δy, vs_; inner_radius=0.2, color=cs, offset_radius=0.2, normalize=false, offset=π/2) - pie!(ax, 6.5 .+ Δx, -6, vs_; inner_radius=0.2, color=cs, offset_radius=0.2, normalize=false, offset=π/2) - pie!(ax, 9.5 .+ Δx, -6 .+ Δy, vs_; inner_radius=0.2, color=cs, offset_radius=0.2, normalize=false, offset=π/2) + pie!(ax, 0.5, -6, vs_; inner_radius = 0.2, color = cs, offset_radius = 0.2, normalize = false, offset = π / 2) + pie!(ax, 3.5, -6 .+ Δy, vs_; inner_radius = 0.2, color = cs, offset_radius = 0.2, normalize = false, offset = π / 2) + pie!(ax, 6.5 .+ Δx, -6, vs_; inner_radius = 0.2, color = cs, offset_radius = 0.2, normalize = false, offset = π / 2) + pie!(ax, 9.5 .+ Δx, -6 .+ Δy, vs_; inner_radius = 0.2, color = cs, offset_radius = 0.2, normalize = false, offset = π / 2) fig end @@ -442,15 +455,15 @@ end end @reference_test "Grouped bar" begin - x1 = ["a_right", "a_right", "a_right", "a_right"] - y1 = [2, 3, -3, -2] - grp_dodge1 = [2, 2, 1, 1] - grp_stack1 = [1, 2, 1, 2] + x1 = ["a_right", "a_right", "a_right", "a_right"] + y1 = [2, 3, -3, -2] + grp_dodge1 = [2, 2, 1, 1] + grp_stack1 = [1, 2, 1, 2] - x2 = ["z_left", "z_left", "z_left", "z_left"] - y2 = [2, 3, -3, -2] - grp_dodge2 = [1, 2, 1, 2] - grp_stack2 = [1, 1, 2, 2] + x2 = ["z_left", "z_left", "z_left", "z_left"] + y2 = [2, 3, -3, -2] + grp_dodge2 = [1, 2, 1, 2] + grp_stack2 = [1, 1, 2, 2] perm = [1, 4, 2, 7, 5, 3, 8, 6] x = [x1; x2][perm] @@ -462,7 +475,7 @@ end tbl = (; x = x, grp_dodge = grp_dodge, grp_stack = grp_stack, y = y) fig = Figure() - ax = Axis(fig[1,1]) + ax = Axis(fig[1, 1]) barplot!(ax, levelcode.(tbl.x), tbl.y, dodge = tbl.grp_dodge, stack = tbl.grp_stack, color = tbl.grp_stack) @@ -482,7 +495,7 @@ end [0.1, 0.35, 0.6, 0.85], [0.1, 0.35, 0.6, 0.85] * 600, [0.1, 0.35, 0.6, 0.85], - 2 .* [0.1, 0.35, 0.6, 0.85] .- 1 + 2 .* [0.1, 0.35, 0.6, 0.85] .- 1, ] scales = (0.02, 12, 0.02, 0.04) for (i, space) in enumerate(spaces) @@ -490,17 +503,21 @@ end s = 1.5scales[i] mesh!( ax, Rect2f(xs[i][i] - 2s, xs[i][j] - 2s, 4s, 4s), space = space, - shading = NoShading, color = :blue) + shading = NoShading, color = :blue + ) lines!( ax, Rect2f(xs[i][i] - 2s, xs[i][j] - 2s, 4s, 4s), - space = space, linewidth = 2, color = :red) + space = space, linewidth = 2, color = :red + ) scatter!( ax, Point2f(xs[i][i], xs[i][j]), color = :orange, marker = Circle, - markersize = 5scales[j], space = space, markerspace = mspace) + markersize = 5scales[j], space = space, markerspace = mspace + ) text!( ax, "$space\n$mspace", position = Point2f(xs[i][i], xs[i][j]), fontsize = scales[j], space = space, markerspace = mspace, - align = (:center, :center), color = :black) + align = (:center, :center), color = :black + ) end end xlims!(ax, 0, 1) @@ -524,7 +541,7 @@ end [0.1, 0.35, 0.6, 0.85], [0.1, 0.35, 0.6, 0.85] * 600, [0.1, 0.35, 0.6, 0.85], - 2 .* [0.1, 0.35, 0.6, 0.85] .- 1 + 2 .* [0.1, 0.35, 0.6, 0.85] .- 1, ] scales = (0.02, 12, 0.02, 0.04) for (i, space) in enumerate(spaces) @@ -532,17 +549,21 @@ end s = 1.5scales[i] mesh!( ax, Rect2f(xs[i][i] - 2s, xs[i][j] - 2s, 4s, 4s), space = space, - shading = NoShading, color = :blue) + shading = NoShading, color = :blue + ) lines!( ax, Rect2f(xs[i][i] - 2s, xs[i][j] - 2s, 4s, 4s), - space = space, linewidth = 2, color = :red) + space = space, linewidth = 2, color = :red + ) scatter!( ax, Point2f(xs[i][i], xs[i][j]), color = :orange, marker = Circle, - markersize = 5scales[j], space = space, markerspace = mspace) + markersize = 5scales[j], space = space, markerspace = mspace + ) text!( ax, "$space\n$mspace", position = Point2f(xs[i][i], xs[i][j]), fontsize = scales[j], space = space, markerspace = mspace, - align = (:center, :center), color = :black) + align = (:center, :center), color = :black + ) end end fig @@ -550,19 +571,19 @@ end @reference_test "Scatter & Text transformations" begin # Check that transformations apply in `space = :data` - fig, ax, p = scatter(Point2f(100, 0.5), marker = 'a', markersize=50) - t = text!(Point2f(100, 0.5), text = "Test", fontsize = 50, transform_marker=true) + fig, ax, p = scatter(Point2f(100, 0.5), marker = 'a', markersize = 50) + t = text!(Point2f(100, 0.5), text = "Test", fontsize = 50, transform_marker = true) translate!(p, -100, 0, 0) translate!(t, -100, 0, 0) # Check that scale and rotate don't act on the marker for scatter (only the position) - p2 = scatter!(ax, Point2f(1, 0), marker= 'a', markersize = 50) - Makie.rotate!(p2, pi/4) + p2 = scatter!(ax, Point2f(1, 0), marker = 'a', markersize = 50) + Makie.rotate!(p2, pi / 4) scale!(p2, 0.5, 0.5, 1) # but do act on glyphs of text - t2 = text!(ax, 1, 0, text = "Test", fontsize = 50, transform_marker=true) - Makie.rotate!(t2, pi/4) + t2 = text!(ax, 1, 0, text = "Test", fontsize = 50, transform_marker = true) + Makie.rotate!(t2, pi / 4) scale!(t2, 0.5, 0.5, 1) xlims!(ax, -0.2, 0.5) @@ -573,37 +594,37 @@ end @reference_test "Array of Images Scatter" begin img = Makie.logo() - scatter(1:2, 1:2, marker = [img, img], markersize=reverse(size(img) ./ 10), axis=(limits=(0.5, 2.5, 0.5, 2.5),)) + scatter(1:2, 1:2, marker = [img, img], markersize = reverse(size(img) ./ 10), axis = (limits = (0.5, 2.5, 0.5, 2.5),)) img2 = load(Makie.assetpath("doge.png")) images = [img, img2] - markersize = map(img-> Vec2f(reverse(size(img) ./ 10)), images) - scatter!(2:-1:1, 1:2, marker = images, markersize=markersize) + markersize = map(img -> Vec2f(reverse(size(img) ./ 10)), images) + scatter!(2:-1:1, 1:2, marker = images, markersize = markersize) current_figure() end @reference_test "2D surface with explicit color" begin - surface(1:10, 1:10, ones(10, 10); color = [RGBf(x*y/100, 0, 0) for x in 1:10, y in 1:10], shading = NoShading) + surface(1:10, 1:10, ones(10, 10); color = [RGBf(x * y / 100, 0, 0) for x in 1:10, y in 1:10], shading = NoShading) end @reference_test "heatmap and image colormap interpolation" begin - f = Figure(size=(500, 500)) + f = Figure(size = (500, 500)) crange = LinRange(0, 255, 10) len = length(crange) img = zeros(Float32, len, len + 2) - img[:, 1] .= 255f0 + img[:, 1] .= 255.0f0 for (i, v) in enumerate(crange) ib = i + 1 - img[2:end-1, ib] .= v - img[1, ib] = 255-v - img[end, ib] = 255-v + img[2:(end - 1), ib] .= v + img[1, ib] = 255 - v + img[end, ib] = 255 - v end - kw(p, interpolate) = (axis=(title="$(p)(interpolate=$(interpolate))", aspect=DataAspect()), interpolate=interpolate, colormap=[:white, :black]) + kw(p, interpolate) = (axis = (title = "$(p)(interpolate=$(interpolate))", aspect = DataAspect()), interpolate = interpolate, colormap = [:white, :black]) for (i, p) in enumerate([heatmap, image]) for (j, interpolate) in enumerate([true, false]) - ax, pl = p(f[i,j], img; kw(p, interpolate)...) + ax, pl = p(f[i, j], img; kw(p, interpolate)...) hidedecorations!(ax) end end @@ -619,11 +640,11 @@ end for (i, cat) in enumerate(categorical) for (j, scale) in enumerate(scales) cg = if cat - cgrad(:viridis, 5; scale = scale, categorical=true) + cgrad(:viridis, 5; scale = scale, categorical = true) else - cgrad(:viridis; scale = scale, categorical=nothing) + cgrad(:viridis; scale = scale, categorical = nothing) end - lines!(ax, Point2f.(LinRange(i+0.1, i+0.9, n), j); color = 1:n, colormap = cg, linewidth = 10) + lines!(ax, Point2f.(LinRange(i + 0.1, i + 0.9, n), j); color = 1:n, colormap = cg, linewidth = 10) end end ax.xticks[] = ((1:length(categorical)) .+ 0.5, ["categorical=false", "categorical=true"]) @@ -632,18 +653,18 @@ end end @reference_test "colormap with specific values" begin - cmap = cgrad([:black,:white,:orange],[0,0.2,1]) - fig = Figure(size=(400,200)) - ax = Axis(fig[1,1]) - x = range(0,1,length=50) - scatter!(fig[1,1],Point2.(x,fill(0.,50)),color=x,colormap=cmap) + cmap = cgrad([:black, :white, :orange], [0, 0.2, 1]) + fig = Figure(size = (400, 200)) + ax = Axis(fig[1, 1]) + x = range(0, 1, length = 50) + scatter!(fig[1, 1], Point2.(x, fill(0.0, 50)), color = x, colormap = cmap) hidedecorations!(ax) - Colorbar(fig[2,1],vertical=false,colormap=cmap) + Colorbar(fig[2, 1], vertical = false, colormap = cmap) fig end @reference_test "colorscale (heatmap)" begin - x = 10.0.^(1:0.1:4) + x = 10.0 .^ (1:0.1:4) y = 1.0:0.1:5.0 fig, ax, hm = heatmap(x, y, (x, y) -> x; axis = (; xscale = log10), colorscale = log10) Colorbar(fig[1, 2], hm) @@ -654,8 +675,8 @@ end xs = 0:0.01:10 ys = 2 .* (1 .+ sin.(xs)) fig = Figure() - lines(fig[1, 1], xs, ys; linewidth=50, color=ys, colorscale=identity) - lines(fig[2, 1], xs, ys; linewidth=50, color=ys, colorscale=sqrt) + lines(fig[1, 1], xs, ys; linewidth = 50, color = ys, colorscale = identity) + lines(fig[2, 1], xs, ys; linewidth = 50, color = ys, colorscale = sqrt) fig end @@ -684,12 +705,14 @@ end f = Figure(size = (800, 800)) for (i, scale) in enumerate([log10, log2, log, sqrt, Makie.logit, identity]) row, col = fldmod1(i, 2) - Axis(f[row, col], yscale = scale, title = string(scale), + Axis( + f[row, col], yscale = scale, title = string(scale), yminorticksvisible = true, yminorgridvisible = true, xminorticksvisible = true, xminorgridvisible = true, yminortickwidth = 4.0, xminortickwidth = 4.0, yminorgridwidth = 6.0, xminorgridwidth = 6.0, - yminorticks = IntervalsBetween(3)) + yminorticks = IntervalsBetween(3) + ) lines!(data, color = :blue) end @@ -697,7 +720,7 @@ end end @reference_test "Tooltip" begin - fig, ax, p = scatter(Point2f(0,0)) + fig, ax, p = scatter(Point2f(0, 0)) xlims!(ax, -10, 10) ylims!(ax, -5, 5) tt = tooltip!(ax, Point2f(0), text = "left", placement = :left) @@ -710,14 +733,16 @@ end tooltip!( ax, 0, 0, text = "right", placement = :right, fontsize = 30, outline_linewidth = 5, offset = 30, triangle_size = 15, - strokewidth = 2f0, strokecolor = :cyan + strokewidth = 2.0f0, strokecolor = :cyan ) # Test depth (this part is expected to fail in CairoMakie) p = tooltip!(ax, -5, -4, "test line\ntest line", backgroundcolor = :lightblue) translate!(p, 0, 0, 100) - mesh!(ax, + mesh!( + ax, Point3f.([-7, -7, -3, -3], [-4, -2, -4, -2], [99, 99, 101, 101]), [1 2 3; 2 3 4], - shading = NoShading, color = :orange) + shading = NoShading, color = :orange + ) fig end @@ -756,21 +781,25 @@ end @reference_test "tricontourf manual vs delaunay" begin n = 20 - angles = range(0, 2pi, length = n+1)[1:end-1] - x = [cos.(angles); 2 .* cos.(angles .+ pi/n)] - y = [sin.(angles); 2 .* sin.(angles .+ pi/n)] - z = (x .- 0.5).^2 + (y .- 0.5).^2 .+ 0.5 .* RNG.randn.() + angles = range(0, 2pi, length = n + 1)[1:(end - 1)] + x = [cos.(angles); 2 .* cos.(angles .+ pi / n)] + y = [sin.(angles); 2 .* sin.(angles .+ pi / n)] + z = (x .- 0.5) .^ 2 + (y .- 0.5) .^ 2 .+ 0.5 .* RNG.randn.() triangulation_inner = reduce(hcat, map(i -> [0, 1, n] .+ i, 1:n)) - triangulation_outer = reduce(hcat, map(i -> [n-1, n, 0] .+ i, 1:n)) + triangulation_outer = reduce(hcat, map(i -> [n - 1, n, 0] .+ i, 1:n)) triangulation = hcat(triangulation_inner, triangulation_outer) - f, ax, _ = tricontourf(x, y, z, triangulation = triangulation, - axis = (; aspect = 1, title = "Manual triangulation")) + f, ax, _ = tricontourf( + x, y, z, triangulation = triangulation, + axis = (; aspect = 1, title = "Manual triangulation") + ) scatter!(x, y, color = z, strokewidth = 1, strokecolor = :black) - tricontourf(f[1, 2], x, y, z, triangulation = Makie.DelaunayTriangulation(), - axis = (; aspect = 1, title = "Delaunay triangulation")) + tricontourf( + f[1, 2], x, y, z, triangulation = Makie.DelaunayTriangulation(), + axis = (; aspect = 1, title = "Delaunay triangulation") + ) scatter!(x, y, color = z, strokewidth = 1, strokecolor = :black) f @@ -778,13 +807,13 @@ end @reference_test "tricontourf with boundary nodes" begin n = 20 - angles = range(0, 2pi, length = n+1)[1:end-1] - x = [cos.(angles); 2 .* cos.(angles .+ pi/n)] - y = [sin.(angles); 2 .* sin.(angles .+ pi/n)] - z = (x .- 0.5).^2 + (y .- 0.5).^2 .+ 0.5.* RNG.randn.() + angles = range(0, 2pi, length = n + 1)[1:(end - 1)] + x = [cos.(angles); 2 .* cos.(angles .+ pi / n)] + y = [sin.(angles); 2 .* sin.(angles .+ pi / n)] + z = (x .- 0.5) .^ 2 + (y .- 0.5) .^ 2 .+ 0.5 .* RNG.randn.() inner = [n:-1:1; n] # clockwise inner - outer = [(n+1):(2n); n+1] # counter-clockwise outer + outer = [(n + 1):(2n); n + 1] # counter-clockwise outer boundary_nodes = [[outer], [inner]] tri = triangulate([x'; y'], boundary_nodes = boundary_nodes) f, ax, _ = tricontourf(tri, z) @@ -794,19 +823,21 @@ end @reference_test "tricontourf with boundary nodes and edges" begin curve_1 = [ - [(0.0, 0.0), (5.0, 0.0), (10.0, 0.0), (15.0, 0.0), (20.0, 0.0), (25.0, 0.0)], - [(25.0, 0.0), (25.0, 5.0), (25.0, 10.0), (25.0, 15.0), (25.0, 20.0), (25.0, 25.0)], - [(25.0, 25.0), (20.0, 25.0), (15.0, 25.0), (10.0, 25.0), (5.0, 25.0), (0.0, 25.0)], - [(0.0, 25.0), (0.0, 20.0), (0.0, 15.0), (0.0, 10.0), (0.0, 5.0), (0.0, 0.0)] + [(0.0, 0.0), (5.0, 0.0), (10.0, 0.0), (15.0, 0.0), (20.0, 0.0), (25.0, 0.0)], + [(25.0, 0.0), (25.0, 5.0), (25.0, 10.0), (25.0, 15.0), (25.0, 20.0), (25.0, 25.0)], + [(25.0, 25.0), (20.0, 25.0), (15.0, 25.0), (10.0, 25.0), (5.0, 25.0), (0.0, 25.0)], + [(0.0, 25.0), (0.0, 20.0), (0.0, 15.0), (0.0, 10.0), (0.0, 5.0), (0.0, 0.0)], ] curve_2 = [ [(4.0, 6.0), (4.0, 14.0), (4.0, 20.0), (18.0, 20.0), (20.0, 20.0)], [(20.0, 20.0), (20.0, 16.0), (20.0, 12.0), (20.0, 8.0), (20.0, 4.0)], - [(20.0, 4.0), (16.0, 4.0), (12.0, 4.0), (8.0, 4.0), (4.0, 4.0), (4.0, 6.0)] + [(20.0, 4.0), (16.0, 4.0), (12.0, 4.0), (8.0, 4.0), (4.0, 4.0), (4.0, 6.0)], ] curve_3 = [ - [(12.906, 10.912), (16.0, 12.0), (16.16, 14.46), (16.29, 17.06), - (13.13, 16.86), (8.92, 16.4), (8.8, 10.9), (12.906, 10.912)] + [ + (12.906, 10.912), (16.0, 12.0), (16.16, 14.46), (16.29, 17.06), + (13.13, 16.86), (8.92, 16.4), (8.8, 10.9), (12.906, 10.912), + ], ] curves = [curve_1, curve_2, curve_3] points = [ @@ -816,9 +847,9 @@ end (6.0, 2.0), (6.2, 3.0), (2.0, 3.0), (2.6, 6.2), (2.0, 8.0), (2.0, 11.0), (5.0, 12.0), (2.0, 17.0), (3.0, 19.0), (6.0, 18.0), (6.5, 14.5), (13.0, 19.0), (13.0, 12.0), (16.0, 8.0), (9.8, 8.0), (7.5, 6.0), - (12.0, 13.0), (19.0, 15.0) + (12.0, 13.0), (19.0, 15.0), ] - boundary_nodes, points = convert_boundary_points_to_indices(curves; existing_points=points) + boundary_nodes, points = convert_boundary_points_to_indices(curves; existing_points = points) edges = Set(((1, 19), (19, 12), (46, 4), (45, 12))) tri = triangulate(points; boundary_nodes = boundary_nodes, segments = edges, check_arguments = false) @@ -828,16 +859,16 @@ end end @reference_test "tricontourf with provided triangulation" begin - θ = [LinRange(0, 2π * (1 - 1/19), 20); 0] - xy = Vector{Vector{Vector{NTuple{2,Float64}}}}() + θ = [LinRange(0, 2π * (1 - 1 / 19), 20); 0] + xy = Vector{Vector{Vector{NTuple{2, Float64}}}}() cx = [0.0, 3.0] for i in 1:2 push!(xy, [[(cx[i] + cos(θ), sin(θ)) for θ in θ]]) push!(xy, [[(cx[i] + 0.5cos(θ), 0.5sin(θ)) for θ in reverse(θ)]]) end boundary_nodes, points = convert_boundary_points_to_indices(xy) - tri = triangulate(points; boundary_nodes=boundary_nodes, check_arguments=false) - z = [(x - 3/2)^2 + y^2 for (x, y) in DelaunayTriangulation.each_point(tri)] + tri = triangulate(points; boundary_nodes = boundary_nodes, check_arguments = false) + z = [(x - 3 / 2)^2 + y^2 for (x, y) in DelaunayTriangulation.each_point(tri)] f, ax, tr = tricontourf(tri, z, colormap = :matter) f @@ -864,9 +895,9 @@ end @reference_test "contour labels with transform_func" begin f = Figure(size = (400, 400)) a = Axis(f[1, 1], xscale = log10) - xs = 10 .^ range(0, 3, length=101) - ys = range(1, 4, length=101) - zs = [sqrt(x*x + y*y) for x in -50:50, y in -50:50] + xs = 10 .^ range(0, 3, length = 101) + ys = range(1, 4, length = 101) + zs = [sqrt(x * x + y * y) for x in -50:50, y in -50:50] contour!(a, xs, ys, zs, labels = true, labelsize = 20) f end @@ -876,7 +907,7 @@ end y = -10:10 # The curvilinear grid: xs = [x + 0.01y^3 for x in x, y in y] - ys = [y + 10cos(x/40) for x in x, y in y] + ys = [y + 10cos(x / 40) for x in x, y in y] # Now, for simplicity, we calculate the `Z` values to be # the radius from the center of the grid (0, 10). @@ -888,7 +919,7 @@ end levels = 0:4:20 # and now, we plot! - fig, ax, srf = surface(xs, ys, fill(0f0, size(zs)); color=zs, shading = NoShading, axis = (; type = Axis, aspect = DataAspect())) + fig, ax, srf = surface(xs, ys, fill(0.0f0, size(zs)); color = zs, shading = NoShading, axis = (; type = Axis, aspect = DataAspect())) ctr = contour!(ax, xs, ys, zs; color = :orange, levels = levels, labels = true, labelfont = :bold, labelsize = 12) fig @@ -898,10 +929,10 @@ end fig = Figure() Axis3(fig[1, 1]) - xs = ys = range(-.5, .5; length = 50) + xs = ys = range(-0.5, 0.5; length = 50) zs = @. √(xs^2 + ys'^2) - levels = .025:.05:.475 + levels = 0.025:0.05:0.475 contour3d!(-zs; levels = -levels, labels = true, color = :blue) contour3d!(+zs; levels = +levels, labels = true, color = :red, labelcolor = :black) fig @@ -934,7 +965,7 @@ end y = RNG.rand(300) for i in 2:5 - ax = Axis(f[fldmod1(i-1, 2)...], title = "bins = $i", aspect = DataAspect()) + ax = Axis(f[fldmod1(i - 1, 2)...], title = "bins = $i", aspect = DataAspect()) hexbin!(ax, x, y, bins = i) wireframe!(ax, Rect2f(Point2f.(x, y)), color = :red) scatter!(ax, x, y, color = :red, markersize = 5) @@ -950,7 +981,7 @@ end y = RNG.rand(300) for i in 2:5 - ax = Axis(f[fldmod1(i-1, 2)...], title = "bins = (3, $i)", aspect = DataAspect()) + ax = Axis(f[fldmod1(i - 1, 2)...], title = "bins = (3, $i)", aspect = DataAspect()) hexbin!(ax, x, y, bins = (3, i)) wireframe!(ax, Rect2f(Point2f.(x, y)), color = :red) scatter!(ax, x, y, color = :red, markersize = 5) @@ -960,7 +991,6 @@ end end - @reference_test "hexbin two cellsizes" begin f = Figure(size = (800, 800)) @@ -1011,10 +1041,14 @@ end y = RNG.randn(100000) f = Figure() - hexbin(f[1, 1], x, y, bins = 40, - axis = (aspect = DataAspect(), title = "scale = identity")) - hexbin(f[1, 2], x, y, bins = 40, colorscale=log10, - axis = (aspect = DataAspect(), title = "scale = log10")) + hexbin( + f[1, 1], x, y, bins = 40, + axis = (aspect = DataAspect(), title = "scale = identity") + ) + hexbin( + f[1, 2], x, y, bins = 40, colorscale = log10, + axis = (aspect = DataAspect(), title = "scale = log10") + ) f end @@ -1023,7 +1057,8 @@ end x = RNG.randn(100000) y = RNG.randn(100000) - f, ax, pl = hexbin(x, y, + f, ax, pl = hexbin( + x, y, bins = 40, axis = (aspect = DataAspect(),), colorrange = (10, 300), @@ -1035,20 +1070,26 @@ end end @reference_test "bracket scalar" begin - f, ax, l = lines(0..9, sin; axis = (; xgridvisible = false, ygridvisible = false)) + f, ax, l = lines(0 .. 9, sin; axis = (; xgridvisible = false, ygridvisible = false)) ylims!(ax, -1.5, 1.5) - bracket!(pi/2, 1, 5pi/2, 1, offset = 5, text = "Period length", style = :square) + bracket!(pi / 2, 1, 5pi / 2, 1, offset = 5, text = "Period length", style = :square) - bracket!(pi/2, 1, pi/2, -1, text = "Amplitude", orientation = :down, - linestyle = :dash, rotation = 0, align = (:right, :center), textoffset = 4, linewidth = 2, color = :red, textcolor = :red) + bracket!( + pi / 2, 1, pi / 2, -1, text = "Amplitude", orientation = :down, + linestyle = :dash, rotation = 0, align = (:right, :center), textoffset = 4, linewidth = 2, color = :red, textcolor = :red + ) - bracket!(2.3, sin(2.3), 4.0, sin(4.0), - text = "Falling", offset = 10, orientation = :up, color = :purple, textcolor = :purple) + bracket!( + 2.3, sin(2.3), 4.0, sin(4.0), + text = "Falling", offset = 10, orientation = :up, color = :purple, textcolor = :purple + ) - bracket!(Point(5.5, sin(5.5)), Point(7.0, sin(7.0)), + bracket!( + Point(5.5, sin(5.5)), Point(7.0, sin(7.0)), text = "Rising", offset = 10, orientation = :down, color = :orange, textcolor = :orange, - fontsize = 30, textoffset = 30, width = 50) + fontsize = 30, textoffset = 30, width = 50 + ) f end @@ -1056,7 +1097,8 @@ end f = Figure() ax = Axis(f[1, 1]) - bracket!(ax, + bracket!( + ax, 1:5, 2:6, 3:7, @@ -1065,8 +1107,9 @@ end orientation = :down, ) - bracket!(ax, - [(Point2f(i, i-0.7), Point2f(i+2, i-0.7)) for i in 1:5], + bracket!( + ax, + [(Point2f(i, i - 0.7), Point2f(i + 2, i - 0.7)) for i in 1:5], text = ["F", "G", "H", "I", "J"], color = [:red, :blue, :green, :orange, :brown], linestyle = [:dash, :dot, :dash, :dot, :dash], @@ -1076,7 +1119,8 @@ end ) # https://github.com/MakieOrg/Makie.jl/issues/3569 - b = bracket!(ax, + b = bracket!( + ax, [5, 6], [1, 2], [6, 7], @@ -1091,24 +1135,24 @@ end hist( f[1, 1], RNG.randn(10^6); - axis=(; yscale=log2) + axis = (; yscale = log2) ) hist( f[1, 2], RNG.randn(10^6); - axis=(; xscale=log2), + axis = (; xscale = log2), direction = :x ) # make a gap in histogram as edge case hist( f[2, 1], - filter!(x-> x<0 || x > 1.5, RNG.randn(10^6)); - axis=(; yscale=log10) + filter!(x -> x < 0 || x > 1.5, RNG.randn(10^6)); + axis = (; yscale = log10) ) hist( f[2, 2], - filter!(x-> x<0 || x > 1.5, RNG.randn(10^6)); - axis=(; xscale=log10), + filter!(x -> x < 0 || x > 1.5, RNG.randn(10^6)); + axis = (; xscale = log10), direction = :x ) f @@ -1116,9 +1160,11 @@ end @reference_test "Barplot label positions" begin f = Figure(size = (450, 450)) - func(fpos; label_position, direction) = barplot(fpos, [1, 1, 2], [1, 2, 3]; + func(fpos; label_position, direction) = barplot( + fpos, [1, 1, 2], [1, 2, 3]; stack = [1, 1, 2], bar_labels = ["One", "Two", "Three"], label_position, - color = [:tomato, :bisque, :slategray2], direction, label_font = :bold) + color = [:tomato, :bisque, :slategray2], direction, label_font = :bold + ) func(f[1, 1]; label_position = :end, direction = :y) ylims!(0, 4) func(f[1, 2]; label_position = :end, direction = :x) @@ -1137,7 +1183,7 @@ end hist(fig[1, 1], data) hist(fig[1, 2], data, bins = 30, color = :orange) a, p = hist(fig[1, 3], data, bins = 10, color = :transparent, strokecolor = :red, strokewidth = 4.0) - a.xgridcolor[] = RGBAf(0,0,0,1); a.ygridcolor[] = RGBAf(0,0,0,1) + a.xgridcolor[] = RGBAf(0, 0, 0, 1); a.ygridcolor[] = RGBAf(0, 0, 0, 1) hist(fig[2, 1], data, normalization = :pdf, direction = :x) hist(fig[2, 2], data, normalization = :density, color = 1:15) @@ -1155,7 +1201,8 @@ end ) hlines!(0.0, color = :black, linewidth = 3) i12 = mod1.(1:10, 2) - hist(fig[4, 2], data, scale_to = :flip, bins = 10, direction = :x, + hist( + fig[4, 2], data, scale_to = :flip, bins = 10, direction = :x, bar_labels = :x, label_size = [14, 10][i12], label_color = [:yellow, :blue][i12], label_offset = [-30, 10][i12] ) @@ -1166,7 +1213,7 @@ end @reference_test "hist(...; gap=0.1)" begin fig = Figure(size = (400, 400)) - hist(fig[1,1], RNG.randn(1000); gap=0.1) + hist(fig[1, 1], RNG.randn(1000); gap = 0.1) fig end @@ -1178,10 +1225,12 @@ end @reference_test "LaTeXStrings linesegment offsets" begin s = Scene(camera = campixel!, size = (600, 600)) for (i, (offx, offy)) in enumerate(zip([0, 20, 50], [0, 10, 30])) - for (j, rot) in enumerate([0, pi/4, pi/2]) - scatter!(s, 150i, 150j, color=:black) - text!(s, 150i, 150j, text = L"\sqrt{x+y}", offset = (offx, offy), - rotation = rot, fontsize = 30) + for (j, rot) in enumerate([0, pi / 4, pi / 2]) + scatter!(s, 150i, 150j, color = :black) + text!( + s, 150i, 150j, text = L"\sqrt{x+y}", offset = (offx, offy), + rotation = rot, fontsize = 30 + ) end end s @@ -1237,11 +1286,11 @@ end p = Makie.Polygon(Point2f[]) q = Makie.Polygon(Point2f[(-1.0, 0.0), (1.0, 0.0), (0.0, 1.0)]) fig, ax, sc = poly([p, q]) - poly!(Axis(fig[1,2]), p, color = :black) - poly!(Axis(fig[2,1]), [p, q], color = [:red, :blue]) - poly!(Axis(fig[2,2]), [p, q], color = :red) - poly!(Axis(fig[3,1]), Makie.MultiPolygon([p]), color = :green) - poly!(Axis(fig[3,2]), Makie.MultiPolygon([p, q]), color = [:black, :red]) + poly!(Axis(fig[1, 2]), p, color = :black) + poly!(Axis(fig[2, 1]), [p, q], color = [:red, :blue]) + poly!(Axis(fig[2, 2]), [p, q], color = :red) + poly!(Axis(fig[3, 1]), Makie.MultiPolygon([p]), color = :green) + poly!(Axis(fig[3, 2]), Makie.MultiPolygon([p, q]), color = [:black, :red]) fig end @@ -1266,38 +1315,43 @@ end end @reference_test "contour with single alpha color" begin - x = range(-π, π; length=50) + x = range(-π, π; length = 50) z = @. sin(x) * cos(x') - fig, ax = contour(x, x, z, color=RGBAf(1,0,0,0.4), linewidth=6) + fig, ax = contour(x, x, z, color = RGBAf(1, 0, 0, 0.4), linewidth = 6) end @reference_test "Triplot with points, ghost edges, and convex hull" begin pts = RNG.rand(2, 50) tri = triangulate(pts; rng = RNG.STABLE_RNG) - fig, ax, sc = triplot(tri, + fig, ax, sc = triplot( + tri, triangle_color = :lightgray, strokewidth = 4, - show_points=true, markersize = 20, markercolor = :orange, - show_ghost_edges=true, ghost_edge_linewidth = 4, - show_convex_hull=true, convex_hull_linewidth = 4 + show_points = true, markersize = 20, markercolor = :orange, + show_ghost_edges = true, ghost_edge_linewidth = 4, + show_convex_hull = true, convex_hull_linewidth = 4 ) fig end @reference_test "Triplot of a constrained triangulation with holes and a custom bounding box" begin - curve_1 = [[ - (0.0, 0.0), (4.0, 0.0), (8.0, 0.0), (12.0, 0.0), (12.0, 4.0), - (12.0, 8.0), (14.0, 10.0), (16.0, 12.0), (16.0, 16.0), - (14.0, 18.0), (12.0, 20.0), (12.0, 24.0), (12.0, 28.0), - (8.0, 28.0), (4.0, 28.0), (0.0, 28.0), (-2.0, 26.0), (0.0, 22.0), - (0.0, 18.0), (0.0, 10.0), (0.0, 8.0), (0.0, 4.0), (-4.0, 4.0), - (-4.0, 0.0), (0.0, 0.0), - ]] - curve_2 = [[ - (4.0, 26.0), (8.0, 26.0), (10.0, 26.0), (10.0, 24.0), - (10.0, 22.0), (10.0, 20.0), (8.0, 20.0), (6.0, 20.0), - (4.0, 20.0), (4.0, 22.0), (4.0, 24.0), (4.0, 26.0) - ]] + curve_1 = [ + [ + (0.0, 0.0), (4.0, 0.0), (8.0, 0.0), (12.0, 0.0), (12.0, 4.0), + (12.0, 8.0), (14.0, 10.0), (16.0, 12.0), (16.0, 16.0), + (14.0, 18.0), (12.0, 20.0), (12.0, 24.0), (12.0, 28.0), + (8.0, 28.0), (4.0, 28.0), (0.0, 28.0), (-2.0, 26.0), (0.0, 22.0), + (0.0, 18.0), (0.0, 10.0), (0.0, 8.0), (0.0, 4.0), (-4.0, 4.0), + (-4.0, 0.0), (0.0, 0.0), + ], + ] + curve_2 = [ + [ + (4.0, 26.0), (8.0, 26.0), (10.0, 26.0), (10.0, 24.0), + (10.0, 22.0), (10.0, 20.0), (8.0, 20.0), (6.0, 20.0), + (4.0, 20.0), (4.0, 22.0), (4.0, 24.0), (4.0, 26.0), + ], + ] curve_3 = [[(4.0, 16.0), (12.0, 16.0), (12.0, 14.0), (4.0, 14.0), (4.0, 16.0)]] curve_4 = [[(4.0, 8.0), (10.0, 8.0), (8.0, 6.0), (6.0, 6.0), (4.0, 8.0)]] curves = [curve_1, curve_2, curve_3, curve_4] @@ -1312,27 +1366,30 @@ end (-4.0, 22.0), (-4.0, 26.0), (-2.0, 28.0), (6.0, 15.0), (7.0, 15.0), (8.0, 15.0), (9.0, 15.0), (10.0, 15.0), (6.2, 7.8), (5.6, 7.8), (5.6, 7.6), (5.6, 7.4), (6.2, 7.4), (6.0, 7.6), - (7.0, 7.8), (7.0, 7.4)] - boundary_nodes, points = convert_boundary_points_to_indices(curves; existing_points=points) - tri = triangulate(points; randomise = false, boundary_nodes=boundary_nodes, rng = RNG.STABLE_RNG) - fig, ax, sc = triplot(tri, - show_points=true, - show_constrained_edges=true, - constrained_edge_linewidth=2, - strokewidth=0.2, - markersize=15, - markercolor=:blue, - show_ghost_edges=true, # not as good because the outer boundary is not convex, but just testing - marker='x', - bounding_box = (-5,20,-5,35)) # also testing the conversion to Float64 for bbox here + (7.0, 7.8), (7.0, 7.4), + ] + boundary_nodes, points = convert_boundary_points_to_indices(curves; existing_points = points) + tri = triangulate(points; randomise = false, boundary_nodes = boundary_nodes, rng = RNG.STABLE_RNG) + fig, ax, sc = triplot( + tri, + show_points = true, + show_constrained_edges = true, + constrained_edge_linewidth = 2, + strokewidth = 0.2, + markersize = 15, + markercolor = :blue, + show_ghost_edges = true, # not as good because the outer boundary is not convex, but just testing + marker = 'x', + bounding_box = (-5, 20, -5, 35) + ) # also testing the conversion to Float64 for bbox here fig end @reference_test "Triplot with nonlinear transformation" begin f = Figure() ax = PolarAxis(f[1, 1]) - points = Point2f[(phi, r) for r in 1:10 for phi in range(0, 2pi, length=36)[1:35]] - noise = i -> 1f-4 * (isodd(i) ? 1 : -1) * i/sqrt(50) # should have small discrepancy + points = Point2f[(phi, r) for r in 1:10 for phi in range(0, 2pi, length = 36)[1:35]] + noise = i -> 1.0f-4 * (isodd(i) ? 1 : -1) * i / sqrt(50) # should have small discrepancy points = points .+ [Point2f(noise(i), noise(i)) for i in eachindex(points)] # The noise forces the triangulation to be unique. Not using RNG to not disrupt the RNG stream later tr = triplot!(ax, points) @@ -1340,7 +1397,7 @@ end end @reference_test "Triplot after adding points and make sure the representative_point_list is correctly updated" begin - points = [(0.0,0.0),(0.95,0.0),(1.0,1.4),(0.0,1.0)] # not 1 so that we have a unique triangulation + points = [(0.0, 0.0), (0.95, 0.0), (1.0, 1.4), (0.0, 1.0)] # not 1 so that we have a unique triangulation tri = Observable(triangulate(points; delete_ghosts = false)) fig, ax, sc = triplot(tri, show_points = true, markersize = 14, show_ghost_edges = true, recompute_centers = true, linestyle = :dash) for p in [(0.3, 0.5), (-1.5, 2.3), (0.2, 0.2), (0.2, 0.5)] @@ -1356,7 +1413,7 @@ end @reference_test "Triplot Showing ghost edges for a triangulation with disjoint boundaries" begin θ = LinRange(0, 2π, 20) |> collect θ[end] = 0 # need to make sure that 2π gives the exact same coordinates as 0 - xy = Vector{Vector{Vector{NTuple{2,Float64}}}}() + xy = Vector{Vector{Vector{NTuple{2, Float64}}}}() cx = 0.0 for i in 1:2 ## Make the exterior circle @@ -1366,18 +1423,18 @@ end cx += 3.0 end boundary_nodes, points = convert_boundary_points_to_indices(xy) - tri = triangulate(points; boundary_nodes=boundary_nodes, check_arguments=false) - fig, ax, sc = triplot(tri, show_ghost_edges=true) + tri = triangulate(points; boundary_nodes = boundary_nodes, check_arguments = false) + fig, ax, sc = triplot(tri, show_ghost_edges = true) fig end @reference_test "Voronoiplot for a centroidal tessellation with an automatic colormap" begin - points = [(0.0,0.0),(1.0,0.0),(1.0,1.0),(0.0,1.0),(0.2,0.2),(0.25,0.6),(0.5,0.3),(0.1,0.15)] - tri = triangulate(points; boundary_nodes = [1,2,3,4,1], rng = RNG.STABLE_RNG) + points = [(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0), (0.2, 0.2), (0.25, 0.6), (0.5, 0.3), (0.1, 0.15)] + tri = triangulate(points; boundary_nodes = [1, 2, 3, 4, 1], rng = RNG.STABLE_RNG) vorn = voronoi(tri) smooth_vorn = centroidal_smooth(vorn; maxiters = 250, rng = RNG.STABLE_RNG) cmap = cgrad(:matter) - fig, ax, sc = voronoiplot(smooth_vorn, markersize=10, strokewidth = 4, markercolor = :red) + fig, ax, sc = voronoiplot(smooth_vorn, markersize = 10, strokewidth = 4, markercolor = :red) fig end @@ -1385,15 +1442,17 @@ end pts = 25RNG.randn(2, 50) tri = triangulate(pts; rng = RNG.STABLE_RNG) vorn = voronoi(tri, clip = false) - fig, ax, sc = voronoiplot(vorn, - show_generators=true, - colormap=:RdBu, - strokecolor=:white, - strokewidth=4, - markersize=25, + fig, ax, sc = voronoiplot( + vorn, + show_generators = true, + colormap = :RdBu, + strokecolor = :white, + strokewidth = 4, + markersize = 25, marker = 'x', - markercolor=:green, - unbounded_edge_extension_factor=5.0) + markercolor = :green, + unbounded_edge_extension_factor = 5.0 + ) xlims!(ax, -120, 120) ylims!(ax, -120, 120) fig @@ -1403,14 +1462,16 @@ end pts = 25RNG.randn(2, 10) tri = triangulate(pts; rng = RNG.STABLE_RNG) vorn = voronoi(tri, clip = true) - fig, ax, sc = voronoiplot(vorn, color = (:blue,0.2), markersize = 20, strokewidth = 4) + fig, ax, sc = voronoiplot(vorn, color = (:blue, 0.2), markersize = 20, strokewidth = 4) # used to be bugged points = [(0.0, 1.0), (-1.0, 2.0), (-2.0, -1.0)] tri = triangulate(points) vorn = voronoi(tri) - voronoiplot(fig[1,2], vorn, show_generators = true, strokewidth = 4, - color = [:red, :blue, :green], markercolor = :white, markersize = 20) + voronoiplot( + fig[1, 2], vorn, show_generators = true, strokewidth = 4, + color = [:red, :blue, :green], markercolor = :white, markersize = 20 + ) fig end @@ -1418,11 +1479,11 @@ end @reference_test "Voronoiplot with a nonlinear transform" begin f = Figure() ax = PolarAxis(f[1, 1], theta_as_x = false) - points = Point2d[(r, phi) for r in 1:10 for phi in range(0, 2pi, length=36)[1:35]] - noise = i -> 1f-4 * (isodd(i) ? 1 : -1) * i/sqrt(50) # should have small discrepancy + points = Point2d[(r, phi) for r in 1:10 for phi in range(0, 2pi, length = 36)[1:35]] + noise = i -> 1.0f-4 * (isodd(i) ? 1 : -1) * i / sqrt(50) # should have small discrepancy points = points .+ [Point2f(noise(i), noise(i)) for i in eachindex(points)] # make triangulation unique - polygon_color = [r for r in 1:10 for phi in range(0, 2pi, length=36)[1:35]] - polygon_color_2 = [phi for r in 1:10 for phi in range(0, 2pi, length=36)[1:35]] + polygon_color = [r for r in 1:10 for phi in range(0, 2pi, length = 36)[1:35]] + polygon_color_2 = [phi for r in 1:10 for phi in range(0, 2pi, length = 36)[1:35]] tr = voronoiplot!(ax, points, smooth = false, show_generators = false, color = polygon_color) Makie.rlims!(ax, 12) # to make rect clip visible if circular clip doesn't happen ax = PolarAxis(f[1, 2], theta_as_x = false) @@ -1439,13 +1500,13 @@ end color = [:red, :blue, :green, :yellow, :cyan, :magenta, :black, :brown] # the polygon colors should not change even if some are not included (because they're outside of the box) fig = Figure() ax1 = Axis(fig[1, 1], title = "Default") - voronoiplot!(ax1, vorn, show_generators = true, markersize=14, strokewidth = 4, color = color) + voronoiplot!(ax1, vorn, show_generators = true, markersize = 14, strokewidth = 4, color = color) ax2 = Axis(fig[1, 2], title = "Some excluded") - voronoiplot!(ax2, vorn, show_generators = true, markersize=14, strokewidth = 4, color = color, clip = BBox(0.0, 5.0, -15.0, 15.0)) + voronoiplot!(ax2, vorn, show_generators = true, markersize = 14, strokewidth = 4, color = color, clip = BBox(0.0, 5.0, -15.0, 15.0)) ax3 = Axis(fig[2, 1], title = "Bigger range") - voronoiplot!(ax3, vorn, show_generators = true, markersize=14, strokewidth = 4, color = color, clip = (-15.0, 15.0, -15.0, 15.0)) + voronoiplot!(ax3, vorn, show_generators = true, markersize = 14, strokewidth = 4, color = color, clip = (-15.0, 15.0, -15.0, 15.0)) ax4 = Axis(fig[2, 2], title = "Only one polygon") - voronoiplot!(ax4, vorn, show_generators = true, markersize=14, strokewidth = 4, color = color, clip = (10.0, 12.0, 2.0, 5.0)) + voronoiplot!(ax4, vorn, show_generators = true, markersize = 14, strokewidth = 4, color = color, clip = (10.0, 12.0, 2.0, 5.0)) for ax in fig.content xlims!(ax4, -15, 15) ylims!(ax4, -15, 15) @@ -1454,24 +1515,24 @@ end end @reference_test "Voronoiplot after adding points" begin - points = Observable([(0.0,0.0), (1.0,0.0), (1.0,1.0), (0.0,1.0)]) - fig, ax, sc = voronoiplot(points, show_generators=true, markersize=36) # make sure any regressions with missing generators are identified, so use 36 + points = Observable([(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0)]) + fig, ax, sc = voronoiplot(points, show_generators = true, markersize = 36) # make sure any regressions with missing generators are identified, so use 36 push!(points[], (2.0, 2.0), (0.5, 0.5), (0.25, 0.25), (0.25, 0.75), (0.75, 0.25), (0.75, 0.75)) notify(points) ax2 = Axis(fig[1, 2]) - voronoiplot!(ax2, voronoi(triangulate(points[])), show_generators=true, markersize=36) - xlims!(ax,-0.5,2.5) - ylims!(ax,-0.5,2.5) - xlims!(ax2,-0.5,2.5) - ylims!(ax2,-0.5,2.5) # need to make sure all generators are shown, and the bounding box is automatically updated + voronoiplot!(ax2, voronoi(triangulate(points[])), show_generators = true, markersize = 36) + xlims!(ax, -0.5, 2.5) + ylims!(ax, -0.5, 2.5) + xlims!(ax2, -0.5, 2.5) + ylims!(ax2, -0.5, 2.5) # need to make sure all generators are shown, and the bounding box is automatically updated fig end function ppu_test_plot(resolution, px_per_unit, scalefactor) - fig, ax, pl = scatter(1:4, markersize=100, color=1:4, figure=(; size=resolution), axis=(; titlesize=50, title="ppu: $px_per_unit, sf: $scalefactor")) + fig, ax, pl = scatter(1:4, markersize = 100, color = 1:4, figure = (; size = resolution), axis = (; titlesize = 50, title = "ppu: $px_per_unit, sf: $scalefactor")) DataInspector(ax) hidedecorations!(ax) - fig + return fig end @reference_test "px_per_unit and scalefactor" begin @@ -1480,7 +1541,7 @@ end @testset begin matr = [(px, scale) for px in [0.5, 1, 2], scale in [0.5, 1, 2]] imgs = map(matr) do (px_per_unit, scalefactor) - img = colorbuffer(ppu_test_plot(resolution, px_per_unit, scalefactor); px_per_unit=px_per_unit, scalefactor=scalefactor) + img = colorbuffer(ppu_test_plot(resolution, px_per_unit, scalefactor); px_per_unit = px_per_unit, scalefactor = scalefactor) @test size(img) == (800, 800) .* px_per_unit return img end @@ -1492,8 +1553,8 @@ end end @reference_test "spurious minor tick (#3487)" begin - fig = Figure(size=(227, 170)) - ax = Axis(fig[1, 1]; yticks = 0:.2:1, yminorticksvisible = true) + fig = Figure(size = (227, 170)) + ax = Axis(fig[1, 1]; yticks = 0:0.2:1, yminorticksvisible = true) ylims!(ax, 0, 1) fig end @@ -1514,11 +1575,11 @@ end fig = Figure() xs = vcat([fill(i, i * 1000) for i in 1:4]...) ys = vcat(RNG.randn(6000), RNG.randn(4000) * 2) - ax, p = violin(fig[1, 1], xs, ys; scale = :area, show_median=true) + ax, p = violin(fig[1, 1], xs, ys; scale = :area, show_median = true) Makie.xlims!(0.2, 4.8); ax.title = "scale=:area" ax, p = violin(fig[2, 1], xs, ys; scale = :count, mediancolor = :red, medianlinewidth = 5) Makie.xlims!(0.2, 4.8); ax.title = "scale=:count" - ax, p = violin(fig[3, 1], xs, ys; scale = :width, show_median=true, mediancolor = :orange, medianlinewidth = 5) + ax, p = violin(fig[3, 1], xs, ys; scale = :width, show_median = true, mediancolor = :orange, medianlinewidth = 5) Makie.xlims!(0.2, 4.8); ax.title = "scale=:width" fig end @@ -1527,20 +1588,23 @@ end fig = Figure() categories = vcat(fill(1, 300), fill(2, 300), fill(3, 300)) - values = vcat(RNG.randn(300), (1.5 .* RNG.rand(300)).^2, -(1.5 .* RNG.rand(300)).^2) + values = vcat(RNG.randn(300), (1.5 .* RNG.rand(300)) .^ 2, -(1.5 .* RNG.rand(300)) .^ 2) violin(fig[1, 1], categories, values) dodge = RNG.rand(1:2, 900) - violin(fig[1, 2], categories, values, dodge = dodge, - color = map(d->d==1 ? :yellow : :orange, dodge), + violin( + fig[1, 2], categories, values, dodge = dodge, + color = map(d -> d == 1 ? :yellow : :orange, dodge), strokewidth = 2, strokecolor = :black, gap = 0.1, dodge_gap = 0.5 ) - violin(fig[2, 1], categories, values, orientation = :horizontal, + violin( + fig[2, 1], categories, values, orientation = :horizontal, color = :gray, side = :left ) - violin!(categories, values, orientation = :horizontal, + violin!( + categories, values, orientation = :horizontal, color = :yellow, side = :right, strokewidth = 2, strokecolor = :black, weights = abs.(values) ) @@ -1559,7 +1623,7 @@ end poly!(a, Rect2f(Point2f(-3.0, 1.8), Vec2f(6, 1)), strokewidth = 2) poly!(a, Point2f[(-3, 1.5), (3, 1.5), (3, 0.5), (-3, 0.5), (-3, 1.5)], strokewidth = 2) - xs = range(-3.0, 3.0, length=101) + xs = range(-3.0, 3.0, length = 101) b = band!(a, xs, -0.4 .* sin.(3 .* xs) .- 2.5, 0.4 .* sin.(3 .* xs) .- 1.0) x = RNG.randn(50) @@ -1578,10 +1642,10 @@ end # if all colorvalues are 1, colorrange will be (0.5, 1.5), mapping everything to blue # TODO, maybe not ideal for spy? sdata = sparse(data .> 0.5) - spy(f[1, 2], sdata; colormap=[:black, :blue, :white]) - spy(f[2, 1], sdata; color=:black, alpha=0.7) + spy(f[1, 2], sdata; colormap = [:black, :blue, :white]) + spy(f[2, 1], sdata; color = :black, alpha = 0.7) data[1, 1] = NaN - spy(f[2, 2], data; highclip=:red, lowclip=(:grey, 0.5), nan_color=:black, colorrange=(0.3, 0.7)) + spy(f[2, 2], data; highclip = :red, lowclip = (:grey, 0.5), nan_color = :black, colorrange = (0.3, 0.7)) f end @@ -1636,28 +1700,32 @@ end fig = Figure() categories = vcat(fill(1, 300), fill(2, 300), fill(3, 300)) - values = RNG.randn(900) .+ range(-1, 1, length=900) + values = RNG.randn(900) .+ range(-1, 1, length = 900) boxplot(fig[1, 1], categories, values) dodge = RNG.rand(1:2, 900) - boxplot(fig[1, 2], categories, values, dodge = dodge, show_notch = true, - color = map(d->d==1 ? :blue : :red, dodge), + boxplot( + fig[1, 2], categories, values, dodge = dodge, show_notch = true, + color = map(d -> d == 1 ? :blue : :red, dodge), outliercolor = RNG.rand([:red, :green, :blue, :black, :orange], 900) ) - ax_vert = Axis(fig[2,1]; + ax_vert = Axis( + fig[2, 1]; xlabel = "categories", ylabel = "values", xticks = (1:3, ["one", "two", "three"]) ) - ax_horiz = Axis(fig[2,2]; - xlabel="values", - ylabel="categories", - yticks=(1:3, ["one", "two", "three"]) + ax_horiz = Axis( + fig[2, 2]; + xlabel = "values", + ylabel = "categories", + yticks = (1:3, ["one", "two", "three"]) ) weights = 1.0 ./ (1.0 .+ abs.(values)) - boxplot!(ax_vert, categories, values, orientation=:vertical, weights = weights, + boxplot!( + ax_vert, categories, values, orientation = :vertical, weights = weights, gap = 0.5, show_notch = true, notchwidth = 0.75, markersize = 5, strokewidth = 2.0, strokecolor = :black, @@ -1666,7 +1734,7 @@ end outlierstrokewidth = 1.0, outlierstrokecolor = :red, width = 1.5, ) - boxplot!(ax_horiz, categories, values; orientation=:horizontal, width = categories ./ 3) + boxplot!(ax_horiz, categories, values; orientation = :horizontal, width = categories ./ 3) fig end @@ -1682,7 +1750,8 @@ end crossbar(fig[1, 1], xs, ys, ymins, ymaxs, dodge = dodge, show_notch = true) - crossbar(fig[1, 2], xs, ys, ymins, ymaxs, + crossbar( + fig[1, 2], xs, ys, ymins, ymaxs, dodge = dodge, dodge_gap = 0.25, gap = 0.05, midlinecolor = :blue, midlinewidth = 5, @@ -1699,13 +1768,13 @@ end x = RNG.randn(200) ecdfplot(f[1, 1], x, color = (:blue, 0.3)) - ecdfplot!(x, color = :red, npoints=10, step = :pre, linewidth = 3) - ecdfplot!(x, color = :orange, npoints=10, step = :center, linewidth = 3) - ecdfplot!(x, color = :green, npoints=10, step = :post, linewidth = 3) + ecdfplot!(x, color = :red, npoints = 10, step = :pre, linewidth = 3) + ecdfplot!(x, color = :orange, npoints = 10, step = :center, linewidth = 3) + ecdfplot!(x, color = :green, npoints = 10, step = :post, linewidth = 3) w = @. x^2 * (1 - x)^2 ecdfplot(f[1, 2], x) - ecdfplot!(x; weights = w, color=:orange) + ecdfplot!(x; weights = w, color = :orange) f end @@ -1739,11 +1808,15 @@ end labels = vcat(fill("red", 500), fill("green", 500)) fig = Figure() - rainclouds(fig[1, 1], labels, data, plot_boxplots = false, cloud_width = 2.0, - markersize = 5.0) + rainclouds( + fig[1, 1], labels, data, plot_boxplots = false, cloud_width = 2.0, + markersize = 5.0 + ) rainclouds(fig[1, 2], labels, data, color = labels, orientation = :horizontal, cloud_width = 2.0) - rainclouds(fig[2, 1], labels, data, clouds = hist, hist_bins = 30, boxplot_nudge = 0.1, - center_boxplot = false, boxplot_width = 0.2, whiskerwidth = 1.0, strokewidth = 3.0) + rainclouds( + fig[2, 1], labels, data, clouds = hist, hist_bins = 30, boxplot_nudge = 0.1, + center_boxplot = false, boxplot_width = 0.2, whiskerwidth = 1.0, strokewidth = 3.0 + ) rainclouds(fig[2, 2], labels, data, color = labels, side = :right, violin_limits = extrema) fig end @@ -1752,12 +1825,16 @@ end fig = Figure() data = cumsum(RNG.randn(4, 21), dims = 2) - ax, sp = series(fig[1, 1], data, labels=["label $i" for i in 1:4], - linewidth = 4, linestyle = :dot, markersize = 15, solid_color = :black) + ax, sp = series( + fig[1, 1], data, labels = ["label $i" for i in 1:4], + linewidth = 4, linestyle = :dot, markersize = 15, solid_color = :black + ) axislegend(ax, position = :lt) - ax, sp = series(fig[2, 1], data, labels=["label $i" for i in 1:4], markersize = 10.0, - marker = Circle, markercolor = :transparent, strokewidth = 2.0, strokecolor = :black) + ax, sp = series( + fig[2, 1], data, labels = ["label $i" for i in 1:4], markersize = 10.0, + marker = Circle, markercolor = :transparent, strokewidth = 2.0, strokecolor = :black + ) axislegend(ax, position = :lt) fig @@ -1770,8 +1847,8 @@ end ys = sin.(xs) stairs(f[1, 1], xs, ys) - stairs(f[2, 1], xs, ys; step=:post, color=:blue, linestyle=:dash) - stairs(f[3, 1], xs, ys; step=:center, color=:red, linestyle=:dot) + stairs(f[2, 1], xs, ys; step = :post, color = :blue, linestyle = :dash) + stairs(f[3, 1], xs, ys; step = :center, color = :red, linestyle = :dot) f end @@ -1782,20 +1859,26 @@ end xs = LinRange(0, 4pi, 30) stem(f[1, 1], xs, sin.(xs)) - stem(f[1, 2], xs, sin, + stem( + f[1, 2], xs, sin, offset = 0.5, trunkcolor = :blue, marker = :rect, stemcolor = :red, color = :orange, markersize = 15, strokecolor = :red, strokewidth = 3, - trunklinestyle = :dash, stemlinestyle = :dashdot) + trunklinestyle = :dash, stemlinestyle = :dashdot + ) - stem(f[2, 1], xs, sin.(xs), + stem( + f[2, 1], xs, sin.(xs), offset = LinRange(-0.5, 0.5, 30), color = LinRange(0, 1, 30), colorrange = (0, 0.5), - trunkcolor = LinRange(0, 1, 30), trunkwidth = 5) + trunkcolor = LinRange(0, 1, 30), trunkwidth = 5 + ) - ax, p = stem(f[2, 2], 0.5xs, 2 .* sin.(xs), 2 .* cos.(xs), + ax, p = stem( + f[2, 2], 0.5xs, 2 .* sin.(xs), 2 .* cos.(xs), offset = Point3f.(0.5xs, sin.(xs), cos.(xs)), - stemcolor = LinRange(0, 1, 30), stemcolormap = :Spectral, stemcolorrange = (0, 0.5)) + stemcolor = LinRange(0, 1, 30), stemcolormap = :Spectral, stemcolorrange = (0, 0.5) + ) center!(ax.scene) zoom!(ax.scene, 0.8) @@ -1809,22 +1892,28 @@ end fig = Figure() waterfall(fig[1, 1], y) - waterfall(fig[1, 2], y, show_direction = true, marker_pos = :cross, - marker_neg = :hline, direction_color = :yellow) + waterfall( + fig[1, 2], y, show_direction = true, marker_pos = :cross, + marker_neg = :hline, direction_color = :yellow + ) colors = Makie.wong_colors() - x = repeat(1:2, inner=5) - group = repeat(1:5, outer=2) + x = repeat(1:2, inner = 5) + group = repeat(1:5, outer = 2) - waterfall(fig[2, 1], x, y, dodge = group, color = colors[group], - show_direction = true, show_final = true, final_color=(colors[6], 1//3), - dodge_gap = 0.1, gap = 0.05) + waterfall( + fig[2, 1], x, y, dodge = group, color = colors[group], + show_direction = true, show_final = true, final_color = (colors[6], 1 // 3), + dodge_gap = 0.1, gap = 0.05 + ) - x = repeat(1:5, outer=2) - group = repeat(1:2, inner=5) + x = repeat(1:5, outer = 2) + group = repeat(1:2, inner = 5) - waterfall(fig[2, 2], x, y, dodge = group, color = colors[group], - show_direction = true, stack = :x, show_final = true) + waterfall( + fig[2, 2], x, y, dodge = group, color = colors[group], + show_direction = true, stack = :x, show_final = true + ) fig end @@ -1836,7 +1925,7 @@ end hspan!(ax, -1, -0.9, color = :lightblue, alpha = 0.5, strokewidth = 2, strokecolor = :black) hspan!(ax, 0.9, 1, xmin = 0.2, xmax = 0.8) vspan!(ax, -1, -0.9) - vspan!(ax, 0.9, 1, ymin = 0.2, ymax = 0.8, strokecolor = RGBf(0,1,0.1), strokewidth = 3) + vspan!(ax, 0.9, 1, ymin = 0.2, ymax = 0.8, strokecolor = RGBf(0, 1, 0.1), strokewidth = 3) ablines!([0.3, 0.7], [-0.2, 0.2], color = :orange, linewidth = 4, linestyle = :dash) diff --git a/ReferenceTests/src/tests/examples3d.jl b/ReferenceTests/src/tests/examples3d.jl index 7140253857e..70ab7496ad2 100644 --- a/ReferenceTests/src/tests/examples3d.jl +++ b/ReferenceTests/src/tests/examples3d.jl @@ -1,21 +1,22 @@ - @reference_test "mesh textured and loaded" begin f = Figure(size = (600, 600)) moon = loadasset("moon.png") - ax, meshplot = mesh(f[1, 1], Sphere(Point3f(0), 1f0), color=moon, - shading=NoShading, axis = (;show_axis=false)) + ax, meshplot = mesh( + f[1, 1], Sphere(Point3f(0), 1.0f0), color = moon, + shading = NoShading, axis = (; show_axis = false) + ) update_cam!(ax.scene, Vec3f(-2, 2, 2), Vec3f(0)) cameracontrols(ax).settings.center[] = false # avoid recenter on display earth = loadasset("earth.png") - m = uv_mesh(Tessellation(Sphere(Point3f(0), 1f0), 60)) - mesh(f[1, 2], m, color=earth, shading=NoShading) + m = uv_mesh(Tessellation(Sphere(Point3f(0), 1.0f0), 60)) + mesh(f[1, 2], m, color = earth, shading = NoShading) catmesh = loadasset("cat.obj") - mesh(f[2, 1], catmesh, color=loadasset("diffusemap.png")) + mesh(f[2, 1], catmesh, color = loadasset("diffusemap.png")) - mesh(f[2, 2], loadasset("cat.obj"); color=:black) + mesh(f[2, 2], loadasset("cat.obj"); color = :black) f end @@ -24,14 +25,14 @@ end function colormesh((geometry, color)) mesh1 = normal_mesh(geometry) npoints = length(GeometryBasics.coordinates(mesh1)) - return GeometryBasics.mesh(mesh1; color=fill(color, npoints)) + return GeometryBasics.mesh(mesh1; color = fill(color, npoints)) end # create an array of differently colored boxes in the direction of the 3 axes - x = Vec3f(0); baselen = 0.2f0; dirlen = 1f0 + x = Vec3f(0); baselen = 0.2f0; dirlen = 1.0f0 rectangles = [ (Rect(Vec3f(x), Vec3f(dirlen, baselen, baselen)), RGBAf(1, 0, 0, 1)), (Rect(Vec3f(x), Vec3f(baselen, dirlen, baselen)), RGBAf(0, 1, 0, 1)), - (Rect(Vec3f(x), Vec3f(baselen, baselen, dirlen)), RGBAf(0, 0, 1, 1)) + (Rect(Vec3f(x), Vec3f(baselen, baselen, dirlen)), RGBAf(0, 0, 1, 1)), ] meshes = map(colormesh, rectangles) @@ -49,30 +50,35 @@ end @reference_test "simple volumes" begin f = Figure() - r = range(-1, stop=1, length=100) - matr = [(x.^2 + y.^2 + z.^2) for x = r, y = r, z = r] - volume(f[1, 1], matr .* (matr .> 1.4), algorithm=:iso, isorange=0.05, isovalue=1.7, colorrange=(0, 1)) + r = range(-1, stop = 1, length = 100) + matr = [(x .^ 2 + y .^ 2 + z .^ 2) for x in r, y in r, z in r] + volume(f[1, 1], matr .* (matr .> 1.4), algorithm = :iso, isorange = 0.05, isovalue = 1.7, colorrange = (0, 1)) - volume(f[1, 2], RNG.rand(32, 32, 32), algorithm=:mip) + volume(f[1, 2], RNG.rand(32, 32, 32), algorithm = :mip) - r = LinRange(-3, 3, 100); # our value range + r = LinRange(-3, 3, 100) # our value range ρ(x, y, z) = exp(-(abs(x))) # function (charge density) - ax, pl = volume(f[2, 1], + ax, pl = volume( + f[2, 1], r, r, r, # coordinates to plot on ρ, # charge density (functions as colorant) - algorithm=:mip, # maximum-intensity-projection - colorrange=(0, 1), + algorithm = :mip, # maximum-intensity-projection + colorrange = (0, 1), ) ax.scene[OldAxis].names.textcolor = :lightgray # let axis labels be seen on dark background ax.scene[OldAxis].ticks.textcolor = :gray # let axis ticks be seen on dark background ax.scene.backgroundcolor[] = to_color(:black) ax.scene.clear[] = true - r = range(-3pi, stop=3pi, length=100) - volume(f[2, 2], r, r, r, (x, y, z) -> cos(x) + sin(y) + cos(z), - colorrange=(0, 1), algorithm=:iso, isorange=0.1f0, axis = (;show_axis=false)) - volume!(r, r, r, (x, y, z) -> cos(x) + sin(y) + cos(z), algorithm=:mip, - colorrange=(0, 1), transformation=(translation=Vec3f(6pi, 0, 0),)) + r = range(-3pi, stop = 3pi, length = 100) + volume( + f[2, 2], r, r, r, (x, y, z) -> cos(x) + sin(y) + cos(z), + colorrange = (0, 1), algorithm = :iso, isorange = 0.1f0, axis = (; show_axis = false) + ) + volume!( + r, r, r, (x, y, z) -> cos(x) + sin(y) + cos(z), algorithm = :mip, + colorrange = (0, 1), transformation = (translation = Vec3f(6pi, 0, 0),) + ) f end @@ -83,24 +89,24 @@ end rot = qrotation(Vec3f(1, 0, 0), 0.5pi) * qrotation(Vec3f(0, 1, 0), 0.7pi) meshscatter( 1:3, 1:3, fill(0, 3, 3), - marker=catmesh, color=img, markersize=1, rotation=rot, - axis=(type=LScene, show_axis=false) + marker = catmesh, color = img, markersize = 1, rotation = rot, + axis = (type = LScene, show_axis = false) ) end @reference_test "Wireframe of mesh, GeoemtryPrimitive and Surface" begin f = Figure() - wireframe(f[1, 1], Sphere(Point3f(0), 1f0)) + wireframe(f[1, 1], Sphere(Point3f(0), 1.0f0)) function xy_data(x, y) r = sqrt(x^2 + y^2) - r == 0.0 ? 1f0 : (sin(r) / r) + r == 0.0 ? 1.0f0 : (sin(r) / r) end N = 30 - lspace = range(-10, stop=10, length=N) + lspace = range(-10, stop = 10, length = N) z = Float32[xy_data(x, y) for x in lspace, y in lspace] - r = range(0, stop=3, length=N) + r = range(0, stop = 3, length = N) wireframe(f[2, 1], r, r, z) wireframe(f[1:2, 2], loadasset("cat.obj")) @@ -112,22 +118,22 @@ end N = 30 function xy_data(x, y) r = sqrt(x^2 + y^2) - r == 0.0 ? 1f0 : (sin(r) / r) + r == 0.0 ? 1.0f0 : (sin(r) / r) end - xrange = range(-2, stop=2, length=N) - surf_func(i) = [Float32(xy_data(x * i, y * i)) for x = xrange, y = xrange] + xrange = range(-2, stop = 2, length = N) + surf_func(i) = [Float32(xy_data(x * i, y * i)) for x in xrange, y in xrange] surface( xrange, xrange, surf_func(10), - color=RNG.rand(RGBAf, 124, 124) + color = RNG.rand(RGBAf, 124, 124) ) end @reference_test "Meshscatter Function" begin - large_sphere = Sphere(Point3f(0), 1f0) + large_sphere = Sphere(Point3f(0), 1.0f0) positions = decompose(Point3f, large_sphere) - colS = [RGBAf(RNG.rand(), RNG.rand(), RNG.rand(), 1.0) for i = 1:length(positions)] - sizesS = [RNG.rand(Point3f) .* 0.05f0 for i = 1:length(positions)] - meshscatter(positions, color=colS, markersize=sizesS) + colS = [RGBAf(RNG.rand(), RNG.rand(), RNG.rand(), 1.0) for i in 1:length(positions)] + sizesS = [RNG.rand(Point3f) .* 0.05f0 for i in 1:length(positions)] + meshscatter(positions, color = colS, markersize = sizesS) end @reference_test "Basic Shading" begin @@ -137,9 +143,9 @@ end pts = Point3f[[0, 0, 0], [1, 0, 0]] markersize = Vec3f[[0.5, 0.2, 0.5], [0.5, 0.2, 0.5]] rotation = [qrotation(Vec3f(1, 0, 0), 0), qrotation(Vec3f(1, 1, 0), π / 4)] - meshscatter(f[1, 1], pts; markersize, rotation, color=:white, diffuse=Vec3f(-2, 0, 4), specular=Vec3f(4, 0, -2)) + meshscatter(f[1, 1], pts; markersize, rotation, color = :white, diffuse = Vec3f(-2, 0, 4), specular = Vec3f(4, 0, -2)) - mesh(f[1, 2], Sphere(Point3f(0), 1f0), color=:orange, shading=NoShading) + mesh(f[1, 2], Sphere(Point3f(0), 1.0f0), color = :orange, shading = NoShading) f end @@ -148,16 +154,16 @@ end f(t, v, s) = (sin(v + t) * s, cos(v + t) * s, (cos(v + t) + sin(v)) * s) t = Observable(0.0) # create a life signal limits = Rect3f(Vec3f(-1.5, -1.5, -3), Vec3f(3, 3, 6)) - fig, ax, p1 = meshscatter(lift(t -> f.(t, range(0, stop=2pi, length=50), 1), t), markersize=0.05) - p2 = meshscatter!(ax, lift(t -> f.(t * 2.0, range(0, stop=2pi, length=50), 1.5), t), markersize=0.05) + fig, ax, p1 = meshscatter(lift(t -> f.(t, range(0, stop = 2pi, length = 50), 1), t), markersize = 0.05) + p2 = meshscatter!(ax, lift(t -> f.(t * 2.0, range(0, stop = 2pi, length = 50), 1.5), t), markersize = 0.05) linepoints = lift(p1[1], p2[1]) do pos1, pos2 map((a, b) -> (a => b), pos1, pos2) end - linesegments!(ax, linepoints, linestyle=:dot) + linesegments!(ax, linepoints, linestyle = :dot) - Record(fig, 1:2; framerate=1) do i + Record(fig, 1:2; framerate = 1) do i t[] = i / 10 end end @@ -167,14 +173,14 @@ end xy = [x, y, z] ((xy') * Matrix(I, 3, 3) * xy) / 20 end - x = range(-2pi, stop=2pi, length=100) + x = range(-2pi, stop = 2pi, length = 100) # c[4] == fourth argument of the above plotting command - fig, ax, c = contour(x, x, x, test, levels=6, alpha=0.3, transparency=true) + fig, ax, c = contour(x, x, x, test, levels = 6, alpha = 0.3, transparency = true) xm, ym, zm = minimum(data_limits(c)) - contour!(ax, x, x, map(v -> v[1, :, :], c[4]), transformation=(:xy, zm), linewidth=2) - heatmap!(ax, x, x, map(v -> v[:, 1, :], c[4]), transformation=(:xz, ym)) - contourf!(ax, x, x, map(v -> v[:, :, 1], c[4]), transformation=(:yz, xm)) + contour!(ax, x, x, map(v -> v[1, :, :], c[4]), transformation = (:xy, zm), linewidth = 2) + heatmap!(ax, x, x, map(v -> v[:, 1, :], c[4]), transformation = (:xz, ym)) + contourf!(ax, x, x, map(v -> v[:, :, 1], c[4]), transformation = (:yz, xm)) # reorder plots for transparency ax.scene.plots[:] = ax.scene.plots[[1, 3, 4, 5, 2]] fig @@ -183,46 +189,46 @@ end @reference_test "Contour3d" begin function xy_data(x, y) r = sqrt(x * x + y * y) - r == 0.0 ? 1f0 : (sin(r) / r) + r == 0.0 ? 1.0f0 : (sin(r) / r) end - r = range(-1, stop=1, length=100) - contour3d(r, r, (x, y) -> xy_data(10x, 10y), levels=20, linewidth=3) + r = range(-1, stop = 1, length = 100) + contour3d(r, r, (x, y) -> xy_data(10x, 10y), levels = 20, linewidth = 3) end @reference_test "Arrows 3D" begin - function SphericalToCartesian(r::T, θ::T, ϕ::T) where T <: AbstractArray + function SphericalToCartesian(r::T, θ::T, ϕ::T) where {T <: AbstractArray} x = @.r * sin(θ) * cos(ϕ) y = @.r * sin(θ) * sin(ϕ) z = @.r * cos(θ) Point3f.(x, y, z) end n = 100^2 # number of points to generate - r = ones(n); + r = ones(n) θ = acos.(1 .- 2 .* RNG.rand(n)) φ = 2π * RNG.rand(n) pts = SphericalToCartesian(r, θ, φ) - arrows(pts, (normalize.(pts) .* 0.1f0), arrowsize=0.02, linecolor=:green, arrowcolor=:darkblue) + arrows(pts, (normalize.(pts) .* 0.1f0), arrowsize = 0.02, linecolor = :green, arrowcolor = :darkblue) end @reference_test "Image on Surface Sphere" begin n = 20 - θ = [0;(0.5:n - 0.5) / n;1] - φ = [(0:2n - 2) * 2 / (2n - 1);2] + θ = [0;(0.5:(n - 0.5)) / n;1] + φ = [(0:(2n - 2)) * 2 / (2n - 1);2] x = [cospi(φ) * sinpi(θ) for θ in θ, φ in φ] y = [sinpi(φ) * sinpi(θ) for θ in θ, φ in φ] z = [cospi(θ) for θ in θ, φ in φ] pts = vec(Point3f.(x, y, z)) - f, ax, p = surface(x, y, z, color=Makie.logo(), transparency=true) + f, ax, p = surface(x, y, z, color = Makie.logo(), transparency = true) end @reference_test "Arrows on Sphere" begin n = 20 - f = (x, y, z) -> x * exp(cos(y) * z) - ∇f = (x, y, z) -> Point3f(exp(cos(y) * z), -sin(y) * z * x * exp(cos(y) * z), x * cos(y) * exp(cos(y) * z)) + f = (x, y, z) -> x * exp(cos(y) * z) + ∇f = (x, y, z) -> Point3f(exp(cos(y) * z), -sin(y) * z * x * exp(cos(y) * z), x * cos(y) * exp(cos(y) * z)) ∇ˢf = (x, y, z) -> ∇f(x, y, z) - Point3f(x, y, z) * dot(Point3f(x, y, z), ∇f(x, y, z)) - θ = [0;(0.5:n - 0.5) / n;1] - φ = [(0:2n - 2) * 2 / (2n - 1);2] + θ = [0;(0.5:(n - 0.5)) / n;1] + φ = [(0:(2n - 2)) * 2 / (2n - 1);2] x = [cospi(φ) * sinpi(θ) for θ in θ, φ in φ] y = [sinpi(φ) * sinpi(θ) for θ in θ, φ in φ] z = [cospi(θ) for θ in θ, φ in φ] @@ -232,7 +238,7 @@ end surface(x, y, z) arrows!( pts, ∇ˢF, - arrowsize=0.03, linecolor=(:white, 0.6), linewidth=0.03 + arrowsize = 0.03, linecolor = (:white, 0.6), linewidth = 0.03 ) current_figure() end @@ -246,7 +252,7 @@ end ax1 = fig[1, 1] = Axis(fig, title = "surface") ax2 = fig[1, 2] = Axis(fig, title = "contour3d") surface!(ax1, vx, vy, foo) - contour3d!(ax2, vx, vy, (x, y) -> foo(x, y), levels=15, linewidth=3) + contour3d!(ax2, vx, vy, (x, y) -> foo(x, y), levels = 15, linewidth = 3) fig end @@ -269,8 +275,8 @@ end indices = connect(1:length(X), TriangleFace) fig = Figure() - poly!(Axis3(fig[1, 1]), vertices, indices; color=C[:], colorscale=identity) - poly!(Axis3(fig[1, 2]), vertices, indices; color=C[:], colorscale=log10) + poly!(Axis3(fig[1, 1]), vertices, indices; color = C[:], colorscale = identity) + poly!(Axis3(fig[1, 2]), vertices, indices; color = C[:], colorscale = log10) fig end @@ -279,7 +285,7 @@ end vy = -1:0.01:1 f(x, y) = (sin(x * 10) + cos(y * 10)) / 4 - scene = Scene(size=(500, 500), camera=cam3d!) + scene = Scene(size = (500, 500), camera = cam3d!) # One way to style the axis is to pass a nested dictionary / named tuple to it. psurf = surface!(scene, vx, vy, f) axis3d!(scene, frame = (linewidth = 2.0,)) @@ -300,10 +306,10 @@ end t = text!( campixel(scene), "Multipole Representation of first resonances of U-238", - position=(wh[1] / 2.0, wh[2] - 20.0), - align=(:center, :center), - fontsize=20, - font="helvetica" + position = (wh[1] / 2.0, wh[2] - 20.0), + align = (:center, :center), + fontsize = 20, + font = "helvetica" ) psurf.converted[3][] = f.(vx .+ 0.5, (vy .+ 0.5)') scene @@ -311,34 +317,34 @@ end @reference_test "Fluctuation 3D" begin # define points/edges - perturbfactor = 4e1 + perturbfactor = 4.0e1 N = 3; nbfacese = 30; radius = 0.02 - large_sphere = Sphere(Point3f(0), 1f0) + large_sphere = Sphere(Point3f(0), 1.0f0) positions = decompose(Point3f, Tessellation(large_sphere, 30)) np = length(positions) - pts = [positions[k][l] for k = 1:length(positions), l = 1:3] + pts = [positions[k][l] for k in 1:length(positions), l in 1:3] pts = vcat(pts, 1.1 .* pts + RNG.randn(size(pts)) / perturbfactor) # light position influence ? edges = hcat(collect(1:np), collect(1:np) .+ np) ne = size(edges, 1); np = size(pts, 1) - cylinder = Cylinder(Point3f(0), Point3f(0, 0, 1.0), 1f0) + cylinder = Cylinder(Point3f(0), Point3f(0, 0, 1.0), 1.0f0) # define markers meshes meshC = normal_mesh(Tessellation(cylinder, nbfacese)) meshS = normal_mesh(Tessellation(large_sphere, 20)) # define colors, markersizes and rotations - pG = [Point3f(pts[k, 1], pts[k, 2], pts[k, 3]) for k = 1:np] - lengthsC = sqrt.(sum((pts[edges[:,1], :] .- pts[edges[:, 2], :]).^2, dims=2)) - sizesC = [Vec3f(radius, radius, lengthsC[i]) for i = 1:ne] - sizesC = [Vec3f(1) for i = 1:ne] - colorsp = [RGBA{Float32}(RNG.rand(), RNG.rand(), RNG.rand(), 1.0) for i = 1:np] - colorsC = [(colorsp[edges[i, 1]] .+ colorsp[edges[i, 2]]) / 2.0 for i = 1:ne] - sizesC = [Vec3f(radius, radius, lengthsC[i]) for i = 1:ne] + pG = [Point3f(pts[k, 1], pts[k, 2], pts[k, 3]) for k in 1:np] + lengthsC = sqrt.(sum((pts[edges[:, 1], :] .- pts[edges[:, 2], :]) .^ 2, dims = 2)) + sizesC = [Vec3f(radius, radius, lengthsC[i]) for i in 1:ne] + sizesC = [Vec3f(1) for i in 1:ne] + colorsp = [RGBA{Float32}(RNG.rand(), RNG.rand(), RNG.rand(), 1.0) for i in 1:np] + colorsC = [(colorsp[edges[i, 1]] .+ colorsp[edges[i, 2]]) / 2.0 for i in 1:ne] + sizesC = [Vec3f(radius, radius, lengthsC[i]) for i in 1:ne] Qlist = zeros(ne, 4) - for k = 1:ne + for k in 1:ne ct = Cylinder( Point3f(pts[edges[k, 1], 1], pts[edges[k, 1], 2], pts[edges[k, 1], 3]), Point3f(pts[edges[k, 2], 1], pts[edges[k, 2], 2], pts[edges[k, 2], 3]), - 1f0 + 1.0f0 ) Q = GeometryBasics.rotation(ct) r = 0.5 * sqrt(1 .+ Q[1, 1] .+ Q[2, 2] .+ Q[3, 3]); Qlist[k, 4] = r @@ -347,29 +353,29 @@ end Qlist[k, 3] = (Q[2, 1] .- Q[1, 2]) / (4 .* r) end - rotationsC = [Vec4f(Qlist[i, 1], Qlist[i, 2], Qlist[i, 3], Qlist[i, 4]) for i = 1:ne] + rotationsC = [Vec4f(Qlist[i, 1], Qlist[i, 2], Qlist[i, 3], Qlist[i, 4]) for i in 1:ne] # plot fig, ax, meshplot = meshscatter( pG[edges[:, 1]], - color=colorsC, marker=meshC, - markersize=sizesC, rotation=rotationsC, + color = colorsC, marker = meshC, + markersize = sizesC, rotation = rotationsC, ) meshscatter!( ax, pG, - color=colorsp, marker=meshS, markersize=radius, + color = colorsp, marker = meshS, markersize = radius, ) fig end @reference_test "Connected Sphere" begin - large_sphere = Sphere(Point3f(0), 1f0) + large_sphere = Sphere(Point3f(0), 1.0f0) positions = decompose(Point3f, large_sphere) linepos = view(positions, RNG.rand(1:length(positions), 1000)) - fig, ax, lineplot = lines(linepos, linewidth=0.1, color=:black, transparency=true) + fig, ax, lineplot = lines(linepos, linewidth = 0.1, color = :black, transparency = true) scatter!( - ax, positions, markersize=10, - strokewidth=2, strokecolor=:white, - color=RGBAf(0.9, 0.2, 0.4, 0.3), transparency=true, + ax, positions, markersize = 10, + strokewidth = 2, strokecolor = :white, + color = RGBAf(0.9, 0.2, 0.4, 0.3), transparency = true, ) fig end @@ -377,71 +383,74 @@ end @reference_test "image scatter" begin scatter( 1:10, 1:10, RNG.rand(10, 10) .* 10, - rotation=normalize.(RNG.rand(Quaternionf, 10 * 10)), - markersize=20, + rotation = normalize.(RNG.rand(Quaternionf, 10 * 10)), + markersize = 20, # can also be an array of images for each point # need to be the same size for best performance, though - marker=Makie.logo() + marker = Makie.logo() ) end @reference_test "Simple meshscatter" begin - large_sphere = Sphere(Point3f(0), 1f0) + large_sphere = Sphere(Point3f(0), 1.0f0) positions = decompose(Point3f, large_sphere) - meshscatter(positions, color=RGBAf(0.9, 0.2, 0.4, 1), markersize=0.05) + meshscatter(positions, color = RGBAf(0.9, 0.2, 0.4, 1), markersize = 0.05) end @reference_test "Animated surface and wireframe" begin function xy_data(x, y) r = sqrt(x^2 + y^2) - r == 0.0 ? 1f0 : (sin(r) / r) + r == 0.0 ? 1.0f0 : (sin(r) / r) end - xrange = range(-2, stop=2, length=50) - surf_func(i) = [Float32(xy_data(x * i, y * i)) for x = xrange, y = xrange] + xrange = range(-2, stop = 2, length = 50) + surf_func(i) = [Float32(xy_data(x * i, y * i)) for x in xrange, y in xrange] z = surf_func(20) fig, ax, surf = surface(xrange, xrange, z) - wf = wireframe!(ax, xrange, xrange, lift(x -> x .+ 1.0, surf[3]), - linewidth=2f0, color=lift(x -> to_colormap(x)[5], surf[:colormap]) + wf = wireframe!( + ax, xrange, xrange, lift(x -> x .+ 1.0, surf[3]), + linewidth = 2.0f0, color = lift(x -> to_colormap(x)[5], surf[:colormap]) ) - Record(fig, range(5, stop=40, length=3); framerate=1) do i + Record(fig, range(5, stop = 40, length = 3); framerate = 1) do i surf[3] = surf_func(i) end end @reference_test "Normals of a Cat" begin x = GeometryBasics.expand_faceviews(loadasset("cat.obj")) - f, a, p = mesh(x, color=:black) + f, a, p = mesh(x, color = :black) pos = map(decompose(Point3f, x), GeometryBasics.normals(x)) do p, n p => p .+ Point(normalize(n) .* 0.05f0) end - linesegments!(pos, color=:blue) + linesegments!(pos, color = :blue) Makie.update_state_before_display!(f) f end @reference_test "Sphere Mesh" begin - mesh(Sphere(Point3f(0), 1f0), color=:blue) + mesh(Sphere(Point3f(0), 1.0f0), color = :blue) end @reference_test "Unicode Marker" begin - scatter(Point3f[(1, 0, 0), (0, 1, 0), (0, 0, 1)], marker=[:x, :circle, :cross], - markersize=35) + scatter( + Point3f[(1, 0, 0), (0, 1, 0), (0, 0, 1)], marker = [:x, :circle, :cross], + markersize = 35 + ) end @reference_test "Merged color Mesh" begin function colormesh((geometry, color)) mesh1 = normal_mesh(geometry) npoints = length(GeometryBasics.coordinates(mesh1)) - return GeometryBasics.mesh(mesh1; color=fill(color, npoints)) + return GeometryBasics.mesh(mesh1; color = fill(color, npoints)) end # create an array of differently colored boxes in the direction of the 3 axes - x = Vec3f(0); baselen = 0.2f0; dirlen = 1f0 + x = Vec3f(0); baselen = 0.2f0; dirlen = 1.0f0 rectangles = [ (Rect(Vec3f(x), Vec3f(dirlen, baselen, baselen)), RGBAf(1, 0, 0, 1)), (Rect(Vec3f(x), Vec3f(baselen, dirlen, baselen)), RGBAf(0, 1, 0, 1)), - (Rect(Vec3f(x), Vec3f(baselen, baselen, dirlen)), RGBAf(0, 0, 1, 1)) + (Rect(Vec3f(x), Vec3f(baselen, baselen, dirlen)), RGBAf(0, 0, 1, 1)), ] meshes = map(colormesh, rectangles) @@ -449,21 +458,21 @@ end end @reference_test "Line GIF" begin - us = range(0, stop=1, length=100) - f, ax, p = linesegments(Rect3f(Vec3f(0, -1, 0), Vec3f(1, 2, 2)); color=:black) - p = lines!(ax, us, sin.(us), zeros(100), linewidth=3, transparency=true, color=:black) + us = range(0, stop = 1, length = 100) + f, ax, p = linesegments(Rect3f(Vec3f(0, -1, 0), Vec3f(1, 2, 2)); color = :black) + p = lines!(ax, us, sin.(us), zeros(100), linewidth = 3, transparency = true, color = :black) lineplots = [p] Makie.translate!(p, 0, 0, 0) colors = to_colormap(:RdYlBu) N = 5 - Record(f, 1:N; framerate=1) do i - t = i/(N/5) + Record(f, 1:N; framerate = 1) do i + t = i / (N / 5) if length(lineplots) < 20 p = lines!( ax, us, sin.(us .+ t), zeros(100), - color=colors[length(lineplots)], - linewidth=3 + color = colors[length(lineplots)], + linewidth = 3 ) pushfirst!(lineplots, p) translate!(p, 0, 0, 0) @@ -482,13 +491,13 @@ end @reference_test "Surface + wireframe + contour" begin N = 51 - x = range(-2, stop=2, length=N) + x = range(-2, stop = 2, length = N) y = x - z = (-x .* exp.(-x.^2 .- (y').^2)) .* 4 + z = (-x .* exp.(-x .^ 2 .- (y') .^ 2)) .* 4 fig, ax, surfaceplot = surface(x, y, z) xm, ym, zm = minimum(data_limits(ax.scene)) - contour!(ax, x, y, z, levels=15, linewidth=2, transformation=(:xy, zm)) - wireframe!(ax, x, y, z, transparency=true, color=(:black, 0.1)) + contour!(ax, x, y, z, levels = 15, linewidth = 2, transformation = (:xy, zm)) + wireframe!(ax, x, y, z, transparency = true, color = (:black, 0.1)) center!(ax.scene) # center the Scene on the display fig end @@ -509,7 +518,7 @@ let P.γ * x[1] - x[3] - P.β, ) f(x) = f(x, P) - streamplot(f, -1.5..1.5, -1.5..1.5, -1.5..1.5, colormap=:magma, gridsize=(10, 10), arrow_size=0.1, transparency=true) + streamplot(f, -1.5 .. 1.5, -1.5 .. 1.5, -1.5 .. 1.5, colormap = :magma, gridsize = (10, 10), arrow_size = 0.1, transparency = true) end end @@ -518,28 +527,28 @@ end fig = Figure(size = (800, 400)) prim = Rect3(Point3f(0), Vec3f(1)) - ps = RNG.rand(Point3f, 10) .+ Point3f(0, 0, 1) + ps = RNG.rand(Point3f, 10) .+ Point3f(0, 0, 1) mat = RNG.rand(4, 4) - A = RNG.rand(4,4,4) + A = RNG.rand(4, 4, 4) # This generates two sets of plots each on two axis. Both axes have one set # without depth_shift (0f0, red) and one at ∓10eps(1f0) (blue, left/right axis). # A negative shift should push the plot in the foreground, positive in the background. - for (i, _shift) in enumerate((-10eps(1f0), 10eps(1f0))) + for (i, _shift) in enumerate((-10eps(1.0f0), 10eps(1.0f0))) ax = LScene(fig[1, i], show_axis = false) - for (color, shift) in zip((:red, :blue), (0f0, _shift)) + for (color, shift) in zip((:red, :blue), (0.0f0, _shift)) mesh!(ax, prim, color = color, depth_shift = shift) lines!(ax, ps, color = color, depth_shift = shift) linesegments!(ax, ps .+ Point3f(-1, 1, 0), color = color, depth_shift = shift) - scatter!(ax, ps, color = color, markersize=10, depth_shift = shift) + scatter!(ax, ps, color = color, markersize = 10, depth_shift = shift) text!(ax, 0, 1, 1.1, text = "Test", color = color, depth_shift = shift) - surface!(ax, -1..0, 1..2, mat, colormap = [color, color], depth_shift = shift) + surface!(ax, -1 .. 0, 1 .. 2, mat, colormap = [color, color], depth_shift = shift) meshscatter!(ax, ps .+ Point3f(-1, 1, 0), color = color, depth_shift = shift) # # left side in axis - heatmap!(ax, 0..1, 0..1, mat, colormap = [color, color], depth_shift = shift) + heatmap!(ax, 0 .. 1, 0 .. 1, mat, colormap = [color, color], depth_shift = shift) # # right side in axis - image!(ax, -1..0, 1..2, mat, colormap = [color, color], depth_shift = shift) + image!(ax, -1 .. 0, 1 .. 2, mat, colormap = [color, color], depth_shift = shift) p = volume!(ax, A, colormap = [:white, color], depth_shift = shift) translate!(p, -1, 0, 0) scale!(p, 0.25, 0.25, 0.25) @@ -559,13 +568,13 @@ end r = Rect2f(-1, -1, 2, 2) for x in (0, 1) for (i, a) in enumerate((0.25, 0.5, 0.75, 1.0)) - ps = [Point3f(a, (0.15 + 0.01y)*(2x-1) , 0.2y) for y in 1:8] + ps = [Point3f(a, (0.15 + 0.01y) * (2x - 1), 0.2y) for y in 1:8] if x == 0 cs = [RGBAf(1, 0, 0, 0.75), RGBAf(0, 1, 0, 0.5), RGBAf(0, 0, 1, 0.25)] elseif x == 1 cs = [RGBAf(1, x, 0, a), RGBAf(0, 1, x, a), RGBAf(x, 0, 1, a)] end - idxs = [1, 2, 3, 2, 1, 3, 1, 2, 1, 2, 3][i:7+i] + idxs = [1, 2, 3, 2, 1, 3, 1, 2, 1, 2, 3][i:(7 + i)] meshscatter!( ax, ps, marker = r, color = cs[idxs], transparency = true @@ -573,7 +582,7 @@ end end end cam = cameracontrols(ax.scene) - cam.fov[] = 22f0 + cam.fov[] = 22.0f0 update_cam!(ax.scene, cam, Vec3f(0.625, 0, 3.5), Vec3f(0.625, 0, 0), Vec3f(0, 1, 0)) cameracontrols(ax).settings.center[] = false # avoid recenter on display fig @@ -587,14 +596,14 @@ end mesh!(ax, Rect2f(0.8, 0.1, 0.1, 0.8), space = :relative, color = :blue, shading = NoShading) linesegments!(ax, Rect2f(-0.5, -0.5, 1, 1), space = :clip, color = :cyan, linewidth = 5) text!(ax, 0, 0.52, text = "Clip Space", align = (:center, :bottom), space = :clip) - image!(ax, 0..40, 0..800, [x for x in range(0, 1, length=40), _ in 1:10], space = :pixel) + image!(ax, 0 .. 40, 0 .. 800, [x for x in range(0, 1, length = 40), _ in 1:10], space = :pixel) end fig end # TODO: get 3D images working in CairoMakie and test them here too @reference_test "Heatmap 3D" begin - heatmap(-2..2, -1..1, RNG.rand(100, 100); axis = (; type = LScene)) + heatmap(-2 .. 2, -1 .. 1, RNG.rand(100, 100); axis = (; type = LScene)) end # Clip Planes @@ -607,16 +616,17 @@ end a.scene.theme[:clip_planes][] = Makie.planes(Rect3f(Point3f(-0.75), Vec3f(1.5))) linesegments!( a, Rect3f(Point3f(-0.75), Vec3f(1.5)), clip_planes = Plane3f[], - fxaa = true, transparency = false, linewidth = 3) + fxaa = true, transparency = false, linewidth = 3 + ) - p = mesh!(Sphere(Point3f(0,0,1), 1f0), transparency = false, color = :orange, backlight = 1.0) + p = mesh!(Sphere(Point3f(0, 0, 1), 1.0f0), transparency = false, color = :orange, backlight = 1.0) wireframe!(p[1][], fxaa = true, color = :cyan) r = range(-pi, pi, length = 101) - surface!(-pi..pi, -pi..pi, [sin(-x - y) for x in r, y in r], transparency = false) + surface!(-pi .. pi, -pi .. pi, [sin(-x - y) for x in r, y in r], transparency = false) scatter!(-1.4:0.1:2, 2:-0.1:-1.4, color = :red) - p = heatmap!(-2..2, -2..2, [sin(x+y) for x in r, y in r], colormap = [:purple, :pink]) + p = heatmap!(-2 .. 2, -2 .. 2, [sin(x + y) for x in r, y in r], colormap = [:purple, :pink]) translate!(p, 0, 0, -0.666) - p = image!(-2..2, -2..2, [cos(x+y) for x in r, y in r], colormap = [:red, :orange]) + p = image!(-2 .. 2, -2 .. 2, [cos(x + y) for x in r, y in r], colormap = [:red, :orange]) translate!(p, 0, 0, -0.333) text!(-1:0.2:1, 1:-0.2:-1, text = ["█" for i in -1:0.2:1], color = :purple) f @@ -626,7 +636,7 @@ end # red vs green matters here, not light vs dark plane = Plane3f(normalize(Vec3f(1)), 0) - f,a,p = mesh( + f, a, p = mesh( Makie.to_mesh(plane, scale = 1.5), color = (:black, 0.5), transparency = true, visible = true ) @@ -635,13 +645,13 @@ end attr = (color = :red, linewidth = 5, fxaa = true) linesegments!(a, Rect3f(Point3f(-1), Vec3f(2)); attr...) - lines!(a, [Point3f(cos(x), sin(x), 0) for x in range(0, 2pi, length=101)]; attr...) + lines!(a, [Point3f(cos(x), sin(x), 0) for x in range(0, 2pi, length = 101)]; attr...) lines!(a, [Point3f(cos(x), sin(x), 0) for x in 1:4:80]; attr...) lines!(a, [Point3f(-1), Point3f(1)]; attr...) - attr = (color = RGBf(0,1,0), overdraw = true, clip_planes = [plane], linewidth = 5, fxaa = true) + attr = (color = RGBf(0, 1, 0), overdraw = true, clip_planes = [plane], linewidth = 5, fxaa = true) linesegments!(a, Rect3f(Point3f(-1), Vec3f(2)), ; attr...) - lines!(a, [Point3f(cos(x), sin(x), 0) for x in range(0, 2pi, length=101)]; attr...) + lines!(a, [Point3f(cos(x), sin(x), 0) for x in range(0, 2pi, length = 101)]; attr...) lines!(a, [Point3f(cos(x), sin(x), 0) for x in 1:4:80]; attr...) lines!(a, [Point3f(-1), Point3f(1)]; attr...) @@ -656,7 +666,7 @@ end a = LScene(f[1, 1]) a.scene.theme[:clip_planes][] = [Plane3f(Vec3f(-2, -1, -0.5), 0.1), Plane3f(Vec3f(-0.5, -1, -2), 0.1)] r = -10:10 - p = voxels!(a, [cos(sin(x+y)+z) for x in r, y in r, z in r]) + p = voxels!(a, [cos(sin(x + y) + z) for x in r, y in r, z in r]) f end @@ -668,20 +678,32 @@ end attr = (clip_planes = clip_planes, axis = (show_axis = false,)) - volume(f[1, 1], -10..10, -10..10, -10..10, data; attr..., - algorithm = :iso, isovalue = 1.0, isorange = 0.1) - volume(f[2, 1], -10..10, -10..10, -10..10, data; attr..., - algorithm = :absorption) + volume( + f[1, 1], -10 .. 10, -10 .. 10, -10 .. 10, data; attr..., + algorithm = :iso, isovalue = 1.0, isorange = 0.1 + ) + volume( + f[2, 1], -10 .. 10, -10 .. 10, -10 .. 10, data; attr..., + algorithm = :absorption + ) - volume(f[1, 2], -10..10, -10..10, -10..10, data; attr..., - algorithm = :mip) - volume(f[2, 2], -10..10, -10..10, -10..10, data; attr..., - algorithm = :absorptionrgba) + volume( + f[1, 2], -10 .. 10, -10 .. 10, -10 .. 10, data; attr..., + algorithm = :mip + ) + volume( + f[2, 2], -10 .. 10, -10 .. 10, -10 .. 10, data; attr..., + algorithm = :absorptionrgba + ) - volume(f[1, 3], -10..10, -10..10, -10..10, data; attr..., - algorithm = :additive) - volume(f[2, 3], -10..10, -10..10, -10..10, data; attr..., - algorithm = :indexedabsorption) + volume( + f[1, 3], -10 .. 10, -10 .. 10, -10 .. 10, data; attr..., + algorithm = :additive + ) + volume( + f[2, 3], -10 .. 10, -10 .. 10, -10 .. 10, data; attr..., + algorithm = :indexedabsorption + ) f end @@ -695,26 +717,28 @@ end wireframe!(a, Rect3f(Point3f(-1), Vec3f(2)), color = :green, linewidth = 5) # verify that space != :data is excluded - lines!(a, -1..1, sin, space = :clip, color = :gray, linewidth = 5) + lines!(a, -1 .. 1, sin, space = :clip, color = :gray, linewidth = 5) linesegments!(a, [100, 200, 300, 400], [100, 100, 100, 100], space = :pixel, color = :gray, linewidth = 5) scatter!(a, [0.2, 0.8], [0.4, 0.6], space = :relative, color = :gray, markersize = 20) f end @reference_test "Surface interpolate attribute" begin - f, ls1, pl = surface(Makie.peaks(20); interpolate=true, axis=(; show_axis=false)) - ls2, pl = surface(f[1, 2], Makie.peaks(20); interpolate=false, axis=(; show_axis=false)) + f, ls1, pl = surface(Makie.peaks(20); interpolate = true, axis = (; show_axis = false)) + ls2, pl = surface(f[1, 2], Makie.peaks(20); interpolate = false, axis = (; show_axis = false)) f end @reference_test "volumeslices" begin r = range(-1, 1, length = 10) - data = RNG.rand(10,10,10) + data = RNG.rand(10, 10, 10) fig = Figure() volumeslices(fig[1, 1], r, r, r, data) - a, p = volumeslices(fig[1, 2], r, r, r, data, bbox_visible = false, colormap = :RdBu, - colorrange = (0.2, 0.8), lowclip = :black, highclip = :green) + a, p = volumeslices( + fig[1, 2], r, r, r, data, bbox_visible = false, colormap = :RdBu, + colorrange = (0.2, 0.8), lowclip = :black, highclip = :green + ) p.update_xz[](3) p.update_yz[](4) p.update_xy[](10) @@ -726,6 +750,6 @@ end f, a, p = mesh(m) cameracontrols(a).settings.center[] = false cameracontrols(a).settings.fixed_axis[] = false # irrelevant here - update_cam!(a.scene, Vec3f(-15, 7, 1), Vec3f(3, 5, 0), Vec3f(0,1,0)) + update_cam!(a.scene, Vec3f(-15, 7, 1), Vec3f(3, 5, 0), Vec3f(0, 1, 0)) f end diff --git a/ReferenceTests/src/tests/figures_and_makielayout.jl b/ReferenceTests/src/tests/figures_and_makielayout.jl index 9173fc56dfc..84cbce8de9f 100644 --- a/ReferenceTests/src/tests/figures_and_makielayout.jl +++ b/ReferenceTests/src/tests/figures_and_makielayout.jl @@ -9,16 +9,18 @@ end @reference_test "Figure with Blocks" begin fig = Figure(size = (900, 900)) - ax, sc = scatter(fig[1, 1][1, 1], RNG.randn(100, 2), axis = (;title = "Random Dots", xlabel = "Time")) + ax, sc = scatter(fig[1, 1][1, 1], RNG.randn(100, 2), axis = (; title = "Random Dots", xlabel = "Time")) sc2 = scatter!(ax, RNG.randn(100, 2) .+ 2, color = :red) ll = fig[1, 1][1, 2] = Legend(fig, [sc, sc2], ["Scatter", "Other"]) - lines(fig[2, 1:2][1, 3][1, 1], 0..3, sin ∘ exp, axis = (;title = "Exponential Sine")) + lines(fig[2, 1:2][1, 3][1, 1], 0 .. 3, sin ∘ exp, axis = (; title = "Exponential Sine")) heatmap(fig[2, 1:2][1, 1], RNG.randn(30, 30)) heatmap(fig[2, 1:2][1, 2], RNG.randn(30, 30), colormap = :grays) lines!(fig[2, 1:2][1, 2], cumsum(RNG.rand(30)), color = :red, linewidth = 10) surface(fig[1, 2], collect(1.0:40), collect(1.0:40), (x, y) -> 10 * cos(x) * sin(y)) - fig[2, 1:2][2, :] = Colorbar(fig, vertical = false, - height = 20, ticklabelalign = (:center, :top), flipaxis = false) + fig[2, 1:2][2, :] = Colorbar( + fig, vertical = false, + height = 20, ticklabelalign = (:center, :top), flipaxis = false + ) fig[3, :] = Menu(fig, options = ["A", "B", "C"]) lt = fig[0, :] = Label(fig, "Figure Demo") fig[5, :] = Textbox(fig) @@ -27,18 +29,18 @@ end @reference_test "Figure with boxes" begin fig = Figure(size = (900, 900)) - Box(fig[1,1], color = :red, strokewidth = 3, linestyle = :solid, strokecolor = :black) - Box(fig[1,2], color = (:red, 0.5), strokewidth = 3, linestyle = :dash, strokecolor = :red) - Box(fig[1,3], color = :white, strokewidth = 3, linestyle = :dot, strokecolor = (:black, 0.5)) - Box(fig[2,1], color = :red, strokewidth = 3, linestyle = :solid, strokecolor = :black, cornerradius = 0) - Box(fig[2,2], color = (:red, 0.5), strokewidth = 3, linestyle = :dash, strokecolor = :red, cornerradius = 20) - Box(fig[2,3], color = :white, strokewidth = 3, linestyle = :dot, strokecolor = (:black, 0.5), cornerradius = (0, 10, 20, 30)) + Box(fig[1, 1], color = :red, strokewidth = 3, linestyle = :solid, strokecolor = :black) + Box(fig[1, 2], color = (:red, 0.5), strokewidth = 3, linestyle = :dash, strokecolor = :red) + Box(fig[1, 3], color = :white, strokewidth = 3, linestyle = :dot, strokecolor = (:black, 0.5)) + Box(fig[2, 1], color = :red, strokewidth = 3, linestyle = :solid, strokecolor = :black, cornerradius = 0) + Box(fig[2, 2], color = (:red, 0.5), strokewidth = 3, linestyle = :dash, strokecolor = :red, cornerradius = 20) + Box(fig[2, 3], color = :white, strokewidth = 3, linestyle = :dot, strokecolor = (:black, 0.5), cornerradius = (0, 10, 20, 30)) fig end @reference_test "menus" begin fig = Figure() - funcs = [sqrt, x->x^2, sin, cos] + funcs = [sqrt, x -> x^2, sin, cos] options = zip(["Square Root", "Square", "Sine", "Cosine"], funcs) menu1 = Menu(fig, options = ["viridis", "heat", "blues"], default = 1) @@ -62,7 +64,7 @@ end @reference_test "Label with text wrapping" begin lorem_ipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." fig = Figure(size = (1000, 660)) - m!(fig, lbl) = mesh!(fig.scene, lbl.layoutobservables.computedbbox, color = (:red, 0.5), shading=NoShading) + m!(fig, lbl) = mesh!(fig.scene, lbl.layoutobservables.computedbbox, color = (:red, 0.5), shading = NoShading) lbl1 = Label(fig[1, 1:2], "HEADER "^10, fontsize = 40, word_wrap = true) m!(fig, lbl1) @@ -138,11 +140,11 @@ end f = Figure() ax = Axis(f[1, 1], backgroundcolor = :gray80) for i in 1:3 - lines!(ax,( 1:10) .* i, label = "$i") + lines!(ax, (1:10) .* i, label = "$i") end # To verify that RGB values differ across entries - axislegend(ax, position = :lt, patchcolor = :red, patchsize = (100, 100), backgroundcolor = :gray50); - Legend(f[1, 2], ax, patchcolor = :gray80, patchsize = (100, 100), backgroundcolor = :gray50); + axislegend(ax, position = :lt, patchcolor = :red, patchsize = (100, 100), backgroundcolor = :gray50) + Legend(f[1, 2], ax, patchcolor = :gray80, patchsize = (100, 100), backgroundcolor = :gray50) f end end @@ -217,8 +219,8 @@ end @reference_test "PolarAxis surface" begin f = Figure() ax = PolarAxis(f[1, 1]) - zs = [r*cos(phi) for phi in range(0, 4pi, length=100), r in range(1, 2, length=100)] - p = surface!(ax, 0..2pi, 0..10, zs, shading = NoShading, colormap = :coolwarm, colorrange=(-2, 2)) + zs = [r * cos(phi) for phi in range(0, 4pi, length = 100), r in range(1, 2, length = 100)] + p = surface!(ax, 0 .. 2pi, 0 .. 10, zs, shading = NoShading, colormap = :coolwarm, colorrange = (-2, 2)) rlims!(ax, 0, 11) # verify that r = 10 doesn't end up at r > 10 translate!(p, 0, 0, -200) Colorbar(f[1, 2], p) @@ -229,13 +231,13 @@ end @reference_test "PolarAxis scatterlines spine" begin f = Figure(size = (800, 400)) ax1 = PolarAxis(f[1, 1], title = "No spine", spinevisible = false, theta_as_x = false) - scatterlines!(ax1, range(0, 1, length=100), range(0, 10pi, length=100), color = 1:100) + scatterlines!(ax1, range(0, 1, length = 100), range(0, 10pi, length = 100), color = 1:100) ax2 = PolarAxis(f[1, 2], title = "Modified spine") ax2.spinecolor[] = :red ax2.spinestyle[] = :dash ax2.spinewidth[] = 5 - scatterlines!(ax2, range(0, 10pi, length=100), range(0, 1, length=100), color = 1:100) + scatterlines!(ax2, range(0, 10pi, length = 100), range(0, 1, length = 100), color = 1:100) f end @@ -252,11 +254,11 @@ end thetaminorgridwidth = 1.0, thetaminorgridstyle = :dash, rgridwidth = 2, rgridcolor = :red, thetagridwidth = 2, thetagridcolor = :blue, - rticklabelsize = 18, rticklabelcolor = :red, rtickangle = pi/6, + rticklabelsize = 18, rticklabelcolor = :red, rtickangle = pi / 6, rticklabelstrokewidth = 1, rticklabelstrokecolor = :white, thetaticklabelsize = 18, thetaticklabelcolor = :blue, thetaticklabelstrokewidth = 1, thetaticklabelstrokecolor = :white, - thetaticks = ([0, π/2, π, 3π/2], ["A", "B", "C", rich("D", color = :orange)]), # https://github.com/MakieOrg/Makie.jl/issues/3583 + thetaticks = ([0, π / 2, π, 3π / 2], ["A", "B", "C", rich("D", color = :orange)]), # https://github.com/MakieOrg/Makie.jl/issues/3583 rticks = ([0.0, 2.5, 5.0, 7.5, 10.0], ["0.0", "2.5", "5.0", "7.5", rich("10.0", color = :orange)]) ) f @@ -264,11 +266,11 @@ end @reference_test "PolarAxis limits" begin f = Figure(size = (800, 600)) - for (i, theta_0) in enumerate((0, -pi/6, pi/2)) - for (j, thetalims) in enumerate(((0, 2pi), (-pi/2, pi/2), (0, pi/12))) - po = PolarAxis(f[i, j], theta_0 = theta_0, thetalimits = thetalims, rlimits = (1 + 2(j-1), 7)) - po.scene.backgroundcolor[] = RGBAf(1,0.5,0.5,1) - lines!(po, range(0, 20pi, length=201), range(0, 10, length=201), color = :white, linewidth = 5) + for (i, theta_0) in enumerate((0, -pi / 6, pi / 2)) + for (j, thetalims) in enumerate(((0, 2pi), (-pi / 2, pi / 2), (0, pi / 12))) + po = PolarAxis(f[i, j], theta_0 = theta_0, thetalimits = thetalims, rlimits = (1 + 2(j - 1), 7)) + po.scene.backgroundcolor[] = RGBAf(1, 0.5, 0.5, 1) + lines!(po, range(0, 20pi, length = 201), range(0, 10, length = 201), color = :white, linewidth = 5) b = Box(f[i, j], color = (:blue, 0.2)) translate!(b.blockscene, 0, 0, 9999) @@ -280,8 +282,8 @@ end end @reference_test "PolarAxis radial shift and clip" begin - phis = range(pi/4, 9pi/4, length=201) - rs = 1.0 ./ sin.(range(pi/4, 3pi/4, length=51)[1:end-1]) + phis = range(pi / 4, 9pi / 4, length = 201) + rs = 1.0 ./ sin.(range(pi / 4, 3pi / 4, length = 51)[1:(end - 1)]) rs = vcat(rs, rs, rs, rs, rs[1]) fig = Figure(size = (900, 300)) @@ -309,10 +311,10 @@ end @reference_test "Axis3 fullbox" begin f = Figure(size = (400, 400)) a = Axis3(f[1, 1], front_spines = true, xspinewidth = 5, yspinewidth = 5, zspinewidth = 5) - mesh!(a, Sphere(Point3f(-0.2, 0.2, 0), 1f0), color = :darkgray, transparency = false) - mesh!(a, Sphere(Point3f(0.2, -0.2, 0), 1f0), color = :darkgray, transparency = true) + mesh!(a, Sphere(Point3f(-0.2, 0.2, 0), 1.0f0), color = :darkgray, transparency = false) + mesh!(a, Sphere(Point3f(0.2, -0.2, 0), 1.0f0), color = :darkgray, transparency = true) - for ((x, y), viskey, colkey) in zip([(1,2), (2,1), (2,2)], [:x, :y, :z], [:y, :z, :x]) + for ((x, y), viskey, colkey) in zip([(1, 2), (2, 1), (2, 2)], [:x, :y, :z], [:y, :z, :x]) kwargs = Dict( Symbol(viskey, :spinesvisible) => false, Symbol(colkey, :spinecolor_1) => :red, @@ -322,10 +324,11 @@ end ) a = Axis3( f[x, y], title = "$viskey hidden, $colkey colored", front_spines = true, - xspinewidth = 5, yspinewidth = 5, zspinewidth = 5; kwargs...) + xspinewidth = 5, yspinewidth = 5, zspinewidth = 5; kwargs... + ) - mesh!(a, Sphere(Point3f(-0.2, 0.2, 0), 1f0), color = :darkgray, transparency = false) - mesh!(a, Sphere(Point3f(0.2, -0.2, 0), 1f0), color = :darkgray, transparency = true) + mesh!(a, Sphere(Point3f(-0.2, 0.2, 0), 1.0f0), color = :darkgray, transparency = false) + mesh!(a, Sphere(Point3f(0.2, -0.2, 0), 1.0f0), color = :darkgray, transparency = true) end f end @@ -338,13 +341,15 @@ end cat = GeometryBasics.expand_faceviews(load(Makie.assetpath("cat.obj"))) cs = 1:length(Makie.coordinates(cat)) - for (bx, by, viewmode) in [(1,1,:fit), (1,2,:fitzoom), (2,1,:free), (2,2,:stretch)] + for (bx, by, viewmode) in [(1, 1, :fit), (1, 2, :fitzoom), (2, 1, :free), (2, 2, :stretch)] gl = GridLayout(fig[by, bx]) Label(gl[0, 1:2], "viewmode = :$viewmode") for (x, rev) in enumerate((true, false)) for (y, aspect) in enumerate((:data, :equal, (1.2, 0.8, 1.0))) - ax = Axis3(gl[y, x], viewmode = viewmode, xreversed = rev, aspect = aspect, - protrusions = protrusions, perspectiveness = perspectiveness) + ax = Axis3( + gl[y, x], viewmode = viewmode, xreversed = rev, aspect = aspect, + protrusions = protrusions, perspectiveness = perspectiveness + ) mesh!(ax, cat, color = cs) # for debug purposes @@ -373,37 +378,47 @@ end end @reference_test "Colorbar for recipes" begin - fig, ax, pl = barplot(1:3; color=1:3, colormap=Makie.Categorical(:viridis), figure=(;size=(800, 800))) - Colorbar(fig[1, 2], pl; size=100) + fig, ax, pl = barplot(1:3; color = 1:3, colormap = Makie.Categorical(:viridis), figure = (; size = (800, 800))) + Colorbar(fig[1, 2], pl; size = 100) x = LinRange(-1, 1, 20) y = LinRange(-1, 1, 20) z = LinRange(-1, 1, 20) values = [sin(x[i]) * cos(y[j]) * sin(z[k]) for i in 1:20, j in 1:20, k in 1:20] # TO not make this fail in CairoMakie, we dont actually plot the volume - _f, ax, cp = contour(-1..1, -1..1, -1..1, values; levels=10, colormap=:viridis) - Colorbar(fig[2, 1], cp; size=300) + _f, ax, cp = contour(-1 .. 1, -1 .. 1, -1 .. 1, values; levels = 10, colormap = :viridis) + Colorbar(fig[2, 1], cp; size = 300) - _f, ax, vs = volumeslices(x, y, z, values, colormap=:bluesreds) + _f, ax, vs = volumeslices(x, y, z, values, colormap = :bluesreds) Colorbar(fig[2, 2], vs) # horizontal colorbars - Colorbar(fig[1, 3][2, 1]; limits=(0, 10), colormap=:viridis, - vertical=false) - Colorbar(fig[1, 3][3, 1]; limits=(0, 5), size=25, - colormap=cgrad(:Spectral, 5; categorical=true), vertical=false) - Colorbar(fig[1, 3][4, 1]; limits=(-1, 1), colormap=:heat, vertical=false, flipaxis=false, - highclip=:cyan, lowclip=:red) + Colorbar( + fig[1, 3][2, 1]; limits = (0, 10), colormap = :viridis, + vertical = false + ) + Colorbar( + fig[1, 3][3, 1]; limits = (0, 5), size = 25, + colormap = cgrad(:Spectral, 5; categorical = true), vertical = false + ) + Colorbar( + fig[1, 3][4, 1]; limits = (-1, 1), colormap = :heat, vertical = false, flipaxis = false, + highclip = :cyan, lowclip = :red + ) xs = LinRange(0, 20, 50) ys = LinRange(0, 15, 50) zs = [cos(x) * sin(y) for x in xs, y in ys] - ax, hm = contourf(fig[2, 3][1, 1], xs, ys, zs; - colormap=:Spectral, levels=[-1, -0.5, -0.25, 0, 0.25, 0.5, 1]) - Colorbar(fig[2, 3][1, 2], hm; ticks=-1:0.25:1) + ax, hm = contourf( + fig[2, 3][1, 1], xs, ys, zs; + colormap = :Spectral, levels = [-1, -0.5, -0.25, 0, 0.25, 0.5, 1] + ) + Colorbar(fig[2, 3][1, 2], hm; ticks = -1:0.25:1) - ax, hm = contourf(fig[3, :][1, 1], xs, ys, zs; - colormap=:Spectral, colorscale=sqrt, levels=[ 0, 0.25, 0.5, 1]) - Colorbar(fig[3, :][1, 2], hm; width=200) + ax, hm = contourf( + fig[3, :][1, 1], xs, ys, zs; + colormap = :Spectral, colorscale = sqrt, levels = [0, 0.25, 0.5, 1] + ) + Colorbar(fig[3, :][1, 2], hm; width = 200) fig end @@ -423,15 +438,15 @@ end airports = Point2f.(eachrow(readdlm(assetpath("airportlocations.csv")))) # Dont use the full dataset, since WGLMakie seems to time out if it's too big fewer = airports[RNG.rand(1:length(airports), 1000)] - fig, ax, ds = datashader(fewer; async=false) - Colorbar(fig[1, 2], ds; width=100) + fig, ax, ds = datashader(fewer; async = false) + Colorbar(fig[1, 2], ds; width = 100) hidedecorations!(ax) hidespines!(ax) normaldist = RNG.randn(Point2f, 100000) ds1 = normaldist .+ (Point2f(-1, 0),) ds2 = normaldist .+ (Point2f(1, 0),) - ax, pl = datashader(fig[2, :], Dict("a" => ds1, "b" => ds2); async=false) + ax, pl = datashader(fig[2, :], Dict("a" => ds1, "b" => ds2); async = false) hidedecorations!(ax) axislegend(ax) fig @@ -439,7 +454,7 @@ end @reference_test "Axis limits with translation, scaling and transform_func" begin f = Figure() - a = Axis(f[1,1], xscale = log10, yscale = log10) + a = Axis(f[1, 1], xscale = log10, yscale = log10) ps = Point2f.([0.1, 0.1, 1000, 1000], [1, 100, 1, 100]) hl = linesegments!(a, ps[[1, 3, 2, 4]], color = :red) vl = linesegments!(a, ps, color = :blue) @@ -454,14 +469,15 @@ end @reference_test "Latex labels after the fact" begin f = Figure(fontsize = 50) ax = Axis(f[1, 1]) - ax.xticks = ([3, 6, 9], [L"x" , L"y" , L"z"]) - ax.yticks = ([3, 6, 9], [L"x" , L"y" , L"z"]) + ax.xticks = ([3, 6, 9], [L"x", L"y", L"z"]) + ax.yticks = ([3, 6, 9], [L"x", L"y", L"z"]) f end @reference_test "Rich text" begin f = Figure(fontsize = 30, size = (800, 600)) - ax = Axis(f[1, 1], + ax = Axis( + f[1, 1], limits = (1, 100, 0.001, 1), xscale = log10, yscale = log2, @@ -496,21 +512,21 @@ end @reference_test "Textbox" begin f = Figure() - tb1 = Makie.Textbox(f[1,1]) + tb1 = Makie.Textbox(f[1, 1]) Makie.set!(tb1, "1234567890qwertyuiop") Makie.focus!(tb1) f.scene.events.mouseposition[] = (297, 221) f.scene.events.mousebutton[] = Makie.MouseButtonEvent(Makie.Mouse.left, Makie.Mouse.press) Makie.defocus!(tb1) - tb2 = Makie.Textbox(f[2,1], width=100) + tb2 = Makie.Textbox(f[2, 1], width = 100) Makie.set!(tb2, "1234567890qwertyuiop") tb2.cursorindex[] = 20 Makie.focus!(tb2) f.scene.events.keyboardbutton[] = Makie.KeyEvent(Makie.Keyboard.backspace, Makie.Keyboard.press) Makie.defocus!(tb2) - tb3 = Makie.Textbox(f[3,1], width=100) + tb3 = Makie.Textbox(f[3, 1], width = 100) Makie.set!(tb3, "1234567890qwertyuiop") tb3.cursorindex[] = 20 Makie.focus!(tb3) @@ -520,7 +536,7 @@ end f.scene.events.keyboardbutton[] = Makie.KeyEvent(Makie.Keyboard.left, Makie.Keyboard.press) Makie.defocus!(tb3) - tb4 = Makie.Textbox(f[4,1], width=100) + tb4 = Makie.Textbox(f[4, 1], width = 100) Makie.set!(tb4, "1234567890qwertyuiop") tb4.cursorindex[] = 20 tb4.cursorindex[] = 10 @@ -536,43 +552,55 @@ end @reference_test "Button - Slider - Toggle - Textbox" begin f = Figure(size = (500, 250)) Makie.Button(f[1, 1:2]) - Makie.Button(f[2, 1:2], buttoncolor = :orange, cornerradius = 20, + Makie.Button( + f[2, 1:2], buttoncolor = :orange, cornerradius = 20, strokecolor = :red, strokewidth = 2, # TODO: allocate space for this - fontsize = 16, labelcolor = :blue) + fontsize = 16, labelcolor = :blue + ) IntervalSlider(f[1, 3]) - sl = IntervalSlider(f[2, 3], range = 0:100, linewidth = 20, - color_inactive = :orange, color_active_dimmed = :lightgreen) + sl = IntervalSlider( + f[2, 3], range = 0:100, linewidth = 20, + color_inactive = :orange, color_active_dimmed = :lightgreen + ) Makie.set_close_to!(sl, 30, 70) Toggle(f[3, 1]) t = Toggle(f[4, 1], framecolor_inactive = :lightblue, rimfraction = 0.6) - t.orientation = 3pi/4 + t.orientation = 3pi / 4 Toggle(f[3, 2], active = true, orientation = :horizontal) - Toggle(f[4, 2], active = true, framecolor_inactive = :lightblue, - framecolor_active = :yellow, rimfraction = 0.6, orientation = :vertical) + Toggle( + f[4, 2], active = true, framecolor_inactive = :lightblue, + framecolor_active = :yellow, rimfraction = 0.6, orientation = :vertical + ) Makie.Slider(f[3, 3]) - sl = Makie.Slider(f[4, 3], range = 0:100, linewidth = 20, color_inactive = :cyan, - color_active_dimmed = :lightgreen) + sl = Makie.Slider( + f[4, 3], range = 0:100, linewidth = 20, color_inactive = :cyan, + color_active_dimmed = :lightgreen + ) Makie.set_close_to!(sl, 30) gl = GridLayout(f[5, 1:3]) Textbox(gl[1, 1]) - Textbox(gl[1, 2], bordercolor = :red, cornerradius = 0, - placeholder = "test string", fontsize = 16, textcolor_placeholder = :blue) - tb = Textbox(gl[1, 3], bordercolor = :black, cornerradius = 20, - fontsize =10, textcolor = :red, boxcolor = :lightblue) + Textbox( + gl[1, 2], bordercolor = :red, cornerradius = 0, + placeholder = "test string", fontsize = 16, textcolor_placeholder = :blue + ) + tb = Textbox( + gl[1, 3], bordercolor = :black, cornerradius = 20, + fontsize = 10, textcolor = :red, boxcolor = :lightblue + ) Makie.set!(tb, "some string") f end @reference_test "Toggle orientation" begin f = Figure() - for x=1:3, y=1:3 - x==y==2 && continue + for x in 1:3, y in 1:3 + x == y == 2 && continue Box(f[x, y], color = :tomato) - Toggle(f[x, y], orientation = atan(x-2,2-y)) + Toggle(f[x, y], orientation = atan(x - 2, 2 - y)) end f end diff --git a/ReferenceTests/src/tests/float32_conversion.jl b/ReferenceTests/src/tests/float32_conversion.jl index f07b853fdda..95859862cea 100644 --- a/ReferenceTests/src/tests/float32_conversion.jl +++ b/ReferenceTests/src/tests/float32_conversion.jl @@ -4,20 +4,20 @@ xlims!(ax, 0, 12) # no ylims! to check autolimits as well ax.xticks[] = (0:12, string.(0:12)) - ax.yticks[] = (1e9 .+ (0:11), ["1e9 + $i" for i in 0:11]) + ax.yticks[] = (1.0e9 .+ (0:11), ["1e9 + $i" for i in 0:11]) # scatter + lines - scatterlines!(1:10, 1e9 .+ (1:10)) - linesegments!(2:11, 1e9 .+ (1:10)) - meshscatter!(3:12, 1e9 .+ (1:10)) - text!(Point2(1, 1e9 + 6), text = L"\frac{\sqrt{1+x}}{2}", fontsize = 20, align = (:left, :center)) + scatterlines!(1:10, 1.0e9 .+ (1:10)) + linesegments!(2:11, 1.0e9 .+ (1:10)) + meshscatter!(3:12, 1.0e9 .+ (1:10)) + text!(Point2(1, 1.0e9 + 6), text = L"\frac{\sqrt{1+x}}{2}", fontsize = 20, align = (:left, :center)) - image!(ax, 0 .. 3, (1e9 + 7) .. (1e9 + 10), [1 2; 3 4]) - heatmap!(ax, 10 .. 11, (1e9 + 2) .. (1e9 + 3), [1 2; 3 4]) - surface!(ax, 10 .. 11, (1e9 + 4) .. (1e9 + 5), [1 2; 3 4]; shading=NoShading) + image!(ax, 0 .. 3, (1.0e9 + 7) .. (1.0e9 + 10), [1 2; 3 4]) + heatmap!(ax, 10 .. 11, (1.0e9 + 2) .. (1.0e9 + 3), [1 2; 3 4]) + surface!(ax, 10 .. 11, (1.0e9 + 4) .. (1.0e9 + 5), [1 2; 3 4]; shading = NoShading) - mesh!(ax, Circle(Point2(5, 1e9 + 8.5), 1.0); color=:red, shading=NoShading) - poly!(ax, [7, 9, 8], 1e9 .+ [2, 2, 3]; strokewidth=2) + mesh!(ax, Circle(Point2(5, 1.0e9 + 8.5), 1.0); color = :red, shading = NoShading) + poly!(ax, [7, 9, 8], 1.0e9 .+ [2, 2, 3]; strokewidth = 2) fig end @@ -29,17 +29,17 @@ end ax = Axis(fig[1, 1]) # scatter + lines - scatterlines!(1e-100 .* (1:10), 1e100 .* (1:10)) - linesegments!(1e-100 .* (2:11), 1e100 .* (1:10)) + scatterlines!(1.0e-100 .* (1:10), 1.0e100 .* (1:10)) + linesegments!(1.0e-100 .* (2:11), 1.0e100 .* (1:10)) # meshscatter!( 1e-100 .* (3:12), 1e100 .* (1:10)) # markersize does not match scales - text!(Point2(1e-100, 6e100), text = "Test", fontsize = 20, align = (:left, :center)) + text!(Point2(1.0e-100, 6.0e100), text = "Test", fontsize = 20, align = (:left, :center)) - image!(ax, 1e-100 .. 3e-100, (7e100) .. (10e100), [1 2; 3 4]) - heatmap!(ax, 10e-100 .. 11e-100, (2e100) .. (3e100), [1 2; 3 4]) - surface!(ax, 10e-100 .. 11e-100, (4e100) .. (5e100), [1 2; 3 4]; shading=NoShading) + image!(ax, 1.0e-100 .. 3.0e-100, (7.0e100) .. (10.0e100), [1 2; 3 4]) + heatmap!(ax, 10.0e-100 .. 11.0e-100, (2.0e100) .. (3.0e100), [1 2; 3 4]) + surface!(ax, 10.0e-100 .. 11.0e-100, (4.0e100) .. (5.0e100), [1 2; 3 4]; shading = NoShading) - mesh!(ax, Rect2d(Point2(5e-100, 8.5e100), Vec2d(1e-100, 1e100)); color=:red, shading=NoShading) - poly!(ax, 1e-100 .* [7, 9, 8], 1e100 .* [2, 2, 3]; strokewidth=2) + mesh!(ax, Rect2d(Point2(5.0e-100, 8.5e100), Vec2d(1.0e-100, 1.0e100)); color = :red, shading = NoShading) + poly!(ax, 1.0e-100 .* [7, 9, 8], 1.0e100 .* [2, 2, 3]; strokewidth = 2) fig end @@ -49,21 +49,21 @@ end fig = Figure() ax = Axis(fig[1, 1]) xlims!(ax, 0, 14) - ylims!(ax, 1e9, 1e9 + 12) + ylims!(ax, 1.0e9, 1.0e9 + 12) ax.xticks[] = (0:12, string.(0:12)) - ax.yticks[] = (1e9 .+ (0:11), ["1e9 + $i" for i in 0:11]) + ax.yticks[] = (1.0e9 .+ (0:11), ["1e9 + $i" for i in 0:11]) shift = Vec3(1, 1, 0) - p1 = scatterlines!(1:10, 1e9 .+ (1:10)) - p2 = linesegments!(2:11, 1e9 .+ (1:10)) - p3 = meshscatter!(3:12, 1e9 .+ (1:10)) - p4 = text!(Point2(1, 1e9 + 6), text = "Test", fontsize = 20, align = (:left, :center)) - p5 = image!(ax, 0 .. 3, (1e9 + 7) .. (1e9 + 10), [1 2; 3 4]) - p6 = heatmap!(ax, 10 .. 11, (1e9 + 2) .. (1e9 + 3), [1 2; 3 4]) - p7 = surface!(ax, 10 .. 11, (1e9 + 4) .. (1e9 + 5), [1 2; 3 4]; shading=NoShading) - p8 = mesh!(ax, Circle(Point2(5, 1e9 + 8.5), 1.0); color=:red, shading=NoShading) - p9 = poly!(ax, [7, 9, 8], 1e9 .+ [2, 2, 3]; strokewidth=2) + p1 = scatterlines!(1:10, 1.0e9 .+ (1:10)) + p2 = linesegments!(2:11, 1.0e9 .+ (1:10)) + p3 = meshscatter!(3:12, 1.0e9 .+ (1:10)) + p4 = text!(Point2(1, 1.0e9 + 6), text = "Test", fontsize = 20, align = (:left, :center)) + p5 = image!(ax, 0 .. 3, (1.0e9 + 7) .. (1.0e9 + 10), [1 2; 3 4]) + p6 = heatmap!(ax, 10 .. 11, (1.0e9 + 2) .. (1.0e9 + 3), [1 2; 3 4]) + p7 = surface!(ax, 10 .. 11, (1.0e9 + 4) .. (1.0e9 + 5), [1 2; 3 4]; shading = NoShading) + p8 = mesh!(ax, Circle(Point2(5, 1.0e9 + 8.5), 1.0); color = :red, shading = NoShading) + p9 = poly!(ax, [7, 9, 8], 1.0e9 .+ [2, 2, 3]; strokewidth = 2) translate!.([p1, p2, p3, p4, p5, p6, p7, p8, p9], (shift,)) @@ -74,16 +74,16 @@ end fig = Figure() ax = Axis(fig[1, 1]) - hspan!(ax, [1e9 + 4.5], [1e9 + 5.5], color = :yellow) - vspan!(ax, [1e9 + 4.5], [1e9 + 5.5], color = :yellow) + hspan!(ax, [1.0e9 + 4.5], [1.0e9 + 5.5], color = :yellow) + vspan!(ax, [1.0e9 + 4.5], [1.0e9 + 5.5], color = :yellow) - hlines!(ax, [1e9 + 4.5, 1e9 + 5.5], color = :red, linewidth = 4) - vlines!(ax, [1e9 + 4.5, 1e9 + 5.5], color = :red, linewidth = 4) + hlines!(ax, [1.0e9 + 4.5, 1.0e9 + 5.5], color = :red, linewidth = 4) + vlines!(ax, [1.0e9 + 4.5, 1.0e9 + 5.5], color = :red, linewidth = 4) - errorbars!(ax, 1e9 .+ (1:9), 1e9 .+ (1:9), 0.3, whiskerwidth = 10, direction = :x) - rangebars!(ax, 1e9 .+ (1:9), 1e9 .+ (0.7:8.7), 1e9 .+ (1.3:9.3), whiskerwidth = 10) + errorbars!(ax, 1.0e9 .+ (1:9), 1.0e9 .+ (1:9), 0.3, whiskerwidth = 10, direction = :x) + rangebars!(ax, 1.0e9 .+ (1:9), 1.0e9 .+ (0.7:8.7), 1.0e9 .+ (1.3:9.3), whiskerwidth = 10) - ablines!(ax, 2 * (1e9 + 5), -1.0) + ablines!(ax, 2 * (1.0e9 + 5), -1.0) fig end @@ -93,7 +93,7 @@ end ax = Axis(fig[1, 1]) ylims!(ax, -1, 23) p = hist!( - ax, 1e9 .+ cos.(range(0, pi, length = 100)), + ax, 1.0e9 .+ cos.(range(0, pi, length = 100)), strokewidth = 2, bins = 10, bar_labels = :y ) fig @@ -104,23 +104,23 @@ end ax = Axis(fig[1, 1]) p = heatmap!(ax, -0.75 .. -0.25, -0.75 .. -0.25, [1 2; 3 4], colormap = [:lightblue, :yellow]) - translate!(p, 1e9, 1e8, 0) - p = image!(ax, 0..1, 0..1, [1 2; 3 4], colormap = [:lightblue, :yellow]) - translate!(p, 1e9, 1e8, 0) + translate!(p, 1.0e9, 1.0e8, 0) + p = image!(ax, 0 .. 1, 0 .. 1, [1 2; 3 4], colormap = [:lightblue, :yellow]) + translate!(p, 1.0e9, 1.0e8, 0) ps = 0.5 .* Makie.Point2d[(-1, -1), (-1, 1), (1, 1), (1, -1)] p = scatter!(ax, ps, marker = '+', markersize = 30) - translate!(p, 1e9, 1e8, 0) + translate!(p, 1.0e9, 1.0e8, 0) p = text!(ax, ps, text = string.(1:4), fontsize = 20) - translate!(p, 1e9, 1e8, 0) + translate!(p, 1.0e9, 1.0e8, 0) - p = lines!(ax, [Point2f(cos(x), sin(x)) for x in range(0, 2pi, length=101)]) - translate!(p, 1e9, 1e8, 0) - p = linesegments!(ax, [0.9 * Point2f(cos(x), sin(x)) for x in range(0, 2pi, length=101)]) - translate!(p, 1e9, 1e8, 0) - p = lines!(ax, [0.8 * Point2f(cos(x), sin(x)) for x in range(0, 2pi, length=101)], linestyle = :dash) - translate!(p, 1e9, 1e8, 0) + p = lines!(ax, [Point2f(cos(x), sin(x)) for x in range(0, 2pi, length = 101)]) + translate!(p, 1.0e9, 1.0e8, 0) + p = linesegments!(ax, [0.9 * Point2f(cos(x), sin(x)) for x in range(0, 2pi, length = 101)]) + translate!(p, 1.0e9, 1.0e8, 0) + p = lines!(ax, [0.8 * Point2f(cos(x), sin(x)) for x in range(0, 2pi, length = 101)], linestyle = :dash) + translate!(p, 1.0e9, 1.0e8, 0) fig end @@ -133,27 +133,27 @@ end # p = heatmap!(ax, -0.75 .. -0.25, -0.75 .. -0.25, [1 2; 3 4], colormap = [:lightblue, :yellow]) # translate!(p, 1e9, 1e8, 0) # rotate!(p, Vec3f(0,0,1), pi/4) - p = image!(ax, 0..1, 0..1, [1 2; 3 4], colormap = [:lightblue, :yellow]) - translate!(p, 1e9, 1e8, 0) - rotate!(p, Vec3f(0,0,1), pi/4) + p = image!(ax, 0 .. 1, 0 .. 1, [1 2; 3 4], colormap = [:lightblue, :yellow]) + translate!(p, 1.0e9, 1.0e8, 0) + rotate!(p, Vec3f(0, 0, 1), pi / 4) ps = 0.5 .* Makie.Point2d[(-1, -1), (-1, 1), (1, 1), (1, -1)] p = scatter!(ax, ps, marker = '+', markersize = 30) - translate!(p, 1e9, 1e8, 0) - rotate!(p, Vec3f(0,0,1), pi/4) + translate!(p, 1.0e9, 1.0e8, 0) + rotate!(p, Vec3f(0, 0, 1), pi / 4) p = text!(ax, ps, text = string.(1:4), fontsize = 20) - translate!(p, 1e9, 1e8, 0) - rotate!(p, Vec3f(0,0,1), pi/4) - - p = lines!(ax, [Point2f(cos(x), sin(x)) for x in range(0, 2pi, length=101)]) - translate!(p, 1e9, 1e8, 0) - rotate!(p, Vec3f(0,0,1), pi/4) - p = linesegments!(ax, [0.9 * Point2f(cos(x), sin(x)) for x in range(0, 2pi, length=101)]) - translate!(p, 1e9, 1e8, 0) - rotate!(p, Vec3f(0,0,1), pi/4) - p = lines!(ax, [0.8 * Point2f(cos(x), sin(x)) for x in range(0, 2pi, length=101)], linestyle = :dash) - translate!(p, 1e9, 1e8, 0) - rotate!(p, Vec3f(0,0,1), pi/4) + translate!(p, 1.0e9, 1.0e8, 0) + rotate!(p, Vec3f(0, 0, 1), pi / 4) + + p = lines!(ax, [Point2f(cos(x), sin(x)) for x in range(0, 2pi, length = 101)]) + translate!(p, 1.0e9, 1.0e8, 0) + rotate!(p, Vec3f(0, 0, 1), pi / 4) + p = linesegments!(ax, [0.9 * Point2f(cos(x), sin(x)) for x in range(0, 2pi, length = 101)]) + translate!(p, 1.0e9, 1.0e8, 0) + rotate!(p, Vec3f(0, 0, 1), pi / 4) + p = lines!(ax, [0.8 * Point2f(cos(x), sin(x)) for x in range(0, 2pi, length = 101)], linestyle = :dash) + translate!(p, 1.0e9, 1.0e8, 0) + rotate!(p, Vec3f(0, 0, 1), pi / 4) fig -end \ No newline at end of file +end diff --git a/ReferenceTests/src/tests/generic_components.jl b/ReferenceTests/src/tests/generic_components.jl index 78024be6c7d..73e9f9220f7 100644 --- a/ReferenceTests/src/tests/generic_components.jl +++ b/ReferenceTests/src/tests/generic_components.jl @@ -3,7 +3,7 @@ @reference_test "picking" begin scene = Scene(size = (230, 370)) campixel!(scene) - + sc1 = scatter!(scene, [20, NaN, 20], [20, NaN, 50], marker = Rect, markersize = 20) sc2 = scatter!(scene, [50, 50, 20, 50], [20, 50, 80, 80], marker = Circle, markersize = 20, color = [:red, :red, :transparent, :red]) ms = meshscatter!(scene, [20, NaN, 50], [110, NaN, 110], markersize = 10) @@ -13,21 +13,22 @@ tp = text!(scene, Point2f[(15, 320), (NaN, NaN), (15, 350)], text = ["█ ●", "hi", "●"], fontsize = 20, align = (:left, :center)) t = tp.plots[1] - i = image!(scene, 80..140, 20..50, rand(RGBf, 3, 2), interpolate = false) - s = surface!(scene, 80..140, 80..110, rand(3, 2), interpolate = false) + i = image!(scene, 80 .. 140, 20 .. 50, rand(RGBf, 3, 2), interpolate = false) + s = surface!(scene, 80 .. 140, 80 .. 110, rand(3, 2), interpolate = false) hm = heatmap!(scene, [80, 110, 140], [140, 170], [1 4; 2 5; 3 6]) # mesh coloring should match triangle placements - m = mesh!(scene, Point2f.([80, 80, 110, 110], [200, 230, 200, 230]), [1 2 3; 2 3 4], color = [1,1,1,2]) - vx = voxels!(scene, [65, 155], [245, 305], [-1, 1], reshape([1,2,3,4,5,6], (3,2,1)), shading = NoShading) - vol = volume!(scene, 80..110, 320..350, -1..1, rand(2,2,2)) - + m = mesh!(scene, Point2f.([80, 80, 110, 110], [200, 230, 200, 230]), [1 2 3; 2 3 4], color = [1, 1, 1, 2]) + vx = voxels!(scene, [65, 155], [245, 305], [-1, 1], reshape([1, 2, 3, 4, 5, 6], (3, 2, 1)), shading = NoShading) + vol = volume!(scene, 80 .. 110, 320 .. 350, -1 .. 1, rand(2, 2, 2)) + # reversed axis - i2 = image!(scene, 210..180, 20..50, rand(RGBf, 2, 2)) - s2 = surface!(scene, 210..180, 80..110, [1 2; 3 4], interpolate = false) + i2 = image!(scene, 210 .. 180, 20 .. 50, rand(RGBf, 2, 2)) + s2 = surface!(scene, 210 .. 180, 80 .. 110, [1 2; 3 4], interpolate = false) hm2 = heatmap!(scene, [210, 180], [140, 170], [1 2; 3 4]) # for ranged picks - m2 = mesh!(scene, + m2 = mesh!( + scene, Point2f[(190, 330), (200, 330), (190, 340), (200, 340)], [1 2 4; 1 4 3] ) @@ -35,7 +36,7 @@ scene # for easy reviewing of the plot # render one frame to generate picking texture - colorbuffer(scene, px_per_unit = 2); + colorbuffer(scene, px_per_unit = 2) # verify that heatmap path is used for heatmaps if Symbol(Makie.current_backend()) == :WGLMakie @@ -52,7 +53,7 @@ else error("picking tests are only meant to run on GLMakie & WGLMakie") end - + # raw picking tests @testset "pick(scene, point)" begin @testset "scatter" begin @@ -93,14 +94,14 @@ end @testset "linesegments" begin - @test pick(scene, 8, 260) == (nothing, 0) # off by a pixel due to AA + @test pick(scene, 8, 260) == (nothing, 0) # off by a pixel due to AA @test pick(scene, 10, 260) == (ls, 2) @test pick(scene, 30, 269) == (ls, 2) @test pick(scene, 30, 271) == (nothing, 0) @test pick(scene, 59, 260) == (ls, 2) @test pick(scene, 61, 260) == (nothing, 0) - @test pick(scene, 8, 290) == (nothing, 0) # off by a pixel due to AA + @test pick(scene, 8, 290) == (nothing, 0) # off by a pixel due to AA @test pick(scene, 10, 290) == (ls, 6) @test pick(scene, 30, 280) == (ls, 6) @test pick(scene, 30, 278) == (nothing, 0) # off by a pixel due to AA @@ -108,7 +109,7 @@ @test pick(scene, 61, 290) == (nothing, 0) end - @testset "text" begin + @testset "text" begin @test pick(scene, 15, 320) == (t, 1) @test pick(scene, 13, 320) == (nothing, 0) # edge checks, further outside due to AA @@ -131,25 +132,25 @@ ) @test pick(scene, p) == (nothing, 0) end - + # cell centered checks - @test pick(scene, 90, 30) == (i, 1) + @test pick(scene, 90, 30) == (i, 1) @test pick(scene, 110, 30) == (i, 2) @test pick(scene, 130, 30) == (i, 3) - @test pick(scene, 90, 40) == (i, 4) + @test pick(scene, 90, 40) == (i, 4) @test pick(scene, 110, 40) == (i, 5) @test pick(scene, 130, 40) == (i, 6) # precise check (around cell intersection) - @test pick(scene, 100-1, 35-1) == (i, 1) - @test pick(scene, 100+1, 35-1) == (i, 2) - @test pick(scene, 100-1, 35+1) == (i, 4) - @test pick(scene, 100+1, 35+1) == (i, 5) - - @test pick(scene, 120-1, 35-1) == (i, 2) - @test pick(scene, 120+1, 35-1) == (i, 3) - @test pick(scene, 120-1, 35+1) == (i, 5) - @test pick(scene, 120+1, 35+1) == (i, 6) + @test pick(scene, 100 - 1, 35 - 1) == (i, 1) + @test pick(scene, 100 + 1, 35 - 1) == (i, 2) + @test pick(scene, 100 - 1, 35 + 1) == (i, 4) + @test pick(scene, 100 + 1, 35 + 1) == (i, 5) + + @test pick(scene, 120 - 1, 35 - 1) == (i, 2) + @test pick(scene, 120 + 1, 35 - 1) == (i, 3) + @test pick(scene, 120 - 1, 35 + 1) == (i, 5) + @test pick(scene, 120 + 1, 35 + 1) == (i, 6) # reversed axis check @test pick(scene, 200, 30) == (i2, 1) @@ -166,29 +167,29 @@ ) @test pick(scene, p) == (nothing, 0) end - + # cell centered checks - @test pick(scene, 90, 90) == (s, 1) - @test pick(scene, 110, 90) == (s, 2) - @test pick(scene, 130, 90) == (s, 3) - @test pick(scene, 90, 100) == (s, 4) + @test pick(scene, 90, 90) == (s, 1) + @test pick(scene, 110, 90) == (s, 2) + @test pick(scene, 130, 90) == (s, 3) + @test pick(scene, 90, 100) == (s, 4) @test pick(scene, 110, 100) == (s, 5) @test pick(scene, 130, 100) == (s, 6) # precise check (around cell intersection) - @test pick(scene, 95-1, 95-1) == (s, 1) - @test pick(scene, 95+1, 95-1) == (s, 2) - @test pick(scene, 95-1, 95+1) == (s, 4) - @test pick(scene, 95+1, 95+1) == (s, 5) - - @test pick(scene, 125-1, 95-1) == (s, 2) - @test pick(scene, 125+1, 95-1) == (s, 3) - @test pick(scene, 125-1, 95+1) == (s, 5) - @test pick(scene, 125+1, 95+1) == (s, 6) + @test pick(scene, 95 - 1, 95 - 1) == (s, 1) + @test pick(scene, 95 + 1, 95 - 1) == (s, 2) + @test pick(scene, 95 - 1, 95 + 1) == (s, 4) + @test pick(scene, 95 + 1, 95 + 1) == (s, 5) + + @test pick(scene, 125 - 1, 95 - 1) == (s, 2) + @test pick(scene, 125 + 1, 95 - 1) == (s, 3) + @test pick(scene, 125 - 1, 95 + 1) == (s, 5) + @test pick(scene, 125 + 1, 95 + 1) == (s, 6) # reversed axis check - @test pick(scene, 200, 90) == (s2, 1) - @test pick(scene, 190, 90) == (s2, 2) + @test pick(scene, 200, 90) == (s2, 1) + @test pick(scene, 190, 90) == (s2, 2) @test pick(scene, 200, 100) == (s2, 3) @test pick(scene, 190, 100) == (s2, 4) end @@ -201,12 +202,12 @@ ) @test pick(scene, p) == (nothing, 0) end - + # cell centered checks - @test pick(scene, 80, 140) == (hm, 1) + @test pick(scene, 80, 140) == (hm, 1) @test pick(scene, 110, 140) == (hm, 2) @test pick(scene, 140, 140) == (hm, 3) - @test pick(scene, 80, 170) == (hm, 4) + @test pick(scene, 80, 170) == (hm, 4) @test pick(scene, 110, 170) == (hm, 5) @test pick(scene, 140, 170) == (hm, 6) @@ -215,7 +216,7 @@ @test pick(scene, 96, 154) == (hm, 2) @test pick(scene, 94, 156) == (hm, 4) @test pick(scene, 96, 156) == (hm, 5) - + @test pick(scene, 124, 154) == (hm, 2) @test pick(scene, 126, 154) == (hm, 3) @test pick(scene, 124, 156) == (hm, 5) @@ -232,10 +233,10 @@ @test pick(scene, 80, 200)[1] == m @test pick(scene, 79, 200) == (nothing, 0) @test pick(scene, 80, 199) == (nothing, 0) - @test pick(scene, 81, 201) == (m, 3) - @test pick(scene, 81, 225) == (m, 3) + @test pick(scene, 81, 201) == (m, 3) + @test pick(scene, 81, 225) == (m, 3) @test pick(scene, 105, 201) == (m, 3) - @test pick(scene, 85, 229) == (m, 4) + @test pick(scene, 85, 229) == (m, 4) @test pick(scene, 109, 205) == (m, 4) @test pick(scene, 109, 229) == (m, 4) @test pick(scene, 109, 229)[1] == m @@ -251,35 +252,35 @@ ) @test pick(scene, p) == (nothing, 0) end - + # cell centered checks - @test pick(scene, 80, 260) == (vx, 1) + @test pick(scene, 80, 260) == (vx, 1) @test pick(scene, 110, 260) == (vx, 2) @test pick(scene, 140, 260) == (vx, 3) - @test pick(scene, 80, 290) == (vx, 4) + @test pick(scene, 80, 290) == (vx, 4) @test pick(scene, 110, 290) == (vx, 5) @test pick(scene, 140, 290) == (vx, 6) # precise check (around cell intersection) - @test pick(scene, 94, 274) == (vx, 1) - @test pick(scene, 96, 274) == (vx, 2) - @test pick(scene, 94, 276) == (vx, 4) - @test pick(scene, 96, 276) == (vx, 5) - + @test pick(scene, 94, 274) == (vx, 1) + @test pick(scene, 96, 274) == (vx, 2) + @test pick(scene, 94, 276) == (vx, 4) + @test pick(scene, 96, 276) == (vx, 5) + @test pick(scene, 124, 274) == (vx, 2) @test pick(scene, 126, 274) == (vx, 3) @test pick(scene, 124, 276) == (vx, 5) @test pick(scene, 126, 276) == (vx, 6) end - + @testset "volume" begin - # volume doesn't produce indices because we can't resolve the depth of + # volume doesn't produce indices because we can't resolve the depth of # the pick - @test pick(scene, 80, 320)[1] == vol - @test pick(scene, 79, 320) == (nothing, 0) - @test pick(scene, 80, 319) == (nothing, 0) - @test pick(scene, 81, 321) == (vol, 0) - @test pick(scene, 81, 349) == (vol, 0) + @test pick(scene, 80, 320)[1] == vol + @test pick(scene, 79, 320) == (nothing, 0) + @test pick(scene, 80, 319) == (nothing, 0) + @test pick(scene, 81, 321) == (vol, 0) + @test pick(scene, 81, 349) == (vol, 0) @test pick(scene, 109, 321) == (vol, 0) @test pick(scene, 109, 349) == (vol, 0) @test pick(scene, 109, 349)[1] == vol @@ -301,27 +302,27 @@ @test pick(scene, 40, 218, 10) == (l2, 5) end @testset "linesegments" begin - @test pick(scene, 5, 280, 10) == (ls, 6) + @test pick(scene, 5, 280, 10) == (ls, 6) end - @testset "text" begin + @testset "text" begin @test pick(scene, 32, 320, 10) == (t, 1) @test pick(scene, 35, 320, 10) == (t, 3) end @testset "image" begin - @test pick(scene, 98, 15, 10) == (i, 1) + @test pick(scene, 98, 15, 10) == (i, 1) @test pick(scene, 102, 15, 10) == (i, 2) @test pick(scene, 200, 15, 10) == (i2, 1) @test pick(scene, 190, 15, 10) == (i2, 2) end @testset "surface" begin - @test pick(scene, 93, 75, 10) == (s, 1) - @test pick(scene, 97, 75, 10) == (s, 2) + @test pick(scene, 93, 75, 10) == (s, 1) + @test pick(scene, 97, 75, 10) == (s, 2) @test pick(scene, 200, 75, 10) == (s2, 1) @test pick(scene, 190, 75, 10) == (s2, 2) end @testset "heatmap" begin - @test pick(scene, 93, 120, 10) == (hm, 1) - @test pick(scene, 97, 120, 10) == (hm, 2) + @test pick(scene, 93, 120, 10) == (hm, 1) + @test pick(scene, 97, 120, 10) == (hm, 2) @test pick(scene, 200, 120, 10) == (hm2, 1) @test pick(scene, 190, 120, 10) == (hm2, 2) end @@ -329,11 +330,11 @@ @test pick(scene, 115, 230, 10) == (m, 4) end @testset "voxel" begin - @test pick(scene, 93, 240, 10) == (vx, 1) - @test pick(scene, 97, 240, 10) == (vx, 2) + @test pick(scene, 93, 240, 10) == (vx, 1) + @test pick(scene, 97, 240, 10) == (vx, 2) end @testset "volume" begin - @test pick(scene, 75, 320, 10) == (vol, 0) + @test pick(scene, 75, 320, 10) == (vol, 0) end @testset "range" begin # mesh!(scene, Rect2f(200, 330, 10, 10)) @@ -418,7 +419,7 @@ # pick(scene, Rect) # grab all indices and generate a plot for them (w/ fixed px_per_unit) full_screen = last.(pick(scene, scene.viewport[])) - + scene2 = Scene(size = 2.0 .* widths(scene.viewport[])) campixel!(scene2) image!(scene2, full_screen, colormap = :viridis) diff --git a/ReferenceTests/src/tests/primitives.jl b/ReferenceTests/src/tests/primitives.jl index ddae6dc6b0c..651f9e2e347 100644 --- a/ReferenceTests/src/tests/primitives.jl +++ b/ReferenceTests/src/tests/primitives.jl @@ -4,15 +4,16 @@ points = Point2f[(1, 1), (1, 2), (2, 3), (2, 1)] linestyles = [ :solid, :dash, :dot, :dashdot, :dashdotdot, - Linestyle([1, 2, 3]), Linestyle([1, 2, 4, 5]) + Linestyle([1, 2, 3]), Linestyle([1, 2, 4, 5]), ] for linewidth in 1:10 for (i, linestyle) in enumerate(linestyles) - lines!(s, - scalar .* (points .+ Point2f(linewidth*2, i * 3.25)), + lines!( + s, + scalar .* (points .+ Point2f(linewidth * 2, i * 3.25)), linewidth = linewidth, linestyle = linestyle, - color=:black + color = :black ) end end @@ -40,18 +41,18 @@ end scene = Scene() cam2d!(scene) r = 4 - sep = 4*r - scatter!(scene, (sep+2*r)*[-1,-1,1,1], (sep+2*r)*[-1,1,-1,1]) + sep = 4 * r + scatter!(scene, (sep + 2 * r) * [-1, -1, 1, 1], (sep + 2 * r) * [-1, 1, -1, 1]) - for i=-1:1 - for j=-1:1 - angle = pi/2 + pi/4*i - x = r*[-cos(angle/2),0,-cos(angle/2)] - y = r*[-sin(angle/2),0,sin(angle/2)] + for i in -1:1 + for j in -1:1 + angle = pi / 2 + pi / 4 * i + x = r * [-cos(angle / 2), 0, -cos(angle / 2)] + y = r * [-sin(angle / 2), 0, sin(angle / 2)] linewidth = 40 * 2.0^j - lines!(scene, x .+ sep*i, y .+ sep*j, color=RGBAf(0,0,0,0.5), linewidth=linewidth) - lines!(scene, x .+ sep*i, y .+ sep*j, color=:red) + lines!(scene, x .+ sep * i, y .+ sep * j, color = RGBAf(0, 0, 0, 0.5), linewidth = linewidth) + lines!(scene, x .+ sep * i, y .+ sep * j, color = :red) end end center!(scene) @@ -65,7 +66,7 @@ end for phi in [130, -121, 119, 90, -60] R = Makie.Mat2f(cosd(phi), sind(phi), -sind(phi), cosd(phi)) r += 0.2 - push!(ps, ps[end] + r * R * normalize(ps[end] - ps[end-1])) + push!(ps, ps[end] + r * R * normalize(ps[end] - ps[end - 1])) end for i in 1:3, j in 1:3 @@ -109,7 +110,7 @@ end ps = [Point2f(0, -0.5), Point2f(1, -0.5)] for phi in [160, -130, 121, 50, 119, -90] # these are 180-miter_angle R = Makie.Mat2f(cosd(phi), sind(phi), -sind(phi), cosd(phi)) - push!(ps, ps[end] + (1 + 0.2 * (phi == 50)) * R * normalize(ps[end] - ps[end-1])) + push!(ps, ps[end] + (1 + 0.2 * (phi == 50)) * R * normalize(ps[end] - ps[end - 1])) end popfirst!(ps) # for alignment, removes 160° corner @@ -119,15 +120,15 @@ end xlims!(-2.7, 2.4) ylims!(-2.5, 2.5) lines!( - ax, ps .+ Point2f(-1.2, -1.2), linewidth = 20, miter_limit = 51pi/180, color = :black, + ax, ps .+ Point2f(-1.2, -1.2), linewidth = 20, miter_limit = 51pi / 180, color = :black, joinstyle = :round ) lines!( - ax, ps .+ Point2f(+1.2, -1.2), linewidth = 20, miter_limit = 129pi/180, color = :black, + ax, ps .+ Point2f(+1.2, -1.2), linewidth = 20, miter_limit = 129pi / 180, color = :black, joinstyle = :bevel ) - lines!(ax, ps .+ Point2f(-1.2, +1.2), linewidth = 20, miter_limit = 51pi/180, color = :black) - lines!(ax, ps .+ Point2f(+1.2, +1.2), linewidth = 20, miter_limit = 129pi/180, color = :black) + lines!(ax, ps .+ Point2f(-1.2, +1.2), linewidth = 20, miter_limit = 51pi / 180, color = :black) + lines!(ax, ps .+ Point2f(+1.2, +1.2), linewidth = 20, miter_limit = 129pi / 180, color = :black) fig end @@ -137,8 +138,8 @@ end # rendered correctly. For perspective projections this can be tricky as # points behind the camera get projected beyond far. lps = let - ps1 = [Point3f(x, 0.2 * (z+1), z) for x in (-8, 0, 8) for z in (-9, -1, -1, 7)] - ps2 = [Point3f(x, 0.2 * (z+1), z) for z in (-9, -1, 7) for x in (-8, 0, 0, 8)] + ps1 = [Point3f(x, 0.2 * (z + 1), z) for x in (-8, 0, 8) for z in (-9, -1, -1, 7)] + ps2 = [Point3f(x, 0.2 * (z + 1), z) for z in (-9, -1, 7) for x in (-8, 0, 0, 8)] vcat(ps1, ps2) end cs = [i for i in (1, 12, 2, 11, 3, 10, 4, 9, 5, 8, 6, 7) for _ in 1:2] @@ -160,23 +161,23 @@ end @reference_test "line color interpolation with clipping" begin # Clipping should not change the color interpolation of a line piece, so # these boxes should match in color - fig = Figure(); - ax = Axis(fig[1,1]); - ylims!(ax, -0.1, 1.1); + fig = Figure() + ax = Axis(fig[1, 1]) + ylims!(ax, -0.1, 1.1) lines!( ax, Rect2f(0, 0, 1, 10), color = 1:5, linewidth = 5, clip_planes = [Plane3f(Point3f(0, 1.0, 0), Vec3f(0, -1, 0))] - ); - lines!(ax, Rect2f(0.1, 0.0, 0.8, 10.0), color = 1:5, linewidth = 5); + ) + lines!(ax, Rect2f(0.1, 0.0, 0.8, 10.0), color = 1:5, linewidth = 5) - ax = Axis(fig[1,2]); - ylims!(ax, -0.1, 1.1); + ax = Axis(fig[1, 2]) + ylims!(ax, -0.1, 1.1) cs = [1, 2, 2, 3, 3, 4, 4, 5] linesegments!( ax, Rect2f(0, 0, 1, 10), color = cs, linewidth = 5, clip_planes = [Plane3f(Point3f(0, 1.0, 0), Vec3f(0, -1, 0))] - ); - linesegments!(ax, Rect2f(0.1, 0.0, 0.8, 10.0), color = cs, linewidth = 5); + ) + linesegments!(ax, Rect2f(0.1, 0.0, 0.8, 10.0), color = cs, linewidth = 5) fig end @@ -184,17 +185,19 @@ end s = Scene(size = (800, 800), camera = campixel!) markersizes = 0:2:30 - markers = [:circle, :rect, :cross, :utriangle, :dtriangle, - 'a', 'x', 'h', 'g', 'Y', 'J', 'α', '↑' + markers = [ + :circle, :rect, :cross, :utriangle, :dtriangle, + 'a', 'x', 'h', 'g', 'Y', 'J', 'α', '↑', ] for (i, ms) in enumerate(markersizes) for (j, m) in enumerate(markers) - scatter!(s, + scatter!( + s, Point2f(i, j) .* 45, marker = m, markersize = ms, - color=:black + color = :black ) end end @@ -205,19 +208,21 @@ end s = Scene(size = (800, 800), camera = campixel!) rotations = range(0, 2pi, length = 15) - markers = [:circle, :rect, :cross, :utriangle, :dtriangle, - 'a', 'x', 'h', 'g', 'Y', 'J', 'α', '↑' + markers = [ + :circle, :rect, :cross, :utriangle, :dtriangle, + 'a', 'x', 'h', 'g', 'Y', 'J', 'α', '↑', ] for (i, rot) in enumerate(rotations) for (j, m) in enumerate(markers) p = Point2f(i, j) .* 45 - scatter!(s, + scatter!( + s, p, marker = m, markersize = 30, rotation = rot, - color=:black + color = :black ) scatter!(s, p, color = :red, markersize = 6) end @@ -235,11 +240,13 @@ function make_billboard_rotations_test_fig(marker) for (k, transform_marker) in zip(0:1, [true, false]) for (i, space, ms) in zip(1:2, [:data, :pixel], [1, 30]) for (j, rot, lbl) in zip(1:3, [Billboard(phis), phis, quats], ["Billboard", "angles", "Quaternion"]) - Label(fig[i+2k, j][1,1], "$space | $lbl | $transform_marker", tellwidth = false) - a, p = scatter(fig[i+2k, j][2,1], ps, marker = marker, + Label(fig[i + 2k, j][1, 1], "$space | $lbl | $transform_marker", tellwidth = false) + a, p = scatter( + fig[i + 2k, j][2, 1], ps, marker = marker, strokewidth = 2, strokecolor = :black, color = :yellow, markersize = ms, markerspace = space, rotation = rot, - transform_marker = transform_marker) + transform_marker = transform_marker + ) Makie.rotate!(p, Vec3f(1, 0.5, 0.1), 1.0) a.scene.camera_controls.settings[:center] = false @@ -248,7 +255,7 @@ function make_billboard_rotations_test_fig(marker) end end - fig + return fig end @reference_test "scatter Billboard and transform_marker for Char markers" begin @@ -271,7 +278,7 @@ end s = Scene(size = (350, 700), camera = campixel!) # half stroke, half glow - strokes = range(1, 4, length=7) + strokes = range(1, 4, length = 7) outline_colors = [:red, :green, :blue, :yellow, :purple, :cyan, :black] colors = [ :red, :green, :blue, @@ -281,8 +288,9 @@ end RGBAf(1, 0, 1, 0), RGBAf(0, 1, 1, 0), RGBAf(1, 1, 0, 0), ] - markers = [:circle, :rect, :cross, :utriangle, :dtriangle, - 'a', 'x', 'h', 'g', 'Y', 'J', 'α', '↑', 'o' + markers = [ + :circle, :rect, :cross, :utriangle, :dtriangle, + 'a', 'x', 'h', 'g', 'Y', 'J', 'α', '↑', 'o', ] for i in eachindex(strokes) @@ -290,7 +298,8 @@ end strokewidth = strokes[i] for (j, (m, c)) in enumerate(zip(markers, colors)) p = Point2f(i, j) .* 45 - scatter!(s, + scatter!( + s, p, marker = m, markersize = 30, color = c, strokewidth = strokewidth, strokecolor = oc, @@ -304,7 +313,7 @@ end s = Scene(size = (350, 700), camera = campixel!) # half stroke, half glow - glows = range(4, 1, length=7) + glows = range(4, 1, length = 7) outline_colors = [:red, :green, :blue, :yellow, :purple, :cyan, :black] colors = [ :red, :green, :blue, @@ -314,8 +323,9 @@ end RGBAf(1, 0, 1, 0), RGBAf(0, 1, 1, 0), RGBAf(1, 1, 0, 0), ] - markers = [:circle, :rect, :cross, :utriangle, :dtriangle, - 'a', 'x', 'h', 'g', 'Y', 'J', 'α', '↑', 'o' + markers = [ + :circle, :rect, :cross, :utriangle, :dtriangle, + 'a', 'x', 'h', 'g', 'Y', 'J', 'α', '↑', 'o', ] for i in eachindex(glows) @@ -323,7 +333,8 @@ end glowwidth = glows[i] for (j, (m, c)) in enumerate(zip(markers, colors)) p = Point2f(i, j) .* 45 - scatter!(s, + scatter!( + s, p, marker = m, markersize = 30, color = c, glowwidth = glowwidth, glowcolor = oc, @@ -335,15 +346,16 @@ end @reference_test "scatter image markers" begin - pixel_types = [ RGBA, RGBAf, RGBA{Float16}, ARGB, ARGB{Float16}, RGB, RGBf, RGB{Float16} ] - rotations = [ 2pi/3 * (i-1) for i = 1:length(pixel_types) ] - s = Scene(size = (100+100*length(pixel_types), 400), camera = campixel!) + pixel_types = [RGBA, RGBAf, RGBA{Float16}, ARGB, ARGB{Float16}, RGB, RGBf, RGB{Float16}] + rotations = [ 2pi / 3 * (i - 1) for i in 1:length(pixel_types) ] + s = Scene(size = (100 + 100 * length(pixel_types), 400), camera = campixel!) filename = Makie.assetpath("icon_transparent.png") marker_image = load(filename) for (i, (rot, pxtype)) in enumerate(zip(rotations, pixel_types)) marker = convert.(pxtype, marker_image) - p = Point2f((i-1) * 100 + 100, 200) - scatter!(s, + p = Point2f((i - 1) * 100 + 100, 200) + scatter!( + s, p, marker = marker, markersize = 75, @@ -393,7 +405,7 @@ end for (i, p) in enumerate(polys) for (j, lw) in enumerate(linewidths) - t = Transformation(scale=Vec3f(scalefactor), translation = Vec3f(1.3 * (i-1), 1.3 * j, 0) .* scalefactor) + t = Transformation(scale = Vec3f(scalefactor), translation = Vec3f(1.3 * (i - 1), 1.3 * j, 0) .* scalefactor) poly!( s, p, @@ -460,7 +472,7 @@ end # Same as above markers = [ :rect, :circle, :cross, :x, :utriangle, :rtriangle, :dtriangle, :ltriangle, :pentagon, - :hexagon, :octagon, :star4, :star5, :star6, :star8, :vline, :hline, 'x', 'X' + :hexagon, :octagon, :star4, :star5, :star6, :star8, :vline, :hline, 'x', 'X', ] for (i, marker) in enumerate(markers) @@ -479,27 +491,31 @@ end f = Figure(size = (800, 800)) ax = Axis(f[1, 1]) - arrow = BezierPath([ - MoveTo(Point(0, 0)), - LineTo(Point(0.3, -0.3)), - LineTo(Point(0.15, -0.3)), - LineTo(Point(0.3, -1)), - LineTo(Point(0, -0.9)), - LineTo(Point(-0.3, -1)), - LineTo(Point(-0.15, -0.3)), - LineTo(Point(-0.3, -0.3)), - ClosePath() - ]) - - circle_with_hole = BezierPath([ - MoveTo(Point(1, 0)), - Makie.EllipticalArc(Point(0, 0), 1, 1, 0, 0, 2pi), - MoveTo(Point(0.5, 0.5)), - LineTo(Point(0.5, -0.5)), - LineTo(Point(-0.5, -0.5)), - LineTo(Point(-0.5, 0.5)), - ClosePath(), - ]) + arrow = BezierPath( + [ + MoveTo(Point(0, 0)), + LineTo(Point(0.3, -0.3)), + LineTo(Point(0.15, -0.3)), + LineTo(Point(0.3, -1)), + LineTo(Point(0, -0.9)), + LineTo(Point(-0.3, -1)), + LineTo(Point(-0.15, -0.3)), + LineTo(Point(-0.3, -0.3)), + ClosePath(), + ] + ) + + circle_with_hole = BezierPath( + [ + MoveTo(Point(1, 0)), + Makie.EllipticalArc(Point(0, 0), 1, 1, 0, 0, 2pi), + MoveTo(Point(0.5, 0.5)), + LineTo(Point(0.5, -0.5)), + LineTo(Point(-0.5, -0.5)), + LineTo(Point(-0.5, 0.5)), + ClosePath(), + ] + ) batsymbol_string = "M96.84 141.998c-4.947-23.457-20.359-32.211-25.862-13.887-11.822-22.963-37.961-16.135-22.041 6.289-3.005-1.295-5.872-2.682-8.538-4.191-8.646-5.318-15.259-11.314-19.774-17.586-3.237-5.07-4.994-10.541-4.994-16.229 0-19.774 21.115-36.758 50.861-43.694.446-.078.909-.154 1.372-.231-22.657 30.039 9.386 50.985 15.258 24.645l2.528-24.367 5.086 6.52H103.205l5.07-6.52 2.543 24.367c5.842 26.278 37.746 5.502 15.414-24.429 29.777 6.951 50.891 23.936 50.891 43.709 0 15.136-12.406 28.651-31.609 37.267 14.842-21.822-10.867-28.266-22.549-5.549-5.502-18.325-21.147-9.341-26.125 13.886z" batsymbol = Makie.scale( @@ -510,20 +526,24 @@ end gh_string = "M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z" github = BezierPath(gh_string, fit = true, flipy = true) - two_circles_with_holes = Makie.scale(BezierPath([ - MoveTo(Point(2.25, 0)), - Makie.EllipticalArc(Point(1.25, 0), 1, 1, 0, 0, 2pi), - ClosePath(), - MoveTo(Point(-0.25, 0)), - Makie.EllipticalArc(Point(-1.25, 0), 1, 1, 0, 0, 2pi), - ClosePath(), - MoveTo(Point(2, 0)), - Makie.EllipticalArc(Point(1.25, 0), 0.75, 0.75, 0, 0, -2pi), - ClosePath(), - MoveTo(Point(-1, 0)), - Makie.EllipticalArc(Point(-1.25, 0), 0.25, 0.25, 0, 0, -2pi), - ClosePath(), - ]), 0.5) + two_circles_with_holes = Makie.scale( + BezierPath( + [ + MoveTo(Point(2.25, 0)), + Makie.EllipticalArc(Point(1.25, 0), 1, 1, 0, 0, 2pi), + ClosePath(), + MoveTo(Point(-0.25, 0)), + Makie.EllipticalArc(Point(-1.25, 0), 1, 1, 0, 0, 2pi), + ClosePath(), + MoveTo(Point(2, 0)), + Makie.EllipticalArc(Point(1.25, 0), 0.75, 0.75, 0, 0, -2pi), + ClosePath(), + MoveTo(Point(-1, 0)), + Makie.EllipticalArc(Point(-1.25, 0), 0.25, 0.25, 0, 0, -2pi), + ClosePath(), + ] + ), 0.5 + ) markers = [ arrow, @@ -546,11 +566,11 @@ end p_big = decompose(Point2f, Circle(Point2f(0), 1)) p_small = decompose(Point2f, Circle(Point2f(0), 0.5)) marker = [Polygon(p_big, [p_small]), Polygon(reverse(p_big), [p_small]), Polygon(p_big, [reverse(p_small)]), Polygon(reverse(p_big), [reverse(p_small)])] - scatter(1:4, fill(0, 4), marker=marker, markersize=100, color=1:4, axis=(limits=(0, 5, -1, 1),)) + scatter(1:4, fill(0, 4), marker = marker, markersize = 100, color = 1:4, axis = (limits = (0, 5, -1, 1),)) end function centered_rect(w, h) - wh, hh = w/2, h/2 + wh, hh = w / 2, h / 2 return Point2f[(-wh, -hh), (-wh, hh), (wh, hh), (wh, -hh)] end @@ -568,15 +588,15 @@ function create_rect(inner) return Makie.to_spritemarker(marker) end -function plot_test!(scene, xoffset, yoffset, inner, reverse=true, marker=create_marker) +function plot_test!(scene, xoffset, yoffset, inner, reverse = true, marker = create_marker) bpath = marker(inner) p = [Point2f(xoffset, yoffset) .+ 150] - if reverse - scatter!(scene, p, marker=bpath, markersize=280, color=:black) - scatter!(scene, p, marker=Rect, markersize=280, color=:red) + return if reverse + scatter!(scene, p, marker = bpath, markersize = 280, color = :black) + scatter!(scene, p, marker = Rect, markersize = 280, color = :red) else - scatter!(scene, p, marker=Rect, markersize=280, color=:red) - scatter!(scene, p, marker=bpath, markersize=280, color=:black) + scatter!(scene, p, marker = Rect, markersize = 280, color = :red) + scatter!(scene, p, marker = bpath, markersize = 280, color = :black) end end @@ -585,12 +605,12 @@ function plot_row!(scene, yoffset, reverse) plot_test!(scene, 0, yoffset + 0, 0.4, reverse) plot_test!(scene, 300, yoffset + 0, 0.3, reverse) plot_test!(scene, 600, yoffset + 0, 0.4, reverse, create_rect) - plot_test!(scene, 900, yoffset + 0, 0.3, reverse, create_rect) + return plot_test!(scene, 900, yoffset + 0, 0.3, reverse, create_rect) end -function draw_marker_test!(scene, marker, center; markersize=300) +function draw_marker_test!(scene, marker, center; markersize = 300) # scatter!(scene, center, distancefield=matr, uv_offset_width=Vec4f(0, 0, 1, 1), markersize=600) - scatter!(scene, center, color=:black, marker=marker, markersize=markersize, markerspace=:pixel) + scatter!(scene, center, color = :black, marker = marker, markersize = markersize, markerspace = :pixel) font = Makie.defaultfont() charextent = Makie.FreeTypeAbstraction.get_extent(font, marker) @@ -600,18 +620,18 @@ function draw_marker_test!(scene, marker, center; markersize=300) w, h = widths(inkbb) .* markersize ox, oy = origin(inkbb) .* markersize mhalf = markersize / 2 - bbmin = center .+ Point2f(-w/2, -h/2) + bbmin = center .+ Point2f(-w / 2, -h / 2) inkbb_scaled = Rect2f(bbmin..., w, h) - lines!(scene, inkbb_scaled, linewidth=5, color=:green) - points = Point2f[(center[1], center[2] - h/2), (center[1], center[2] + h/2), (center[1] - w/2, center[2]), (center[1] + w/2, center[2])] - linesegments!(scene, points, color=:red) + lines!(scene, inkbb_scaled, linewidth = 5, color = :green) + points = Point2f[(center[1], center[2] - h / 2), (center[1], center[2] + h / 2), (center[1] - w / 2, center[2]), (center[1] + w / 2, center[2])] + linesegments!(scene, points, color = :red) - scene + return scene end @reference_test "marke glyph alignment" begin - scene = Scene(size=(1200, 1200)) + scene = Scene(size = (1200, 1200)) campixel!(scene) # marker is in front, so it should not be smaller than the background rectangle plot_row!(scene, 0, false) @@ -622,30 +642,30 @@ end # Markers should be well aligned to the red cross and just about touch the green # boundingbox! - draw_marker_test!(scene, 'x', Point2f(150, 750); markersize=550) - draw_marker_test!(scene, 'X', Point2f(450, 750); markersize=400) - draw_marker_test!(scene, 'I', Point2f(750, 750); markersize=400) - draw_marker_test!(scene, 'O', Point2f(1050, 750); markersize=300) + draw_marker_test!(scene, 'x', Point2f(150, 750); markersize = 550) + draw_marker_test!(scene, 'X', Point2f(450, 750); markersize = 400) + draw_marker_test!(scene, 'I', Point2f(750, 750); markersize = 400) + draw_marker_test!(scene, 'O', Point2f(1050, 750); markersize = 300) - draw_marker_test!(scene, 'L', Point2f(150, 1050); markersize=350) - draw_marker_test!(scene, 'Y', Point2f(450, 1050); markersize=350) - draw_marker_test!(scene, 'y', Point2f(750, 1050); markersize=350) - draw_marker_test!(scene, 'u', Point2f(1050, 1050); markersize=500) + draw_marker_test!(scene, 'L', Point2f(150, 1050); markersize = 350) + draw_marker_test!(scene, 'Y', Point2f(450, 1050); markersize = 350) + draw_marker_test!(scene, 'y', Point2f(750, 1050); markersize = 350) + draw_marker_test!(scene, 'u', Point2f(1050, 1050); markersize = 500) scene end @reference_test "Surface with NaN points" begin # prepare surface data - zs = [x^2 + y^2 for x in range(-2, 0, length=10), y in range(-2, 0, length=10)] + zs = [x^2 + y^2 for x in range(-2, 0, length = 10), y in range(-2, 0, length = 10)] ns = copy(zs) ns[4, 3:6] .= NaN # plot surface - f, a, p = surface(1..10, 1..10, ns, colormap = [:lightblue, :lightblue]) + f, a, p = surface(1 .. 10, 1 .. 10, ns, colormap = [:lightblue, :lightblue]) # plot a wireframe so we can see what's going on, and in which cells. m = Makie.surface2mesh(to_value.(p.converted)...) - scatter!(a, m.position, color = isnan.(m.normal), depth_shift = -1f-3) - wireframe!(a, m, depth_shift = -1f-3, color = :black) + scatter!(a, m.position, color = isnan.(m.normal), depth_shift = -1.0f-3) + wireframe!(a, m, depth_shift = -1.0f-3, color = :black) f end @@ -657,7 +677,7 @@ end range(-1, 1, length = 21), -cos.(range(-pi, pi, length = 21)), [sin(y) for x in range(-0.5pi, 0.5pi, length = 21), y in range(-0.5pi, 0.5pi, length = 21)], - axis = (show_axis = false, ), + axis = (show_axis = false,), invert_normals = invert ) end @@ -670,8 +690,8 @@ end lab2 = lab1 # lab2 = L"\frac{a}{b} - \sqrt{b}" # this will not work until #2667 is fixed - barplot(fig[1,1], [1, 2], [0.5, 0.2], bar_labels = [lab1, lab2], flip_labels_at = 0.3, direction=:x) - barplot(fig[1,2], [1, 2], [0.5, 0.2], bar_labels = [lab1, lab2], flip_labels_at = 0.3) + barplot(fig[1, 1], [1, 2], [0.5, 0.2], bar_labels = [lab1, lab2], flip_labels_at = 0.3, direction = :x) + barplot(fig[1, 2], [1, 2], [0.5, 0.2], bar_labels = [lab1, lab2], flip_labels_at = 0.3) fig end @@ -686,33 +706,39 @@ end c = RGBf(0, 1, 1) m = RGBf(1, 0, 1) k = RGBf(0, 0, 0) - [r w g w b w k w; - w w w w w w w w; - r k g k b k w k; - k k k k k k k k] + [ + r w g w b w k w; + w w w w w w w w; + r k g k b k w k; + k k k k k k k k + ] end # Use same uvs/texture-sections for every side of one voxel id - flat_uv_map = [Vec4f(x, x + 1 / 2, y, y + 1 / 4) - for x in range(0.0, 1.0; length=3)[1:(end - 1)] - for y in range(0.0, 1.0; length=5)[1:(end - 1)]] - - flat_voxels = UInt8[1, 0, 3, - 0, 0, 0, - 2, 0, 4, - 0, 0, 0, - 0, 0, 0, - 0, 0, 0, - 5, 0, 7, - 0, 0, 0, - 6, 0, 8] + flat_uv_map = [ + Vec4f(x, x + 1 / 2, y, y + 1 / 4) + for x in range(0.0, 1.0; length = 3)[1:(end - 1)] + for y in range(0.0, 1.0; length = 5)[1:(end - 1)] + ] + + flat_voxels = UInt8[ + 1, 0, 3, + 0, 0, 0, + 2, 0, 4, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 5, 0, 7, + 0, 0, 0, + 6, 0, 8, + ] # Reshape the flat vector into a 3D array of dimensions 3x3x3. voxels_3d = reshape(flat_voxels, (3, 3, 3)) - fig = Figure(; size=(800, 400)) - a1 = LScene(fig[1, 1]; show_axis=false) - p1 = voxels!(a1, voxels_3d; uvmap=flat_uv_map, color=texture) + fig = Figure(; size = (800, 400)) + a1 = LScene(fig[1, 1]; show_axis = false) + p1 = voxels!(a1, voxels_3d; uvmap = flat_uv_map, color = texture) # Use red for x, green for y, blue for z sided_uv_map = Matrix{Vec4f}(undef, 1, 6) @@ -720,8 +746,8 @@ end sided_uv_map[1, 4:6] .= flat_uv_map[5:7] sided_voxels = reshape(UInt8[1], 1, 1, 1) - a2 = LScene(fig[1, 2]; show_axis=false) - p2 = voxels!(a2, sided_voxels; uvmap=sided_uv_map, color=texture) + a2 = LScene(fig[1, 2]; show_axis = false) + p2 = voxels!(a2, sided_voxels; uvmap = sided_uv_map, color = texture) fig end @@ -729,12 +755,14 @@ end @reference_test "Voxel - colors and colormap" begin # test direct mapping of ids to colors & upsampling of vector colormap fig = Figure(size = (800, 400)) - chunk = reshape(UInt8[1, 0, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0, 0, 0, 7, 0, 8], - (3, 3, 3)) + chunk = reshape( + UInt8[1, 0, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0, 0, 0, 7, 0, 8], + (3, 3, 3) + ) cs = [:white, :red, :green, :blue, :black, :orange, :cyan, :magenta] - voxels(fig[1, 1], chunk, color = cs, axis=(show_axis = false,)) - a, p = voxels(fig[1, 2], Float32.(chunk), colormap = [:red, :blue], is_air = x -> x == 0.0, axis=(show_axis = false,)) + voxels(fig[1, 1], chunk, color = cs, axis = (show_axis = false,)) + a, p = voxels(fig[1, 2], Float32.(chunk), colormap = [:red, :blue], is_air = x -> x == 0.0, axis = (show_axis = false,)) fig end @@ -742,15 +770,15 @@ end # test that lowclip and highclip are visible for values just outside the colorrange fig = Figure(size = (800, 400)) chunk = reshape(collect(1:900), 30, 30, 1) - a1, _ = voxels(fig[1,1], chunk, lowclip = :red, highclip = :red, colorrange = (1.0, 900.0), shading = NoShading) - a2, _ = voxels(fig[1,2], chunk, lowclip = :red, highclip = :red, colorrange = (1.1, 899.9), shading = NoShading) - foreach(a -> update_cam!(a.scene, Vec3f(0, 0, 40), Vec3f(0), Vec3f(0,1,0)), (a1, a2)) + a1, _ = voxels(fig[1, 1], chunk, lowclip = :red, highclip = :red, colorrange = (1.0, 900.0), shading = NoShading) + a2, _ = voxels(fig[1, 2], chunk, lowclip = :red, highclip = :red, colorrange = (1.1, 899.9), shading = NoShading) + foreach(a -> update_cam!(a.scene, Vec3f(0, 0, 40), Vec3f(0), Vec3f(0, 1, 0)), (a1, a2)) fig end @reference_test "Voxel - gap attribute" begin # test direct mapping of ids to colors & upsampling of vector colormap - voxels(RNG.rand(3,3,3), gap = 0.3) + voxels(RNG.rand(3, 3, 3), gap = 0.3) end @reference_test "Plot transform overwrite" begin @@ -764,10 +792,10 @@ end empty!(ax.scene.lights) hidedecorations!(ax) - heatmap!(ax, 0..0.5, 0..0.5, [i+j for i in 1:10, j in 1:10], transformation = Transformation()) - image!(ax, 0..0.5, 0.5..1, [i+j for i in 1:10, j in 1:10], transformation = Transformation()) + heatmap!(ax, 0 .. 0.5, 0 .. 0.5, [i + j for i in 1:10, j in 1:10], transformation = Transformation()) + image!(ax, 0 .. 0.5, 0.5 .. 1, [i + j for i in 1:10, j in 1:10], transformation = Transformation()) mesh!(ax, Rect2f(0.5, 0.0, 1.0, 0.25), transformation = Transformation(), color = :green) - p = surface!(ax, 0.5..1, 0.25..0.75, [i+j for i in 1:10, j in 1:10], transformation = Transformation()) + p = surface!(ax, 0.5 .. 1, 0.25 .. 0.75, [i + j for i in 1:10, j in 1:10], transformation = Transformation()) translate!(p, Vec3f(0, 0, -20)) poly!(ax, Rect2f(0.5, 0.75, 1.0, 1.0), transformation = Transformation(), color = :blue) @@ -782,7 +810,7 @@ end @reference_test "uv_transform" begin fig = Figure(size = (400, 400)) - img = [RGBf(1,0,0) RGBf(0,1,0); RGBf(0,0,1) RGBf(1,1,1)] + img = [RGBf(1, 0, 0) RGBf(0, 1, 0); RGBf(0, 0, 1) RGBf(1, 1, 1)] function create_block(f, gl, args...; kwargs...) ax, p = f(gl[1, 1], args..., uv_transform = I; kwargs...) @@ -791,7 +819,7 @@ end hidedecorations!(ax) ax, p = f(gl[2, 1], args..., uv_transform = (Vec2f(0.5), Vec2f(0.5)); kwargs...) hidedecorations!(ax) - ax, p = f(gl[2, 2], args..., uv_transform = Makie.Mat{2,3,Float32}(-1,0,0,-1,1,1); kwargs...) + ax, p = f(gl[2, 2], args..., uv_transform = Makie.Mat{2, 3, Float32}(-1, 0, 0, -1, 1, 1); kwargs...) hidedecorations!(ax) end @@ -799,15 +827,16 @@ end create_block(mesh, gl, Rect2f(0, 0, 1, 1), color = img) gl = fig[1, 2] = GridLayout() - create_block(surface, gl, 0..1, 0..1, zeros(10, 10), color = img) + create_block(surface, gl, 0 .. 1, 0 .. 1, zeros(10, 10), color = img) gl = fig[2, 1] = GridLayout() create_block( - meshscatter, gl, Point2f[(0,0), (0,1), (1,0), (1,1)], color = img, - marker = Makie.uv_normal_mesh(Rect2f(0,0,1,1)), markersize = 1.0) + meshscatter, gl, Point2f[(0, 0), (0, 1), (1, 0), (1, 1)], color = img, + marker = Makie.uv_normal_mesh(Rect2f(0, 0, 1, 1)), markersize = 1.0 + ) gl = fig[2, 2] = GridLayout() - create_block(image, gl, 0..1, 0..1, img) + create_block(image, gl, 0 .. 1, 0 .. 1, img) fig end @@ -823,35 +852,39 @@ end color = cow, uv_transform = [ Makie.uv_transform(:rotl90) * - Makie.uv_transform(Vec2f(x, y+1/N), Vec2f(1/M, -1/N)) - for x in range(0, 1, length = M+1)[1:M] - for y in range(0, 1, length = N+1)[1:N] + Makie.uv_transform(Vec2f(x, y + 1 / N), Vec2f(1 / M, -1 / N)) + for x in range(0, 1, length = M + 1)[1:M] + for y in range(0, 1, length = N + 1)[1:N] ], markersize = Vec3f(0.9, 0.9, 1), marker = uv_normal_mesh(Rect2f(-0.5, -0.5, 1, 1)) ) hidedecorations!(a) - xlims!(a, 0.3, M+0.7) - ylims!(a, 0.3, N+0.7) + xlims!(a, 0.3, M + 0.7) + ylims!(a, 0.3, N + 0.7) f end @reference_test "Scatter with FastPixel" begin f = Figure() row = [(1, :pixel, 20), (2, :data, 0.5)] points3d = decompose(Point3f, Rect3(Point3f(0), Vec3f(1))) - column = [(1, points3d, Axis3), (2, points3d, LScene), - (3, 1:4, Axis)] + column = [ + (1, points3d, Axis3), (2, points3d, LScene), + (3, 1:4, Axis), + ] for (i, space, msize) in row for (j, data, AT) in column ax = AT(f[i, j]) - if ax isa Union{Axis,Axis3} + if ax isa Union{Axis, Axis3} ax isa Axis && (ax.aspect = DataAspect()) ax.title = "$space" end - scatter!(ax, data; markersize=msize, markerspace=space, marker=Makie.FastPixel()) - scatter!(ax, data; - markersize=msize, markerspace=space, marker=Rect, - strokewidth=2, strokecolor=:red, color=:transparent,) + scatter!(ax, data; markersize = msize, markerspace = space, marker = Makie.FastPixel()) + scatter!( + ax, data; + markersize = msize, markerspace = space, marker = Rect, + strokewidth = 2, strokecolor = :red, color = :transparent, + ) end end f @@ -863,17 +896,19 @@ end f = Figure(size = (600, 400)) for (i, interp) in enumerate((true, false)) - for (j, plot_func) in enumerate(( - (fp, x, y, cs, interp) -> image(fp, x, y, cs, colormap = :viridis, interpolate = interp), - (fp, x, y, cs, interp) -> heatmap(fp, x, y, cs, colormap = :viridis, interpolate = interp), - (fp, x, y, cs, interp) -> surface(fp, x, y, zeros(size(cs)), color = cs, colormap = :viridis, interpolate = interp, shading = NoShading) - )) + for (j, plot_func) in enumerate( + ( + (fp, x, y, cs, interp) -> image(fp, x, y, cs, colormap = :viridis, interpolate = interp), + (fp, x, y, cs, interp) -> heatmap(fp, x, y, cs, colormap = :viridis, interpolate = interp), + (fp, x, y, cs, interp) -> surface(fp, x, y, zeros(size(cs)), color = cs, colormap = :viridis, interpolate = interp, shading = NoShading), + ) + ) gl = GridLayout(f[i, j]) a, p = plot_func(gl[1, 1], (1, 4), (1, 4), img, interp) hidedecorations!(a) - a, p = plot_func(gl[2, 1], (1, 4), 4..1, img, interp) + a, p = plot_func(gl[2, 1], (1, 4), 4 .. 1, img, interp) hidedecorations!(a) a, p = plot_func(gl[1, 2], (4, 1), (1, 4), img, interp) hidedecorations!(a) @@ -889,9 +924,9 @@ end fig = Figure(size = (400, 500)) Label(fig[0, 1], tellwidth = false, "meshscatter") Label(fig[0, 2], tellwidth = false, "mesh") - Label(fig[1, 0], tellheight = false, rotation = pi/2, "simple") - Label(fig[2, 0], tellheight = false, rotation = pi/2, "log10") - Label(fig[3, 0], tellheight = false, rotation = pi/2, "float32convert") + Label(fig[1, 0], tellheight = false, rotation = pi / 2, "simple") + Label(fig[2, 0], tellheight = false, rotation = pi / 2, "log10") + Label(fig[3, 0], tellheight = false, rotation = pi / 2, "float32convert") kwargs = (markersize = 1, transform_marker = false, shading = NoShading) kwargs2 = (color = Makie.wong_colors()[1], shading = NoShading) @@ -899,9 +934,9 @@ end # no special transformations, must match limits = (0.8, 3.2, 0.8, 3.2) ax = Axis(fig[1, 1], limits = limits) - meshscatter!(ax, [Point2f(2)], marker = Circle(Point2f(0), 1f0); kwargs...) + meshscatter!(ax, [Point2f(2)], marker = Circle(Point2f(0), 1.0f0); kwargs...) ax = Axis(fig[1, 2], limits = limits) - mesh!(ax, Circle(Point2f(2), 1f0); kwargs2...) + mesh!(ax, Circle(Point2f(2), 1.0f0); kwargs2...) # log10 transform, center must match (meshscatter does not transform vertices # because that would destroy performance) @@ -913,12 +948,12 @@ end mesh!(ax, Circle(Point2f(1), 0.5f0); kwargs2...) # f32c can be applied - ticks = (1e12 .+ (-1f6:1f6:1f6), string.(-1:1) .* ("f6",)) - axis_kwargs = (xticks = ticks, yticks = ticks, limits = 1e12 .+ (-1.2e6, 1.2e6, -1.2e6, 1.2e6)) + ticks = (1.0e12 .+ (-1.0f6:1.0f6:1.0f6), string.(-1:1) .* ("f6",)) + axis_kwargs = (xticks = ticks, yticks = ticks, limits = 1.0e12 .+ (-1.2e6, 1.2e6, -1.2e6, 1.2e6)) ax1 = Axis(fig[3, 1]; axis_kwargs...) - meshscatter!(ax1, [Point2f(1e12)], marker = Circle(Point2f(0), 1f6); kwargs...) + meshscatter!(ax1, [Point2f(1.0e12)], marker = Circle(Point2f(0), 1.0f6); kwargs...) ax2 = Axis(fig[3, 2]; axis_kwargs...) - mesh!(ax2, Circle(Makie.Point2d(1e12), 1e6); kwargs2...) + mesh!(ax2, Circle(Makie.Point2d(1.0e12), 1.0e6); kwargs2...) fig end @@ -927,16 +962,16 @@ end Label(fig[0, 1], tellwidth = false, "meshscatter") Label(fig[0, 2], tellwidth = false, "mesh") Label(fig[0, 3], tellwidth = false, "meshscatter\ntransformable") - Label(fig[1, 0], tellheight = false, rotation = pi/2, "simple") - Label(fig[2, 0], tellheight = false, rotation = pi/2, "log10") - Label(fig[3, 0], tellheight = false, rotation = pi/2, "float32convert") + Label(fig[1, 0], tellheight = false, rotation = pi / 2, "simple") + Label(fig[2, 0], tellheight = false, rotation = pi / 2, "log10") + Label(fig[3, 0], tellheight = false, rotation = pi / 2, "float32convert") kwargs = (markersize = 1, shading = NoShading) kwargs2 = (color = Makie.wong_colors()[1], shading = NoShading) function transform!(p, x, rotate = true) scale!(p, 0.5, 0.5, 0.5) if rotate - Makie.rotate!(p, pi/2) + Makie.rotate!(p, pi / 2) translate!(p, x, 0, 0) else translate!(p, x, x, 0) @@ -946,11 +981,11 @@ end # scale shrinks so left should be 2x bigger than rest limits = (-0.2, 2.2, -0.2, 2.2) ax = Axis(fig[1, 1], limits = limits) - p1 = meshscatter!(ax, [Point2f(2)], marker = Circle(Point2f(0), 1f0); transform_marker = false, kwargs...) + p1 = meshscatter!(ax, [Point2f(2)], marker = Circle(Point2f(0), 1.0f0); transform_marker = false, kwargs...) ax = Axis(fig[1, 2], limits = limits) - p2 = mesh!(ax, Circle(Point2f(2), 1f0); kwargs2...) + p2 = mesh!(ax, Circle(Point2f(2), 1.0f0); kwargs2...) ax = Axis(fig[1, 3], limits = limits) - p3 = meshscatter!(ax, [Point2f(2)], marker = Circle(Point2f(0), 1f0); transform_marker = true, kwargs...) + p3 = meshscatter!(ax, [Point2f(2)], marker = Circle(Point2f(0), 1.0f0); transform_marker = true, kwargs...) transform!.((p1, p2, p3), 2) # center must match, left 2x bigger than right @@ -965,15 +1000,15 @@ end transform!.((p4, p5, p6), 0) # center must match, left 2x bigger than rest - ticks = (1e12 .+ (-10f5:5f5:10f5), string.(-10:5:10) .* ("f5",)) - axis_kwargs = (xticks = ticks, yticks = ticks, limits = 1e12 .+ (-1.2e6, 1.2e6, -1.2e6, 1.2e6)) + ticks = (1.0e12 .+ (-10.0f5:5.0f5:10.0f5), string.(-10:5:10) .* ("f5",)) + axis_kwargs = (xticks = ticks, yticks = ticks, limits = 1.0e12 .+ (-1.2e6, 1.2e6, -1.2e6, 1.2e6)) ax1 = Axis(fig[3, 1]; axis_kwargs...) - p7 = meshscatter!(ax1, [Point2f(1e12)], marker = Circle(Point2f(0), 1f6); transform_marker = false, kwargs...) + p7 = meshscatter!(ax1, [Point2f(1.0e12)], marker = Circle(Point2f(0), 1.0f6); transform_marker = false, kwargs...) ax2 = Axis(fig[3, 2]; axis_kwargs...) - p8 = mesh!(ax2, Circle(Makie.Point2d(1e12), 1e6); kwargs2...) + p8 = mesh!(ax2, Circle(Makie.Point2d(1.0e12), 1.0e6); kwargs2...) ax3 = Axis(fig[3, 3]; axis_kwargs...) - p9 = meshscatter!(ax3, [Point2f(1e12)], marker = Circle(Point2f(0), 1f6); transform_marker = true, kwargs...) - transform!.((p7, p8, p9), 5e11, false) + p9 = meshscatter!(ax3, [Point2f(1.0e12)], marker = Circle(Point2f(0), 1.0f6); transform_marker = true, kwargs...) + transform!.((p7, p8, p9), 5.0e11, false) fig end @@ -984,16 +1019,16 @@ end xlims!(ax, -6.5, 6.5); ylims!(ax, -10, 10) ax.xticks[] = (-5:2:5, ["BezierPath", "Circle", "Rect", "Char", "FastPixel", "Image"]) ax.yticks[] = ([-7.5, -2.75, 2.25, 7.25], [":pixel", ":data", ":relative", ":clip"]) - ax.yticklabelrotation[] = pi/2 + ax.yticklabelrotation[] = pi / 2 - img = [RGBf(r, 0.7, b) for r in range(0, 1, length=4), b in range(0, 1, length=4)] + img = [RGBf(r, 0.7, b) for r in range(0, 1, length = 4), b in range(0, 1, length = 4)] rect_corners = Point2f[(-0.5, -0.5), (-0.5, 0.5), (0.5, 0.5), (0.5, -0.5), (-0.5, -0.5), (NaN, NaN)] for (y, offset, space, markersize) in [ - (-8.5, (0, 0), :pixel, 40), (-5.5, (0, -20), :pixel, 40), - (-4, (0, 0), :data, 1.8), (-0.5, (0, -1), :data, 1.8), + (-8.5, (0, 0), :pixel, 40), (-5.5, (0, -20), :pixel, 40), + (-4, (0, 0), :data, 1.8), (-0.5, (0, -1), :data, 1.8), (+1, (0, 0), :relative, 0.1), (+4.5, (0, -0.05), :relative, 0.1), - (+6, (0, 0), :clip, 0.2), (+9.5, (0, -0.1), :clip, 0.2), + (+6, (0, 0), :clip, 0.2), (+9.5, (0, -0.1), :clip, 0.2), ] # Generate scatter plots with different marker types @@ -1001,16 +1036,16 @@ end scatter!(ax, Point2f(-5, y), marker = :ltriangle; kwargs...) scatter!(ax, Point2f(-3, y), marker = Circle; kwargs...) scatter!(ax, Point2f(-1, y), marker = Rect; kwargs...) - scatter!(ax, Point2f( 1, y), marker = 'x'; kwargs...) + scatter!(ax, Point2f(1, y), marker = 'x'; kwargs...) if space in (:data, :pixel) - scatter!(ax, Point2f( 3, y), marker = FastPixel(); kwargs...) + scatter!(ax, Point2f(3, y), marker = FastPixel(); kwargs...) end - scatter!(ax, Point2f( 5, y), marker = img; kwargs...) + scatter!(ax, Point2f(5, y), marker = img; kwargs...) # Generate outlines (transform to markerspace, generate rect based on markersize, add offset) xs = space in (:data, :pixel) ? (-5:2:5) : [-5, -3, -1, 1, 5] transformed = map(Point2f.(xs, y)) do pos - pos_ms = Makie.project(ax.scene, :data, space, pos)[Vec(1,2)] + pos_ms = Makie.project(ax.scene, :data, space, pos)[Vec(1, 2)] rect_ps = [pos_ms .+ markersize .* xy .+ offset for xy in rect_corners] return rect_ps end @@ -1027,31 +1062,31 @@ end xlims!(ax, -6.5, 6.5); ylims!(ax, -10, 10) ax.xticks[] = (-5:2.5:5, ["BezierPath", "Circle", "Rect", "Char", "Image"]) ax.yticks[] = ([-7.5, -2.75, 2.25, 7.25], [":pixel", ":data", ":relative", ":clip"]) - ax.yticklabelrotation[] = pi/2 + ax.yticklabelrotation[] = pi / 2 - img = [RGBf(r, 0.7, b) for r in range(0, 1, length=4), b in range(0, 1, length=4)] + img = [RGBf(r, 0.7, b) for r in range(0, 1, length = 4), b in range(0, 1, length = 4)] rotation = 0.3f0 - rect_corners = [Point2f(cos(a), sin(a)) ./ sqrt(2) for a in (range(0.0, 2pi, length=5) .+ pi/4 .+ rotation)] + rect_corners = [Point2f(cos(a), sin(a)) ./ sqrt(2) for a in (range(0.0, 2pi, length = 5) .+ pi / 4 .+ rotation)] push!(rect_corners, Point2f(NaN)) for (y, offset, space, markersize) in [ - (-8.5, (0, 0), :pixel, 40), (-5.5, (0, -20), :pixel, 40), - (-4, (0, 0), :data, 1.8), (-0.5, (0, -1), :data, 1.8), + (-8.5, (0, 0), :pixel, 40), (-5.5, (0, -20), :pixel, 40), + (-4, (0, 0), :data, 1.8), (-0.5, (0, -1), :data, 1.8), (+1, (0, 0), :relative, 0.1), (+4.5, (0, -0.05), :relative, 0.1), - (+6, (0, 0), :clip, 0.2), (+9.5, (0, -0.1), :clip, 0.2), + (+6, (0, 0), :clip, 0.2), (+9.5, (0, -0.1), :clip, 0.2), ] # Generate scatter plots with different marker types kwargs = (markerspace = space, markersize = markersize, marker_offset = offset, rotation = rotation) scatter!(ax, Point2f(-5, y), marker = :ltriangle; kwargs...) scatter!(ax, Point2f(-2.5, y), marker = Circle; kwargs...) - scatter!(ax, Point2f( 0, y), marker = Rect; kwargs...) - scatter!(ax, Point2f( 2.5, y), marker = 'x'; kwargs...) - scatter!(ax, Point2f( 5, y), marker = img; kwargs...) + scatter!(ax, Point2f(0, y), marker = Rect; kwargs...) + scatter!(ax, Point2f(2.5, y), marker = 'x'; kwargs...) + scatter!(ax, Point2f(5, y), marker = img; kwargs...) # Generate outlines (transform to markerspace, generate rect based on markersize, add offset) transformed = map(Point2f.(-5:2.5:5, y)) do pos - pos_ms = Makie.project(ax.scene, :data, space, pos)[Vec(1,2)] + pos_ms = Makie.project(ax.scene, :data, space, pos)[Vec(1, 2)] rect_ps = [pos_ms .+ markersize .* xy .+ offset for xy in rect_corners] return rect_ps end @@ -1067,24 +1102,24 @@ end update_cam!(ax.scene, Vec3f(12), Vec3f(1, 2, -2)) cameracontrols(ax).settings.center[] = false - img = [RGBf(r, 0.7, b) for r in range(0, 1, length=4), b in range(0, 1, length=4)] + img = [RGBf(r, 0.7, b) for r in range(0, 1, length = 4), b in range(0, 1, length = 4)] rotation = qrotation(Vec3f(1), 0.8) rect_corners = Point2f[(-0.5, -0.5), (-0.5, 0.5), (0.5, 0.5), (0.5, -0.5), (-0.5, -0.5), (NaN, NaN)] for (y, offset, space, markersize) in [ - (-8.5, (0, 0, 0), :pixel, 20), (-6, (0, -10, 0), :pixel, 20), - (-2, (0, 0, 0), :data, 1.5), (1, (0, -1, 0), :data, 1.5), - (+3, (0, 0, 0), :relative, 0.05), (+4.5, (0, -0.025, 0), :relative, 0.05), - (+8, (0, 0, 0), :clip, 0.1), (+9, (0, -0.05, 0), :clip, 0.1), + (-8.5, (0, 0, 0), :pixel, 20), (-6, (0, -10, 0), :pixel, 20), + (-2, (0, 0, 0), :data, 1.5), (1, (0, -1, 0), :data, 1.5), + (+3, (0, 0, 0), :relative, 0.05), (+4.5, (0, -0.025, 0), :relative, 0.05), + (+8, (0, 0, 0), :clip, 0.1), (+9, (0, -0.05, 0), :clip, 0.1), ] # Generate scatter plots with different marker types kwargs = (markerspace = space, markersize = markersize, marker_offset = offset, rotation = rotation) - scatter!(ax, Point2f(-5, y), marker = :ltriangle; kwargs...) + scatter!(ax, Point2f(-5, y), marker = :ltriangle; kwargs...) scatter!(ax, Point2f(-2.5, y), marker = Circle; kwargs...) - scatter!(ax, Point2f( 0, y), marker = Rect; kwargs...) - scatter!(ax, Point2f( 2.5, y), marker = 'x'; kwargs...) - scatter!(ax, Point2f( 5, y), marker = img; kwargs...) + scatter!(ax, Point2f(0, y), marker = Rect; kwargs...) + scatter!(ax, Point2f(2.5, y), marker = 'x'; kwargs...) + scatter!(ax, Point2f(5, y), marker = img; kwargs...) # Generate outlines (transform to markerspace, generate rect based on markersize, add offset) transformed = map(ax.scene.camera.projectionview) do _ @@ -1096,7 +1131,7 @@ end end vcat(transformed...) end - p = lines!(ax, transformed, color = :black, linewidth = 2, space = space, depth_shift = -5f-2) + p = lines!(ax, transformed, color = :black, linewidth = 2, space = space, depth_shift = -5.0f-2) end fig diff --git a/ReferenceTests/src/tests/recipes.jl b/ReferenceTests/src/tests/recipes.jl index 547920a0538..2ab0e0050c2 100644 --- a/ReferenceTests/src/tests/recipes.jl +++ b/ReferenceTests/src/tests/recipes.jl @@ -2,12 +2,12 @@ import Makie: Plot, default_theme, plot!, to_value struct Simulation grid::Vector{Point3f} end - # Probably worth having a macro for this! -function Makie.default_theme(scene::SceneLike, ::Type{<: Plot(Simulation)}) - Theme( - advance=0, - molecule_sizes=[0.08, 0.04, 0.04], - molecule_colors=[:maroon, :deepskyblue2, :deepskyblue2] +# Probably worth having a macro for this! +function Makie.default_theme(scene::SceneLike, ::Type{<:Plot(Simulation)}) + return Theme( + advance = 0, + molecule_sizes = [0.08, 0.04, 0.04], + molecule_colors = [:maroon, :deepskyblue2, :deepskyblue2] ) end # The recipe! - will get called for plot(!)(x::SimulationResult) @@ -21,15 +21,15 @@ function Makie.plot!(p::Plot(Simulation)) pos = to_value(mpos) N = length(pos) sizes = lift(p[:molecule_sizes]) do s - repeat(s, outer=N ÷ 3) + repeat(s, outer = N ÷ 3) end sizes = lift(p[:molecule_sizes]) do s - repeat(s, outer=N ÷ 3) + repeat(s, outer = N ÷ 3) end colors = lift(p[:molecule_colors]) do c - repeat(c, outer=N ÷ 3) + repeat(c, outer = N ÷ 3) end - scene = meshscatter!(p, mpos, markersize=sizes, color=colors) + scene = meshscatter!(p, mpos, markersize = sizes, color = colors) indices = Int[] for i in 1:3:N push!(indices, i, i + 1, i, i + 2) @@ -37,16 +37,16 @@ function Makie.plot!(p::Plot(Simulation)) meshplot = p.plots[end] # meshplot is the last plot we added to p # meshplot[1] -> the positions (first argument) converted to points, so # we don't do the conversion 2 times for linesegments! - linesegments!(p, lift(x -> view(x, indices), meshplot[1])) + return linesegments!(p, lift(x -> view(x, indices), meshplot[1])) end @reference_test "Type recipe for molecule simulation" begin # To write out a video of the whole simulation n = 5 - r = range(-1, stop=1, length=n) + r = range(-1, stop = 1, length = n) grid = Point3f.(r, reshape(r, (1, n, 1)), reshape(r, (1, 1, n))) - molecules = map(1:(n^3) * 3) do i + molecules = map(1:((n^3) * 3)) do i i3 = ((i - 1) ÷ 3) + 1 xy = 0.1; z = 0.08 i % 3 == 1 && return grid[i3] diff --git a/ReferenceTests/src/tests/short_tests.jl b/ReferenceTests/src/tests/short_tests.jl index 6d111230245..1c5f81731e4 100644 --- a/ReferenceTests/src/tests/short_tests.jl +++ b/ReferenceTests/src/tests/short_tests.jl @@ -1,23 +1,23 @@ -@reference_test "thick arc" arc(Point2f(0), 10f0, 0f0, pi, linewidth=20) +@reference_test "thick arc" arc(Point2f(0), 10.0f0, 0.0f0, pi, linewidth = 20) @reference_test "poly stroke & array input" begin f = Figure(size = (500, 300)) - poly(f[1, 1], Recti(0, 0, 200, 200), strokewidth=20, strokecolor=:red, color=(:black, 0.4)) + poly(f[1, 1], Recti(0, 0, 200, 200), strokewidth = 20, strokecolor = :red, color = (:black, 0.4)) poly(f[1, 2], [Rect(0, 0, 20, 20)]) - scatter!(Rect(0, 0, 20, 20), color=:red, markersize=20) + scatter!(Rect(0, 0, 20, 20), color = :red, markersize = 20) f end @reference_test "char marker scenespace" begin - f, ax, pl = lines(Rect(0, 0, 1, 1), linewidth=4) - scatter!([Point2f(0.5, 0.5)], markersize=1, markerspace=:data, marker='I') + f, ax, pl = lines(Rect(0, 0, 1, 1), linewidth = 4) + scatter!([Point2f(0.5, 0.5)], markersize = 1, markerspace = :data, marker = 'I') f end @reference_test "lines per element colors, OffsetArrays, #3704" begin f = Figure() - lines(f[1, 1], RNG.rand(10), RNG.rand(10), color=RNG.rand(10), linewidth=10) - lines(f[1, 2], RNG.rand(10), RNG.rand(10), color=RNG.rand(RGBAf, 10), linewidth=10) + lines(f[1, 1], RNG.rand(10), RNG.rand(10), color = RNG.rand(10), linewidth = 10) + lines(f[1, 2], RNG.rand(10), RNG.rand(10), color = RNG.rand(RGBAf, 10), linewidth = 10) # lines issue #3704 lines(f[2, 2], 1:10, sin, color = [fill(0, 9); fill(1, 1)], linewidth = 3, colormap = [:red, :cyan]) f @@ -26,39 +26,39 @@ end @reference_test "lines inputs" begin f = Figure() lines(f[1, 1], Circle(Point2f(0), Float32(1))) - lines(f[1, 2], -1..1, x -> x^2) + lines(f[1, 2], -1 .. 1, x -> x^2) lines(f[2, 1], Makie.OffsetArrays.Origin(-50)(1:100)) f end @reference_test "scatter inputs" begin f = Figure() - scatter(f[1, 1], 0..1, RNG.rand(10), markersize=RNG.rand(10) .* 20) + scatter(f[1, 1], 0 .. 1, RNG.rand(10), markersize = RNG.rand(10) .* 20) scatter(f[1, 2], LinRange(0, 1, 10), RNG.rand(10)) colors = Makie.resample(to_colormap(:Spectral), 20) - scatter!(RNG.rand(20), RNG.rand(20), markersize=RNG.rand(20) .* 20, color=colors) - - scatter(f[2, 1], -1..1, x -> x^2) - scatter(f[2, 2], RNG.randn(10), color=:blue, glowcolor=:orange, glowwidth=10) + scatter!(RNG.rand(20), RNG.rand(20), markersize = RNG.rand(20) .* 20, color = colors) + + scatter(f[2, 1], -1 .. 1, x -> x^2) + scatter(f[2, 2], RNG.randn(10), color = :blue, glowcolor = :orange, glowwidth = 10) f end @reference_test "scatter rotation" begin - angles = range(0, stop=2pi, length=20) + angles = range(0, stop = 2pi, length = 20) pos = Point2f.(sin.(angles), cos.(angles)) - f, ax, pl = scatter(pos, markersize=0.2, markerspace=:data, rotation=-angles, marker='▲', axis=(;aspect = DataAspect())) - scatter!(pos, markersize=10, color=:red) + f, ax, pl = scatter(pos, markersize = 0.2, markerspace = :data, rotation = -angles, marker = '▲', axis = (; aspect = DataAspect())) + scatter!(pos, markersize = 10, color = :red) f end @reference_test "heatmap log scale, transparent colormap" begin f = Figure(size = (500, 250)) - heatmap(f[1, 1], RNG.rand(10, 5), axis = (yscale = log10, xscale=log10)) - heatmap(f[1, 2], RNG.rand(50, 50), colormap=(:RdBu, 0.2)) + heatmap(f[1, 1], RNG.rand(10, 5), axis = (yscale = log10, xscale = log10)) + heatmap(f[1, 2], RNG.rand(50, 50), colormap = (:RdBu, 0.2)) f end -@reference_test "contour small x or y" begin +@reference_test "contour small x or y" begin f = Figure(size = (500, 300)) contour(f[1, 1], RNG.rand(10, 50)) contour(f[1, 2], RNG.rand(50, 10)) @@ -67,10 +67,12 @@ end @reference_test "contour levels and colors" begin f = Figure() - contour(f[1, 1], RNG.randn(50, 40), levels=3) - contour(f[1, 2], RNG.randn(50, 40), levels=[0.1, 0.5, 0.8]) - contour(f[2, 1], RNG.randn(33, 30), levels=[0.1, 0.5, 0.9], - color=[:black, :green, (:blue, 0.4)], linewidth=2) + contour(f[1, 1], RNG.randn(50, 40), levels = 3) + contour(f[1, 2], RNG.randn(50, 40), levels = [0.1, 0.5, 0.8]) + contour( + f[2, 1], RNG.randn(33, 30), levels = [0.1, 0.5, 0.9], + color = [:black, :green, (:blue, 0.4)], linewidth = 2 + ) contour( f[2, 2], RNG.rand(33, 30) .* 6 .- 3, levels = [-2.5, 0.4, 0.5, 0.6, 2.5], colormap = [(:black, 0.2), :red, :blue, :green, (:black, 0.2)], @@ -80,25 +82,25 @@ end end @reference_test "streamplot with func" begin - v(x::Point2{T}) where T = Point2{T}(x[2], 4 * x[1]) - streamplot(v, -2..2, -2..2) + v(x::Point2{T}) where {T} = Point2{T}(x[2], 4 * x[1]) + streamplot(v, -2 .. 2, -2 .. 2) end -@reference_test "meshscatter colors, Axis3" begin +@reference_test "meshscatter colors, Axis3" begin f = Figure() - meshscatter(f[1, 1], RNG.rand(10), RNG.rand(10), RNG.rand(10), color=RNG.rand(10)) - meshscatter(f[1, 2], RNG.rand(10), RNG.rand(10), RNG.rand(10), color=RNG.rand(RGBAf, 10), transparency=true) - meshscatter(f[2, 1], RNG.rand(Point3f, 10), axis=(type=Axis3,)) + meshscatter(f[1, 1], RNG.rand(10), RNG.rand(10), RNG.rand(10), color = RNG.rand(10)) + meshscatter(f[1, 2], RNG.rand(10), RNG.rand(10), RNG.rand(10), color = RNG.rand(RGBAf, 10), transparency = true) + meshscatter(f[2, 1], RNG.rand(Point3f, 10), axis = (type = Axis3,)) f end @reference_test "transparent mesh texture" begin - s1 = uv_mesh(Sphere(Point3f(0), 1f0)) - f, ax, pl = mesh(uv_mesh(Sphere(Point3f(0), 1f0)), color=RNG.rand(50, 50)) + s1 = uv_mesh(Sphere(Point3f(0), 1.0f0)) + f, ax, pl = mesh(uv_mesh(Sphere(Point3f(0), 1.0f0)), color = RNG.rand(50, 50)) # ugh, bug In GeometryTypes for UVs of non unit spheres. - s2 = uv_mesh(Sphere(Point3f(0), 1f0)) + s2 = uv_mesh(Sphere(Point3f(0), 1.0f0)) s2.position .= s2.position .+ (Point3f(0, 2, 0),) - mesh!(s2, color=RNG.rand(RGBAf, 50, 50)) + mesh!(s2, color = RNG.rand(RGBAf, 50, 50)) f end @@ -107,17 +109,17 @@ end NR = 31 function xy_data(x, y) r = sqrt(x^2 + y^2) - r == 0.0 ? 1f0 : (sin(r) / r) + r == 0.0 ? 1.0f0 : (sin(r) / r) end - lspace = range(-10, stop=10, length=NL) - rspace = range(-10, stop=10, length=NR) + lspace = range(-10, stop = 10, length = NL) + rspace = range(-10, stop = 10, length = NR) z = Float32[xy_data(x, y) for x in lspace, y in rspace] - l = range(0, stop=3, length=NL) - r = range(0, stop=3, length=NR) + l = range(0, stop = 3, length = NL) + r = range(0, stop = 3, length = NR) surface( l, r, z, - colormap=:Spectral + colormap = :Spectral ) end @@ -126,17 +128,17 @@ end NR = 31 function xy_data(x, y) r = sqrt(x^2 + y^2) - r == 0.0 ? 1f0 : (sin(r) / r) + r == 0.0 ? 1.0f0 : (sin(r) / r) end - lspace = range(-10, stop=10, length=NL) - rspace = range(-10, stop=10, length=NR) + lspace = range(-10, stop = 10, length = NL) + rspace = range(-10, stop = 10, length = NR) z = Float32[xy_data(x, y) for x in lspace, y in rspace] - l = range(0, stop=3, length=NL) - r = range(0, stop=3, length=NR) + l = range(0, stop = 3, length = NL) + r = range(0, stop = 3, length = NR) surface( [l for l in l, r in r], [r for l in l, r in r], z, - colormap=:Spectral + colormap = :Spectral ) end @@ -177,18 +179,18 @@ end @reference_test "lines linesegments width test" begin res = 200 - s = Scene(camera=campixel!, size=(res, res)) + s = Scene(camera = campixel!, size = (res, res)) half = res / 2 linewidth = 10 - xstart = half - (half/2) + xstart = half - (half / 2) xend = xstart + 100 - half_w = linewidth/2 + half_w = linewidth / 2 - lines!(s, Point2f[(xstart, half), (xend, half)], linewidth=linewidth) - scatter!(s, Point2f[(xstart, half + half_w), (xstart, half - half_w), (xend, half + half_w), (xend, half - half_w)], color=:red, markersize=2) + lines!(s, Point2f[(xstart, half), (xend, half)], linewidth = linewidth) + scatter!(s, Point2f[(xstart, half + half_w), (xstart, half - half_w), (xend, half + half_w), (xend, half - half_w)], color = :red, markersize = 2) - l2 = linesegments!(s, Point2f[(xstart, half), (xend, half)], linewidth=linewidth, color=:gray) - s2 = scatter!(s, Point2f[(xstart, half + half_w), (xstart, half - half_w), (xend, half + half_w), (xend, half - half_w)], color=:red, markersize=2) + l2 = linesegments!(s, Point2f[(xstart, half), (xend, half)], linewidth = linewidth, color = :gray) + s2 = scatter!(s, Point2f[(xstart, half + half_w), (xstart, half - half_w), (xend, half + half_w), (xend, half - half_w)], color = :red, markersize = 2) for p in (l2, s2) translate!(p, 0, 20, 0) @@ -198,22 +200,26 @@ end end @reference_test "multipoly with multi strokes" begin - P = Polygon.([Point2f[[0.45, 0.05], [0.64, 0.15], [0.37, 0.62]], - Point2f[[0.32, 0.66], [0.46, 0.59], [0.09, 0.08]]]) + P = Polygon.( + [ + Point2f[[0.45, 0.05], [0.64, 0.15], [0.37, 0.62]], + Point2f[[0.32, 0.66], [0.46, 0.59], [0.09, 0.08]], + ] + ) poly(P, color = [:red, :green], strokecolor = [:blue, :red], strokewidth = 2) end @reference_test "fast pixel marker" begin - scatter(RNG.rand(Point2f, 10000), marker=Makie.FastPixel()) + scatter(RNG.rand(Point2f, 10000), marker = Makie.FastPixel()) end @reference_test "pattern barplot" begin - barplot(1:5, color=Makie.LinePattern(linecolor=:red, background_color=:orange)) + barplot(1:5, color = Makie.LinePattern(linecolor = :red, background_color = :orange)) end @reference_test "barplot lowclip highclip nan_color" begin f = Figure() - attrs = (color=[-Inf, 2, NaN, Inf], colorrange=(2, 3), highclip = :red, lowclip=:green, nan_color=:black) + attrs = (color = [-Inf, 2, NaN, Inf], colorrange = (2, 3), highclip = :red, lowclip = :green, nan_color = :black) barplot(f[1, 1], 1:4; attrs...) poly( f[1, 2], @@ -223,11 +229,11 @@ end Point2f[(2, 1), (4, 1), (4, 2), (2, 2)], Point2f[(0, 1), (2, 1), (2, 2), (0, 2)], ]; - strokewidth=2, attrs... + strokewidth = 2, attrs... ) meshscatter(f[2, 1], 1:4, zeros(4), 1:4; attrs...) volcano = readdlm(Makie.assetpath("volcano.csv"), ',', Float64) - ax, cf = contourf(f[2, 2], volcano, levels = range(100, 180, length = 10), extendlow = :green, extendhigh = :red, nan_color=:black) + ax, cf = contourf(f[2, 2], volcano, levels = range(100, 180, length = 10), extendlow = :green, extendhigh = :red, nan_color = :black) Colorbar(f[:, 3], cf) f end @@ -239,9 +245,9 @@ end end @reference_test "scene visibility" begin - f, ax, pl = scatter(1:4, markersize=200) - ax2, pl = scatter(f[1, 2][1, 1], 1:4, color=1:4, markersize=200) - ax3, pl = scatter(f[1, 2][2, 1], 1:4, color=1:4, markersize=200) + f, ax, pl = scatter(1:4, markersize = 200) + ax2, pl = scatter(f[1, 2][1, 1], 1:4, color = 1:4, markersize = 200) + ax3, pl = scatter(f[1, 2][2, 1], 1:4, color = 1:4, markersize = 200) ax3.scene.visible[] = false ax2.scene.visible[] = false ax2.blockscene.visible[] = false @@ -252,8 +258,8 @@ end # https://github.com/MakieOrg/Makie.jl/issues/2392 Makie.inline!(false) f = Figure() - Menu(f[1,1], options=["one", "two", "three"]) - screen = display(f; visible=false) + Menu(f[1, 1], options = ["one", "two", "three"]) + screen = display(f; visible = false) # Close the window & redisplay close(screen) # Now, menu should be displayed again and not stay blank! @@ -261,14 +267,14 @@ end end @reference_test "space test in transformed axis" begin - f = lines(exp.(0.1*(1.0:100)); axis=(yscale=log10,)) - poly!(Rect(1, 1, 100, 100), color=:red, space=:pixel) - scatter!(2*mod.(1:100:10000, 97), 2*mod.(1:101:10000, 97), color=:blue, space=:pixel) - scatter!(Point2f(0, 0.25), space=:clip) - lines!([0.5,0.5], [0, 1]; space=:relative) - lines!([50,50], [0, 100]; space=:pixel) - lines!([0,1], [0.25, 0.25]; space=:clip) - scatter!(Point2f(0.5, 0), space=:relative) + f = lines(exp.(0.1 * (1.0:100)); axis = (yscale = log10,)) + poly!(Rect(1, 1, 100, 100), color = :red, space = :pixel) + scatter!(2 * mod.(1:100:10000, 97), 2 * mod.(1:101:10000, 97), color = :blue, space = :pixel) + scatter!(Point2f(0, 0.25), space = :clip) + lines!([0.5, 0.5], [0, 1]; space = :relative) + lines!([50, 50], [0, 100]; space = :pixel) + lines!([0, 1], [0.25, 0.25]; space = :clip) + scatter!(Point2f(0.5, 0), space = :relative) f end @@ -278,18 +284,18 @@ end ax2 = Axis(fig[1, 2]) ax3 = Axis(fig[2, 2]) ax4 = Axis(fig[2, 1]) - scatter!(ax1, 1:10, 1:10; markersize=50, color=1:10) - scatter!(ax2, 1:10, 1:10; markersize=50, color=:red) + scatter!(ax1, 1:10, 1:10; markersize = 50, color = 1:10) + scatter!(ax2, 1:10, 1:10; markersize = 50, color = :red) heatmap!(ax3, -8:0.1:8, 8:0.1:8, (x, y) -> sin(x) + cos(y)) - meshscatter!(ax4, 1:10, 1:10; markersize=1, color=:red) - img1 = colorbuffer(ax1; include_decorations=true) - img2 = colorbuffer(ax2; include_decorations=false) - img3 = colorbuffer(ax3; include_decorations=true) - img4 = colorbuffer(ax4; include_decorations=false) - f, ax5, pl = image(rotr90(img1); axis=(; aspect=DataAspect())) - ax6, pl = image(f[1, 2], rotr90(img2); axis=(; aspect=DataAspect())) - ax7, pl = image(f[2, 2], rotr90(img3); axis=(; aspect=DataAspect())) - ax8, pl = image(f[2, 1], rotr90(img4); axis=(; aspect=DataAspect())) + meshscatter!(ax4, 1:10, 1:10; markersize = 1, color = :red) + img1 = colorbuffer(ax1; include_decorations = true) + img2 = colorbuffer(ax2; include_decorations = false) + img3 = colorbuffer(ax3; include_decorations = true) + img4 = colorbuffer(ax4; include_decorations = false) + f, ax5, pl = image(rotr90(img1); axis = (; aspect = DataAspect())) + ax6, pl = image(f[1, 2], rotr90(img2); axis = (; aspect = DataAspect())) + ax7, pl = image(f[2, 2], rotr90(img3); axis = (; aspect = DataAspect())) + ax8, pl = image(f[2, 1], rotr90(img4); axis = (; aspect = DataAspect())) hidedecorations!(ax5) hidedecorations!(ax6) hidedecorations!(ax7) @@ -299,10 +305,10 @@ end @reference_test "Scene backgroundcolor" begin root = Scene(size = (500, 500)) - Scene(root, viewport = Rect2f(0,0,250,250), backgroundcolor = :red, clear = true) - Scene(root, viewport = Rect2f(250,0,250,250), backgroundcolor = :blue, clear = true) - Scene(root, viewport = Rect2f(50,300,300,50), backgroundcolor = :cyan, clear = true) - Scene(root, viewport = Rect2f(350,400,50,200), backgroundcolor = :orange, clear = true) + Scene(root, viewport = Rect2f(0, 0, 250, 250), backgroundcolor = :red, clear = true) + Scene(root, viewport = Rect2f(250, 0, 250, 250), backgroundcolor = :blue, clear = true) + Scene(root, viewport = Rect2f(50, 300, 300, 50), backgroundcolor = :cyan, clear = true) + Scene(root, viewport = Rect2f(350, 400, 50, 200), backgroundcolor = :orange, clear = true) root end diff --git a/ReferenceTests/src/tests/specapi.jl b/ReferenceTests/src/tests/specapi.jl index a1d55214128..1f6d038284b 100644 --- a/ReferenceTests/src/tests/specapi.jl +++ b/ReferenceTests/src/tests/specapi.jl @@ -3,14 +3,14 @@ import Makie.SpecApi as S function synchronize() # This is very unfortunate, but deletion and updates # are async in WGLMakie and there is no way for use to synchronize on them YET - if nameof(Makie.CURRENT_BACKEND[]) == :WGLMakie + return if nameof(Makie.CURRENT_BACKEND[]) == :WGLMakie sleep(2) end end function sync_step!(stepper) synchronize() - Makie.step!(stepper) + return Makie.step!(stepper) end @reference_test "FigureSpec" begin @@ -18,40 +18,52 @@ end st = Makie.Stepper(f) sync_step!(st) obs = pl[1] - obs[] = S.GridLayout([S.Axis(; plots=[S.Lines(1:4; color=:black, linewidth=5), S.Scatter(1:4; markersize=20)]) - S.Axis3(; plots=[S.Scatter(Rect3f(Vec3f(0), Vec3f(1)); color=:red, markersize=50)])]) + obs[] = S.GridLayout( + [ + S.Axis(; plots = [S.Lines(1:4; color = :black, linewidth = 5), S.Scatter(1:4; markersize = 20)]) + S.Axis3(; plots = [S.Scatter(Rect3f(Vec3f(0), Vec3f(1)); color = :red, markersize = 50)]) + ] + ) sync_step!(st) obs[] = begin - ax = S.Axis(; plots=[S.Scatter(1:4)]) - ax2 = S.Axis3(; title="Title 0", plots=[S.Scatter(1:4; color=1:4, markersize=20)]) - c = S.Colorbar(; limits=(0, 1), colormap=:heat) + ax = S.Axis(; plots = [S.Scatter(1:4)]) + ax2 = S.Axis3(; title = "Title 0", plots = [S.Scatter(1:4; color = 1:4, markersize = 20)]) + c = S.Colorbar(; limits = (0, 1), colormap = :heat) S.GridLayout([ax ax2 c]) end sync_step!(st) obs[] = begin - p1 = S.Scatter(1:4; markersize=50) - ax = S.Axis(; plots=[p1], title="Title 1") - p2 = S.Scatter(2:4; color=1:3, markersize=30) - ax2 = S.Axis3(; plots=[p2]) - c = S.Colorbar(; limits=(2, 10), colormap=:viridis, width=50) + p1 = S.Scatter(1:4; markersize = 50) + ax = S.Axis(; plots = [p1], title = "Title 1") + p2 = S.Scatter(2:4; color = 1:3, markersize = 30) + ax2 = S.Axis3(; plots = [p2]) + c = S.Colorbar(; limits = (2, 10), colormap = :viridis, width = 50) S.GridLayout([ax ax2 c]) end sync_step!(st) - ax1 = S.Axis(; plots=[S.Scatter(1:4; markersize=20), S.Lines(1:4; color=:darkred, linewidth=6)]) - ax2 = S.Axis3(; plots=[S.Scatter(Rect3f(Vec3f(0), Vec3f(1)); color=(:red, 0.5), markersize=30)]) + ax1 = S.Axis(; plots = [S.Scatter(1:4; markersize = 20), S.Lines(1:4; color = :darkred, linewidth = 6)]) + ax2 = S.Axis3(; plots = [S.Scatter(Rect3f(Vec3f(0), Vec3f(1)); color = (:red, 0.5), markersize = 30)]) obs[] = S.GridLayout([ax1 ax2]) sync_step!(st) - elem_1 = [LineElement(; color=:red, linestyle=nothing), - MarkerElement(; color=:blue, marker='x', markersize=15, - strokecolor=:black)] - - elem_2 = [PolyElement(; color=:red, strokecolor=:blue, strokewidth=1), - LineElement(; color=:black, linestyle=:dash)] - - elem_3 = LineElement(; color=:green, linestyle=nothing, - points=Point2f[(0, 0), (0, 1), (1, 0), (1, 1)]) + elem_1 = [ + LineElement(; color = :red, linestyle = nothing), + MarkerElement(; + color = :blue, marker = 'x', markersize = 15, + strokecolor = :black + ), + ] + + elem_2 = [ + PolyElement(; color = :red, strokecolor = :blue, strokewidth = 1), + LineElement(; color = :black, linestyle = :dash), + ] + + elem_3 = LineElement(; + color = :green, linestyle = nothing, + points = Point2f[(0, 0), (0, 1), (1, 0), (1, 1)] + ) obs[] = begin S.GridLayout(S.Legend([elem_1, elem_2, elem_3], ["elem 1", "elem 2", "elem 3"], "Legend Title")) @@ -71,13 +83,15 @@ end end struct PlotGrid - nplots::Tuple{Int,Int} + nplots::Tuple{Int, Int} end function Makie.convert_arguments(::Type{<:AbstractPlot}, obj::PlotGrid) - plots = [S.Lines(1:4; linewidth=5, color=Cycled(1)), - S.Lines(2:5; linewidth=7, color=Cycled(2))] - axes = [S.Axis(; plots=plots) for i in 1:obj.nplots[1], j in 1:obj.nplots[2]] + plots = [ + S.Lines(1:4; linewidth = 5, color = Cycled(1)), + S.Lines(2:5; linewidth = 7, color = Cycled(2)), + ] + axes = [S.Axis(; plots = plots) for i in 1:obj.nplots[1], j in 1:obj.nplots[2]] return S.GridLayout(axes) end @@ -88,10 +102,10 @@ end function Makie.convert_arguments(::Type{<:AbstractPlot}, obj::LineScatter, data...) plots = PlotSpec[] if obj.show_lines - push!(plots, S.Lines(data...; linewidth=5)) + push!(plots, S.Lines(data...; linewidth = 5)) end if obj.show_scatter - push!(plots, S.Scatter(data...; markersize=20)) + push!(plots, S.Scatter(data...; markersize = 20)) end return plots end @@ -117,39 +131,41 @@ end st end -AxNoTicks(;kw...) = S.Axis(; xticksvisible=false, - yticksvisible=false, yticklabelsvisible=false, - xticklabelsvisible=false, kw...) +AxNoTicks(; kw...) = S.Axis(; + xticksvisible = false, + yticksvisible = false, yticklabelsvisible = false, + xticklabelsvisible = false, kw... +) @reference_test "Moving Plots in SpecApi" begin pl1 = S.Heatmap((1, 4), (1, 4), Makie.peaks(50)) - pl2 = S.Scatter(1:4; color=1:4, markersize=30, strokewidth=1, strokecolor=:black) - ax1 = AxNoTicks(; plots=[pl1, pl2]) + pl2 = S.Scatter(1:4; color = 1:4, markersize = 30, strokewidth = 1, strokecolor = :black) + ax1 = AxNoTicks(; plots = [pl1, pl2]) grid = S.GridLayout(AxNoTicks()) - f, _, pl = plot(S.GridLayout([ax1 grid]; colgaps=Fixed(4)); figure=(; figure_padding=2, size=(500, 100))) + f, _, pl = plot(S.GridLayout([ax1 grid]; colgaps = Fixed(4)); figure = (; figure_padding = 2, size = (500, 100))) cb1 = copy(colorbuffer(f)) - pl1 = S.Heatmap((1, 4), (1, 4), Makie.peaks(50); colormap=:inferno) + pl1 = S.Heatmap((1, 4), (1, 4), Makie.peaks(50); colormap = :inferno) ax1 = AxNoTicks() - grid = S.GridLayout(AxNoTicks(; plots=[pl1, pl2])) - pl[1] = S.GridLayout([ax1 grid]; colgaps=Fixed(4)) + grid = S.GridLayout(AxNoTicks(; plots = [pl1, pl2])) + pl[1] = S.GridLayout([ax1 grid]; colgaps = Fixed(4)) cb2 = copy(colorbuffer(f)) pl1 = S.Heatmap((1, 4), (1, 4), Makie.peaks(50)) - ax1 = AxNoTicks(; plots=[pl1]) - ax2 = S.GridLayout(AxNoTicks(; plots=[pl2])) - pl[1] = S.GridLayout([ax1 ax2]; colgaps=Fixed(4)) + ax1 = AxNoTicks(; plots = [pl1]) + ax2 = S.GridLayout(AxNoTicks(; plots = [pl2])) + pl[1] = S.GridLayout([ax1 ax2]; colgaps = Fixed(4)) cb3 = copy(colorbuffer(f)) imgs = hcat(rotr90.((cb1, cb2, cb3))...) - s = Scene(; size=size(imgs)) - image!(s, imgs; space=:pixel) + s = Scene(; size = size(imgs)) + image!(s, imgs; space = :pixel) s end function to_plot(plots) axes = map(permutedims(plots)) do plot - ax = AxNoTicks(; plots=[plot]) + ax = AxNoTicks(; plots = [plot]) return S.GridLayout([ax S.Colorbar(plot)]) end return S.GridLayout(axes) @@ -157,57 +173,63 @@ end @reference_test "Colorbar from Plots" begin data = vcat((1:4)', (4:-1:1)') - plots = [S.Heatmap(data), - S.Image(data), - S.Lines(1:4; linewidth=4, color=1:4), - S.Scatter(1:4; markersize=20, color=1:4)] + plots = [ + S.Heatmap(data), + S.Image(data), + S.Lines(1:4; linewidth = 4, color = 1:4), + S.Scatter(1:4; markersize = 20, color = 1:4), + ] obs = Observable(to_plot(plots)) - fig = plot(obs; figure=(; size=(700, 150))) + fig = plot(obs; figure = (; size = (700, 150))) img1 = copy(colorbuffer(fig)) - plots = [S.Heatmap(data; colormap=:inferno), - S.Image(data; colormap=:inferno), - S.Lines(1:4; linewidth=4, color=1:4, colormap=:inferno), - S.Scatter(1:4; markersize=20, color=1:4, colormap=:inferno)] + plots = [ + S.Heatmap(data; colormap = :inferno), + S.Image(data; colormap = :inferno), + S.Lines(1:4; linewidth = 4, color = 1:4, colormap = :inferno), + S.Scatter(1:4; markersize = 20, color = 1:4, colormap = :inferno), + ] obs[] = to_plot(plots) img2 = copy(colorbuffer(fig)) - plots = [S.Heatmap(data; colorrange=(2, 3)), - S.Image(data; colorrange=(2, 3)), - S.Lines(1:4; linewidth=4, color=1:4, colorrange=(2, 3)), - S.Scatter(1:4; markersize=20, color=1:4, colorrange=(2, 3))] + plots = [ + S.Heatmap(data; colorrange = (2, 3)), + S.Image(data; colorrange = (2, 3)), + S.Lines(1:4; linewidth = 4, color = 1:4, colorrange = (2, 3)), + S.Scatter(1:4; markersize = 20, color = 1:4, colorrange = (2, 3)), + ] obs[] = to_plot(plots) img3 = copy(colorbuffer(fig)) imgs = hcat(rotr90.((img3, img2, img1))...) - s = Scene(; size=size(imgs)) - image!(s, imgs; space=:pixel) + s = Scene(; size = size(imgs)) + image!(s, imgs; space = :pixel) s end @reference_test "Axis links" begin axiis = broadcast(1:2, (1:2)') do x, y - S.Axis(; title="$x, $y") + S.Axis(; title = "$x, $y") end f, _, pl = plot( - S.GridLayout(axiis; xaxislinks=vec(axiis[1:2, 1]), yaxislinks=vec(axiis[1:2, 2])); - figure=(; size=(500, 250)), + S.GridLayout(axiis; xaxislinks = vec(axiis[1:2, 1]), yaxislinks = vec(axiis[1:2, 2])); + figure = (; size = (500, 250)), ) for ax in f.content[[1, 3]] limits!(ax, 2, 3, 2, 3) end - img1 = rotr90(colorbuffer(f; update=false)) + img1 = rotr90(colorbuffer(f; update = false)) for ax in f.content limits!(ax, 0, 10, 0, 10) end - pl[1] = S.GridLayout(axiis; xaxislinks=vec(axiis[1:2, 2]), yaxislinks=vec(axiis[1:2, 1])) + pl[1] = S.GridLayout(axiis; xaxislinks = vec(axiis[1:2, 2]), yaxislinks = vec(axiis[1:2, 1])) for ax in f.content[[1, 3]] limits!(ax, 2, 3, 2, 3) end sleep(0.1) - img2 = rotr90(colorbuffer(f; update=false)) + img2 = rotr90(colorbuffer(f; update = false)) large = hcat(img2, img1) - s = Scene(; size=size(large)) - image!(s, large; space=:pixel) + s = Scene(; size = size(large)) + image!(s, large; space = :pixel) s end diff --git a/ReferenceTests/src/tests/text.jl b/ReferenceTests/src/tests/text.jl index 3c09c2a0435..3c1525e34e3 100644 --- a/ReferenceTests/src/tests/text.jl +++ b/ReferenceTests/src/tests/text.jl @@ -5,33 +5,38 @@ heatmap!(ax, values) - text!(ax, + text!( + ax, string.(round.(vec(values'), digits = 2)), position = [Point2f(x, y) for x in 1:10 for y in 1:10], align = (:center, :center), color = ifelse.(vec(values') .< 0.3, :white, :black), - fontsize = 12) + fontsize = 12 + ) fig end @reference_test "2D text" begin f = Figure() pos = [Point2f(0, 0), Point2f(10, 10)] - text(f[1, 1], + text( + f[1, 1], ["0 is the ORIGIN of this", "10 says hi"], position = pos, axis = (aspect = DataAspect(),), markerspace = :data, align = (:center, :center), - fontsize = 2) + fontsize = 2 + ) scatter!(pos) - text(f[2, 1], + text( + f[2, 1], ". This is an annotation!", - position=(300, 200), - align=(:center, :center), - fontsize=60, - font="Blackchancery" + position = (300, 200), + align = (:center, :center), + fontsize = 60, + font = "Blackchancery" ) f @@ -42,17 +47,18 @@ end ax = fig[1, 1] = Axis(fig) pos = (500, 500) posis = Point2f[] - for r in range(0, stop=2pi, length=20) + for r in range(0, stop = 2pi, length = 20) p = pos .+ (sin(r) * 100.0, cos(r) * 100) push!(posis, p) - text!(ax, "test", - position=p, - fontsize=50, - rotation=1.5pi - r, - align=(:center, :center) + text!( + ax, "test", + position = p, + fontsize = 50, + rotation = 1.5pi - r, + align = (:center, :center) ) end - scatter!(ax, posis, markersize=10) + scatter!(ax, posis, markersize = 10) fig end @@ -65,13 +71,15 @@ end i = 1 for halign in (:right, :center, :left), valign in (:top, :center, :bottom) - for rotation in (-pi/6, 0.0, pi/6) - text!(scene, string(halign) * "/" * string(valign) * + for rotation in (-pi / 6, 0.0, pi / 6) + text!( + scene, string(halign) * "/" * string(valign) * " " * string(round(rad2deg(rotation), digits = 0)) * "°", color = (:black, 0.5), position = points[i], align = (halign, valign), - rotation = rotation) + rotation = rotation + ) end i += 1 end @@ -82,23 +90,31 @@ end @reference_test "multi_strings_multi_positions" begin scene = Scene(camera = campixel!, size = (800, 800)) - angles = (-pi/6, 0.0, pi/6) + angles = (-pi / 6, 0.0, pi / 6) points = [Point(x, y) .* 200 for x in 1:3 for y in 1:3 for angle in angles] - aligns = [(halign, valign) for halign in - (:right, :center, :left) for valign in (:top, :center, :bottom) for rotation in angles] - rotations = [rotation for _ in - (:right, :center, :left) for _ in (:top, :center, :bottom) for rotation in angles] - - strings = [string(halign) * "/" * string(valign) * - " " * string(round(rad2deg(rotation), digits = 0)) * "°" + aligns = [ + (halign, valign) for halign in + (:right, :center, :left) for valign in (:top, :center, :bottom) for rotation in angles + ] + rotations = [ + rotation for _ in + (:right, :center, :left) for _ in (:top, :center, :bottom) for rotation in angles + ] + + strings = [ + string(halign) * "/" * string(valign) * + " " * string(round(rad2deg(rotation), digits = 0)) * "°" for halign in (:right, :center, :left) for valign in (:top, :center, :bottom) - for rotation in angles] + for rotation in angles + ] - scatter!(scene, points, marker = :circle, markersize = 10px, color=:black) + scatter!(scene, points, marker = :circle, markersize = 10px, color = :black) - text!(scene, points, text = strings, align = aligns, rotation = rotations, - color = [(:black, alpha) for alpha in LinRange(0.3, 0.7, length(points))]) + text!( + scene, points, text = strings, align = aligns, rotation = rotations, + color = [(:black, alpha) for alpha in LinRange(0.3, 0.7, length(points))] + ) scene end @@ -107,30 +123,36 @@ end scene = Scene(camera = campixel!, size = (800, 800)) points = [Point(x, y) .* 200 for x in 1:3 for y in 1:3] - scatter!(scene, points, marker = :circle, markersize = 10px, color=:black) + scatter!(scene, points, marker = :circle, markersize = 10px, color = :black) symbols = (:left, :center, :right) for ((justification, halign), point) in zip(Iterators.product(symbols, symbols), points) - t = text!(scene, "a\nshort\nparagraph", + t = text!( + scene, "a\nshort\nparagraph", color = (:black, 0.5), position = point, align = (halign, :center), - justification = justification) + justification = justification + ) bb = boundingbox(t, :pixel) wireframe!(scene, bb, color = (:red, 0.2)) end for (p, al) in zip(points[3:3:end], (:left, :center, :right)) - text!(scene, p .+ (0, 80), text = "align :" * string(al), - align = (:center, :baseline)) + text!( + scene, p .+ (0, 80), text = "align :" * string(al), + align = (:center, :baseline) + ) end for (p, al) in zip(points[7:9], (:left, :center, :right)) - text!(scene, p .+ (80, 0), text = "justification\n:" * string(al), - align = (:center, :top), rotation = pi/2) + text!( + scene, p .+ (80, 0), text = "justification\n:" * string(al), + align = (:center, :top), rotation = pi / 2 + ) end scene @@ -139,10 +161,11 @@ end @reference_test "single and multi boundingboxes" begin scene = Scene(camera = campixel!, size = (600, 600)) - t1 = text!(scene, + t1 = text!( + scene, fill("makie", 4), - position = [(150, 150) .+ 60 * Point2f(cos(a), sin(a)) for a in pi/4:pi/2:7pi/4], - rotation = pi/4:pi/2:7pi/4, + position = [(150, 150) .+ 60 * Point2f(cos(a), sin(a)) for a in (pi / 4):(pi / 2):(7pi / 4)], + rotation = (pi / 4):(pi / 2):(7pi / 4), align = (:left, :center), fontsize = 30, markerspace = :data @@ -150,10 +173,11 @@ end wireframe!(scene, boundingbox(t1, :data), color = (:blue, 0.3)) - t2 = text!(scene, + t2 = text!( + scene, fill("makie", 4), - position = [(150, 450) .+ 60 * Point2f(cos(a), sin(a)) for a in pi/4:pi/2:7pi/4], - rotation = pi/4:pi/2:7pi/4, + position = [(150, 450) .+ 60 * Point2f(cos(a), sin(a)) for a in (pi / 4):(pi / 2):(7pi / 4)], + rotation = (pi / 4):(pi / 2):(7pi / 4), align = (:left, :center), fontsize = 30, markerspace = :pixel @@ -161,9 +185,10 @@ end wireframe!(scene, boundingbox(t2, :pixel), color = (:red, 0.3)) - for a in pi/4:pi/2:7pi/4 + for a in (pi / 4):(pi / 2):(7pi / 4) - t = text!(scene, + t = text!( + scene, "makie", position = (450, 150) .+ 60 * Point2f(cos(a), sin(a)), rotation = a, @@ -174,7 +199,8 @@ end wireframe!(scene, boundingbox(t, :data), color = (:blue, 0.3)) - t2 = text!(scene, + t2 = text!( + scene, "makie", position = (450, 450) .+ 60 * Point2f(cos(a), sin(a)), rotation = a, @@ -197,43 +223,48 @@ end f[1, 1], fill("Makie", 7), rotation = [i / 7 * 1.5pi for i in 1:7], - position = [Point3f(0, 0, i/2) for i in 1:7], + position = [Point3f(0, 0, i / 2) for i in 1:7], color = [cgrad(:viridis)[x] for x in LinRange(0, 1, 7)], align = (:left, :baseline), fontsize = 1, markerspace = :data, - axis=(; type=LScene) + axis = (; type = LScene) ) positions = RNG.rand(Point3f, 10) - meshscatter(f[1, 2], positions, color=:white) + meshscatter(f[1, 2], positions, color = :white) text!( fill("Annotation", 10), position = positions, align = (:center, :center), fontsize = 16, markerspace = :pixel, - overdraw=false) - - p1 = Point3f(0,0,0) - p2 = Point3f(1,0,0) - meshscatter(f[2, 1], [p1, p2]; markersize=0.3, color=[:purple, :yellow]) - text!(p1; text="A", align=(:center, :center), glowwidth=10.0, glowcolor=:white, color=:black, fontsize=40, overdraw=true) - text!(p2; text="B", align=(:center, :center), glowwidth=20.0, glowcolor=(:black, 0.6), color=:white, fontsize=40, overdraw=true) - + overdraw = false + ) + + p1 = Point3f(0, 0, 0) + p2 = Point3f(1, 0, 0) + meshscatter(f[2, 1], [p1, p2]; markersize = 0.3, color = [:purple, :yellow]) + text!(p1; text = "A", align = (:center, :center), glowwidth = 10.0, glowcolor = :white, color = :black, fontsize = 40, overdraw = true) + text!(p2; text = "B", align = (:center, :center), glowwidth = 20.0, glowcolor = (:black, 0.6), color = :white, fontsize = 40, overdraw = true) + f end @reference_test "empty_lines" begin scene = Scene(camera = campixel!, size = (200, 200)) - t1 = text!(scene, "Line1\nLine 2\n\nLine4", - position = (50, 100), align = (:center, :center), markerspace = :data) + t1 = text!( + scene, "Line1\nLine 2\n\nLine4", + position = (50, 100), align = (:center, :center), markerspace = :data + ) wireframe!(scene, boundingbox(t1, :data), color = (:red, 0.3)) - t2 = text!(scene, "\nLine 2\nLine 3\n\n\nLine6\n\n", - position = (150, 100), align = (:center, :center), markerspace = :data) + t2 = text!( + scene, "\nLine 2\nLine 3\n\n\nLine6\n\n", + position = (150, 100), align = (:center, :center), markerspace = :data + ) wireframe!(scene, boundingbox(t2, :data), color = (:blue, 0.3)) @@ -245,23 +276,29 @@ end f = Figure(size = (1000, 1000)) barplot(f[1, 1], 3:5) text!(1, 3, text = "bar 1", offset = (0, 10), align = (:center, :baseline)) - text!([(2, 4), (3, 5)], text = ["bar 2", "bar 3"], + text!( + [(2, 4), (3, 5)], text = ["bar 2", "bar 3"], offset = [(0, -10), (0, -20)], - align = (:center, :top), color = :white) + align = (:center, :top), color = :white + ) scatter(f[1, 2], Point2f(0, 0)) text!(0, 0, text = "hello", offset = (40, 0), align = (:left, :center)) - text!(0, 0, text = "hello", offset = (40, 0), align = (:left, :center), - rotation = -pi/4) - text!(0, 0, text = "hello", offset = (40, 0), align = (:left, :center), - rotation = pi/4) + text!( + 0, 0, text = "hello", offset = (40, 0), align = (:left, :center), + rotation = -pi / 4 + ) + text!( + 0, 0, text = "hello", offset = (40, 0), align = (:left, :center), + rotation = pi / 4 + ) scatter(f[2, 1], Point2f[(0, 0), (10, 0), (20, 10)]) text!(0, 0, text = "ABC", markerspace = :data, offset = (0, 0), color = (:red, 0.3), align = (:left, :baseline)) text!(0, 0, text = "ABC", markerspace = :data, offset = (10, 0), color = (:green, 0.3), align = (:left, :baseline)) text!(0, 0, text = "ABC", markerspace = :data, offset = (20, 10), color = (:blue, 0.3), align = (:left, :baseline)) - LScene(f[2, 2], show_axis=false) + LScene(f[2, 2], show_axis = false) scatter!(Point3f[(0, 0, 0), (2, 2, 2)]) text!(1, 1, 1, text = "hello", offset = (10, 10)) @@ -271,19 +308,22 @@ end @reference_test "Log10 text" begin barplot([1, 10, 100], fillto = 0.1, axis = (yscale = log10,)) - text!([(1, 1), (2, 10), (3, 100)], text = ["bar 1", "bar 2", "bar 3"], - offset = (0, -10), color = :white, align = (:center, :top)) + text!( + [(1, 1), (2, 10), (3, 100)], text = ["bar 1", "bar 2", "bar 3"], + offset = (0, -10), color = :white, align = (:center, :top) + ) tightlimits!(current_axis(), Bottom()) current_figure() end @reference_test "latex strings" begin - f, ax , l = lines(cumsum(RNG.randn(1000)), + f, ax, l = lines( + cumsum(RNG.randn(1000)), axis = ( - title = L"\sum_k{x y_k}", - xlabel = L"\lim_{x →\infty} A^j v_{(a + b)_k}^i \sqrt{23.5} x!= \sqrt{\frac{1+6}{4+a+g}}\int_{0}^{2π} \sin(x) dx", - ylabel = L"x + y - \sin(x) × \tan(y) + \sqrt{2}", - ), + title = L"\sum_k{x y_k}", + xlabel = L"\lim_{x →\infty} A^j v_{(a + b)_k}^i \sqrt{23.5} x!= \sqrt{\frac{1+6}{4+a+g}}\int_{0}^{2π} \sin(x) dx", + ylabel = L"x + y - \sin(x) × \tan(y) + \sqrt{2}", + ), figure = (fontsize = 18,) ) text!(500, 0, text = L"\int_{0}^{2π} \sin(x) dx") @@ -295,16 +335,22 @@ end @reference_test "latex (axis, scene, bbox)" begin f = Figure(size = (500, 300)) - text(f[1, 1], 1, 1, text = L"\frac{\sqrt{x + y}}{\sqrt{x + y}}", fontsize = 50, - rotation = pi/4, align = (:center, :center)) - + text( + f[1, 1], 1, 1, text = L"\frac{\sqrt{x + y}}{\sqrt{x + y}}", fontsize = 50, + rotation = pi / 4, align = (:center, :center) + ) + s = LScene(f[1, 2], scenekw = (camera = campixel!,), show_axis = false) - text!(s, L"\sqrt{2}", position = (100, 50), rotation = pi/2, fontsize = 20, - markerspace = :data) - - t = text!(s, L"\int_0^5x^2+2ab", position = Point2f(50, 150), rotation = 0.0, - fontsize = 20, markerspace = :data) - wireframe!(s, boundingbox(t, :data), color=:black) + text!( + s, L"\sqrt{2}", position = (100, 50), rotation = pi / 2, fontsize = 20, + markerspace = :data + ) + + t = text!( + s, L"\int_0^5x^2+2ab", position = Point2f(50, 150), rotation = 0.0, + fontsize = 20, markerspace = :data + ) + wireframe!(s, boundingbox(t, :data), color = :black) f end @@ -315,11 +361,13 @@ end textnode = Observable([L"\int_0^5x^2+2ab", L"\int_0^5x^2+2ab"]) posnode = Observable(Point2f[(50, 50), (100, 100)]) - t = text!(s, + t = text!( + s, textnode, position = posnode, rotation = 0.0, - markerspace = :data) + markerspace = :data + ) Makie.step!(st) ## change lengths @@ -332,14 +380,18 @@ end @reference_test "update annotation style" begin s = Scene(camera = campixel!) st = Stepper(s) - textposnode = Observable([ - (L"\int_0^5x^2+2ab", Point2f(50, 50)), - (L"\int_0^5x^2+2ab", Point2f(100, 100)), - ]) + textposnode = Observable( + [ + (L"\int_0^5x^2+2ab", Point2f(50, 50)), + (L"\int_0^5x^2+2ab", Point2f(100, 100)), + ] + ) - t = text!(s, + t = text!( + s, textposnode, - markerspace = :data) + markerspace = :data + ) Makie.step!(st) ## change lengths @@ -349,34 +401,37 @@ end end @reference_test "latex ticks" begin - lines(0..25, x -> 4 * sin(x) / (cos(3x) + 4), figure = (fontsize = 25,), + lines( + 0 .. 25, x -> 4 * sin(x) / (cos(3x) + 4), figure = (fontsize = 25,), axis = ( xticks = (0:10:20, [L"10^{-3.5}", L"10^{-4.5}", L"10^{-5.5}"]), yticks = ([-1, 0, 1], [L"\sum_%$i{xy}" for i in 1:3]), - yticklabelrotation = pi/8, + yticklabelrotation = pi / 8, title = L"\int_0^1{x^2}", xlabel = L"\sum_k{x_k ⋅ y_k}", - ylabel = L"\int_a^b{\sqrt{abx}}" + ylabel = L"\int_a^b{\sqrt{abx}}", ), ) end @reference_test "dynamic latex ticks" begin - lines(0..25, x -> 4 * sin(x) / (cos(3x) + 4), + lines( + 0 .. 25, x -> 4 * sin(x) / (cos(3x) + 4), figure = (fontsize = 16,), - axis = (xtickformat = (xs -> [L"e^{\sqrt{%$x}}+\sum" for x in xs]), )) + axis = (xtickformat = (xs -> [L"e^{\sqrt{%$x}}+\sum" for x in xs]),) + ) end @reference_test "Word Wrapping" begin lorem_ipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - fig = Figure(size=(600, 500)) + fig = Figure(size = (600, 500)) ax = Axis(fig[1, 1]) - text!(ax, 0, 0, text = latexstring(L"$1$ " * lorem_ipsum), word_wrap_width=250, fontsize = 12, align = (:left, :bottom), justification = :left, color = :black) - text!(ax, 0, 0, text = lorem_ipsum, word_wrap_width=250, fontsize = 12, align = (:left, :top), justification = :right, color = :black) - text!(ax, 0, 0, text = lorem_ipsum, word_wrap_width=250, fontsize = 12, align = (:right, :bottom), justification = :center, color = :red) - text!(ax, -0.3, 0, text = lorem_ipsum, word_wrap_width=200, fontsize = 12, align = (:center, :top), color = :blue) + text!(ax, 0, 0, text = latexstring(L"$1$ " * lorem_ipsum), word_wrap_width = 250, fontsize = 12, align = (:left, :bottom), justification = :left, color = :black) + text!(ax, 0, 0, text = lorem_ipsum, word_wrap_width = 250, fontsize = 12, align = (:left, :top), justification = :right, color = :black) + text!(ax, 0, 0, text = lorem_ipsum, word_wrap_width = 250, fontsize = 12, align = (:right, :bottom), justification = :center, color = :red) + text!(ax, -0.3, 0, text = lorem_ipsum, word_wrap_width = 200, fontsize = 12, align = (:center, :top), color = :blue) xlims!(ax, -0.8, 0.8) ylims!(ax, -0.8, 0.6) fig @@ -401,4 +456,4 @@ end p[1][] = "-!ħ█?-" # "!ħ█?" are all new symbols Makie.step!(st) st -end \ No newline at end of file +end diff --git a/ReferenceTests/src/tests/unitful.jl b/ReferenceTests/src/tests/unitful.jl index e6a96ec2422..9fd6360e2f2 100644 --- a/ReferenceTests/src/tests/unitful.jl +++ b/ReferenceTests/src/tests/unitful.jl @@ -1,15 +1,15 @@ using Makie.Dates, Makie.Unitful, Test @reference_test "combining units, error for numbers" begin - f, ax, pl = scatter(Second(1):Second(600):Second(100*60), 1:10, markersize=20, color=1:10) - scatter!(ax, Hour(1):Hour(1):Hour(10), 1:10; markersize=20, color=1:10, colormap=:reds) + f, ax, pl = scatter(Second(1):Second(600):Second(100 * 60), 1:10, markersize = 20, color = 1:10) + scatter!(ax, Hour(1):Hour(1):Hour(10), 1:10; markersize = 20, color = 1:10, colormap = :reds) @test_throws Unitful.DimensionError scatter!(ax, rand(10), 1:10) # should error! f end @reference_test "Basic units" begin f = Figure() - scatter(f[1, 1], u"ns" .* (1:10), u"d" .* (1:10), markersize=20, color=1:10) + scatter(f[1, 1], u"ns" .* (1:10), u"d" .* (1:10), markersize = 20, color = 1:10) linesegments(f[1, 2], 1:10, Nanosecond.(round.(LinRange(0, 4599800000000, 10)))) scatter(f[2, 1], u"cm" .* (1:10), u"d" .* (1:10)) f diff --git a/ReferenceTests/src/tests/updating.jl b/ReferenceTests/src/tests/updating.jl index 1482da75cc3..724a631e6e2 100644 --- a/ReferenceTests/src/tests/updating.jl +++ b/ReferenceTests/src/tests/updating.jl @@ -1,10 +1,10 @@ @reference_test "updating 2d primitives" begin fig = Figure() t = Observable(1) - text(fig[1, 1], lift(i-> map(j-> ("$j", Point2f(j*30, 0)), 1:i), t), axis=(limits=(0, 380, -10, 10),), fontsize=50) - scatter(fig[1, 2], lift(i-> Point2f.((1:i).*30, 0), t), axis=(limits=(0, 330, -10, 10),), markersize=50) - linesegments(fig[2, 1], lift(i-> Point2f.((2:2:4i).*30, 0), t), axis=(limits=(30, 650, -10, 10),), linewidth=20) - lines(fig[2, 2], lift(i-> Point2f.((2:2:4i).*30, 0), t), axis=(limits=(30, 650, -10, 10),), linewidth=20) + text(fig[1, 1], lift(i -> map(j -> ("$j", Point2f(j * 30, 0)), 1:i), t), axis = (limits = (0, 380, -10, 10),), fontsize = 50) + scatter(fig[1, 2], lift(i -> Point2f.((1:i) .* 30, 0), t), axis = (limits = (0, 330, -10, 10),), markersize = 50) + linesegments(fig[2, 1], lift(i -> Point2f.((2:2:4i) .* 30, 0), t), axis = (limits = (30, 650, -10, 10),), linewidth = 20) + lines(fig[2, 2], lift(i -> Point2f.((2:2:4i) .* 30, 0), t), axis = (limits = (30, 650, -10, 10),), linewidth = 20) st = Stepper(fig) @@ -21,21 +21,21 @@ end @reference_test "updating multiple meshes" begin - points = Observable(Point3f[(1,0,0), (0,1,0), (0,0,1)]) + points = Observable(Point3f[(1, 0, 0), (0, 1, 0), (0, 0, 1)]) - meshes = map(p->Makie.normal_mesh(Sphere(p, 0.2)), points[]) - colors = map(p->RGBf(normalize(p)...), points[]) + meshes = map(p -> Makie.normal_mesh(Sphere(p, 0.2)), points[]) + colors = map(p -> RGBf(normalize(p)...), points[]) fig, ax, pl = mesh(meshes; color = colors) st = Stepper(fig) Makie.step!(st) on(points) do pts - pl[1].val = map(p->Makie.normal_mesh(Sphere(p, 0.2)), points[]) - pl.color.val = map(p->RGBf(normalize(p)...), points[]) + pl[1].val = map(p -> Makie.normal_mesh(Sphere(p, 0.2)), points[]) + pl.color.val = map(p -> RGBf(normalize(p)...), points[]) notify(pl[1]) end - append!(points[], Point3f[(0,1,1), (1,0,1), (1,1,0)]) + append!(points[], Point3f[(0, 1, 1), (1, 0, 1), (1, 1, 0)]) notify(points) Makie.step!(st) end @@ -43,12 +43,12 @@ end function generate_plot(N = 3) points = Observable(Point2f[]) color = Observable(RGBAf[]) - fig, ax, pl = scatter(points, color=color, markersize=1.0, marker=Circle, markerspace=:data, axis=(type=Axis, aspect=DataAspect(), limits=(0.4, N + 0.6, 0.4, N + 0.6),), figure=(size=(800, 800),)) + fig, ax, pl = scatter(points, color = color, markersize = 1.0, marker = Circle, markerspace = :data, axis = (type = Axis, aspect = DataAspect(), limits = (0.4, N + 0.6, 0.4, N + 0.6)), figure = (size = (800, 800),)) function update_func(ij) push!(points.val, Point2f(Tuple(ij))) - push!(color.val, RGBAf((Tuple(ij)./N)..., 0, 1)) + push!(color.val, RGBAf((Tuple(ij) ./ N)..., 0, 1)) notify(color) - notify(points) + return notify(points) end return fig, CartesianIndices((N, N)), update_func end @@ -60,10 +60,10 @@ end function load_frames(video, dir) framedir = joinpath(dir, "frames") - isdir(framedir) && rm(framedir; recursive=true, force=true) + isdir(framedir) && rm(framedir; recursive = true, force = true) mkdir(framedir) Makie.extract_frames(video, framedir) - return map(readdir(framedir; join=true)) do path + return map(readdir(framedir; join = true)) do path return convert(Matrix{RGB{N0f8}}, load(path)) end end @@ -73,7 +73,7 @@ function compare_videos(reference, vpath, dir) n = length(to_compare) @test n == length(reference) - @test all(1:n) do i + return @test all(1:n) do i v = ReferenceTests.compare_images(reference[i], to_compare[i]) return v < 0.2 end @@ -92,7 +92,7 @@ end compare_videos(reference, path, dir) fig, iter, func = generate_plot(2) - vso = Makie.Record(func, fig, iter; format="mkv") + vso = Makie.Record(func, fig, iter; format = "mkv") path = joinpath(dir, "test.$format") save(path, vso) compare_videos(reference, path, dir) @@ -104,7 +104,7 @@ end @reference_test "deletion" begin f = Figure() - l = Legend(f[1, 1], [LineElement(color=:red)], ["Line"]) + l = Legend(f[1, 1], [LineElement(color = :red)], ["Line"]) s = display(f) @test f.scene.current_screens[1] === s @test f.scene.children[1].current_screens[1] === s @@ -113,13 +113,13 @@ end @test f.scene.current_screens[1] === s ## legend should be gone ax = Axis(f[1, 1]) - scatter!(ax, 1:4, markersize=200, color=1:4) + scatter!(ax, 1:4, markersize = 200, color = 1:4) f end @reference_test "deletion and observable args" begin obs = Observable(1:5) - f, ax, pl = scatter(obs; markersize=150) + f, ax, pl = scatter(obs; markersize = 150) s = display(f) # So, for GLMakie it will be 2, since we register an additional listener for # State changes for the on demand renderloop @@ -135,8 +135,8 @@ end @reference_test "interactive colorscale - mesh" begin brain = load(assetpath("brain.stl")) color = [abs(tri[1][2]) for tri in brain for i in 1:3] - f, ax, m = mesh(brain; color, colorscale=identity) - mesh(f[1, 2], brain; color, colorscale=log10) + f, ax, m = mesh(brain; color, colorscale = identity) + mesh(f[1, 2], brain; color, colorscale = log10) st = Stepper(f) Makie.step!(st) m.colorscale = log10 @@ -145,9 +145,9 @@ end @reference_test "interactive colorscale - heatmap" begin data = exp.(abs.(RNG.randn(20, 20))) - f, ax, hm = heatmap(data, colorscale=log10, axis=(; title="log10")) + f, ax, hm = heatmap(data, colorscale = log10, axis = (; title = "log10")) Colorbar(f[1, 2], hm) - ax2, hm2 = heatmap(f[1, 3], data, colorscale=log10, axis=(; title="log10")) + ax2, hm2 = heatmap(f[1, 3], data, colorscale = log10, axis = (; title = "log10")) st = Stepper(f) Makie.step!(st) @@ -164,9 +164,9 @@ end x = RNG.randn(1_000) y = RNG.randn(1_000) f = Figure() - hexbin(f[1, 1], x, y; axis=(aspect=DataAspect(), title="identity")) - ax, hb = hexbin(f[1, 2], x, y; colorscale=log, axis=(aspect=DataAspect(), title="log")) - Colorbar(f[1, end+1], hb) + hexbin(f[1, 1], x, y; axis = (aspect = DataAspect(), title = "identity")) + ax, hb = hexbin(f[1, 2], x, y; colorscale = log, axis = (aspect = DataAspect(), title = "log")) + Colorbar(f[1, end + 1], hb) st = Stepper(f) Makie.step!(st) hb.colorscale = identity @@ -185,7 +185,7 @@ end xlims!(a, 0, 61) ylims!(a, -0.1, 1.1) Record(f, 1:60, framerate = 30) do i - push!(ps.val, Point2f(i, f.scene.events.tick[].delta_time > 1e-6)) + push!(ps.val, Point2f(i, f.scene.events.tick[].delta_time > 1.0e-6)) notify(ps) f.scene.events.tick[] = Makie.Tick(Makie.UnknownTickState, 0, 0.0, 0.0) end @@ -193,13 +193,15 @@ end end @reference_test "Moving plots with move_to" begin - f, ax, pl1 = scatter(5:-1:1; markersize=20, axis=(; title="Axis 1")) - pl2 = poly!(ax, Rect2f(10, 10, 100, 100); color=:green, space=:pixel) - pl3 = scatter!(ax, 1:5; color=Float64[1:5;], markersize=0.5, colorrange=(1, 5), lowclip=:black, - highclip=:red, markerspace=:data) - pl4 = poly!(ax, Rect2f(0, 0, 1, 1); color=(:green, 0.5), strokewidth=2, strokecolor=:black) + f, ax, pl1 = scatter(5:-1:1; markersize = 20, axis = (; title = "Axis 1")) + pl2 = poly!(ax, Rect2f(10, 10, 100, 100); color = :green, space = :pixel) + pl3 = scatter!( + ax, 1:5; color = Float64[1:5;], markersize = 0.5, colorrange = (1, 5), lowclip = :black, + highclip = :red, markerspace = :data + ) + pl4 = poly!(ax, Rect2f(0, 0, 1, 1); color = (:green, 0.5), strokewidth = 2, strokecolor = :black) f - img1 = copy(colorbuffer(f; px_per_unit=1)) + img1 = copy(colorbuffer(f; px_per_unit = 1)) plots = [pl1, pl2, pl3, pl4] get_listener_lengths() = map(plots) do x arg_l = length(x[1].listeners) @@ -208,8 +210,8 @@ end end listener_lengths_1 = get_listener_lengths() - ax2 = Axis(f[1, 2]; title="Axis 2") - ls = LScene(f[2, :]; show_axis=false) + ax2 = Axis(f[1, 2]; title = "Axis 2") + ls = LScene(f[2, :]; show_axis = false) scene = Makie.camrelative(ls.scene) Makie.move_to!(pl2, ax2.scene) @@ -222,7 +224,7 @@ end @test listener_lengths_1 == get_listener_lengths() - img2 = copy(colorbuffer(f; px_per_unit=1)) + img2 = copy(colorbuffer(f; px_per_unit = 1)) @test length(ax.scene.plots) == 1 @test ax.scene.plots[1] === pl1 @test length(ax2.scene.plots) == 2 @@ -244,27 +246,29 @@ end delete!(ax2) trim!(f.layout) - img3 = copy(colorbuffer(f; px_per_unit=1)) + img3 = copy(colorbuffer(f; px_per_unit = 1)) @test listener_lengths_1 == get_listener_lengths() imgs = hcat(rotr90.((img1, img2, img3))...) - s = Scene(; size=size(imgs)) - image!(s, imgs; space=:pixel) + s = Scene(; size = size(imgs)) + image!(s, imgs; space = :pixel) s end @reference_test "updating surface size" begin - X = Observable(-5:5) - Y = Observable(-5:5) - Z = Observable([0.01 * x*x * y*y for x in X.val, y in Y.val]) + X = Observable(-5:5) + Y = Observable(-5:5) + Z = Observable([0.01 * x * x * y * y for x in X.val, y in Y.val]) - f = Figure(size = (800, 400)) + f = Figure(size = (800, 400)) surface(f[1, 1], X, Y, Z) - surface(f[1, 2], map(collect, X), map(collect, Y), Z) - surface(f[1, 3], + surface(f[1, 2], map(collect, X), map(collect, Y), Z) + surface( + f[1, 3], map((X, Y) -> [x for x in X, y in Y], X, Y), - map((X, Y) -> [y for x in X, y in Y], X, Y), Z) + map((X, Y) -> [y for x in X, y in Y], X, Y), Z + ) st = Stepper(f) Makie.step!(st) @@ -274,7 +278,7 @@ end Makie.step!(st) X.val = -5:5 - Z.val = [0.01 * x*x * y*y for x in X.val, y in Y.val] + Z.val = [0.01 * x * x * y * y for x in X.val, y in Y.val] notify(Z) Makie.step!(st) end diff --git a/ReferenceUpdater/src/ReferenceUpdater.jl b/ReferenceUpdater/src/ReferenceUpdater.jl index bca0ba7513a..ed68d4d53eb 100644 --- a/ReferenceUpdater/src/ReferenceUpdater.jl +++ b/ReferenceUpdater/src/ReferenceUpdater.jl @@ -11,7 +11,7 @@ import TOML using Dates function github_token() - get(ENV, "GITHUB_TOKEN") do + return get(ENV, "GITHUB_TOKEN") do try readchomp(`gh auth token`) catch @@ -27,7 +27,7 @@ basedir(files...) = normpath(joinpath(@__DIR__, "..", files...)) function __init__() # cleanup downloaded files when julia closes - atexit(wipe_cache!) + return atexit(wipe_cache!) end end diff --git a/ReferenceUpdater/src/image_download.jl b/ReferenceUpdater/src/image_download.jl index bc3098a0faa..ba7299b475f 100644 --- a/ReferenceUpdater/src/image_download.jl +++ b/ReferenceUpdater/src/image_download.jl @@ -1,5 +1,5 @@ function upload_release(user, repo, token, tag, path) - ghr_jll.ghr() do ghr_path + return ghr_jll.ghr() do ghr_path run(`$ghr_path -replace -u $(user) -r $(repo) -t $(token) $(tag) $(path)`) end end @@ -11,19 +11,19 @@ function last_major_version() return "v" * string(VersionNumber(version.major, version.minor)) end -function upload_reference_images(path=basedir("recorded"), tag=last_major_version()) - mktempdir() do dir +function upload_reference_images(path = basedir("recorded"), tag = last_major_version()) + return mktempdir() do dir tarfile = joinpath(dir, "reference_images.tar") Tar.create(path, tarfile) upload_release("MakieOrg", "Makie.jl", github_token(), tag, tarfile) end end -function download_refimages(tag=last_major_version()) +function download_refimages(tag = last_major_version()) url = "https://github.com/MakieOrg/Makie.jl/releases/download/$(tag)/reference_images.tar" images_tar = Downloads.download(url) images = tempname() - isdir(images) && rm(images, recursive=true, force=true) + isdir(images) && rm(images, recursive = true, force = true) Tar.extract(images_tar, images) rm(images_tar) return images diff --git a/ReferenceUpdater/src/local_server.jl b/ReferenceUpdater/src/local_server.jl index 6b17c54a730..eb6bde25346 100644 --- a/ReferenceUpdater/src/local_server.jl +++ b/ReferenceUpdater/src/local_server.jl @@ -51,7 +51,7 @@ function serve_update_page_from_dir(folder) end @info "Uploading updated reference images under tag \"$tag\"" - try + return try upload_reference_images(tempdir, tag) @info "Upload successful. You can ctrl+c out now." HTTP.Response(200, "Upload successful") @@ -87,7 +87,7 @@ function serve_update_page_from_dir(folder) HTTP.register!(router, "GET", "/**", serve_local_file) @info "Starting server. Open http://localhost:8849 in your browser to view. Ctrl+C to quit." - try + return try HTTP.serve(router, HTTP.Sockets.localhost, 8849) catch e if e isa InterruptException @@ -175,11 +175,13 @@ function download_artifacts(; commit = nothing, pr = nothing) end end - error(""" - No \"ReferenceImages\" artifact found for commit $headsha and job id $(check["id"]). - This could be because the job's workflow run ($(job["run_url"])) has not completed, yet. - Artifacts are only available for complete runs. - """) + error( + """ + No \"ReferenceImages\" artifact found for commit $headsha and job id $(check["id"]). + This could be because the job's workflow run ($(job["run_url"])) has not completed, yet. + Artifacts are only available for complete runs. + """ + ) end """ @@ -210,7 +212,8 @@ update_from_previous_version(source_version = "v0.21.0", target_version = "v0.22 """ function update_from_previous_version(; source_version::String, target_version::String, - commit = nothing, pr = nothing, score_threshold = 0.03) + commit = nothing, pr = nothing, score_threshold = 0.03 + ) tmpdir = download_artifacts(commit = commit, pr = pr) @@ -254,8 +257,10 @@ function update_from_previous_version(; return end - update_from_previous_version(changed_or_missing; - source_version = source_version, target_version = target_version) + update_from_previous_version( + changed_or_missing; + source_version = source_version, target_version = target_version + ) return end @@ -273,7 +278,8 @@ github release version. """ function update_from_previous_version( changed_or_missing::Vector{String}; - source_version::String, target_version::String) + source_version::String, target_version::String + ) # Merge new and old @info "Downloading new reference image set (target)" @@ -310,15 +316,15 @@ function update_from_previous_version( end function unzip(file, exdir = "") - fileFullPath = isabspath(file) ? file : joinpath(pwd(),file) + fileFullPath = isabspath(file) ? file : joinpath(pwd(), file) basePath = dirname(fileFullPath) - outPath = (exdir == "" ? basePath : (isabspath(exdir) ? exdir : joinpath(pwd(),exdir))) + outPath = (exdir == "" ? basePath : (isabspath(exdir) ? exdir : joinpath(pwd(), exdir))) isdir(outPath) ? "" : mkdir(outPath) @info "Extracting zip file $file to $outPath" zarchive = ZipFile.Reader(fileFullPath) for f in zarchive.files - fullFilePath = joinpath(outPath,f.name) - if (endswith(f.name,"/") || endswith(f.name,"\\")) + fullFilePath = joinpath(outPath, f.name) + if (endswith(f.name, "/") || endswith(f.name, "\\")) mkdir(fullFilePath) else mkpath(dirname(fullFilePath)) @@ -326,7 +332,7 @@ function unzip(file, exdir = "") end end close(zarchive) - @info "Extracted zip file" + return @info "Extracted zip file" end @@ -366,7 +372,8 @@ function group_scores(path) open(joinpath(path, "scores_table.tsv"), "w") do file for (filename, scores) in data_vec skip = scores .== -1.0 - println(file, + println( + file, ifelse(skip[1], "0.0", scores[1]), '\t', ifelse(skip[1], "", "GLMakie/$filename"), '\t', ifelse(skip[2], "0.0", scores[2]), '\t', ifelse(skip[2], "", "CairoMakie/$filename"), '\t', ifelse(skip[3], "0.0", scores[3]), '\t', ifelse(skip[3], "", "WGLMakie/$filename") @@ -405,7 +412,8 @@ function group_files(path, input_filename, output_filename) # generate new structured file open(joinpath(path, output_filename), "w") do file for (filename, valid) in data - println(file, + println( + file, ifelse(valid[1], "GLMakie/$filename", "INVALID"), '\t', ifelse(valid[2], "CairoMakie/$filename", "INVALID"), '\t', ifelse(valid[3], "WGLMakie/$filename", "INVALID") diff --git a/WGLMakie/src/WGLMakie.jl b/WGLMakie/src/WGLMakie.jl index cba970079df..7a8bab83088 100644 --- a/WGLMakie/src/WGLMakie.jl +++ b/WGLMakie/src/WGLMakie.jl @@ -57,7 +57,7 @@ Note, that the `screen_config` can also be set permanently via `Makie.set_theme! $(Base.doc(ScreenConfig)) """ -function activate!(; inline::Union{Automatic,Bool}=LAST_INLINE[], screen_config...) +function activate!(; inline::Union{Automatic, Bool} = LAST_INLINE[], screen_config...) Makie.inline!(inline) LAST_INLINE[] = inline Makie.set_active_backend!(WGLMakie) @@ -88,7 +88,7 @@ function __init__() end # re-export Makie, including deprecated names -for name in names(Makie, all=true) +for name in names(Makie, all = true) if Base.isexported(Makie, name) && name !== :Button && name !== :Slider @eval using Makie: $(name) @eval export $(name) diff --git a/WGLMakie/src/display.jl b/WGLMakie/src/display.jl index 52e29b8998c..4e53e8ee075 100644 --- a/WGLMakie/src/display.jl +++ b/WGLMakie/src/display.jl @@ -1,4 +1,3 @@ - """ * `framerate = 30`: Set framerate (frames per second) to a higher number for smoother animations, or to a lower to use less resources. * `resize_to = nothing`: Resize the canvas to the parent element with `resize_to=:parent`, or to the body if `resize_to = :body`. The default `nothing`, will resize nothing. @@ -9,11 +8,13 @@ struct ScreenConfig resize_to::Any # nothing # We use nothing, since that serializes correctly to nothing in JS, which is important since that's where we calculate the defaults! # For the theming, we need to use Automatic though, since that's the Makie meaning for gets calculated somewhere else - px_per_unit::Union{Nothing,Float64} # nothing, a.k.a the browser px_per_unit (devicePixelRatio) - scalefactor::Union{Nothing,Float64} + px_per_unit::Union{Nothing, Float64} # nothing, a.k.a the browser px_per_unit (devicePixelRatio) + scalefactor::Union{Nothing, Float64} resize_to_body::Bool - function ScreenConfig(framerate::Number, resize_to::Any, px_per_unit::Union{Number,Automatic,Nothing}, - scalefactor::Union{Number,Automatic,Nothing}, resize_to_body::Union{Nothing,Bool}) + function ScreenConfig( + framerate::Number, resize_to::Any, px_per_unit::Union{Number, Automatic, Nothing}, + scalefactor::Union{Number, Automatic, Nothing}, resize_to_body::Union{Nothing, Bool} + ) if px_per_unit isa Automatic px_per_unit = nothing end @@ -28,8 +29,8 @@ struct ScreenConfig resize_to = resize_to_body ? :body : nothing end end - ResizeType = Union{Nothing,Symbol} - if !(resize_to isa Union{ResizeType,Tuple{ResizeType,ResizeType}}) + ResizeType = Union{Nothing, Symbol} + if !(resize_to isa Union{ResizeType, Tuple{ResizeType, ResizeType}}) error("Only nothing, :parent, or :body allowed, or a tuple of those for width/height.") end return new(framerate, resize_to, px_per_unit, scalefactor) @@ -48,13 +49,13 @@ $(Base.doc(MakieScreen)) """ mutable struct Screen <: Makie.MakieScreen plot_initialized::Channel{Any} - session::Union{Nothing,Session} - scene::Union{Nothing,Scene} + session::Union{Nothing, Session} + scene::Union{Nothing, Scene} displayed_scenes::Set{String} config::ScreenConfig - canvas::Union{Nothing,Bonito.HTMLElement} + canvas::Union{Nothing, Bonito.HTMLElement} tick_clock::Makie.BudgetedTimer - function Screen(scene::Union{Nothing,Scene}, config::ScreenConfig) + function Screen(scene::Union{Nothing, Scene}, config::ScreenConfig) timer = Makie.BudgetedTimer(1.0 / 30.0) screen = new(Channel{Any}(1), nothing, scene, Set{String}(), config, nothing, timer) @@ -67,18 +68,18 @@ mutable struct Screen <: Makie.MakieScreen end function Screen(; config...) - config = Makie.merge_screen_config(ScreenConfig, Dict{Symbol,Any}(config)) + config = Makie.merge_screen_config(ScreenConfig, Dict{Symbol, Any}(config)) return Screen(nothing, config) end -function scene_already_displayed(screen::Screen, scene=screen.scene) +function scene_already_displayed(screen::Screen, scene = screen.scene) scene === nothing && return false screen.scene === scene || return false screen.canvas === nothing && return false return !isnothing(screen.session) && - isready(screen.session) && isready(screen.plot_initialized) && - js_uuid(screen.scene) in screen.displayed_scenes + isready(screen.session) && isready(screen.plot_initialized) && + js_uuid(screen.scene) in screen.displayed_scenes end function render_with_init(screen::Screen, session::Session, scene::Scene) @@ -140,7 +141,7 @@ struct WithConfig end function WithConfig(fig::Makie.FigureLike; kw...) - config = Makie.merge_screen_config(ScreenConfig, Dict{Symbol,Any}(kw)) + config = Makie.merge_screen_config(ScreenConfig, Dict{Symbol, Any}(kw)) return WithConfig(fig, config) end @@ -153,21 +154,22 @@ function Bonito.jsrender(session::Session, wconfig::WithConfig) end - function Base.show(io::IO, screen::Screen) c = screen.config ppu = c.px_per_unit sf = c.scalefactor three_str = sprint(io -> show(io, MIME"text/plain"(), screen.plot_initialized)) - return print(io, """WGLMakie.Screen( - framerate = $(c.framerate), - resize_to = $(c.resize_to), - px_per_unit = $(isnothing(ppu) ? :automatic : ppu), - scalefactor = $(isnothing(sf) ? :automatic : sf), - session = $(isnothing(screen.session) ? :nothing : isopen(screen.session)), - three = $(three_str), - scene = $(isnothing(screen.scene) ? :nothing : screen.scene), - )""") + return print( + io, """WGLMakie.Screen( + framerate = $(c.framerate), + resize_to = $(c.resize_to), + px_per_unit = $(isnothing(ppu) ? :automatic : ppu), + scalefactor = $(isnothing(sf) ? :automatic : sf), + session = $(isnothing(screen.session) ? :nothing : isopen(screen.session)), + three = $(three_str), + scene = $(isnothing(screen.scene) ? :nothing : screen.scene), + )""" + ) end # Resizing the scene is enough for WGLMakie @@ -189,7 +191,7 @@ end for M in Makie.WEB_MIMES @eval begin function Makie.backend_show(screen::Screen, io::IO, m::$M, scene::Scene) - inline_display = App(title="WGLMakie") do session::Session + inline_display = App(title = "WGLMakie") do session::Session return render_with_init(screen, session, scene) end Base.show(io, m, inline_display) @@ -198,7 +200,7 @@ for M in Makie.WEB_MIMES end end -function Makie.backend_showable(::Type{Screen}, ::T) where {T<:MIME} +function Makie.backend_showable(::Type{Screen}, ::T) where {T <: MIME} return T in Makie.WEB_MIMES end @@ -209,10 +211,12 @@ function Base.size(screen::Screen) return size(screen.scene) end -function get_screen_session(screen::Screen; timeout=100, - error::Union{Nothing,String}=nothing)::Union{Nothing,Session} +function get_screen_session( + screen::Screen; timeout = 100, + error::Union{Nothing, String} = nothing + )::Union{Nothing, Session} function throw_error(status) - if !isnothing(error) + return if !isnothing(error) message = "Can't get three: $(status)\n$(error)" Base.error(message) else @@ -228,12 +232,12 @@ function get_screen_session(screen::Screen; timeout=100, throw_error("Screen Session uninitialized. Not yet displayed? Session status: $(screen.session.status), id: $(session.id)") return nothing end - success = Bonito.wait_for_ready(session; timeout=timeout) + success = Bonito.wait_for_ready(session; timeout = timeout) if success !== :success throw_error("Timed out waiting for session to get ready") return nothing end - success = Bonito.wait_for(() -> isready(screen.plot_initialized); timeout=timeout) + success = Bonito.wait_for(() -> isready(screen.plot_initialized); timeout = timeout) # Throw error if error message specified if success !== :success throw_error("Timed out waiting $(timeout)s for session to get initialize") @@ -255,7 +259,7 @@ end # TODO, create optimized screens, forward more options to JS/WebGL function Screen(scene::Scene; kw...) - config = Makie.merge_screen_config(ScreenConfig, Dict{Symbol,Any}(kw)) + config = Makie.merge_screen_config(ScreenConfig, Dict{Symbol, Any}(kw)) return Screen(scene, config) end Screen(scene::Scene, config::ScreenConfig, ::IO, ::MIME) = Screen(scene, config) @@ -275,14 +279,14 @@ function Base.display(screen::Screen, scene::Scene; unused...) if scene_already_displayed(screen, scene) return screen end - app = App(title="WGLMakie") do session + app = App(title = "WGLMakie") do session return render_with_init(screen, session, scene) end display(app) - Bonito.wait_for(()-> !isnothing(screen.session)) + Bonito.wait_for(() -> !isnothing(screen.session)) Bonito.wait_for_ready(screen.session) # wait for plot to be full initialized, so that operations don't get racy (e.g. record/RamStepper & friends) - get_screen_session(screen; error="Waiting for plot to be initialized in display") + get_screen_session(screen; error = "Waiting for plot to be initialized in display") return screen end @@ -296,7 +300,7 @@ function session2image(session::Session, scene::Scene) }) }() """ - picture_base64 = Bonito.evaljs_value(session, to_data; timeout=100) + picture_base64 = Bonito.evaljs_value(session, to_data; timeout = 100) picture_base64 = replace(picture_base64, "data:image/png;base64," => "") bytes = Bonito.Base64.base64decode(picture_base64) return PNGFiles.load(IOBuffer(bytes)) @@ -306,7 +310,7 @@ function Makie.colorbuffer(screen::Screen) if isnothing(screen.session) Base.display(screen, screen.scene) end - session = get_screen_session(screen; error="Not able to show scene in a browser") + session = get_screen_session(screen; error = "Not able to show scene in a browser") return session2image(session, screen.scene) end @@ -323,16 +327,18 @@ function insert_scene!(session::Session, screen::Screen, scene::Scene) parent = scene.parent parent_uuid = js_uuid(parent) err = "Cannot find scene js_uuid(scene) == $(parent_uuid)" - evaljs_value(session, js""" - $(WGL).then(WGL=> { - const parent = WGL.find_scene($(parent_uuid)); - if (!parent) { - throw new Error($(err)) - } - const new_scene = WGL.deserialize_scene($scene_ser, parent.screen); - parent.scene_children.push(new_scene); - }) - """) + evaljs_value( + session, js""" + $(WGL).then(WGL=> { + const parent = WGL.find_scene($(parent_uuid)); + if (!parent) { + throw new Error($(err)) + } + const new_scene = WGL.deserialize_scene($scene_ser, parent.screen); + parent.scene_children.push(new_scene); + }) + """ + ) mark_as_displayed!(screen, scene) return false end @@ -348,7 +354,7 @@ function insert_plot!(session::Session, scene::Scene, @nospecialize(plot::Plot)) $(WGL).then(WGL=> { WGL.insert_plot($(js_uuid(scene)), $plot_data); })""" - Bonito.evaljs_value(plot_sub, js; timeout=50) + Bonito.evaljs_value(plot_sub, js; timeout = 50) @assert !haskey(plot.attributes, :__wgl_session) plot.attributes[:__wgl_session] = plot_sub return @@ -358,7 +364,7 @@ function Base.insert!(screen::Screen, scene::Scene, @nospecialize(plot::PlotList return nothing end function Base.insert!(screen::Screen, scene::Scene, @nospecialize(plot::Plot)) - session = get_screen_session(screen; error="Plot needs to be displayed to insert additional plots") + session = get_screen_session(screen; error = "Plot needs to be displayed to insert additional plots") if js_uuid(scene) in screen.displayed_scenes insert_plot!(session, scene, plot) else @@ -378,27 +384,31 @@ function Base.insert!(screen::Screen, scene::Scene, @nospecialize(plot::Plot)) return end -function delete_js_objects!(screen::Screen, plot_uuids::Vector{String}, - session::Union{Nothing,Session}) +function delete_js_objects!( + screen::Screen, plot_uuids::Vector{String}, + session::Union{Nothing, Session} + ) main_session = get_screen_session(screen) isnothing(main_session) && return # if no session we haven't displayed and dont need to delete # Eval in root session, since main_session might be gone (e.g. getting closed just shortly before freeing the plots) root = Bonito.root_session(main_session) isready(root) || return nothing - Bonito.evaljs(root, js""" - $(WGL).then(WGL=> { - WGL.delete_plots($(plot_uuids)); - })""") + Bonito.evaljs( + root, js""" + $(WGL).then(WGL=> { + WGL.delete_plots($(plot_uuids)); + })""" + ) !isnothing(session) && close(session) return end -function all_plots_scenes(scene::Scene; scene_uuids=String[], plots=Plot[]) +function all_plots_scenes(scene::Scene; scene_uuids = String[], plots = Plot[]) push!(scene_uuids, js_uuid(scene)) append!(plots, scene.plots) for child in scene.children - all_plots_scenes(child; plots=plots, scene_uuids=scene_uuids) + all_plots_scenes(child; plots = plots, scene_uuids = scene_uuids) end return scene_uuids, plots end @@ -417,28 +427,32 @@ function delete_js_objects!(screen::Screen, scene::Scene) end end - Bonito.evaljs(root, js""" - $(WGL).then(WGL=> { - WGL.delete_scenes($scene_uuids, $(js_uuid.(plots))); - })""") + Bonito.evaljs( + root, js""" + $(WGL).then(WGL=> { + WGL.delete_scenes($scene_uuids, $(js_uuid.(plots))); + })""" + ) return end -struct LockfreeQueue{T,F} +struct LockfreeQueue{T, F} # Double buffering to be lock free queue1::Vector{T} queue2::Vector{T} current_queue::Threads.Atomic{Int} - task::Base.RefValue{Union{Nothing,Task}} + task::Base.RefValue{Union{Nothing, Task}} execute_job::F end -function LockfreeQueue{T}(execute_job::F) where {T,F} - return LockfreeQueue{T,F}(T[], - T[], - Threads.Atomic{Int}(1), - Base.RefValue{Union{Nothing,Task}}(nothing), - execute_job) +function LockfreeQueue{T}(execute_job::F) where {T, F} + return LockfreeQueue{T, F}( + T[], + T[], + Threads.Atomic{Int}(1), + Base.RefValue{Union{Nothing, Task}}(nothing), + execute_job + ) end function run_jobs!(queue::LockfreeQueue) @@ -473,7 +487,7 @@ end function Base.push!(queue::LockfreeQueue, item) run_jobs!(queue) # Push to unused queue: - if queue.current_queue[] == 1 + return if queue.current_queue[] == 1 push!(queue.queue2, item) else push!(queue.queue1, item) @@ -481,8 +495,8 @@ function Base.push!(queue::LockfreeQueue, item) end const DISABLE_JS_FINALZING = Base.RefValue(false) -const DELETE_QUEUE = LockfreeQueue{Tuple{Screen,Vector{String},Union{Session,Nothing}}}(delete_js_objects!) -const SCENE_DELETE_QUEUE = LockfreeQueue{Tuple{Screen,Scene}}(delete_js_objects!) +const DELETE_QUEUE = LockfreeQueue{Tuple{Screen, Vector{String}, Union{Session, Nothing}}}(delete_js_objects!) +const SCENE_DELETE_QUEUE = LockfreeQueue{Tuple{Screen, Scene}}(delete_js_objects!) function Base.delete!(screen::Screen, scene::Scene, plot::Plot) # only queue atomics to actually delete on js diff --git a/WGLMakie/src/events.jl b/WGLMakie/src/events.jl index 51ba85d56d4..6dd9f2612ea 100644 --- a/WGLMakie/src/events.jl +++ b/WGLMakie/src/events.jl @@ -95,7 +95,7 @@ function connect_scene_events!(screen::Screen, scene::Scene, comm::Observable) if button != Keyboard.unknown e.keyboardbutton[] = KeyEvent(button, Keyboard.press) end - if length(keydown[2])==1 && isascii(keydown[2]) + if length(keydown[2]) == 1 && isascii(keydown[2]) e.unicode_input[] = keydown[2][1] end end @@ -113,7 +113,7 @@ function connect_scene_events!(screen::Screen, scene::Scene, comm::Observable) resize!(scene, tuple(resize...)) end catch err - @warn "Error in window event callback" exception=(err, Base.catch_backtrace()) + @warn "Error in window event callback" exception = (err, Base.catch_backtrace()) end return end diff --git a/WGLMakie/src/imagelike.jl b/WGLMakie/src/imagelike.jl index b5a9cb8bce8..43bce8c5bf8 100644 --- a/WGLMakie/src/imagelike.jl +++ b/WGLMakie/src/imagelike.jl @@ -16,26 +16,30 @@ function create_shader(mscene::Scene, plot::Surface) apply_transform_and_f32_conversion(plot, f32c, grid_ps) end positions = Buffer(ps) - rect = lift(z -> Tessellation(Rect2(0f0, 0f0, 1f0, 1f0), size(z)), plot, pz) + rect = lift(z -> Tessellation(Rect2(0.0f0, 0.0f0, 1.0f0, 1.0f0), size(z)), plot, pz) fs = lift(r -> decompose(QuadFace{Int}, r), plot, rect) fs = map((ps, fs) -> filter(f -> !any(i -> (i > length(ps)) || isnan(ps[i]), f), fs), plot, ps, fs) faces = Buffer(fs) # This adjusts uvs (compared to decompose_uv) so texture sampling starts at # the center of a texture pixel rather than the edge, fixing # https://github.com/MakieOrg/Makie.jl/pull/2598#discussion_r1152552196 - uv = Buffer(lift(plot, rect) do r - Nx, Ny = r.nvertices - if (Nx, Ny) == (2, 2) - Vec2f[(0,1), (1,1), (1,0), (0,0)] - else - f = Vec2f(1 / Nx, 1 / Ny) - [f .* Vec2f(0.5 + i, 0.5 + j) for j in Ny-1:-1:0 for i in 0:Nx-1] + uv = Buffer( + lift(plot, rect) do r + Nx, Ny = r.nvertices + if (Nx, Ny) == (2, 2) + Vec2f[(0, 1), (1, 1), (1, 0), (0, 0)] + else + f = Vec2f(1 / Nx, 1 / Ny) + [f .* Vec2f(0.5 + i, 0.5 + j) for j in (Ny - 1):-1:0 for i in 0:(Nx - 1)] + end + end + ) + normals = Buffer( + lift(plot, ps, fs, plot.invert_normals) do ps, fs, invert + ns = Makie.nan_aware_normals(ps, fs) + return invert ? -ns : ns end - end) - normals = Buffer(lift(plot, ps, fs, plot.invert_normals) do ps, fs, invert - ns = Makie.nan_aware_normals(ps, fs) - return invert ? -ns : ns - end) + ) per_vertex = Dict(:positions => positions, :faces => faces, :uv => uv, :normal => normals) uniforms = Dict(:uniform_color => color, :color => false, :model => model, :PICKING_INDEX_FROM_UV => true) @@ -45,9 +49,9 @@ function create_shader(mscene::Scene, plot::Surface) M = convert_attribute(x, Key{:uv_transform}(), Key{:surface}()) # Why transpose? if M === nothing - return Mat3f(0,1,0, 1,0,0, 0,0,1) + return Mat3f(0, 1, 0, 1, 0, 0, 0, 0, 1) else - return Mat3f(0,1,0, 1,0,0, 0,0,1) * Mat3f(M[1], M[2], 0, M[3], M[4], 0, M[5], M[6], 1) + return Mat3f(0, 1, 0, 1, 0, 0, 0, 0, 1) * Mat3f(M[1], M[2], 0, M[3], M[4], 0, M[5], M[6], 1) end end @@ -74,13 +78,13 @@ function create_shader(mscene::Scene, plot::Union{Heatmap, Image}) M = convert_attribute(x, Key{:uv_transform}(), Key{:image}()) # Why transpose? if M === nothing - return Mat3f(0,1,0, 1,0,0, 0,0,1) + return Mat3f(0, 1, 0, 1, 0, 0, 0, 0, 1) else - return Mat3f(0,1,0, 1,0,0, 0,0,1) * Mat3f(M[1], M[2], 0, M[3], M[4], 0, M[5], M[6], 1) + return Mat3f(0, 1, 0, 1, 0, 0, 0, 0, 1) * Mat3f(M[1], M[2], 0, M[3], M[4], 0, M[5], M[6], 1) end end else - uniforms[:uv_transform] = Observable(Mat3f(0,1,0, -1,0,0, 1,0,1)) + uniforms[:uv_transform] = Observable(Mat3f(0, 1, 0, -1, 0, 0, 1, 0, 1)) end return draw_mesh(mscene, mesh, plot, uniforms) @@ -106,7 +110,6 @@ function create_shader(mscene::Scene, plot::Volume) shininess = lift(x -> convert_attribute(x, Key{:shininess}()), plot, plot.shininess) - uniforms = Dict{Symbol, Any}( :modelinv => modelinv, :isovalue => lift(Float32, plot, plot.isovalue), @@ -128,12 +131,11 @@ function create_shader(mscene::Scene, plot::Volume) :object_id => UInt32(0) ) - handle_color!(plot, uniforms, nothing, :volumedata; permute_tex=false) + handle_color!(plot, uniforms, nothing, :volumedata; permute_tex = false) return Program(WebGL(), lasset("volume.vert"), lasset("volume.frag"), box, uniforms) end - xy_convert(x::Makie.EndPoints, n) = LinRange(x..., n + 1) xy_convert(x::AbstractArray, n) = x @@ -167,8 +169,8 @@ function limits_to_uvmesh(plot, f32c) # Special path for ranges of length 2 which # can be displayed as a rectangle t = Makie.transform_func_obs(plot)[] - px = lift(identity, plot, px; ignore_equal_values=true) - py = lift(identity, plot, py; ignore_equal_values=true) + px = lift(identity, plot, px; ignore_equal_values = true) + py = lift(identity, plot, py; ignore_equal_values = true) if px[] isa Makie.EndPoints && py[] isa Makie.EndPoints && Makie.is_identity_transform(t) rect = lift(plot, px, py) do x, y xmin, xmax = x @@ -181,12 +183,12 @@ function limits_to_uvmesh(plot, f32c) faces = Buffer(decompose(GLTriangleFace, rect[])) uv = Buffer(decompose_uv(rect[])) else - px = lift((x, z) -> xy_convert(x, size(z, 1)), px, pz; ignore_equal_values=true) - py = lift((y, z) -> xy_convert(y, size(z, 2)), py, pz; ignore_equal_values=true) + px = lift((x, z) -> xy_convert(x, size(z, 1)), px, pz; ignore_equal_values = true) + py = lift((y, z) -> xy_convert(y, size(z, 2)), py, pz; ignore_equal_values = true) # TODO: Use Makie.surface2mesh grid_ps = lift((x, y) -> Makie.matrix_grid(x, y, zeros(length(x), length(y))), plot, px, py) positions = Buffer(apply_transform_and_f32_conversion(plot, f32c, grid_ps)) - resolution = lift((x, y) -> (length(x), length(y)), plot, px, py; ignore_equal_values=true) + resolution = lift((x, y) -> (length(x), length(y)), plot, px, py; ignore_equal_values = true) faces = Buffer(lift(fast_faces, plot, resolution)) uv = Buffer(lift(fast_uv, plot, resolution)) end diff --git a/WGLMakie/src/lines.jl b/WGLMakie/src/lines.jl index 239b3cd2e37..d4e14b0436a 100644 --- a/WGLMakie/src/lines.jl +++ b/WGLMakie/src/lines.jl @@ -17,9 +17,9 @@ function serialize_three(scene::Scene, plot::Union{Lines, LineSegments}) # TODO: maybe convert nothing to Sampler([-1.0]) to allowed dynamic linestyles? if isnothing(to_value(linestyle)) uniforms[:pattern] = false - uniforms[:pattern_length] = 1f0 + uniforms[:pattern_length] = 1.0f0 else - uniforms[:pattern] = Sampler(lift(Makie.linestyle_to_sdf, plot, linestyle); x_repeat=:repeat) + uniforms[:pattern] = Sampler(lift(Makie.linestyle_to_sdf, plot, linestyle); x_repeat = :repeat) uniforms[:pattern_length] = lift(ls -> Float32(last(ls) - first(ls)), plot, linestyle) end @@ -45,8 +45,8 @@ function serialize_three(scene::Scene, plot::Union{Lines, LineSegments}) # make the p1 -- p2 segment draw, which is what indices does. indices = Observable(UInt32[]) points_transformed = lift( - plot, f32c, transform_func_obs(plot), plot.model, plot[1], plot.space - ) do f32c, tf, model, ps, space + plot, f32c, transform_func_obs(plot), plot.model, plot[1], plot.space + ) do f32c, tf, model, ps, space transformed_points = apply_transform_and_f32_conversion(f32c, tf, model, ps, space) # TODO: Do this in javascript? @@ -66,7 +66,7 @@ function serialize_three(scene::Scene, plot::Union{Lines, LineSegments}) # does previous point close loop? # loop started && 3+ segments && start == end if loop_start_idx != -1 && (loop_start_idx + 2 < length(indices[])) && - (transformed_points[indices[][loop_start_idx]] ≈ transformed_points[i-1]) + (transformed_points[indices[][loop_start_idx]] ≈ transformed_points[i - 1]) # start -v v- end # adjust from j j j+1 .. i-2 i-1 @@ -77,12 +77,12 @@ function serialize_three(scene::Scene, plot::Union{Lines, LineSegments}) # be drawn (which we want as that segment would overlap) # tweak duplicated vertices to be loop vertices - push!(indices[], indices[][loop_start_idx+1]) - indices[][loop_start_idx-1] = i-2 + push!(indices[], indices[][loop_start_idx + 1]) + indices[][loop_start_idx - 1] = i - 2 # nan is inserted at bottom (and not necessary for start/end) else # no loop, duplicate end point - push!(indices[], i-1) + push!(indices[], i - 1) end end loop_start_idx = -1 @@ -93,7 +93,7 @@ function serialize_three(scene::Scene, plot::Union{Lines, LineSegments}) # line section start - duplicate point push!(indices[], i) # first point in a potential loop - loop_start_idx = length(indices[])+1 + loop_start_idx = length(indices[]) + 1 end was_nan = false end @@ -105,10 +105,10 @@ function serialize_three(scene::Scene, plot::Union{Lines, LineSegments}) # Finish line (insert duplicate end point or close loop) if !was_nan if loop_start_idx != -1 && (loop_start_idx + 2 < length(indices[])) && - (transformed_points[indices[][loop_start_idx]] ≈ transformed_points[end]) + (transformed_points[indices[][loop_start_idx]] ≈ transformed_points[end]) - push!(indices[], indices[][loop_start_idx+1]) - indices[][loop_start_idx-1] = prevind(transformed_points, lastindex(transformed_points)) + push!(indices[], indices[][loop_start_idx + 1]) + indices[][loop_start_idx - 1] = prevind(transformed_points, lastindex(transformed_points)) else push!(indices[], lastindex(transformed_points)) end @@ -141,31 +141,31 @@ function serialize_three(scene::Scene, plot::Union{Lines, LineSegments}) # clip -> pixel, but we can skip scene offset scale = Vec2f(0.5 * res[1], 0.5 * res[2]) # position of start of first drawn line segment (TODO: deal with multiple nans at start) - clip = pvm * to_ndim(Point4f, to_ndim(Point3f, ps[2], 0f0), 1f0) + clip = pvm * to_ndim(Point4f, to_ndim(Point3f, ps[2], 0.0f0), 1.0f0) prev = scale .* Point2f(clip) ./ clip[4] # calculate cumulative pixel scale length - output[1] = 0f0 # duplicated point - output[2] = 0f0 # start of first line segment - output[end] = 0f0 # duplicated end point + output[1] = 0.0f0 # duplicated point + output[2] = 0.0f0 # start of first line segment + output[end] = 0.0f0 # duplicated end point i = 3 # end of first line segment, start of second while i < length(ps) if isfinite(ps[i]) - clip = pvm * to_ndim(Point4f, to_ndim(Point3f, ps[i], 0f0), 1f0) + clip = pvm * to_ndim(Point4f, to_ndim(Point3f, ps[i], 0.0f0), 1.0f0) current = scale .* Point2f(clip) ./ clip[4] l = norm(current - prev) - output[i] = output[i-1] + l + output[i] = output[i - 1] + l prev = current i += 1 else # a vertex section (NaN, A, B, C) does not draw, so # norm(B - A) should not contribute to line length. # (norm(B - A) is 0 for capped lines but not for loops) - output[i] = 0f0 - output[i+1] = 0f0 - if i+2 <= length(ps) - output[min(end, i+2)] = 0f0 - clip = pvm * to_ndim(Point4f, to_ndim(Point3f, ps[i+2], 0f0), 1f0) + output[i] = 0.0f0 + output[i + 1] = 0.0f0 + if i + 2 <= length(ps) + output[min(end, i + 2)] = 0.0f0 + clip = pvm * to_ndim(Point4f, to_ndim(Point3f, ps[i + 2], 0.0f0), 1.0f0) prev = scale .* Point2f(clip) ./ clip[4] end i += 3 @@ -201,7 +201,7 @@ function serialize_three(scene::Scene, plot::Union{Lines, LineSegments}) end uniforms[:clip_planes] = lift(plot, scene.camera.projectionview, plot.clip_planes, plot.space) do pv, planes, space - Makie.is_data_space(space) || return [Vec4f(0, 0, 0, -1e9) for _ in 1:8] + Makie.is_data_space(space) || return [Vec4f(0, 0, 0, -1.0e9) for _ in 1:8] if length(planes) > 8 @warn("Only up to 8 clip planes are supported. The rest are ignored!", maxlog = 1) @@ -213,8 +213,8 @@ function serialize_three(scene::Scene, plot::Union{Lines, LineSegments}) for i in 1:min(length(planes), 8) output[i] = Makie.gl_plane_format(clip_planes[i]) end - for i in min(length(planes), 8)+1:8 - output[i] = Vec4f(0, 0, 0, -1e9) + for i in (min(length(planes), 8) + 1):8 + output[i] = Vec4f(0, 0, 0, -1.0e9) end return output end diff --git a/WGLMakie/src/meshes.jl b/WGLMakie/src/meshes.jl index 238fa885c99..36d78713587 100644 --- a/WGLMakie/src/meshes.jl +++ b/WGLMakie/src/meshes.jl @@ -18,7 +18,7 @@ function converted_attribute(plot::AbstractPlot, key::Symbol) end end -function handle_color!(plot, uniforms, buffers, uniform_color_name = :uniform_color; permute_tex=true) +function handle_color!(plot, uniforms, buffers, uniform_color_name = :uniform_color; permute_tex = true) color = plot.calculated_colors minfilter = to_value(get(plot, :interpolate, true)) ? :linear : :nearest @@ -32,15 +32,15 @@ function handle_color!(plot, uniforms, buffers, uniform_color_name = :uniform_co buffers[:color] = Buffer(color) elseif color[] isa Makie.AbstractPattern uniforms[:pattern] = true - uniforms[uniform_color_name] = Sampler(convert_texture(color); minfilter=minfilter) + uniforms[uniform_color_name] = Sampler(convert_texture(color); minfilter = minfilter) elseif color[] isa AbstractMatrix - uniforms[uniform_color_name] = Sampler(convert_texture(color); minfilter=minfilter) + uniforms[uniform_color_name] = Sampler(convert_texture(color); minfilter = minfilter) elseif color[] isa Makie.ColorMapping if color[].color_scaled[] isa AbstractVector buffers[:color] = Buffer(color[].color_scaled) else color_scaled = convert_texture(color[].color_scaled) - uniforms[uniform_color_name] = Sampler(color_scaled; minfilter=minfilter) + uniforms[uniform_color_name] = Sampler(color_scaled; minfilter = minfilter) end uniforms[:colormap] = Sampler(color[].colormap) uniforms[:colorrange] = color[].colorrange_scaled @@ -62,9 +62,9 @@ end lift_or(f, p, x) = f(x) lift_or(f, @nospecialize(p), x::Observable) = lift(f, p, x) -function draw_mesh(mscene::Scene, per_vertex, plot, uniforms; permute_tex=true) +function draw_mesh(mscene::Scene, per_vertex, plot, uniforms; permute_tex = true) filter!(kv -> !(kv[2] isa Function), uniforms) - handle_color!(plot, uniforms, per_vertex; permute_tex=permute_tex) + handle_color!(plot, uniforms, per_vertex; permute_tex = permute_tex) get!(uniforms, :ambient, Vec3f(1)) get!(uniforms, :light_direction, Vec3f(1)) @@ -106,8 +106,8 @@ function create_shader(scene::Scene, plot::Makie.Mesh) get_attribute(mesh, key) = lift(x -> getproperty(x, key), plot, mesh) data = GeometryBasics.vertex_attributes(mesh_signal[]) - uniforms = Dict{Symbol,Any}() - attributes = Dict{Symbol,Any}() + uniforms = Dict{Symbol, Any}() + attributes = Dict{Symbol, Any}() uniforms[:interpolate_in_fragment_shader] = get(plot, :interpolate_in_fragment_shader, true) @@ -136,5 +136,5 @@ function create_shader(scene::Scene, plot::Makie.Mesh) attributes[:faces] = faces attributes[:positions] = positions - return draw_mesh(scene, attributes, plot, uniforms; permute_tex=false) + return draw_mesh(scene, attributes, plot, uniforms; permute_tex = false) end diff --git a/WGLMakie/src/particles.jl b/WGLMakie/src/particles.jl index abc6cc2edee..01eedc25d5a 100644 --- a/WGLMakie/src/particles.jl +++ b/WGLMakie/src/particles.jl @@ -1,4 +1,3 @@ - function handle_color_getter!(uniform_dict, per_instance) if haskey(uniform_dict, :color) && haskey(per_instance, :color) to_value(uniform_dict[:color]) isa Bool && delete!(uniform_dict, :color) @@ -35,14 +34,16 @@ function handle_color_getter!(uniform_dict, per_instance) return end -const IGNORE_KEYS = Set([ - :shading, :overdraw, :distancefield, :space, :markerspace, :fxaa, - :visible, :transformation, :alpha, :linewidth, :transparency, :marker, - :light_direction, :light_color, - :cycle, :label, :inspector_clear, :inspector_hover, - :inspector_label, :axis_cyclerr, :dim_conversions, :material, :clip_planes - # TODO add model here since we generally need to apply patch_model? -]) +const IGNORE_KEYS = Set( + [ + :shading, :overdraw, :distancefield, :space, :markerspace, :fxaa, + :visible, :transformation, :alpha, :linewidth, :transparency, :marker, + :light_direction, :light_color, + :cycle, :label, :inspector_clear, :inspector_hover, + :inspector_label, :axis_cyclerr, :dim_conversions, :material, :clip_planes, + # TODO add model here since we generally need to apply patch_model? + ] +) function create_shader(scene::Scene, plot::MeshScatter) # Potentially per instance attributes @@ -62,7 +63,7 @@ function create_shader(scene::Scene, plot::MeshScatter) return (!haskey(per_instance, k)) && isscalar(v[]) end - uniform_dict = Dict{Symbol,Any}() + uniform_dict = Dict{Symbol, Any}() color_keys = Set([:color, :colormap, :highclip, :lowclip, :nan_color, :colorrange, :colorscale, :calculated_colors]) for (k, v) in uniforms k in IGNORE_KEYS && continue @@ -97,14 +98,14 @@ function create_shader(scene::Scene, plot::MeshScatter) uniform_dict[:normal] = Vec3f(0) end - uniform_dict[:depth_shift] = get(plot, :depth_shift, Observable(0f0)) + uniform_dict[:depth_shift] = get(plot, :depth_shift, Observable(0.0f0)) uniform_dict[:backlight] = plot.backlight # Make sure these exist get!(uniform_dict, :ambient, Vec3f(0.1)) get!(uniform_dict, :diffuse, Vec3f(0.9)) get!(uniform_dict, :specular, Vec3f(0.3)) - get!(uniform_dict, :shininess, 8f0) + get!(uniform_dict, :shininess, 8.0f0) get!(uniform_dict, :light_direction, Vec3f(1)) get!(uniform_dict, :light_color, Vec3f(1)) get!(uniform_dict, :PICKING_INDEX_FROM_UV, false) @@ -120,7 +121,7 @@ function create_shader(scene::Scene, plot::MeshScatter) uv_transform = map(plot, plot[:uv_transform]) do x M = convert_attribute(x, Key{:uv_transform}(), Key{:meshscatter}()) # why transpose? - T = Mat3f(0,1,0, 1,0,0, 0,0,1) + T = Mat3f(0, 1, 0, 1, 0, 0, 0, 0, 1) if M === nothing return T elseif M isa Mat @@ -136,8 +137,10 @@ function create_shader(scene::Scene, plot::MeshScatter) uniform_dict[:uv_transform] = uv_transform end - return InstancedProgram(WebGL(), lasset("particles.vert"), lasset("mesh.frag"), - instance, VertexArray(; per_instance...), uniform_dict) + return InstancedProgram( + WebGL(), lasset("particles.vert"), lasset("mesh.frag"), + instance, VertexArray(; per_instance...), uniform_dict + ) end using Makie: to_spritemarker @@ -154,22 +157,26 @@ struct NoDataTextureAtlas <: ShaderAbstractions.AbstractSampler{Float16, 2} end function serialize_three(fta::NoDataTextureAtlas) - tex = Dict(:type => "Sampler", :data => "texture_atlas", - :size => [fta.dims...], :three_format => three_format(Float16), - :three_type => three_type(Float16), - :minFilter => three_filter(:linear), - :magFilter => three_filter(:linear), - :wrapS => "RepeatWrapping", - :anisotropy => 16f0) + tex = Dict( + :type => "Sampler", :data => "texture_atlas", + :size => [fta.dims...], :three_format => three_format(Float16), + :three_type => three_type(Float16), + :minFilter => three_filter(:linear), + :magFilter => three_filter(:linear), + :wrapS => "RepeatWrapping", + :anisotropy => 16.0f0 + ) tex[:wrapT] = "RepeatWrapping" return tex end function scatter_shader(scene::Scene, attributes, plot) # Potentially per instance attributes - per_instance_keys = (:pos, :rotation, :markersize, :color, :intensity, - :uv_offset_width, :quad_offset, :marker_offset) - uniform_dict = Dict{Symbol,Any}() + per_instance_keys = ( + :pos, :rotation, :markersize, :color, :intensity, + :uv_offset_width, :quad_offset, :marker_offset, + ) + uniform_dict = Dict{Symbol, Any}() uniform_dict[:image] = false marker = nothing atlas = wgl_texture_atlas() @@ -204,8 +211,12 @@ function scatter_shader(scene::Scene, attributes, plot) return !haskey(per_instance, k) end - color_keys = Set([:color, :colormap, :highclip, :lowclip, :nan_color, :colorrange, :colorscale, - :calculated_colors]) + color_keys = Set( + [ + :color, :colormap, :highclip, :lowclip, :nan_color, :colorrange, :colorscale, + :calculated_colors, + ] + ) for (k, v) in uniforms k in IGNORE_KEYS && continue @@ -215,7 +226,7 @@ function scatter_shader(scene::Scene, attributes, plot) if !isnothing(marker) get!(uniform_dict, :shape_type) do - return lift(plot, marker; ignore_equal_values=true) do marker + return lift(plot, marker; ignore_equal_values = true) do marker return Cint(Makie.marker_to_sdf_shape(to_spritemarker(marker))) end end @@ -226,7 +237,7 @@ function scatter_shader(scene::Scene, attributes, plot) uniform_dict[:distancefield] = NoDataTextureAtlas(size(atlas.data)) uniform_dict[:atlas_texture_size] = Float32(size(atlas.data, 1)) # Texture must be quadratic else - uniform_dict[:atlas_texture_size] = 0f0 + uniform_dict[:atlas_texture_size] = 0.0f0 uniform_dict[:distancefield] = Observable(false) end @@ -237,27 +248,29 @@ function scatter_shader(scene::Scene, attributes, plot) to_value(per_instance[:color]) isa Bool && delete!(per_instance, :color) end - instance = uv_mesh(Rect2f(-0.5f0, -0.5f0, 1f0, 1f0)) + instance = uv_mesh(Rect2f(-0.5f0, -0.5f0, 1.0f0, 1.0f0)) # Don't send obs, since it's overwritten in JS to be updated by the camera uniform_dict[:resolution] = to_value(scene.camera.resolution) - uniform_dict[:px_per_unit] = 1f0 + uniform_dict[:px_per_unit] = 1.0f0 # id + picking gets filled in JS, needs to be here to emit the correct shader uniforms uniform_dict[:picking] = false uniform_dict[:object_id] = UInt32(0) # Make sure these exist - get!(uniform_dict, :strokewidth, 0f0) + get!(uniform_dict, :strokewidth, 0.0f0) get!(uniform_dict, :strokecolor, RGBAf(0, 0, 0, 0)) - get!(uniform_dict, :glowwidth, 0f0) + get!(uniform_dict, :glowwidth, 0.0f0) get!(uniform_dict, :glowcolor, RGBAf(0, 0, 0, 0)) _, arr = first(per_instance) - if any(v-> length(arr) != length(v), values(per_instance)) + if any(v -> length(arr) != length(v), values(per_instance)) lens = [k => length(v) for (k, v) in per_instance] error("Not all have the same length: $(lens)") end - return InstancedProgram(WebGL(), lasset("sprites.vert"), lasset("sprites.frag"), - instance, VertexArray(; per_instance...), uniform_dict) + return InstancedProgram( + WebGL(), lasset("sprites.vert"), lasset("sprites.frag"), + instance, VertexArray(; per_instance...), uniform_dict + ) end function create_shader(scene::Scene, plot::Scatter) @@ -275,7 +288,7 @@ function create_shader(scene::Scene, plot::Scatter) attributes[:billboard] = lift(rot -> isa(rot, Billboard), plot, plot.rotation) attributes[:model] = model - attributes[:depth_shift] = get(plot, :depth_shift, Observable(0f0)) + attributes[:depth_shift] = get(plot, :depth_shift, Observable(0.0f0)) delete!(attributes, :uv_offset_width) filter!(kv -> !(kv[2] isa Function), attributes) @@ -294,27 +307,31 @@ function create_shader(scene::Scene, plot::Makie.Text{<:Tuple{<:Union{<:Makie.Gl offset = plot.offset atlas = wgl_texture_atlas() - glyph_data = lift(plot, pos, glyphcollection, offset; ignore_equal_values=true) do pos, gc, offset + glyph_data = lift(plot, pos, glyphcollection, offset; ignore_equal_values = true) do pos, gc, offset Makie.text_quads(atlas, pos, to_value(gc), offset) end # unpack values from the one signal: positions, char_offset, quad_offset, uv_offset_width, scale = map((1, 2, 3, 4, 5)) do i - return lift(getindex, plot, glyph_data, i; ignore_equal_values=true) + return lift(getindex, plot, glyph_data, i; ignore_equal_values = true) end - uniform_color = lift(plot, glyphcollection; ignore_equal_values=true) do gc + uniform_color = lift(plot, glyphcollection; ignore_equal_values = true) do gc if gc isa AbstractArray - reduce(vcat, (Makie.collect_vector(g.colors, length(g.glyphs)) for g in gc); - init=RGBAf[]) + reduce( + vcat, (Makie.collect_vector(g.colors, length(g.glyphs)) for g in gc); + init = RGBAf[] + ) else gc.colors.sv end end - uniform_rotation = lift(plot, glyphcollection; ignore_equal_values=true) do gc + uniform_rotation = lift(plot, glyphcollection; ignore_equal_values = true) do gc if gc isa AbstractArray - reduce(vcat, (Makie.collect_vector(g.rotations, length(g.glyphs)) for g in gc); - init=Quaternionf[]) + reduce( + vcat, (Makie.collect_vector(g.rotations, length(g.glyphs)) for g in gc); + init = Quaternionf[] + ) else gc.rotations.sv end @@ -334,7 +351,7 @@ function create_shader(scene::Scene, plot::Makie.Text{<:Tuple{<:Union{<:Makie.Gl :uv_offset_width => uv_offset_width, :transform_marker => get(plot.attributes, :transform_marker, Observable(true)), :billboard => Observable(false), - :depth_shift => get(plot, :depth_shift, Observable(0f0)), + :depth_shift => get(plot, :depth_shift, Observable(0.0f0)), :glowwidth => plot.glowwidth, :glowcolor => plot.glowcolor, ) diff --git a/WGLMakie/src/picking.jl b/WGLMakie/src/picking.jl index bd8c36b0355..bc49ddd1aaf 100644 --- a/WGLMakie/src/picking.jl +++ b/WGLMakie/src/picking.jl @@ -1,14 +1,15 @@ - function pick_native(screen::Screen, rect::Rect2i) (x, y) = minimum(rect) (w, h) = widths(rect) session = get_screen_session(screen) - empty = Matrix{Tuple{Union{Nothing,AbstractPlot},Int}}(undef, 0, 0) + empty = Matrix{Tuple{Union{Nothing, AbstractPlot}, Int}}(undef, 0, 0) isnothing(session) && return empty scene = screen.scene - picking_data = Bonito.evaljs_value(session, js""" - Promise.all([$(WGL), $(scene)]).then(([WGL, scene]) => WGL.pick_native_matrix(scene, $x, $y, $w, $h)) - """) + picking_data = Bonito.evaljs_value( + session, js""" + Promise.all([$(WGL), $(scene)]).then(([WGL, scene]) => WGL.pick_native_matrix(scene, $x, $y, $w, $h)) + """ + ) if isnothing(picking_data) return empty end @@ -39,9 +40,11 @@ function Makie.pick_closest(scene::Scene, screen::Screen, xy, range::Integer) session = get_screen_session(screen) # E.g. if websocket got closed isnothing(session) && return (nothing, 0) - selection = Bonito.evaljs_value(session, js""" - Promise.all([$(WGL), $(scene)]).then(([WGL, scene]) => WGL.pick_closest(scene, $(xy_vec), $(range))) - """) + selection = Bonito.evaljs_value( + session, js""" + Promise.all([$(WGL), $(scene)]).then(([WGL, scene]) => WGL.pick_closest(scene, $(xy_vec), $(range))) + """ + ) lookup = plot_lookup(scene) !haskey(lookup, selection[1]) && return (nothing, 0) plt = lookup[selection[1]] @@ -54,14 +57,16 @@ function Makie.pick_sorted(scene::Scene, screen::Screen, xy, range) range = round(Int, range) session = get_screen_session(screen) # E.g. if websocket got closed - isnothing(session) && return Tuple{Plot,Int}[] - selection = Bonito.evaljs_value(session, js""" - Promise.all([$(WGL), $(scene)]).then(([WGL, scene]) => { - const picked = WGL.pick_sorted(scene, $(xy_vec), $(range)) - return picked - }) - """) - isnothing(selection) && return Tuple{Plot,Int}[] + isnothing(session) && return Tuple{Plot, Int}[] + selection = Bonito.evaljs_value( + session, js""" + Promise.all([$(WGL), $(scene)]).then(([WGL, scene]) => { + const picked = WGL.pick_sorted(scene, $(xy_vec), $(range)) + return picked + }) + """ + ) + isnothing(selection) && return Tuple{Plot, Int}[] lookup = plot_lookup(scene) filter!(((id, idx),) -> haskey(lookup, id), selection) return map(selection) do (id, idx) @@ -117,13 +122,13 @@ struct ToolTip scene::Scene callback::Bonito.JSCode plot_uuids::Vector{String} - function ToolTip(figlike, callback; plots=nothing) + function ToolTip(figlike, callback; plots = nothing) scene = Makie.get_scene(figlike) if isnothing(plots) plots = scene.plots end - all_plots = js_uuid.(filter!(x-> x.inspectable[], Makie.collect_atomic_plots(plots))) - new(scene, callback, all_plots) + all_plots = js_uuid.(filter!(x -> x.inspectable[], Makie.collect_atomic_plots(plots))) + return new(scene, callback, all_plots) end end @@ -131,13 +136,15 @@ const POPUP_CSS = Bonito.Asset(@path joinpath(@__DIR__, "popup.css")) function Bonito.jsrender(session::Session, tt::ToolTip) scene = tt.scene - popup = DOM.div("", class="popup") - Bonito.evaljs(session, js""" - $(scene).then(scene => { - const plots_to_pick = new Set($(tt.plot_uuids)); - const callback = $(tt.callback); - WGL.register_popup($popup, scene, plots_to_pick, callback) - }) - """) + popup = DOM.div("", class = "popup") + Bonito.evaljs( + session, js""" + $(scene).then(scene => { + const plots_to_pick = new Set($(tt.plot_uuids)); + const callback = $(tt.callback); + WGL.register_popup($popup, scene, plots_to_pick, callback) + }) + """ + ) return DOM.span(Bonito.jsrender(session, POPUP_CSS), popup) end diff --git a/WGLMakie/src/precompiles.jl b/WGLMakie/src/precompiles.jl index a4837686cf6..f55fc93e233 100644 --- a/WGLMakie/src/precompiles.jl +++ b/WGLMakie/src/precompiles.jl @@ -9,13 +9,13 @@ macro compile(block) # while precompiling # So we just do all parts of the stack we can do without browser scene = Makie.get_scene(figlike) - session = Session(Bonito.NoConnection(); asset_server=Bonito.NoServer()) + session = Session(Bonito.NoConnection(); asset_server = Bonito.NoServer()) three_display(Screen(scene), session, scene) Bonito.jsrender(session, figlike) s = serialize_scene(scene) Bonito.SerializedMessage(session, Dict(:data => s)) session = Session() - app = App(()-> DOM.div(figlike)) + app = App(() -> DOM.div(figlike)) dom = Bonito.session_dom(session, app) show(IOBuffer(), Bonito.Hyperscript.Pretty(dom)) close(session) diff --git a/WGLMakie/src/serialization.jl b/WGLMakie/src/serialization.jl index d4f8bbfe9f8..a04f59ec170 100644 --- a/WGLMakie/src/serialization.jl +++ b/WGLMakie/src/serialization.jl @@ -52,8 +52,8 @@ function serialize_three(array::Buffer) return serialize_three(flatten_buffer(array)) end -function serialize_three(array::AbstractArray{T}) where {T<:Union{N0f8,UInt8,Int32,UInt32,Float32,Float16,Float64}} - vec(convert(Array, array)) +function serialize_three(array::AbstractArray{T}) where {T <: Union{N0f8, UInt8, Int32, UInt32, Float32, Float16, Float64}} + return vec(convert(Array, array)) end function serialize_three(p::Makie.AbstractPattern) @@ -65,10 +65,10 @@ three_format(::Type{<:Real}) = "RedFormat" three_format(::Type{<:RGB}) = "RGBFormat" three_format(::Type{<:RGBA}) = "RGBAFormat" -three_format(::Type{<: Makie.VecTypes{1}}) = "RedFormat" -three_format(::Type{<: Makie.VecTypes{2}}) = "RGFormat" -three_format(::Type{<: Makie.VecTypes{3}}) = "RGBFormat" -three_format(::Type{<: Makie.VecTypes{4}}) = "RGBAFormat" +three_format(::Type{<:Makie.VecTypes{1}}) = "RedFormat" +three_format(::Type{<:Makie.VecTypes{2}}) = "RGFormat" +three_format(::Type{<:Makie.VecTypes{3}}) = "RGBFormat" +three_format(::Type{<:Makie.VecTypes{4}}) = "RGBAFormat" three_type(::Type{Float16}) = "FloatType" three_type(::Type{Float32}) = "FloatType" @@ -92,17 +92,19 @@ function three_repeat(s::Symbol) error("Unknown repeat mode '$s'") end -function serialize_three(color::Sampler{T,N}) where {T,N} - tex = Dict(:type => "Sampler", - :data => serialize_three(color.data), - :size => Int32[size(color.data)...], - :three_format => three_format(T), - :three_type => three_type(eltype(T)), - :minFilter => three_filter(color.minfilter), - :magFilter => three_filter(color.magfilter), - :wrapS => three_repeat(color.repeat[1]), - :mipmap => color.mipmap, - :anisotropy => color.anisotropic) +function serialize_three(color::Sampler{T, N}) where {T, N} + tex = Dict( + :type => "Sampler", + :data => serialize_three(color.data), + :size => Int32[size(color.data)...], + :three_format => three_format(T), + :three_type => three_type(eltype(T)), + :minFilter => three_filter(color.minfilter), + :magFilter => three_filter(color.magfilter), + :wrapS => three_repeat(color.repeat[1]), + :mipmap => color.mipmap, + :anisotropy => color.anisotropic + ) if N > 1 tex[:wrapT] = three_repeat(color.repeat[2]) end @@ -113,7 +115,7 @@ function serialize_three(color::Sampler{T,N}) where {T,N} end function serialize_uniforms(dict::Dict) - result = Dict{Symbol,Any}() + result = Dict{Symbol, Any}() for (k, v) in dict # we don't send observables and instead use # uniform_updater(dict) @@ -123,7 +125,6 @@ function serialize_uniforms(dict::Dict) end - """ flatten_buffer(array::AbstractArray) @@ -131,7 +132,7 @@ Flattens `array` array to be a 1D Vector of Float32 / UInt8. If presented with AbstractArray{<: Colorant/Tuple/SVector}, it will flatten those to their element type. """ -function flatten_buffer(array::AbstractArray{<: Number}) +function flatten_buffer(array::AbstractArray{<:Number}) return array end function flatten_buffer(array::AbstractArray{<:AbstractFloat}) @@ -141,7 +142,7 @@ function flatten_buffer(array::Buffer) return flatten_buffer(getfield(array, :data)) end -function flatten_buffer(array::AbstractArray{T}) where {T<:N0f8} +function flatten_buffer(array::AbstractArray{T}) where {T <: N0f8} return collect(reinterpret(UInt8, array)) end @@ -159,13 +160,17 @@ isscalar(x::Billboard) = isscalar(x.rotation) isscalar(x::Observable) = isscalar(x[]) isscalar(x) = true -function ShaderAbstractions.type_string(::ShaderAbstractions.AbstractContext, - ::Type{<:Makie.Quaternion}) +function ShaderAbstractions.type_string( + ::ShaderAbstractions.AbstractContext, + ::Type{<:Makie.Quaternion} + ) return "vec4" end -function ShaderAbstractions.convert_uniform(::ShaderAbstractions.AbstractContext, - t::Quaternion) +function ShaderAbstractions.convert_uniform( + ::ShaderAbstractions.AbstractContext, + t::Quaternion + ) return convert(Quaternion, t) end @@ -187,9 +192,11 @@ function serialize_buffer_attribute(buffer::AbstractVector{T}) where {T} end function serialize_named_buffer(va::ShaderAbstractions.VertexArray) - return Dict(map(ShaderAbstractions.buffers(va)) do (name, buff) - return name => serialize_buffer_attribute(buff) - end) + return Dict( + map(ShaderAbstractions.buffers(va)) do (name, buff) + return name => serialize_buffer_attribute(buff) + end + ) end function register_geometry_updates(@nospecialize(plot), update_buffer::Observable, named_buffers::ShaderAbstractions.VertexArray) @@ -265,12 +272,14 @@ function serialize_three(@nospecialize(plot), program::Program) register_geometry_updates(plot, attribute_updater, program) # TODO, make this configurable in ShaderAbstractions update_shader(x) = replace(x, "#version 300 es" => "") - return Dict(:vertexarrays => serialize_named_buffer(program.vertexarray), - :faces => indices, :uniforms => uniforms, - :vertex_source => update_shader(program.vertex_source), - :fragment_source => update_shader(program.fragment_source), - :uniform_updater => uniform_updater(plot, program.uniforms), - :attribute_updater => attribute_updater) + return Dict( + :vertexarrays => serialize_named_buffer(program.vertexarray), + :faces => indices, :uniforms => uniforms, + :vertex_source => update_shader(program.vertex_source), + :fragment_source => update_shader(program.fragment_source), + :uniform_updater => uniform_updater(plot, program.uniforms), + :attribute_updater => attribute_updater + ) end function serialize_scene(scene::Scene) @@ -289,7 +298,7 @@ function serialize_scene(scene::Scene) nothing end - children = map(child-> serialize_scene(child), scene.children) + children = map(child -> serialize_scene(child), scene.children) dirlight = Makie.get_directional_light(scene) light_dir = isnothing(dirlight) ? Observable(Vec3f(1)) : dirlight.direction @@ -312,7 +321,7 @@ function serialize_scene(scene::Scene) return serialized end -function serialize_plots(scene::Scene, plots::Vector{Plot}, result=[]) +function serialize_plots(scene::Scene, plots::Vector{Plot}, result = []) for plot in plots # if no plots inserted, this truly is an atomic if isempty(plot.plots) @@ -370,10 +379,10 @@ function serialize_three(scene::Scene, @nospecialize(plot::AbstractPlot)) if plot isa Voxels clip_planes = map( - plot, plot.converted..., plot.model, plot.clip_planes, plot.space - ) do xs, ys, zs, chunk, model, planes, space + plot, plot.converted..., plot.model, plot.clip_planes, plot.space + ) do xs, ys, zs, chunk, model, planes, space - Makie.is_data_space(space) || return [Vec4f(0, 0, 0, -1e9) for _ in 1:8] + Makie.is_data_space(space) || return [Vec4f(0, 0, 0, -1.0e9) for _ in 1:8] # model/modelinv has no perspective projection so we should be fine # with just applying it to the plane origin and transpose(inv(modelinv)) @@ -384,18 +393,20 @@ function serialize_three(scene::Scene, @nospecialize(plot::AbstractPlot)) Makie.scalematrix(Vec3f(width ./ size(chunk))) * Makie.translationmatrix(Vec3f(mini)) modelinv = inv(_model) - @assert isapprox(modelinv[4, 4], 1, atol = 1e-6) + @assert isapprox(modelinv[4, 4], 1, atol = 1.0e-6) output = Vector{Vec4f}(undef, 8) for i in 1:min(length(planes), 8) origin = modelinv * to_ndim(Point4f, planes[i].distance * planes[i].normal, 1) normal = transpose(_model) * to_ndim(Vec4f, planes[i].normal, 0) - distance = dot(Vec3f(origin[1], origin[2], origin[3]) / origin[4], - Vec3f(normal[1], normal[2], normal[3])) + distance = dot( + Vec3f(origin[1], origin[2], origin[3]) / origin[4], + Vec3f(normal[1], normal[2], normal[3]) + ) output[i] = Vec4f(normal[1], normal[2], normal[3], distance) end - for i in min(length(planes), 8)+1:8 - output[i] = Vec4f(0, 0, 0, -1e9) + for i in (min(length(planes), 8) + 1):8 + output[i] = Vec4f(0, 0, 0, -1.0e9) end return output @@ -413,24 +424,26 @@ function serialize_three(scene::Scene, @nospecialize(plot::AbstractPlot)) end clip_planes = map(plot, model2, plot.clip_planes, plot.space) do model, planes, space - Makie.is_data_space(space) || return [Vec4f(0, 0, 0, -1e9) for _ in 1:8] + Makie.is_data_space(space) || return [Vec4f(0, 0, 0, -1.0e9) for _ in 1:8] # model/modelinv has no perspective projection so we should be fine # with just applying it to the plane origin and transpose(inv(modelinv)) # to plane.normal modelinv = inv(model) - @assert isapprox(modelinv[4, 4], 1, atol = 1e-6) + @assert isapprox(modelinv[4, 4], 1, atol = 1.0e-6) output = Vector{Vec4f}(undef, 8) for i in 1:min(length(planes), 8) origin = modelinv * to_ndim(Point4f, planes[i].distance * planes[i].normal, 1) normal = transpose(model2[]) * to_ndim(Vec4f, planes[i].normal, 0) - distance = dot(Vec3f(origin[1], origin[2], origin[3]) / origin[4], - Vec3f(normal[1], normal[2], normal[3])) + distance = dot( + Vec3f(origin[1], origin[2], origin[3]) / origin[4], + Vec3f(normal[1], normal[2], normal[3]) + ) output[i] = Vec4f(normal[1], normal[2], normal[3], distance) end - for i in min(length(planes), 8)+1:8 - output[i] = Vec4f(0, 0, 0, -1e9) + for i in (min(length(planes), 8) + 1):8 + output[i] = Vec4f(0, 0, 0, -1.0e9) end return output @@ -439,7 +452,7 @@ function serialize_three(scene::Scene, @nospecialize(plot::AbstractPlot)) else clip_planes = map(plot, plot.clip_planes, plot.space) do planes, space - Makie.is_data_space(space) || return [Vec4f(0, 0, 0, -1e9) for _ in 1:8] + Makie.is_data_space(space) || return [Vec4f(0, 0, 0, -1.0e9) for _ in 1:8] if length(planes) > 8 @warn("Only up to 8 clip planes are supported. The rest are ignored!", maxlog = 1) @@ -449,8 +462,8 @@ function serialize_three(scene::Scene, @nospecialize(plot::AbstractPlot)) for i in 1:min(length(planes), 8) output[i] = Makie.gl_plane_format(planes[i]) end - for i in min(length(planes), 8)+1:8 - output[i] = Vec4f(0, 0, 0, -1e10) + for i in (min(length(planes), 8) + 1):8 + output[i] = Vec4f(0, 0, 0, -1.0e10) end return output diff --git a/WGLMakie/src/three_plot.jl b/WGLMakie/src/three_plot.jl index 6ee36ffc719..d845f49b6fb 100644 --- a/WGLMakie/src/three_plot.jl +++ b/WGLMakie/src/three_plot.jl @@ -1,5 +1,3 @@ - - # We use objectid to find objects on the js side js_uuid(object) = string(objectid(object)) @@ -8,23 +6,25 @@ function Bonito.print_js_code(io::IO, plot::AbstractPlot, context::Bonito.JSSour # This is a bit more complicated then it has to be, since evaljs / on_document_load # isn't guaranteed to run after plot initialization in an App... So, if we don't find any plots, # we have to check again after inserting new plots - Bonito.print_js_code(io, js"""(new Promise(resolve => { - $(WGL).then(WGL=> { - const find = ()=> { - const plots = WGL.find_plots($(uuids)) - if (plots.length > 0) { - resolve(plots) - } else { - WGL.on_next_insert(find) - } - }; - find() - }) - }))""", context) + return Bonito.print_js_code( + io, js"""(new Promise(resolve => { + $(WGL).then(WGL=> { + const find = ()=> { + const plots = WGL.find_plots($(uuids)) + if (plots.length > 0) { + resolve(plots) + } else { + WGL.on_next_insert(find) + } + }; + find() + }) + }))""", context + ) end function Bonito.print_js_code(io::IO, scene::Scene, context::Bonito.JSSourceContext) - Bonito.print_js_code(io, js"""$(WGL).then(WGL=> WGL.find_scene($(js_uuid(scene))))""", context) + return Bonito.print_js_code(io, js"""$(WGL).then(WGL=> WGL.find_scene($(js_uuid(scene))))""", context) end function three_display(screen::Screen, session::Session, scene::Scene) @@ -33,44 +33,47 @@ function three_display(screen::Screen, session::Session, scene::Scene) window_open = scene.events.window_open width, height = size(scene) canvas_width = lift(x -> [round.(Int, widths(x))...], scene, viewport(scene)) - canvas = DOM.m("canvas"; - tabindex="0", style="display: block", + canvas = DOM.m( + "canvas"; + tabindex = "0", style = "display: block", # Pass JupyterLab specific attributes to prevent it from capturing keyboard shortcuts # and to suppress the JupyterLab context menu in Makie plots, see: # https://jupyterlab.readthedocs.io/en/4.2.x/extension/notebook.html#keyboard-interaction-model # https://jupyterlab.readthedocs.io/en/4.2.x/extension/extension_points.html#context-menu - dataLmSuppressShortcuts=true, dataJpSuppressContextMenu=nothing, + dataLmSuppressShortcuts = true, dataJpSuppressContextMenu = nothing, ) - wrapper = DOM.div(canvas; style="width: 100%; height: 100%") - comm = Observable(Dict{String,Any}()) + wrapper = DOM.div(canvas; style = "width: 100%; height: 100%") + comm = Observable(Dict{String, Any}()) done_init = Observable{Any}(nothing) # Keep texture atlas in parent session, so we don't need to send it over and over again ta = Bonito.Retain(TEXTURE_ATLAS) - evaljs(session, js""" - $(WGL).then(WGL => { - try { - const wrapper = $wrapper - const canvas = $canvas - if (wrapper == null || canvas == null) { + evaljs( + session, js""" + $(WGL).then(WGL => { + try { + const wrapper = $wrapper + const canvas = $canvas + if (wrapper == null || canvas == null) { + return + } + const renderer = WGL.create_scene( + wrapper, canvas, $canvas_width, $scene_serialized, $comm, $width, $height, + $(ta), $(config.framerate), $(config.resize_to), $(config.px_per_unit), $(config.scalefactor) + ) + const gl = renderer.getContext() + const err = gl.getError() + if (err != gl.NO_ERROR) { + throw new Error("WebGL error: " + WGL.wglerror(gl, err)) + } + $(done_init).notify(true) + } catch (e) { + Bonito.Connection.send_error("error initializing scene", e) + $(done_init).notify(e) return } - const renderer = WGL.create_scene( - wrapper, canvas, $canvas_width, $scene_serialized, $comm, $width, $height, - $(ta), $(config.framerate), $(config.resize_to), $(config.px_per_unit), $(config.scalefactor) - ) - const gl = renderer.getContext() - const err = gl.getError() - if (err != gl.NO_ERROR) { - throw new Error("WebGL error: " + WGL.wglerror(gl, err)) - } - $(done_init).notify(true) - } catch (e) { - Bonito.Connection.send_error("error initializing scene", e) - $(done_init).notify(e) - return - } - }) - """) + }) + """ + ) on(session, done_init) do val window_open[] = true end @@ -84,13 +87,15 @@ function Makie.move_to!(screen::Screen, plot::Plot, scene::Scene) session = get_screen_session(screen) # Make sure target scene is serialized insert_scene!(session, screen, scene) - return evaljs(session, js""" - $(scene).then(scene=> { - $(plot).then(meshes=> { - meshes.forEach(m => { - m.plot_object.move_to(scene) + return evaljs( + session, js""" + $(scene).then(scene=> { + $(plot).then(meshes=> { + meshes.forEach(m => { + m.plot_object.move_to(scene) + }) }) }) - }) - """) + """ + ) end diff --git a/WGLMakie/src/voxel.jl b/WGLMakie/src/voxel.jl index f8ba21e5242..31952b523f6 100644 --- a/WGLMakie/src/voxel.jl +++ b/WGLMakie/src/voxel.jl @@ -45,12 +45,13 @@ function create_shader(scene::Scene, plot::Makie.Voxels) # adjust model matrix with placement matrix uniform_dict[:model] = map( - plot, plot.converted..., plot.model - ) do xs, ys, zs, chunk, model + plot, plot.converted..., plot.model + ) do xs, ys, zs, chunk, model mini = minimum.((xs, ys, zs)) width = maximum.((xs, ys, zs)) .- mini - return Mat4f(model * - Makie.transformationmatrix(Vec3f(mini), Vec3f(width ./ size(chunk))) + return Mat4f( + model * + Makie.transformationmatrix(Vec3f(mini), Vec3f(width ./ size(chunk))) ) end @@ -90,14 +91,16 @@ function create_shader(scene::Scene, plot::Makie.Voxels) N = sum(size(chunk)) N_instances = ifelse(gap > 0.01, 2 * N, N + 3) if N_instances != length(dummy_data[]) # avoid updating unnecessarily - dummy_data[] = [0f0 for _ in 1:N_instances] + dummy_data[] = [0.0f0 for _ in 1:N_instances] end return end notify(plot.gap) - instance = GeometryBasics.mesh(Rect2(0f0, 0f0, 1f0, 1f0)) + instance = GeometryBasics.mesh(Rect2(0.0f0, 0.0f0, 1.0f0, 1.0f0)) - return InstancedProgram(WebGL(), lasset("voxel.vert"), lasset("voxel.frag"), - instance, VertexArray(dummy = dummy_data), uniform_dict) + return InstancedProgram( + WebGL(), lasset("voxel.vert"), lasset("voxel.frag"), + instance, VertexArray(dummy = dummy_data), uniform_dict + ) end diff --git a/WGLMakie/test/offline_export.jl b/WGLMakie/test/offline_export.jl index 109dca0443e..9397133c0c1 100644 --- a/WGLMakie/test/offline_export.jl +++ b/WGLMakie/test/offline_export.jl @@ -1,7 +1,7 @@ using Bonito, WGLMakie, Makie function handler(session, request) - return scatter(1:4, color=1:4) + return scatter(1:4, color = 1:4) end dir = joinpath(@__DIR__, "exported") @@ -10,4 +10,4 @@ Bonito.export_standalone(handler, dir) # Then serve it with e.g. LiveServer using LiveServer -LiveServer.serve(dir=dir) +LiveServer.serve(dir = dir) diff --git a/WGLMakie/test/runtests.jl b/WGLMakie/test/runtests.jl index 3573a2f8674..31d2733cc4a 100644 --- a/WGLMakie/test/runtests.jl +++ b/WGLMakie/test/runtests.jl @@ -21,19 +21,21 @@ import Electron @test !showable("blaaa", f) end -excludes = Set([ - "Image on Surface Sphere", # TODO: texture rotated 180° - # "heatmaps & surface", # TODO: fix direct NaN -> nancolor conversion - "Array of Images Scatter", # scatter does not support texture images - - "Order Independent Transparency", - "fast pixel marker", - "Textured meshscatter", # not yet implemented - "3D Contour with 2D contour slices", # looks like a z-fighting issue -]) +excludes = Set( + [ + "Image on Surface Sphere", # TODO: texture rotated 180° + # "heatmaps & surface", # TODO: fix direct NaN -> nancolor conversion + "Array of Images Scatter", # scatter does not support texture images + + "Order Independent Transparency", + "fast pixel marker", + "Textured meshscatter", # not yet implemented + "3D Contour with 2D contour slices", # looks like a z-fighting issue + ] +) Makie.inline!(Makie.automatic) -edisplay = Bonito.use_electron_display(devtools=true) +edisplay = Bonito.use_electron_display(devtools = true) @testset "reference tests" begin @testset "refimages" begin @@ -48,15 +50,15 @@ edisplay = Bonito.use_electron_display(devtools=true) Makie.CURRENT_FIGURE[] = nothing app = App(nothing) display(edisplay, app) - GC.gc(true); + GC.gc(true) # Somehow this may take a while to get emptied completely p_key = "Object.keys(WGL.plot_cache)" - value = @time Bonito.wait_for(() -> (GC.gc(true); isempty(run(edisplay.window, p_key))); timeout=50) + value = @time Bonito.wait_for(() -> (GC.gc(true); isempty(run(edisplay.window, p_key))); timeout = 50) @show run(edisplay.window, p_key) @test value == :success s_keys = "Object.keys(Bonito.Sessions.SESSIONS)" - value = @time Bonito.wait_for(() -> (GC.gc(true); length(run(edisplay.window, s_keys)) == 2); timeout=50) + value = @time Bonito.wait_for(() -> (GC.gc(true); length(run(edisplay.window, s_keys)) == 2); timeout = 50) @show run(edisplay.window, s_keys) @show app.session[].id @show app.session[].parent @@ -103,11 +105,11 @@ edisplay = Bonito.use_electron_display(devtools=true) function check_tick(tick, state, count) @test tick.state == state @test tick.count == count - @test tick.time > 1e-9 - @test tick.delta_time > 1e-9 + @test tick.time > 1.0e-9 + @test tick.delta_time > 1.0e-9 end - f, a, p = scatter(rand(10)); + f, a, p = scatter(rand(10)) @test events(f).tick[] == Makie.Tick() filename = "$(tempname()).png" @@ -127,7 +129,7 @@ edisplay = Bonito.use_electron_display(devtools=true) end - f, a, p = scatter(rand(10)); + f, a, p = scatter(rand(10)) filename = "$(tempname()).mp4" try tick_record = Makie.Tick[] @@ -139,8 +141,8 @@ edisplay = Bonito.use_electron_display(devtools=true) for (i, tick) in enumerate(tick_record[start:end]) @test tick.state == Makie.OneTimeRenderTick - @test tick.count == i-1 - @test tick.time ≈ dt * (i-1) + @test tick.count == i - 1 + @test tick.time ≈ dt * (i - 1) @test tick.delta_time ≈ dt end finally @@ -148,7 +150,7 @@ edisplay = Bonito.use_electron_display(devtools=true) end # test destruction of tick overwrite - f, a, p = scatter(rand(10)); + f, a, p = scatter(rand(10)) let io = VideoStream(f) @test events(f).tick[] == Makie.Tick(Makie.OneTimeRenderTick, 0, 0.0, 1.0 / io.options.framerate) diff --git a/docs/attrdocs_block.jl b/docs/attrdocs_block.jl index 58230c3565f..d337abd0898 100644 --- a/docs/attrdocs_block.jl +++ b/docs/attrdocs_block.jl @@ -1,8 +1,8 @@ abstract type AttrdocsBlocks <: Documenter.Expanders.NestedExpanderPipeline end -Documenter.Selectors.order(::Type{AttrdocsBlocks}) = 8.0 # like @example -Documenter.Selectors.matcher(::Type{AttrdocsBlocks}, node, page, doc) = Documenter.iscode(node, r"^@attrdocs") +Documenter.Selectors.order(::Type{AttrdocsBlocks}) = 8.0 # like @example +Documenter.Selectors.matcher(::Type{AttrdocsBlocks}, node, page, doc) = Documenter.iscode(node, r"^@attrdocs") # this type is just for a helper node which we can push child elements to that are # at the end flattened as if they were all on the level of the container @@ -13,7 +13,7 @@ end MarkdownAST.can_contain(::Container, ::MarkdownAST.AbstractElement) = true function DocumenterVitepress.render(io::IO, mime::MIME"text/plain", node::MarkdownAST.Node, c::Container, page, doc; kwargs...) - DocumenterVitepress.render(io, mime, node, node.children, page, doc; kwargs...) + return DocumenterVitepress.render(io, mime, node, node.children, page, doc; kwargs...) end function attrs_examples_docs_defaults(type::Type{<:Makie.Block}) @@ -23,7 +23,7 @@ function attrs_examples_docs_defaults(type::Type{<:Makie.Block}) all_docs = Makie._attribute_docs(type) all_defaults = Makie.attribute_default_expressions(type) - (; attrkeys, all_examples, all_docs, all_defaults) + return (; attrkeys, all_examples, all_docs, all_defaults) end function attrs_examples_docs_defaults(type::Type{<:Makie.Plot}) @@ -36,7 +36,7 @@ function attrs_examples_docs_defaults(type::Type{<:Makie.Plot}) all_docs = Dict([(attr => something(meta.docstring, "No docs available.")) for (attr, meta) in metadata]) all_defaults = Dict([(attr => meta.default_expr) for (attr, meta) in metadata]) - (; attrkeys, all_examples, all_docs, all_defaults) + return (; attrkeys, all_examples, all_docs, all_defaults) end function Documenter.Selectors.runner(::Type{AttrdocsBlocks}, node, page, doc) @@ -50,7 +50,7 @@ function Documenter.Selectors.runner(::Type{AttrdocsBlocks}, node, page, doc) for attrkey in attrkeys - heading = @ast MarkdownAST.Heading(3) do + heading = @ast MarkdownAST.Heading(3) do "$attrkey" end push!(node.children, heading) @@ -61,7 +61,7 @@ function Documenter.Selectors.runner(::Type{AttrdocsBlocks}, node, page, doc) MarkdownAST.Code(default_str) end push!(node.children, default_para) - + docs = get(all_docs, attrkey, nothing) docs_md = Markdown.parse(docs) docs_node = convert(MarkdownAST.Node, docs_md) diff --git a/docs/buildutils/deploydocs.jl b/docs/buildutils/deploydocs.jl index baa18395945..6b6a0a7f606 100644 --- a/docs/buildutils/deploydocs.jl +++ b/docs/buildutils/deploydocs.jl @@ -14,7 +14,7 @@ end function deployparameters(; repo, push_preview, devbranch, devurl) cfg = Documenter.GitHubActions() deploy_decision = Documenter.deploy_folder(cfg; repo, push_preview, devbranch, devurl) - (; + return (; all_ok = deploy_decision.all_ok, branch = deploy_decision.branch, repo = deploy_decision.repo, @@ -34,9 +34,9 @@ function deploy(params; root = Documenter.currentdir(), target) deploy_repo = params.repo # Change to the root directory and try to deploy the docs. - cd(root) do + return cd(root) do sha = readchomp(`$(Documenter.git()) rev-parse --short HEAD`) - + @debug "pushing new documentation to remote: '$deploy_repo:$deploy_branch'." mktempdir() do temp push_build(; @@ -56,7 +56,7 @@ end function push_build(; root, temp, repo, - branch="gh-pages", dirname="", target="site", sha="", + branch = "gh-pages", dirname = "", target = "site", sha = "", config, subfolder, is_preview::Bool ) @@ -73,7 +73,7 @@ function push_build(; ) # Generate a closure with common commands for ssh and https - function git_commands(sshconfig=nothing) + function git_commands(sshconfig = nothing) # Setup git. run(`$(git()) init`) run(`$(git()) config user.name "Documenter.jl"`) @@ -115,9 +115,11 @@ function push_build(; Documenter.gitrm_copy(target_dir, deploy_dir) open(joinpath(deploy_dir, "siteinfo.js"), "w") do io - println(io, """ - var DOCUMENTER_CURRENT_VERSION = "$subfolder"; - """) + println( + io, """ + var DOCUMENTER_CURRENT_VERSION = "$subfolder"; + """ + ) end all_folders = [x for x in readdir(dirname) if isdir(joinpath(dirname, x))] @@ -129,10 +131,12 @@ function push_build(; max_version = version_folders[begin] open(joinpath(dirname, "versions.js"), "w") do io - println(io, """ - var DOCUMENTER_NEWEST = "$max_version"; - var DOCUMENTER_STABLE = "stable"; - """) + println( + io, """ + var DOCUMENTER_NEWEST = "$max_version"; + var DOCUMENTER_STABLE = "stable"; + """ + ) println(io, "var DOC_VERSIONS = [") for folder in ["stable"; version_folders; "dev"] @@ -151,7 +155,7 @@ function push_build(; # Add, commit, and push the docs to the remote. run(`$(git()) add -A .`) - if !success(`$(git()) diff --cached --exit-code`) + return if !success(`$(git()) diff --cached --exit-code`) run(`$(git()) commit -m "build based on $sha"`) run(`$(git()) push -q upstream HEAD:$branch`) else @@ -161,23 +165,25 @@ function push_build(; # upstream is used by the closures above, kind of hard to track upstream = Documenter.authenticated_repo_url(config) - try + return try cd(() -> withenv(git_commands, NO_KEY_ENV...), temp) - Documenter.post_status(config; repo=repo, type="success", subfolder=subfolder) + Documenter.post_status(config; repo = repo, type = "success", subfolder = subfolder) catch e - @error "Failed to push:" exception=(e, catch_backtrace()) - Documenter.post_status(config; repo=repo, type="error") + @error "Failed to push:" exception = (e, catch_backtrace()) + Documenter.post_status(config; repo = repo, type = "error") rethrow(e) end end function generate_sitemap(dirname, max_version) folder = joinpath(dirname, max_version) - open(joinpath(dirname, "sitemap.xml"), "w") do io - println(io, """ - - - """) + return open(joinpath(dirname, "sitemap.xml"), "w") do io + println( + io, """ + + + """ + ) for (root, dirs, files) in walkdir(folder) for file in files @@ -185,14 +191,16 @@ function generate_sitemap(dirname, max_version) url = joinpath("https://docs.makie.org/stable", relpath(joinpath(root, file), folder)) # canonical links should not have a trailing `index.html` url = replace(url, r"index\.html$" => "") - println(io, """ - - $url - - """) + println( + io, """ + + $url + + """ + ) end end println(io, "") end -end \ No newline at end of file +end diff --git a/docs/buildutils/redirect_generation.jl b/docs/buildutils/redirect_generation.jl index 75b6bc5e4cd..3b53c66fac1 100644 --- a/docs/buildutils/redirect_generation.jl +++ b/docs/buildutils/redirect_generation.jl @@ -1,10 +1,12 @@ function generate_redirects(rules; dry_run = true) htmlpaths = cd("build") do - collect(Iterators.flatmap(walkdir(".")) do (root, dirs, files) - (chop(joinpath(root, file), head = 1, tail = 0) for file in files if endswith(file, ".html")) - end) + collect( + Iterators.flatmap(walkdir(".")) do (root, dirs, files) + (chop(joinpath(root, file), head = 1, tail = 0) for file in files if endswith(file, ".html")) + end + ) end - redirects_dict = Dict{String,String}() + redirects_dict = Dict{String, String}() for rule in rules for path in htmlpaths redirect_file = replace(path, rule) @@ -19,7 +21,7 @@ function generate_redirects(rules; dry_run = true) strs = ["\"$r\" (redirects to \"$(redirects_dict[r])\")" for r in overwrites] error("The following redirect files would overwrite existing files:\n$(join(strs, "\n"))") end - + for (redirect_file, existing_file) in redirects_dict write_redirection_html(redirect_file, existing_file; dry_run) end @@ -31,30 +33,32 @@ function write_redirection_html(redirect_file, existing_file; dry_run) rel = relpath(existing_file, dirname(redirect_file)) @assert startswith(redirect_file, "/") @assert startswith(existing_file, "/") - + @info "Adding redirect from $redirect_file to $existing_file" if !dry_run cd("build") do filepath = "." * redirect_file mkpath(splitdir(filepath)[1]) open(filepath, "w") do io - print(io, """ - - - - - - - - Page Redirection - - - If you are not redirected automatically, follow this link. - - - """) + print( + io, """ + + + + + + + + Page Redirection + + + If you are not redirected automatically, follow this link. + + + """ + ) end end end diff --git a/docs/copy_changelog.jl b/docs/copy_changelog.jl index 7f507bd5f90..9860545c958 100644 --- a/docs/copy_changelog.jl +++ b/docs/copy_changelog.jl @@ -1,5 +1,5 @@ all_lines = collect(eachline(joinpath("..", "CHANGELOG.md"))) -links = Dict{String,String}() +links = Dict{String, String}() kept_lines = filter(all_lines) do line islink = match(r"\[(Unreleased|\d+\.\d+\.\d+)\]: http.*", line) !== nothing if islink @@ -10,9 +10,13 @@ kept_lines = filter(all_lines) do line end open(joinpath("src", "changelog.md"), "w") do io for line in kept_lines - println(io, replace(line, r"## \[(Unreleased|\d+\.\d+\.\d+)\]" => function (str) - url = links[str[4:end]] - "$str($url)" - end)) + println( + io, replace( + line, r"## \[(Unreleased|\d+\.\d+\.\d+)\]" => function (str) + url = links[str[4:end]] + return "$str($url)" + end + ) + ) end -end \ No newline at end of file +end diff --git a/docs/fake_interaction.jl b/docs/fake_interaction.jl index 6e8cf03be43..929a6fdc699 100644 --- a/docs/fake_interaction.jl +++ b/docs/fake_interaction.jl @@ -31,24 +31,28 @@ function Makie.plot!(p::Cursor) poly = lift(p.width, p.notch, p.shaftwidth, p.shaftlength, p.headlength) do w, draw, wshaft, lshaft, lhead ps = Point2f[ (0, 0), - (-w/2, -lhead), - (-wshaft/2, -lhead+draw), - (-wshaft/2, -lhead-lshaft), - (wshaft/2, -lhead-lshaft), - (wshaft/2, -lhead+draw), - (w/2, -lhead), + (-w / 2, -lhead), + (-wshaft / 2, -lhead + draw), + (-wshaft / 2, -lhead - lshaft), + (wshaft / 2, -lhead - lshaft), + (wshaft / 2, -lhead + draw), + (w / 2, -lhead), ] - angle = asin((-w/2) / (-lhead)) + angle = asin((-w / 2) / (-lhead)) - Makie.Polygon(map(ps) do point - Makie.Mat2f(cos(angle), sin(angle), -sin(angle), cos(angle)) * point - end) + Makie.Polygon( + map(ps) do point + Makie.Mat2f(cos(angle), sin(angle), -sin(angle), cos(angle)) * point + end + ) end - scatter!(p, p[1], marker = poly, markersize = p.multiplier, color = p.color, strokecolor = p.strokecolor, strokewidth = p.strokewidth, - glowcolor = (:black, 0.10), glowwidth = 2, transform_marker = true) - + scatter!( + p, p[1], marker = poly, markersize = p.multiplier, color = p.color, strokecolor = p.strokecolor, strokewidth = p.strokewidth, + glowcolor = (:black, 0.1), glowwidth = 2, transform_marker = true + ) + return p end @@ -58,7 +62,7 @@ end struct MouseTo{T} target::T - duration::Union{Nothing,Float64} + duration::Union{Nothing, Float64} end MouseTo(target) = MouseTo(target, nothing) @@ -71,17 +75,17 @@ function mousepositions_frame(m::MouseTo, startpos, t) keyframe_to = Animations.Keyframe(dur, Point2f(m.target)) pos = Animations.interpolate(saccadic(2), t, keyframe_from, keyframe_to) - [pos] + return [pos] end function mousepositions_end(m::MouseTo, startpos) - [m.target] + return [m.target] end duration(mouseto::MouseTo, prev_position) = mouseto.duration === nothing ? automatic_duration(mouseto, prev_position) : mouseto.duration function automatic_duration(mouseto::MouseTo, prev_position) dist = sqrt(+(((mouseto.target .- prev_position) .^ 2)...)) - 0.6 + dist / 1000 * 0.5 + return 0.6 + dist / 1000 * 0.5 end struct Wait @@ -251,4 +255,4 @@ interaction_record(figlike, filepath, events::AbstractVector; kwargs...) = inter relative_pos(block, rel) = Point2f(block.layoutobservables.computedbbox[].origin .+ rel .* block.layoutobservables.computedbbox[].widths) -end \ No newline at end of file +end diff --git a/docs/figure_block.jl b/docs/figure_block.jl index 30a3db017d0..da492c46ca2 100644 --- a/docs/figure_block.jl +++ b/docs/figure_block.jl @@ -1,8 +1,8 @@ abstract type FigureBlocks <: Documenter.Expanders.NestedExpanderPipeline end -Documenter.Selectors.order(::Type{FigureBlocks}) = 8.0 # like @example -Documenter.Selectors.matcher(::Type{FigureBlocks}, node, page, doc) = Documenter.iscode(node, r"^@figure") +Documenter.Selectors.order(::Type{FigureBlocks}) = 8.0 # like @example +Documenter.Selectors.matcher(::Type{FigureBlocks}, node, page, doc) = Documenter.iscode(node, r"^@figure") module MakieDocsHelpers import ImageTransformations @@ -11,7 +11,7 @@ module MakieDocsHelpers struct Png bytes::Vector{UInt8} - size_px::Tuple{Int,Int} + size_px::Tuple{Int, Int} id::String end @@ -20,14 +20,14 @@ module MakieDocsHelpers title::String end - FIGURES = Dict{PageInfo,Vector{Png}}() - struct AsMIME{M<:MIME,V} + FIGURES = Dict{PageInfo, Vector{Png}}() + struct AsMIME{M <: MIME, V} mime::M value::V end - Base.show(io::IO, m::MIME"image/svg+xml", a::AsMIME{MIME"image/svg+xml"}) = show(io,m, a.value) - Base.show(io::IO, m::MIME"image/png", a::AsMIME{MIME"image/png"}) = show(io,m, a.value) + Base.show(io::IO, m::MIME"image/svg+xml", a::AsMIME{MIME"image/svg+xml"}) = show(io, m, a.value) + Base.show(io::IO, m::MIME"image/png", a::AsMIME{MIME"image/png"}) = show(io, m, a.value) function register_figure!(page, pagetitle, id, figurelike) vec = get!(Vector, FIGURES, PageInfo(page, pagetitle)) @@ -39,7 +39,7 @@ module MakieDocsHelpers size_px = Tuple(round.(Int, reverse(size(img)) ./ px_per_unit)) ntrim = 3 # `restrict` makes dark border pixels which we cut off - img = @view ImageTransformations.restrict(img)[ntrim:end-ntrim,ntrim:end-ntrim] + img = @view ImageTransformations.restrict(img)[ntrim:(end - ntrim), ntrim:(end - ntrim)] # img = @view ImageTransformations.restrict(img)[ntrim:end-ntrim,ntrim:end-ntrim] io = IOBuffer() FileIO.save(FileIO.Stream{FileIO.format"PNG"}(Makie.raw_io(io)), img) @@ -50,10 +50,10 @@ module MakieDocsHelpers struct FileInfo filename::String id::String - size_px::Tuple{Int,Int} + size_px::Tuple{Int, Int} end struct OverviewSection - d::Dict{PageInfo,Vector{FileInfo}} + d::Dict{PageInfo, Vector{FileInfo}} end function OverviewSection(page::String) @@ -63,7 +63,7 @@ module MakieDocsHelpers match(r, pageinfo.path) !== nothing end - fileinfo_dict = Dict{PageInfo,Vector{FileInfo}}() + fileinfo_dict = Dict{PageInfo, Vector{FileInfo}}() for (pageinfo, pngs) in pairs(filtered) fileinfos = map(pngs) do png filename = "$(string(hash(png.bytes), base = 62)).png" @@ -75,7 +75,7 @@ module MakieDocsHelpers fileinfo_dict[pageinfo] = fileinfos end - OverviewSection(fileinfo_dict) + return OverviewSection(fileinfo_dict) end function Base.show(io::IO, ::MIME"text/markdown", o::OverviewSection) @@ -87,45 +87,51 @@ module MakieDocsHelpers println(io) println(io, """
""") for fileinfo in fileinfos - println(io, """ - - - - """) + println( + io, """ + + + + """ + ) end println(io, "
") println(io) end - println(io, """ - - """) + + """ + ) end end function Documenter.Selectors.runner(::Type{FigureBlocks}, node, page, doc) - title = first(Iterators.filter(page.elements) do el - el isa Markdown.Header{1} - end).text[] + title = first( + Iterators.filter(page.elements) do el + el isa Markdown.Header{1} + end + ).text[] el = node.element infoexpr = Meta.parse(el.info) @@ -153,12 +159,14 @@ function Documenter.Selectors.runner(::Type{FigureBlocks}, node, page, doc) end end - kwargs = Dict(map(kwargs) do expr - if !(expr isa Expr) && expr.head !== :(=) && length(expr.args) == 2 && expr.args[1] isa Symbol && expr.args[2] isa Union{String,Number,Symbol} - error("Invalid keyword arg expression: $expr") + kwargs = Dict( + map(kwargs) do expr + if !(expr isa Expr) && expr.head !== :(=) && length(expr.args) == 2 && expr.args[1] isa Symbol && expr.args[2] isa Union{String, Number, Symbol} + error("Invalid keyword arg expression: $expr") + end + expr.args[1] => expr.args[2] end - expr.args[1] => expr.args[2] - end) + ) el.info = "@example $blockname" id = string(hash(el.code), base = 16)[1:7] @@ -177,24 +185,26 @@ function Documenter.Selectors.runner(::Type{FigureBlocks}, node, page, doc) # this makes images look sharp as intended, and it improves the accuracy with which one gets to # image examples from the overview pages, as with annotated width and height the right locations can # be computed even before all the images have been loaded. Otherwise they are usually wrong the first time. - MarkdownAST.insert_after!(node, @ast Documenter.RawNode(:html, "")) + return MarkdownAST.insert_after!(node, @ast Documenter.RawNode(:html, "")) end -function transform_figure_code(code::String; id::String, page::String, pagetitle::String, is_continued::Bool, backend::Symbol = :CairoMakie, mime=:png) +function transform_figure_code(code::String; id::String, page::String, pagetitle::String, is_continued::Bool, backend::Symbol = :CairoMakie, mime = :png) backend in (:CairoMakie, :GLMakie) || error("Invalid backend $backend") mimetype = mime == :svg ? "image/svg+xml" : mime == :png ? "image/png" : error("Unknown mimetype $mime") - (is_continued ? "" : """ - using $backend - $backend.activate!(; px_per_unit = 2) # hide - """) * - """ - import ..MakieDocsHelpers # hide - var"#result" = begin # hide - $code - end # hide - MakieDocsHelpers.register_figure!("$page", "$pagetitle", "$id", var"#result") # hide - save("$id.$mime", var"#result") # hide - nothing # hide - """ -end \ No newline at end of file + return ( + is_continued ? "" : """ + using $backend + $backend.activate!(; px_per_unit = 2) # hide + """ + ) * + """ + import ..MakieDocsHelpers # hide + var"#result" = begin # hide + $code + end # hide + MakieDocsHelpers.register_figure!("$page", "$pagetitle", "$id", var"#result") # hide + save("$id.$mime", var"#result") # hide + nothing # hide + """ +end diff --git a/docs/makedocs.jl b/docs/makedocs.jl index d7f0b9e3cd7..2c58d514f35 100644 --- a/docs/makedocs.jl +++ b/docs/makedocs.jl @@ -53,7 +53,7 @@ function nested_filter(x, regex) _match(x::Pair) = x[2] isa String ? match(regex, x[2]) !== nothing : true fn(el::Pair) = el[2] isa Vector ? el[1] => nested_filter(el[2], regex) : el fn(el) = el - filter(_match, map(fn, x)) + return filter(_match, map(fn, x)) end unnest(vec::Vector) = collect(Iterators.flatten([unnest(el) for el in vec])) @@ -141,13 +141,13 @@ pages = [ ], "Generic Concepts" => [ "reference/generic/clip_planes.md", - "reference/generic/transformations.md" + "reference/generic/transformations.md", ], "Scene" => [ "reference/scene/lighting.md", "reference/scene/matcap.md", "reference/scene/SSAO.md", - ] + ], ], "Tutorials" => [ "tutorials/getting-started.md", @@ -198,15 +198,15 @@ pages = [ "API" => "api.md", "Changelog" => "changelog.md", "Ecosystem" => "ecosystem.md", - ] + ], ] function make_docs(; pages) empty!(MakieDocsHelpers.FIGURES) - Documenter.makedocs(; - sitename="Makie", - format=DocumenterVitepress.MarkdownVitepress(; + return Documenter.makedocs(; + sitename = "Makie", + format = DocumenterVitepress.MarkdownVitepress(; repo = "github.com/MakieOrg/Makie.jl", devurl = "dev", devbranch = "master", @@ -230,18 +230,20 @@ make_docs(; # DocumenterVitepress moves rendered files from `build/final_site` into `build` on CI by default, but not when running locally -generate_redirects([ - r"/reference/blocks/(.*).html" => s"/examples/blocks/\1/index.html", - r"/reference/blocks/(.*).html" => s"/reference/blocks/\1/index.html", - r"/reference/plots/(.*).html" => s"/examples/plotting_functions/\1/index.html", - r"/reference/plots/(.*).html" => s"/reference/plots/\1/index.html", - r"/explanations/(.*).html" => s"/documentation/\1/index.html", - r"/tutorials/(.*).html" => s"/tutorials/\1/index.html", - r"/explanations/(.*).html" => s"/explanations/\1/index.html", - "/explanations/observables.html" => "/explanations/nodes/index.html", - "/reference/plots/overview.html" => "/reference/plots/index.html", - "/reference/blocks/overview.html" => "/reference/blocks/index.html", - "/tutorials/getting-started.html" => "/tutorials/basic-tutorial.html", -], dry_run = false) +generate_redirects( + [ + r"/reference/blocks/(.*).html" => s"/examples/blocks/\1/index.html", + r"/reference/blocks/(.*).html" => s"/reference/blocks/\1/index.html", + r"/reference/plots/(.*).html" => s"/examples/plotting_functions/\1/index.html", + r"/reference/plots/(.*).html" => s"/reference/plots/\1/index.html", + r"/explanations/(.*).html" => s"/documentation/\1/index.html", + r"/tutorials/(.*).html" => s"/tutorials/\1/index.html", + r"/explanations/(.*).html" => s"/explanations/\1/index.html", + "/explanations/observables.html" => "/explanations/nodes/index.html", + "/reference/plots/overview.html" => "/reference/plots/index.html", + "/reference/blocks/overview.html" => "/reference/blocks/index.html", + "/tutorials/getting-started.html" => "/tutorials/basic-tutorial.html", + ], dry_run = false +) deploy(params; target = "build") diff --git a/docs/misc/banner/banner.jl b/docs/misc/banner/banner.jl index e67d6c9dd91..6ac43ad4e4c 100644 --- a/docs/misc/banner/banner.jl +++ b/docs/misc/banner/banner.jl @@ -5,7 +5,7 @@ GLMakie.activate!() function copy_scene_settings(s) cc = cameracontrols(s) - ( + return ( viewport = s.viewport[], eyeposition = cc.eyeposition[], lookat = cc.lookat[], @@ -37,8 +37,10 @@ end ## s = Scene(camera = cam3d!, show_axis = false, center = false) r = range(-2, 15, length = 60) -wireframe!(s, r, r, ((x, y) -> sin(x) * cos(y) * max((x - 2) / 7, 0)).(r, (r)'), - transparency = true) +wireframe!( + s, r, r, ((x, y) -> sin(x) * cos(y) * max((x - 2) / 7, 0)).(r, (r)'), + transparency = true +) apply_camera_settings!(s, settings) @@ -50,7 +52,6 @@ s settings = copy_scene_settings(s) - ## settingsfile = joinpath(@__DIR__, "camerasettings.txt") diff --git a/docs/misc/mandelbrot/mandelbrot_video.jl b/docs/misc/mandelbrot/mandelbrot_video.jl index b909d7aa75a..41dc73ffaa7 100644 --- a/docs/misc/mandelbrot/mandelbrot_video.jl +++ b/docs/misc/mandelbrot/mandelbrot_video.jl @@ -1,13 +1,18 @@ function mandelbrot(x, y) - z = c = x + y*im - for i in 1:100.0; abs(z) > 2 && return i; z = z^2 + c; end; 0 + z = c = x + y * im + for i in 1:100.0 + abs(z) > 2 && return i; z = z^2 + c + end + return 0 end x = Observable(range(-2, 1, length = 400)) y = Observable(range(-1, 1, length = 300)) -fig, ax, img = heatmap(x, y, mandelbrot, colormap = Reverse(:deep), - figure = (size = (400, 300),)) +fig, ax, img = heatmap( + x, y, mandelbrot, colormap = Reverse(:deep), + figure = (size = (400, 300),) +) hidedecorations!(ax) record(fig, "mandelbrot.mp4", 1:200) do frame diff --git a/docs/shortdocs_block.jl b/docs/shortdocs_block.jl index 5e94c054f5d..f6bc4044679 100644 --- a/docs/shortdocs_block.jl +++ b/docs/shortdocs_block.jl @@ -1,8 +1,8 @@ abstract type ShortDocsBlocks <: Documenter.Expanders.NestedExpanderPipeline end -Documenter.Selectors.order(::Type{ShortDocsBlocks}) = 3.0 # like @docs -Documenter.Selectors.matcher(::Type{ShortDocsBlocks}, node, page, doc) = Documenter.iscode(node, r"^@shortdocs") +Documenter.Selectors.order(::Type{ShortDocsBlocks}) = 3.0 # like @docs +Documenter.Selectors.matcher(::Type{ShortDocsBlocks}, node, page, doc) = Documenter.iscode(node, r"^@shortdocs") function unlink_with_all_following_siblings!(node) next = node.next @@ -47,4 +47,5 @@ function Documenter.Selectors.runner(::Type{ShortDocsBlocks}, node, page, doc) error("Found no Attributes section in above markdown ast") end end + return end diff --git a/docs/src/explanations/colormap_generation.jl b/docs/src/explanations/colormap_generation.jl index 161bab192d9..82650a1e03a 100644 --- a/docs/src/explanations/colormap_generation.jl +++ b/docs/src/explanations/colormap_generation.jl @@ -17,7 +17,7 @@ function colors_svg(key::Symbol, cs, w, h; categorical) if categorical for (i, c) in enumerate(cs) html *= """ - + """ end else @@ -73,4 +73,3 @@ struct ColorTable end Base.show(io::IO, ::MIME"text/html", c::ColorTable) = print(io, generate_colorschemes_table(c.keys)) - diff --git a/docs/src/reference/plotting-2.7-billion-points.jl b/docs/src/reference/plotting-2.7-billion-points.jl index c9ae61305c1..77c49cab2c8 100644 --- a/docs/src/reference/plotting-2.7-billion-points.jl +++ b/docs/src/reference/plotting-2.7-billion-points.jl @@ -20,16 +20,20 @@ function uuwrite(io, ref::Base.RefValue{T}) where {T} return ccall(:ios_write, Csize_t, (Ptr{Nothing}, Ptr{T}, Csize_t), io.ios, ref, sizeof(T)) end -function save2bin(path, n=typemax(Int)) +function save2bin(path, n = typemax(Int)) str = MMapString(path) # Parser descriptor of 'num,num,num\n' which is the format in the csv - rec = Record((Field(Numeric(Float32)), - Field(Numeric(Float32)), - Field(Numeric(Float32); eoldelim=true))) + rec = Record( + ( + Field(Numeric(Float32)), + Field(Numeric(Float32)), + Field(Numeric(Float32); eoldelim = true), + ) + ) # skip the header... pos = findfirst(x -> x == '\n', str) + 1 # Nice thing is Julia's findfirst works with any iterator io = open("gpspoints.bin", "w") - ref = Base.RefValue{NTuple{2,Float32}}() + ref = Base.RefValue{NTuple{2, Float32}}() @inbounds while pos < length(str) p_or_null, pos = tryparsenext(rec, str, pos, length(str)) isnull(p_or_null) && continue @@ -49,19 +53,21 @@ path = "gpspoints.bin" points = Mmap.mmap(open(path, "r"), Vector{Point2f}); # ~ 26s @time begin - f, ax, pl = datashader(points; - # For a big dataset its interesting to see how long each aggregation takes - show_timings=true, - # Use a local operation which is faster to calculate and looks good! - local_post=x -> log10(x + 1), - #= + f, ax, pl = datashader( + points; + # For a big dataset its interesting to see how long each aggregation takes + show_timings = true, + # Use a local operation which is faster to calculate and looks good! + local_post = x -> log10(x + 1), + #= in the code we used to save the binary, we had the points in the wrong order. A good chance to demonstrate the `point_func` argument, Which gets applied to every point before aggregating it =# - point_func=reverse, - axis=(; type=Axis, autolimitaspect=1), - figure=(; figure_padding=0, size=(1200, 600))) + point_func = reverse, + axis = (; type = Axis, autolimitaspect = 1), + figure = (; figure_padding = 0, size = (1200, 600)) + ) hidedecorations!(ax) hidespines!(ax) display(f) diff --git a/metrics/collect_metrics.jl b/metrics/collect_metrics.jl index b0e34978f14..4a1074d98f8 100644 --- a/metrics/collect_metrics.jl +++ b/metrics/collect_metrics.jl @@ -47,8 +47,9 @@ for metric_target in metric_targets glmakieversion = match(r"version = \"(.*?)\"", read("GLMakie/Project.toml", String))[1] cairomakieversion = match(r"version = \"(.*?)\"", read("CairoMakie/Project.toml", String))[1] commit_date = DateTime( - strip(String(read(`git show -s --format=%ci`)))[1:end-6], - "yyyy-mm-dd HH:MM:SS") + strip(String(read(`git show -s --format=%ci`)))[1:(end - 6)], + "yyyy-mm-dd HH:MM:SS" + ) df = DataFrame() date = now() @@ -83,19 +84,21 @@ for metric_target in metric_targets include_string(Main, p) end - push!(df, ( - date = date, - commit_date = commit_date, - metric_target = metric_target, - juliaversion = string(Sys.VERSION), - makie = makieversion, - glmakie = glmakieversion, - cairomakie = cairomakieversion, - name = partname, - time = timing.time, - allocations = timing.bytes, - gc_time = timing.gctime, - )) + push!( + df, ( + date = date, + commit_date = commit_date, + metric_target = metric_target, + juliaversion = string(Sys.VERSION), + makie = makieversion, + glmakie = glmakieversion, + cairomakie = cairomakieversion, + name = partname, + time = timing.time, + allocations = timing.bytes, + gc_time = timing.gctime, + ) + ) end finally diff --git a/metrics/ttfp/benchmark-ttfp.jl b/metrics/ttfp/benchmark-ttfp.jl index 22d0841360c..c940d056f28 100644 --- a/metrics/ttfp/benchmark-ttfp.jl +++ b/metrics/ttfp/benchmark-ttfp.jl @@ -15,12 +15,12 @@ if Package === :WGLMakie Bonito.use_electron_display() end -set_theme!(size=(800, 600)) +set_theme!(size = (800, 600)) GC.gc() -create_time = @ctime fig = scatter(1:4; color=1:4, colormap=:turbo, markersize=20, visible=true) +create_time = @ctime fig = scatter(1:4; color = 1:4, colormap = :turbo, markersize = 20, visible = true) GC.gc() -display_time = @ctime colorbuffer(fig; px_per_unit=1) +display_time = @ctime colorbuffer(fig; px_per_unit = 1) using JSON using Pkg @@ -41,7 +41,7 @@ macro simple_median_time(expr) Float64(elapsedtime) end - quote + return quote times = Float64[] for i in 1:101 t = Core.eval(Main, $(QuoteNode(time_expr))) @@ -52,16 +52,16 @@ macro simple_median_time(expr) median(times) end end -@time "creating figure" figure_time = @simple_median_time fig = scatter(1:4; color=1:4, colormap=:turbo, markersize=20, visible=true) -fig = scatter(1:4; color=1:4, colormap=:turbo, markersize=20, visible=true) -@time "colorbuffer" colorbuffer_time = @simple_median_time colorbuffer(fig; px_per_unit=1) +@time "creating figure" figure_time = @simple_median_time fig = scatter(1:4; color = 1:4, colormap = :turbo, markersize = 20, visible = true) +fig = scatter(1:4; color = 1:4, colormap = :turbo, markersize = 20, visible = true) +@time "colorbuffer" colorbuffer_time = @simple_median_time colorbuffer(fig; px_per_unit = 1) using Statistics push!(old[4], figure_time) push!(old[5], colorbuffer_time) -open(io-> JSON.print(io, old), result, "w") +open(io -> JSON.print(io, old), result, "w") try rm("test.png") diff --git a/metrics/ttfp/run-benchmark.jl b/metrics/ttfp/run-benchmark.jl index e1c193d73c5..ec5934f74c4 100644 --- a/metrics/ttfp/run-benchmark.jl +++ b/metrics/ttfp/run-benchmark.jl @@ -2,140 +2,144 @@ 1) Use one GH-Action job in the end to merge all results and comment in one go (instead of merging with existing comment) 2) Improve analysis of benchmark resutls to account for the variance in the benchmarks. 3) Upload raw benchmark data as artifacts to e.g. create plots from It -=# - -using Pkg -Pkg.activate(@__DIR__) -Pkg.instantiate() -pkg"registry up" -Pkg.update() - -using JSON, AlgebraOfGraphics, CairoMakie, DataFrames, Bootstrap -using Statistics: median -Package = ARGS[1] -n_samples = length(ARGS) > 1 ? parse(Int, ARGS[2]) : 7 -base_branch = length(ARGS) > 2 ? ARGS[3] : "master" - -# Package = "CairoMakie" -# n_samples = 2 -# base_branch = "breaking-release" - -@info("Benchmarking $(Package) against $(base_branch) with $(n_samples) samples") - - -function run_benchmarks(projects; n=n_samples) - benchmark_file = joinpath(@__DIR__, "benchmark-ttfp.jl") - # go A, A, B, B, A, A, B, B, etc. because if A or B have some effect on their - # subsequent run, then we distribute those more evenly. If we used A, B, A, B then - # B would always influence A and A always B which might bias the results (something - # that can carry over separate processes like thermal throttling or so) - - A, B = projects - As = Iterators.partition(fill(A, n), 2) - Bs = Iterators.partition(fill(B, n), 2) - - for project in Iterators.flatten(Iterators.flatten(zip(As, Bs))) - println(basename(project)) - run(`$(Base.julia_cmd()) --startup-file=no --project=$(project) $benchmark_file $Package`) - end - return -end - -function make_project_folder(name) - result = "$name-benchmark.json" - isfile(result) && rm(result) # remove old benchmark resutls - project = joinpath(@__DIR__, "benchmark-projects", name) - # It seems, that between julia versions, the manifest must be deleted to not get problems - isdir(project) && rm(project; force=true, recursive=true) - mkpath(project) - return project -end - - -ENV["JULIA_PKG_PRECOMPILE_AUTO"] = 0 -project1 = make_project_folder("current-pr") -Pkg.activate(project1) -if Package == "WGLMakie" - Pkg.add([(; name="Electron")]) -end -pkgs = NamedTuple[(; path="./MakieCore"), (; path="."), (; path="./$Package")] -# cd("dev/Makie") -Pkg.develop(pkgs) -Pkg.add([(; name="JSON")]) - -@time Pkg.precompile() - -project2 = make_project_folder(base_branch) -Pkg.activate(project2) -pkgs = [(; rev=base_branch, name="MakieCore"), (; rev=base_branch, name="Makie"), (; rev=base_branch, name="$Package"), (;name="JSON")] -Package == "WGLMakie" && push!(pkgs, (; name="Electron")) -Pkg.add(pkgs) - -@time Pkg.precompile() - -projects = [project1, project2] -projnames = map(basename, [project1, project2]) - -run_benchmarks(projects) - -json_files = map(projnames) do pname - "$(pname)-benchmark.json" -end - -colnames = ["using", "first create", "first display", "create", "display"] - -df = reduce(vcat, map(json_files, projnames) do filename, pname - arrs = map(x -> map(identity, x), JSON.parsefile(filename)) - df = DataFrame(colnames .=> arrs) - df.name .= pname - df - end) - -## - -fgrid = AlgebraOfGraphics.data(df) * - mapping(:name, colnames .=> (x -> x / 1e9) .=> "time (s)", color = :name, layout = dims(1) => renamer(colnames)) * - visual(RainClouds, orientation = :horizontal, markersize = 5, show_median = false, plot_boxplots = false) |> - draw( - scales(Color = (; legend = false)), - facet = (; linkxaxes = false), - axis = (; xticklabelrotation = pi/4, width = 200, height = 150), - figure = (; title = "$Package Benchmarks") - ) - -df_current_pr = df[df.name .== projnames[1], :] -df_base_branch = df[df.name .== projnames[2], :] - -medians_df = map(names(df_current_pr, Not(:name))) do colname - col_base = df_base_branch[!, colname] - col_pr = df_current_pr[!, colname] - medians_base = bootstrap(median, col_base, Bootstrap.BasicSampling(1000)) - medians_pr = bootstrap(median, col_pr, Bootstrap.BasicSampling(1000)) - ratios = Bootstrap.straps(medians_pr)[1] ./ Bootstrap.straps(medians_base)[1] - colname => ratios -end |> DataFrame - -specmedians = AlgebraOfGraphics.data(stack(medians_df)) * - mapping(:variable => presorted => "", :value => "Ratios of medians\n$(projnames[1]) / $(projnames[2])") * visual(Violin, show_median = true) - -background_bands = AlgebraOfGraphics.pregrouped([0.75:0.05:1.20], [0.8:0.05:1.25]) * - AlgebraOfGraphics.visual(HSpan, color = range(-1, 1, length = 10), colormap = [:green, :white, :tomato], alpha = 0.5) - -zeroline = AlgebraOfGraphics.pregrouped([1]) * AlgebraOfGraphics.visual(HLines, color = :gray60) - -spec = background_bands + zeroline + specmedians - -AlgebraOfGraphics.draw!(fgrid.figure[2, 3], spec, axis = (; - yaxisposition = :right, - xticklabelrotation = pi/4, - title = "Bootstrapped median ratios", - yautolimitmargin = (0, 0), - yticks = WilkinsonTicks(7, k_min = 5), -)) - -resize_to_layout!(fgrid.figure) - -## - -mkpath("benchmark_results") -save(joinpath("benchmark_results", "$Package.svg"), fgrid) +=# + +using Pkg +Pkg.activate(@__DIR__) +Pkg.instantiate() +pkg"registry up" +Pkg.update() + +using JSON, AlgebraOfGraphics, CairoMakie, DataFrames, Bootstrap +using Statistics: median +Package = ARGS[1] +n_samples = length(ARGS) > 1 ? parse(Int, ARGS[2]) : 7 +base_branch = length(ARGS) > 2 ? ARGS[3] : "master" + +# Package = "CairoMakie" +# n_samples = 2 +# base_branch = "breaking-release" + +@info("Benchmarking $(Package) against $(base_branch) with $(n_samples) samples") + + +function run_benchmarks(projects; n = n_samples) + benchmark_file = joinpath(@__DIR__, "benchmark-ttfp.jl") + # go A, A, B, B, A, A, B, B, etc. because if A or B have some effect on their + # subsequent run, then we distribute those more evenly. If we used A, B, A, B then + # B would always influence A and A always B which might bias the results (something + # that can carry over separate processes like thermal throttling or so) + + A, B = projects + As = Iterators.partition(fill(A, n), 2) + Bs = Iterators.partition(fill(B, n), 2) + + for project in Iterators.flatten(Iterators.flatten(zip(As, Bs))) + println(basename(project)) + run(`$(Base.julia_cmd()) --startup-file=no --project=$(project) $benchmark_file $Package`) + end + return +end + +function make_project_folder(name) + result = "$name-benchmark.json" + isfile(result) && rm(result) # remove old benchmark resutls + project = joinpath(@__DIR__, "benchmark-projects", name) + # It seems, that between julia versions, the manifest must be deleted to not get problems + isdir(project) && rm(project; force = true, recursive = true) + mkpath(project) + return project +end + + +ENV["JULIA_PKG_PRECOMPILE_AUTO"] = 0 +project1 = make_project_folder("current-pr") +Pkg.activate(project1) +if Package == "WGLMakie" + Pkg.add([(; name = "Electron")]) +end +pkgs = NamedTuple[(; path = "./MakieCore"), (; path = "."), (; path = "./$Package")] +# cd("dev/Makie") +Pkg.develop(pkgs) +Pkg.add([(; name = "JSON")]) + +@time Pkg.precompile() + +project2 = make_project_folder(base_branch) +Pkg.activate(project2) +pkgs = [(; rev = base_branch, name = "MakieCore"), (; rev = base_branch, name = "Makie"), (; rev = base_branch, name = "$Package"), (; name = "JSON")] +Package == "WGLMakie" && push!(pkgs, (; name = "Electron")) +Pkg.add(pkgs) + +@time Pkg.precompile() + +projects = [project1, project2] +projnames = map(basename, [project1, project2]) + +run_benchmarks(projects) + +json_files = map(projnames) do pname + "$(pname)-benchmark.json" +end + +colnames = ["using", "first create", "first display", "create", "display"] + +df = reduce( + vcat, map(json_files, projnames) do filename, pname + arrs = map(x -> map(identity, x), JSON.parsefile(filename)) + df = DataFrame(colnames .=> arrs) + df.name .= pname + df + end +) + +## + +fgrid = AlgebraOfGraphics.data(df) * + mapping(:name, colnames .=> (x -> x / 1.0e9) .=> "time (s)", color = :name, layout = dims(1) => renamer(colnames)) * + visual(RainClouds, orientation = :horizontal, markersize = 5, show_median = false, plot_boxplots = false) |> + draw( + scales(Color = (; legend = false)), + facet = (; linkxaxes = false), + axis = (; xticklabelrotation = pi / 4, width = 200, height = 150), + figure = (; title = "$Package Benchmarks") +) + +df_current_pr = df[df.name .== projnames[1], :] +df_base_branch = df[df.name .== projnames[2], :] + +medians_df = map(names(df_current_pr, Not(:name))) do colname + col_base = df_base_branch[!, colname] + col_pr = df_current_pr[!, colname] + medians_base = bootstrap(median, col_base, Bootstrap.BasicSampling(1000)) + medians_pr = bootstrap(median, col_pr, Bootstrap.BasicSampling(1000)) + ratios = Bootstrap.straps(medians_pr)[1] ./ Bootstrap.straps(medians_base)[1] + colname => ratios +end |> DataFrame + +specmedians = AlgebraOfGraphics.data(stack(medians_df)) * + mapping(:variable => presorted => "", :value => "Ratios of medians\n$(projnames[1]) / $(projnames[2])") * visual(Violin, show_median = true) + +background_bands = AlgebraOfGraphics.pregrouped([0.75:0.05:1.2], [0.8:0.05:1.25]) * + AlgebraOfGraphics.visual(HSpan, color = range(-1, 1, length = 10), colormap = [:green, :white, :tomato], alpha = 0.5) + +zeroline = AlgebraOfGraphics.pregrouped([1]) * AlgebraOfGraphics.visual(HLines, color = :gray60) + +spec = background_bands + zeroline + specmedians + +AlgebraOfGraphics.draw!( + fgrid.figure[2, 3], spec, axis = (; + yaxisposition = :right, + xticklabelrotation = pi / 4, + title = "Bootstrapped median ratios", + yautolimitmargin = (0, 0), + yticks = WilkinsonTicks(7, k_min = 5), + ) +) + +resize_to_layout!(fgrid.figure) + +## + +mkpath("benchmark_results") +save(joinpath("benchmark_results", "$Package.svg"), fgrid) diff --git a/precompile/shared-precompile.jl b/precompile/shared-precompile.jl index 00170acc780..6d91824799f 100644 --- a/precompile/shared-precompile.jl +++ b/precompile/shared-precompile.jl @@ -1,109 +1,115 @@ -# File to run to snoop/trace all functions to compile -using GeometryBasics - -@compile scatter(1:4; color=1:4, colormap=:turbo, markersize=20, visible=true) - -@compile poly(Recti(0, 0, 200, 200), strokewidth=20, strokecolor=:red, color=(:black, 0.4)) - -@compile scatter(0..1, rand(10), markersize=rand(10) .* 20) -@compile scatter(LinRange(0, 1, 10), rand(10)) -@compile scatter(-1..1, x -> x^2) - -@compile begin - f, ax, pl = lines(Rect(0, 0, 1, 1), linewidth=4) - scatter!([Point2f(0.5, 0.5)], markersize=1, markerspace=:data, marker='I') - f -end - -@compile lines(rand(10), rand(10), color=rand(10), linewidth=10) -@compile lines(rand(10), rand(10), color=rand(RGBAf, 10), linewidth=10) -@compile lines(Circle(Point2f(0), Float32(1))) -@compile lines(-1..1, x -> x^2) - -@compile heatmap(rand(50, 50), colormap=(:RdBu, 0.2)) - -@compile contour(randn(100, 90), levels=3) -@compile contour(randn(33, 30), levels=[0.1, 0.5, 0.9], color=[:black, :green, (:blue, 0.4)], linewidth=2) - -@compile meshscatter(rand(10), rand(10), rand(10), color=rand(10)) -@compile meshscatter(rand(Point3f, 10), color=rand(RGBAf, 10), transparency=true) - -@compile begin - l = range(-10, stop=10, length=10) - surface(l, l, rand(10, 10), colormap=:Spectral) -end - -@compile begin - NL = 30 - NR = 31 - - l = range(0, stop=3, length=NL) - r = range(0, stop=3, length=NR) - surface( - [l for l in l, r in r], [r for l in l, r in r], rand(NL, NR), - colormap=:Spectral - ) -end - -@compile begin - heatmap(rand(10, 5), axis = (yscale = log10, xscale=log10)) -end - -@compile begin - x = [1 0 - 2 3] - heatmap(1:2, 1:-1:0, x) -end - -@compile begin - res = 200 - s = Scene(camera=campixel!, size=(res, res)) - half = res / 2 - linewidth = 10 - xstart = half - (half/2) - xend = xstart + 100 - half_w = linewidth/2 - - lines!(s, Point2f[(xstart, half), (xend, half)], linewidth=linewidth) - scatter!(s, Point2f[(xstart, half + half_w), (xstart, half - half_w), (xend, half + half_w), (xend, half - half_w)], color=:red, markersize=2) - - l2 = linesegments!(s, Point2f[(xstart, half), (xend, half)], linewidth=linewidth, color=:gray) - s2 = scatter!(s, Point2f[(xstart, half + half_w), (xstart, half - half_w), (xend, half + half_w), (xend, half - half_w)], color=:red, markersize=2) - - for p in (l2, s2) - translate!(p, 0, 20, 0) - end - - s -end - -@compile begin - P = Polygon.([Point2f[[0.45, 0.05], [0.64, 0.15], [0.37, 0.62]], - Point2f[[0.32, 0.66], [0.46, 0.59], [0.09, 0.08]]]) - poly(P, color = [:red, :green], strokecolor = [:blue, :red], strokewidth = 2) -end - -@compile begin - meshscatter(rand(Point3f, 10), axis=(type=Axis3,)) -end - -@compile begin - f = Figure() - ax = Makie.Axis(f) - Makie.Toggle(f) - Makie.Slider(f) - Makie.LScene(f) - Makie.PolarAxis(f) - Makie.IntervalSlider(f) - lines!(ax, 1:2, label = "Line") - Makie.Legend(f, ax, "Default", nbanks = 2) - Makie.Box(f) - Makie.Label(f) - Makie.Textbox(f) - Makie.Axis3(f) - Makie.Colorbar(f) - Makie.Button(f) - Makie.Menu(f, options=["one"]) - Makie.SliderGrid(f, (label = "Label", range = 0:1:2, startvalue = 1)) - f -end +# File to run to snoop/trace all functions to compile +using GeometryBasics + +@compile scatter(1:4; color = 1:4, colormap = :turbo, markersize = 20, visible = true) + +@compile poly(Recti(0, 0, 200, 200), strokewidth = 20, strokecolor = :red, color = (:black, 0.4)) + +@compile scatter(0 .. 1, rand(10), markersize = rand(10) .* 20) +@compile scatter(LinRange(0, 1, 10), rand(10)) +@compile scatter(-1 .. 1, x -> x^2) + +@compile begin + f, ax, pl = lines(Rect(0, 0, 1, 1), linewidth = 4) + scatter!([Point2f(0.5, 0.5)], markersize = 1, markerspace = :data, marker = 'I') + f +end + +@compile lines(rand(10), rand(10), color = rand(10), linewidth = 10) +@compile lines(rand(10), rand(10), color = rand(RGBAf, 10), linewidth = 10) +@compile lines(Circle(Point2f(0), Float32(1))) +@compile lines(-1 .. 1, x -> x^2) + +@compile heatmap(rand(50, 50), colormap = (:RdBu, 0.2)) + +@compile contour(randn(100, 90), levels = 3) +@compile contour(randn(33, 30), levels = [0.1, 0.5, 0.9], color = [:black, :green, (:blue, 0.4)], linewidth = 2) + +@compile meshscatter(rand(10), rand(10), rand(10), color = rand(10)) +@compile meshscatter(rand(Point3f, 10), color = rand(RGBAf, 10), transparency = true) + +@compile begin + l = range(-10, stop = 10, length = 10) + surface(l, l, rand(10, 10), colormap = :Spectral) +end + +@compile begin + NL = 30 + NR = 31 + + l = range(0, stop = 3, length = NL) + r = range(0, stop = 3, length = NR) + surface( + [l for l in l, r in r], [r for l in l, r in r], rand(NL, NR), + colormap = :Spectral + ) +end + +@compile begin + heatmap(rand(10, 5), axis = (yscale = log10, xscale = log10)) +end + +@compile begin + x = [ + 1 0 + 2 3 + ] + heatmap(1:2, 1:-1:0, x) +end + +@compile begin + res = 200 + s = Scene(camera = campixel!, size = (res, res)) + half = res / 2 + linewidth = 10 + xstart = half - (half / 2) + xend = xstart + 100 + half_w = linewidth / 2 + + lines!(s, Point2f[(xstart, half), (xend, half)], linewidth = linewidth) + scatter!(s, Point2f[(xstart, half + half_w), (xstart, half - half_w), (xend, half + half_w), (xend, half - half_w)], color = :red, markersize = 2) + + l2 = linesegments!(s, Point2f[(xstart, half), (xend, half)], linewidth = linewidth, color = :gray) + s2 = scatter!(s, Point2f[(xstart, half + half_w), (xstart, half - half_w), (xend, half + half_w), (xend, half - half_w)], color = :red, markersize = 2) + + for p in (l2, s2) + translate!(p, 0, 20, 0) + end + + s +end + +@compile begin + P = Polygon.( + [ + Point2f[[0.45, 0.05], [0.64, 0.15], [0.37, 0.62]], + Point2f[[0.32, 0.66], [0.46, 0.59], [0.09, 0.08]], + ] + ) + poly(P, color = [:red, :green], strokecolor = [:blue, :red], strokewidth = 2) +end + +@compile begin + meshscatter(rand(Point3f, 10), axis = (type = Axis3,)) +end + +@compile begin + f = Figure() + ax = Makie.Axis(f) + Makie.Toggle(f) + Makie.Slider(f) + Makie.LScene(f) + Makie.PolarAxis(f) + Makie.IntervalSlider(f) + lines!(ax, 1:2, label = "Line") + Makie.Legend(f, ax, "Default", nbanks = 2) + Makie.Box(f) + Makie.Label(f) + Makie.Textbox(f) + Makie.Axis3(f) + Makie.Colorbar(f) + Makie.Button(f) + Makie.Menu(f, options = ["one"]) + Makie.SliderGrid(f, (label = "Label", range = 0:1:2, startvalue = 1)) + f +end diff --git a/relocatability.jl b/relocatability.jl index 6977bdd8eff..6f7d8fc1274 100644 --- a/relocatability.jl +++ b/relocatability.jl @@ -36,7 +36,7 @@ makie_dir = @__DIR__ # Add packages from branch, to make it easier to move the code later (e.g. when running this locally) # Since, package dir is much easier to move then the active project (on windows at least). paths = ["MakieCore", "", BACKEND] -Pkg.develop(map(x -> (; path=joinpath(makie_dir, x)), paths)) +Pkg.develop(map(x -> (; path = joinpath(makie_dir, x)), paths)) if BACKEND == "WGLMakie" pkg"add Electron@5.1" @@ -51,7 +51,7 @@ Pkg.add("PackageCompiler") using PackageCompiler -create_app(joinpath(pwd(), "MakieApp"), "executable"; force=true, incremental=true, include_transitive_dependencies=false) +create_app(joinpath(pwd(), "MakieApp"), "executable"; force = true, incremental = true, include_transitive_dependencies = false) exe = joinpath(pwd(), "executable", "bin", "MakieApp") # `run` allows to see potential informative printouts, `success` swallows those p = run(`$(exe)`) @@ -61,8 +61,8 @@ julia_pkg_dir = joinpath(Base.DEPOT_PATH[1], "packages") @test isdir(julia_pkg_dir) mvd_julia_pkg_dir = julia_pkg_dir * ".old" new_makie_dir = makie_dir * ".old" -mv(julia_pkg_dir, mvd_julia_pkg_dir; force=true) -mv(makie_dir, new_makie_dir; force=true) +mv(julia_pkg_dir, mvd_julia_pkg_dir; force = true) +mv(makie_dir, new_makie_dir; force = true) # Move package dir so that we can test relocatability (hardcoded paths to package dir being invalid now) try @info "Running executable in relocated mode..." diff --git a/src/Makie.jl b/src/Makie.jl index 5ae8e337191..0dc5fb740d9 100644 --- a/src/Makie.jl +++ b/src/Makie.jl @@ -89,7 +89,7 @@ using MakieCore: Pixel, px, Unit, Billboard using MakieCore: NoShading, FastShading, MultiLightShading using MakieCore: not_implemented_for import MakieCore: plot, plot!, theme, plotfunc, plottype, merge_attributes!, calculated_attributes!, - get_attribute, plotsym, plotkey, attributes, used_attributes + get_attribute, plotsym, plotkey, attributes, used_attributes import MakieCore: create_axis_like, create_axis_like!, figurelike_return, figurelike_return! import MakieCore: arrows, heatmap, image, lines, linesegments, mesh, meshscatter, poly, scatter, surface, text, volume, voxels import MakieCore: arrows!, heatmap!, image!, lines!, linesegments!, mesh!, meshscatter!, poly!, scatter!, surface!, text!, volume!, voxels! @@ -299,7 +299,7 @@ export mouseover, onpick, pick, Events, Keyboard, Mouse, is_mouseinside export ispressed, Exclusively export connect_screen export window_area, window_open, mouse_buttons, mouse_position, mouseposition_px, - scroll, keyboard_buttons, unicode_input, dropped_files, hasfocus, entered_window + scroll, keyboard_buttons, unicode_input, dropped_files, hasfocus, entered_window export disconnect! export DataInspector export Consume @@ -347,14 +347,14 @@ export assetpath using PNGFiles # default icon for Makie -function load_icon(name::String)::Matrix{NTuple{4,UInt8}} +function load_icon(name::String)::Matrix{NTuple{4, UInt8}} img = PNGFiles.load(name)::Matrix{RGBA{Colors.N0f8}} - return reinterpret(NTuple{4,UInt8}, img) + return reinterpret(NTuple{4, UInt8}, img) end function icon() path = assetpath("icons") - icons = readdir(path; join=true) + icons = readdir(path; join = true) return map(load_icon, icons) end @@ -369,21 +369,21 @@ function __init__() # Make GridLayoutBase default row and colgaps themeable when using Makie # This mutates module-level state so it could mess up other libraries using # GridLayoutBase at the same time as Makie, which is unlikely, though - GridLayoutBase.DEFAULT_COLGAP_GETTER[] = function() - return convert(Float64, to_value(Makie.theme(:colgap; default=GridLayoutBase.DEFAULT_COLGAP[]))) + GridLayoutBase.DEFAULT_COLGAP_GETTER[] = function () + return convert(Float64, to_value(Makie.theme(:colgap; default = GridLayoutBase.DEFAULT_COLGAP[]))) end - GridLayoutBase.DEFAULT_ROWGAP_GETTER[] = function() - return convert(Float64, to_value(Makie.theme(:rowgap; default=GridLayoutBase.DEFAULT_ROWGAP[]))) + GridLayoutBase.DEFAULT_ROWGAP_GETTER[] = function () + return convert(Float64, to_value(Makie.theme(:rowgap; default = GridLayoutBase.DEFAULT_ROWGAP[]))) end # fonts aren't cacheable by precompilation, so we need to empty it on load! empty!(FONT_CACHE) cfg_path = joinpath(homedir(), ".config", "makie", "theme.jl") if isfile(cfg_path) @warn "The global configuration file is no longer supported." * - "Please include the file manually with `include(\"$cfg_path\")` before plotting." + "Please include the file manually with `include(\"$cfg_path\")` before plotting." end - global makie_cache_dir = @get_scratch!("makie") + return global makie_cache_dir = @get_scratch!("makie") end include("figures.jl") @@ -397,9 +397,9 @@ include("basic_recipes/text.jl") include("basic_recipes/raincloud.jl") include("deprecated.jl") -export Arrows , Heatmap , Image , Lines , LineSegments , Mesh , MeshScatter , Poly , Scatter , Surface , Text , Volume , Wireframe, Voxels -export arrows , heatmap , image , lines , linesegments , mesh , meshscatter , poly , scatter , surface , text , volume , wireframe, voxels -export arrows! , heatmap! , image! , lines! , linesegments! , mesh! , meshscatter! , poly! , scatter! , surface! , text! , volume! , wireframe!, voxels! +export Arrows, Heatmap, Image, Lines, LineSegments, Mesh, MeshScatter, Poly, Scatter, Surface, Text, Volume, Wireframe, Voxels +export arrows, heatmap, image, lines, linesegments, mesh, meshscatter, poly, scatter, surface, text, volume, wireframe, voxels +export arrows!, heatmap!, image!, lines!, linesegments!, mesh!, meshscatter!, poly!, scatter!, surface!, text!, volume!, wireframe!, voxels! export AmbientLight, PointLight, DirectionalLight, SpotLight, EnvironmentLight, RectLight, SSAO export FastPixel diff --git a/src/basic_recipes/ablines.jl b/src/basic_recipes/ablines.jl index ad01cdf3921..3cfa6bcea18 100644 --- a/src/basic_recipes/ablines.jl +++ b/src/basic_recipes/ablines.jl @@ -33,13 +33,13 @@ function Makie.plot!(p::ABLines) notify(p[1]) linesegments!(p, points; p.attributes...) - p + return p end data_limits(::ABLines) = Rect3f(Point3f(NaN), Vec3f(NaN)) boundingbox(::ABLines, space::Symbol = :data) = Rect3f(Point3f(NaN), Vec3f(NaN)) function abline!(args...; kwargs...) - Base.depwarn("abline! is deprecated and will be removed in the future. Use ablines / ablines! instead." , :abline!, force = true) - ablines!(args...; kwargs...) + Base.depwarn("abline! is deprecated and will be removed in the future. Use ablines / ablines! instead.", :abline!, force = true) + return ablines!(args...; kwargs...) end diff --git a/src/basic_recipes/annotations.jl b/src/basic_recipes/annotations.jl index 23836caf2d3..fd87c64a3eb 100644 --- a/src/basic_recipes/annotations.jl +++ b/src/basic_recipes/annotations.jl @@ -7,16 +7,20 @@ Plots an array of texts at each position in `positions`. MakieCore.documented_attributes(Text)... end -function convert_arguments(::Type{<: Annotations}, - strings::AbstractVector{<: AbstractString}, - text_positions::AbstractVector{<: Point{N, T}}) where {N, T} - return (map(strings, text_positions) do str, pos - (String(str), Point{N, float_type(T)}(pos)) - end,) +function convert_arguments( + ::Type{<:Annotations}, + strings::AbstractVector{<:AbstractString}, + text_positions::AbstractVector{<:Point{N, T}} + ) where {N, T} + return ( + map(strings, text_positions) do str, pos + (String(str), Point{N, float_type(T)}(pos)) + end, + ) end function plot!(plot::Annotations) # annotations are not necessary anymore with the different text behavior text!(plot, plot[1]; plot.attributes...) - plot + return plot end diff --git a/src/basic_recipes/arc.jl b/src/basic_recipes/arc.jl index b89e9bd5efd..2a637ead96d 100644 --- a/src/basic_recipes/arc.jl +++ b/src/basic_recipes/arc.jl @@ -21,11 +21,11 @@ end function plot!(p::Arc) args = getindex.(p, (:origin, :radius, :start_angle, :stop_angle, :resolution)) positions = lift(p, args...) do origin, radius, start_angle, stop_angle, resolution - return map(range(start_angle, stop=stop_angle, length=resolution)) do angle + return map(range(start_angle, stop = stop_angle, length = resolution)) do angle return origin .+ Point2f((cos(angle), sin(angle)) .* radius) end end attr = Attributes(p) delete!(attr, :resolution) - lines!(p, attr, positions) + return lines!(p, attr, positions) end diff --git a/src/basic_recipes/arrows.jl b/src/basic_recipes/arrows.jl index ef872dd0290..7a1b42efaf9 100644 --- a/src/basic_recipes/arrows.jl +++ b/src/basic_recipes/arrows.jl @@ -8,22 +8,26 @@ function arrow_head(N, marker::Automatic, quality) if N == 2 return :utriangle else - merge([ - _circle(Point3f(0), 0.5f0, Vec3f(0,0,-1), quality), - _mantle(Point3f(0), Point3f(0,0,1), 0.5f0, 0f0, quality) - ]) + merge( + [ + _circle(Point3f(0), 0.5f0, Vec3f(0, 0, -1), quality), + _mantle(Point3f(0), Point3f(0, 0, 1), 0.5f0, 0.0f0, quality), + ] + ) end end arrow_tail(N, marker, quality) = marker function arrow_tail(N, marker::Automatic, quality) - if N == 2 + return if N == 2 nothing else - merge([ - _circle(Point3f(0,0,-1), 0.5f0, Vec3f(0,0,-1), quality), - _mantle(Point3f(0,0,-1), Point3f(0), 0.5f0, 0.5f0, quality) - ]) + merge( + [ + _circle(Point3f(0, 0, -1), 0.5f0, Vec3f(0, 0, -1), quality), + _mantle(Point3f(0, 0, -1), Point3f(0), 0.5f0, 0.5f0, quality), + ] + ) end end @@ -34,7 +38,7 @@ function _mantle(origin, extremity, r1, r2, N) # Equivalent to # xy = cos(atan(temp)) # z = sin(atan(temp)) - temp = -(r2-r1) / norm(extremity .- origin) + temp = -(r2 - r1) / norm(extremity .- origin) xy = 1.0 / sqrt(temp^2 + 1) z = temp / sqrt(temp^2 + 1) @@ -42,61 +46,61 @@ function _mantle(origin, extremity, r1, r2, N) normals = Vector{Vec3f}(undef, 2N) faces = Vector{GLTriangleFace}(undef, 2N) - for (i, phi) in enumerate(0:dphi:2pi-0.5dphi) + for (i, phi) in enumerate(0:dphi:(2pi - 0.5dphi)) coords[2i - 1] = origin .+ r1 * Vec3f(cos(phi), sin(phi), 0) coords[2i] = extremity .+ r2 * Vec3f(cos(phi), sin(phi), 0) - normals[2i - 1] = Vec3f(xy*cos(phi), xy*sin(phi), z) - normals[2i] = Vec3f(xy*cos(phi), xy*sin(phi), z) - faces[2i - 1] = GLTriangleFace(2i-1, mod1(2i+1, 2N), 2i) - faces[2i] = GLTriangleFace(mod1(2i+1, 2N), mod1(2i+2, 2N), 2i) + normals[2i - 1] = Vec3f(xy * cos(phi), xy * sin(phi), z) + normals[2i] = Vec3f(xy * cos(phi), xy * sin(phi), z) + faces[2i - 1] = GLTriangleFace(2i - 1, mod1(2i + 1, 2N), 2i) + faces[2i] = GLTriangleFace(mod1(2i + 1, 2N), mod1(2i + 2, 2N), 2i) end - GeometryBasics.mesh(coords, faces; normal = normals) + return GeometryBasics.mesh(coords, faces; normal = normals) end # GeometryBasics.Circle doesn't work with Point3f... function _circle(origin, r, normal, N) dphi = 2pi / N - coords = Vector{Point3f}(undef, N+1) - normals = fill(normal, N+1) + coords = Vector{Point3f}(undef, N + 1) + normals = fill(normal, N + 1) faces = Vector{GLTriangleFace}(undef, N) - for (i, phi) in enumerate(0:dphi:2pi-0.5dphi) + for (i, phi) in enumerate(0:dphi:(2pi - 0.5dphi)) coords[i] = origin .+ r * Vec3f(cos(phi), sin(phi), 0) - faces[i] = GLTriangleFace(N+1, mod1(i+1, N), i) + faces[i] = GLTriangleFace(N + 1, mod1(i + 1, N), i) end - coords[N+1] = origin + coords[N + 1] = origin - GeometryBasics.mesh(coords, faces; normal = normals) + return GeometryBasics.mesh(coords, faces; normal = normals) end -function convert_arguments(::Type{<: Arrows}, x, y, u, v) +function convert_arguments(::Type{<:Arrows}, x, y, u, v) return (Point2{float_type(x, y)}.(x, y), Vec2{float_type(u, v)}.(u, v)) end -function convert_arguments(::Type{<: Arrows}, x::AbstractVector, y::AbstractVector, u::AbstractMatrix, v::AbstractMatrix) +function convert_arguments(::Type{<:Arrows}, x::AbstractVector, y::AbstractVector, u::AbstractMatrix, v::AbstractMatrix) return (vec(Point2{float_type(x, y)}.(x, y')), vec(Vec2{float_type(u, v)}.(u, v))) end -function convert_arguments(::Type{<: Arrows}, x, y, z, u, v, w) +function convert_arguments(::Type{<:Arrows}, x, y, z, u, v, w) return (Point3{float_type(x, y, z)}.(x, y, z), Vec3{float_type(u, v, w)}.(u, v, w)) end -function plot!(arrowplot::Arrows{<: Tuple{AbstractVector{<: Point{N}}, V}}) where {N, V} +function plot!(arrowplot::Arrows{<:Tuple{AbstractVector{<:Point{N}}, V}}) where {N, V} @extract arrowplot ( points, directions, colormap, colorscale, normalize, align, arrowtail, color, linecolor, linestyle, linewidth, lengthscale, arrowhead, arrowsize, arrowcolor, quality, # passthrough diffuse, specular, shininess, shading, - fxaa, ssao, transparency, visible, inspectable + fxaa, ssao, transparency, visible, inspectable, ) - line_c = lift((a, c)-> a === automatic ? c : a , arrowplot, linecolor, color) - arrow_c = lift((a, c)-> a === automatic ? c : a , arrowplot, arrowcolor, color) + line_c = lift((a, c) -> a === automatic ? c : a, arrowplot, linecolor, color) + arrow_c = lift((a, c) -> a === automatic ? c : a, arrowplot, arrowcolor, color) fxaa_bool = lift(fxaa -> fxaa == automatic ? N == 3 : fxaa, arrowplot, fxaa) # automatic == fxaa for 3D marker_head = lift((ah, q) -> arrow_head(N, ah, q), arrowplot, arrowhead, quality) - if N == 2 + return if N == 2 headstart = lift(arrowplot, points, directions, normalize, align, lengthscale) do points, dirs, n, align, s map(points, dirs) do p1, dir dir = n ? LinearAlgebra.normalize(dir) : dir @@ -134,19 +138,19 @@ function plot!(arrowplot::Arrows{<: Tuple{AbstractVector{<: Point{N}}, V}}) wher linesegments!( arrowplot, headstart, - color=line_c, colormap=colormap, colorscale=colorscale, linestyle=linestyle, - colorrange=arrowplot.colorrange, - linewidth=lift(lw -> lw === automatic ? 1.0f0 : lw, arrowplot, linewidth), + color = line_c, colormap = colormap, colorscale = colorscale, linestyle = linestyle, + colorrange = arrowplot.colorrange, + linewidth = lift(lw -> lw === automatic ? 1.0f0 : lw, arrowplot, linewidth), fxaa = fxaa_bool, inspectable = inspectable, transparency = transparency, visible = visible, ) scatter!( arrowplot, - lift(x-> last.(x), arrowplot, headstart), - marker=marker_head, - markersize = lift(as-> as === automatic ? theme(scene, :markersize)[] : as, arrowplot, arrowsize), + lift(x -> last.(x), arrowplot, headstart), + marker = marker_head, + markersize = lift(as -> as === automatic ? theme(scene, :markersize)[] : as, arrowplot, arrowsize), color = arrow_c, rotation = rotations, strokewidth = 0.0, - colormap=colormap, markerspace=arrowplot.markerspace, colorrange=arrowplot.colorrange, + colormap = colormap, markerspace = arrowplot.markerspace, colorrange = arrowplot.colorrange, fxaa = fxaa_bool, inspectable = inspectable, transparency = transparency, visible = visible ) diff --git a/src/basic_recipes/axis.jl b/src/basic_recipes/axis.jl index d4b50772941..c2a263e6535 100644 --- a/src/basic_recipes/axis.jl +++ b/src/basic_recipes/axis.jl @@ -2,11 +2,11 @@ module Formatters using Showoff function scientific(ticks::AbstractVector) - Showoff.showoff(ticks, :scientific) + return Showoff.showoff(ticks, :scientific) end function plain(ticks::AbstractVector) - try + return try Showoff.showoff(ticks, :plain) catch e bt = Base.catch_backtrace() @@ -22,10 +22,10 @@ using .Formatters to_3tuple(x) = ntuple(i -> x, Val(3)) -to_3tuple(x::NTuple{3,Any}) = x +to_3tuple(x::NTuple{3, Any}) = x to_2tuple(x) = ntuple(i -> x, Val(2)) -to_2tuple(x::NTuple{2,Any}) = x +to_2tuple(x::NTuple{2, Any}) = x """ $(SIGNATURES) @@ -37,12 +37,12 @@ $(ATTRIBUTES) """ @recipe(Axis3D) do scene - q1 = qrotation(Vec3f(1, 0, 0), -0.5f0*pi) - q2 = qrotation(Vec3f(0, 0, 1), 1f0*pi) + q1 = qrotation(Vec3f(1, 0, 0), -0.5f0 * pi) + q2 = qrotation(Vec3f(0, 0, 1), 1.0f0 * pi) tickrotations3d = ( - qrotation(Vec3f(0,0,1), -1.5pi), + qrotation(Vec3f(0, 0, 1), -1.5pi), q2, - qrotation(Vec3f(1, 0, 0), -0.5pi) * q2 + qrotation(Vec3f(1, 0, 0), -0.5pi) * q2, ) axisnames_rotation3d = tickrotations3d tickalign3d = ( @@ -55,8 +55,8 @@ $(ATTRIBUTES) grid_color = RGBAf(0.5, 0.5, 0.5, 0.4) grid_thickness = 1 axis_linewidth = 1.5 - gridthickness = ntuple(x-> 1f0, Val(3)) - axislinewidth = ntuple(x->1.5f0, Val(3)) + gridthickness = ntuple(x -> 1.0f0, Val(3)) + axislinewidth = ntuple(x -> 1.5f0, Val(3)) tsize = 5 # in percent Attributes( visible = true, @@ -103,19 +103,19 @@ end isaxis(x) = false isaxis(x::Axis3D) = true -const Limits{N} = NTuple{N, <:Tuple{<: Number, <: Number}} +const Limits{N} = NTuple{N, <:Tuple{<:Number, <:Number}} function default_ticks(limits::Limits, ticks, scale_func::Function) - default_ticks.(limits, (ticks,), scale_func) + return default_ticks.(limits, (ticks,), scale_func) end default_ticks(limits::Tuple{Number, Number}, ticks, scale_func::Function) = default_ticks(limits..., ticks, scale_func) function default_ticks( lmin::Number, lmax::Number, - ticks::AbstractVector{<: Number}, scale_func::Function + ticks::AbstractVector{<:Number}, scale_func::Function ) - scale_func.((filter(t -> lmin <= t <= lmax, ticks))) + return scale_func.((filter(t -> lmin <= t <= lmax, ticks))) end function default_ticks( @@ -129,7 +129,7 @@ function default_ticks( k_max = 8, # maximum number of ticks ) length(scaled_ticks) == 1 && isnan(scaled_ticks[1]) && return [-Inf, Inf] - scaled_ticks + return scaled_ticks end function default_ticks( @@ -145,30 +145,30 @@ function default_ticks( # chosen ticks is not too much bigger than amin - amax: strict_span = false, ) - scaled_ticks + return scaled_ticks end function default_ticks(x::Automatic, limits::Tuple, n) - default_ticks(limits, n, identity) + return default_ticks(limits, n, identity) end function default_ticks(ticks::Tuple, limits::Tuple, n::Tuple) - default_ticks.(ticks, (limits,), n) + return default_ticks.(ticks, (limits,), n) end default_ticks(ticks::Tuple, limits::Limits, n) = default_ticks.(ticks, limits, (n,)) default_ticks(ticks::Tuple, limits::Limits, n::Tuple) = default_ticks.(ticks, limits, n) -default_ticks(ticks::AbstractVector{<: Number}, limits, n) = ticks +default_ticks(ticks::AbstractVector{<:Number}, limits, n) = ticks -function default_labels(x::NTuple{N, Any}, formatter::Function) where N - default_labels.(x, formatter) +function default_labels(x::NTuple{N, Any}, formatter::Function) where {N} + return default_labels.(x, formatter) end function default_labels(x::AbstractVector, y::AbstractVector, formatter::Function = Formatters.plain) - default_labels.((x, y), formatter) + return default_labels.((x, y), formatter) end function default_labels(ticks::AbstractVector, formatter::Function = Formatters.plain) @@ -184,10 +184,10 @@ end default_labels(x::Automatic, ranges, formatter) = default_labels(ranges, formatter) default_labels(x::Tuple, ranges::Tuple, formatter) = default_labels.(x, ranges, (formatter,)) default_labels(x::Tuple, ranges, formatter) = default_labels.(x, (ranges,), (formatter,)) -default_labels(x::AbstractVector{<: AbstractString}, ranges, formatter::Function) = x -default_labels(x::AbstractVector{<: AbstractString}, ranges::AbstractVector, formatter::Function) = x +default_labels(x::AbstractVector{<:AbstractString}, ranges, formatter::Function) = x +default_labels(x::AbstractVector{<:AbstractString}, ranges::AbstractVector, formatter::Function) = x -function convert_arguments(::Type{<: Axis3D}, limits::Rect) +function convert_arguments(::Type{<:Axis3D}, limits::Rect) e = (minimum(limits), maximum(limits)) return (((e[1][1], e[2][1]), (e[1][2], e[2][2]), (e[1][3], e[2][3])),) end @@ -195,7 +195,7 @@ end a_length(x::AbstractVector) = length(x) a_length(x::Automatic) = x -function calculated_attributes!(::Type{<: Axis3D}, plot) +function calculated_attributes!(::Type{<:Axis3D}, plot) ticks = plot.ticks args = (plot[1], ticks.ranges, ticks.labels, ticks.formatter) ticks[:ranges_labels] = lift(args...) do lims, ranges, labels, formatter @@ -207,21 +207,21 @@ function calculated_attributes!(::Type{<: Axis3D}, plot) return end -function labelposition(ranges, dim, dir, tgap, origin::StaticVector{N}) where N +function labelposition(ranges, dim, dir, tgap, origin::StaticVector{N}) where {N} a, b = extrema(ranges[dim]) whalf = Float32(((b - a) / 2)) halfaxis = GeometryBasics.unit(Point{N, Float32}, dim) .* whalf - origin .+ (halfaxis .+ (normalize(dir) * tgap)) + return origin .+ (halfaxis .+ (normalize(dir) * tgap)) end -_widths(x::Tuple{<: Number, <: Number}) = x[2] - x[1] +_widths(x::Tuple{<:Number, <:Number}) = x[2] - x[1] _widths(x) = Float32(maximum(x) - minimum(x)) to3tuple(x::Tuple{Any}) = (x[1], x[1], x[1]) to3tuple(x::Tuple{Any, Any}) = (x[1], x[2], x[2]) to3tuple(x::Tuple{Any, Any, Any}) = x -to3tuple(x) = ntuple(i-> x, Val(3)) +to3tuple(x) = ntuple(i -> x, Val(3)) function draw_axis3d(textbuffer, linebuffer, scale, limits, ranges_labels, fonts, args...) # make sure we extend all args to 3D @@ -240,9 +240,9 @@ function draw_axis3d(textbuffer, linebuffer, scale, limits, ranges_labels, fonts start!(textbuffer) start!(linebuffer) - limit_widths = map(x-> x[2] - x[1], limits) + limit_widths = map(x -> x[2] - x[1], limits) # pad the drawn limits and use them as the ranges - limits = map((lim, p)-> (lim[1] - p, lim[2] + p), limits, limit_widths .* padding) + limits = map((lim, p) -> (lim[1] - p, lim[2] + p), limits, limit_widths .* padding) mini, maxi = first.(limits), last.(limits) @@ -253,7 +253,7 @@ function draw_axis3d(textbuffer, linebuffer, scale, limits, ranges_labels, fonts axisnames_size = (%) .* axisnames_size # index of the direction in which ticks and labels are drawn - offset_indices = Vec(ntuple(i-> ifelse(i != 2, mod1(i + 1, N), 1), N)) + offset_indices = Vec(ntuple(i -> ifelse(i != 2, mod1(i + 1, N), 1), N)) # These need the real limits, not (%), to be scale-aware titlegap = 0.01limit_widths[offset_indices] .* titlegap tgap = 0.01limit_widths[offset_indices] .* tgap @@ -300,7 +300,7 @@ function draw_axis3d(textbuffer, linebuffer, scale, limits, ranges_labels, fonts if showgrid[i] c = gridcolors[i] thickness = gridthickness[i] - for _j = (i + 1):(i + N - 1) + for _j in (i + 1):(i + N - 1) j = mod1(_j, N) dir = GeometryBasics.unit(Point{N, Float32}, j) range = ranges[j] @@ -322,10 +322,14 @@ function plot!(axis::Axis3D) scene = get_scene(axis) # Disable any non linear transform for the axis plot! axis.transformation.transform_func[] = identity - textbuffer = TextBuffer(axis, Point3, transparency = true, markerspace = :data, - inspectable = axis.inspectable, visible = axis.visible) - linebuffer = LinesegmentBuffer(axis, Point3, transparency = true, inspectable = axis.inspectable, - visible = axis.visible) + textbuffer = TextBuffer( + axis, Point3, transparency = true, markerspace = :data, + inspectable = axis.inspectable, visible = axis.visible + ) + linebuffer = LinesegmentBuffer( + axis, Point3, transparency = true, inspectable = axis.inspectable, + visible = axis.visible + ) tstyle, ticks, frame = to_value.(getindex.(axis, (:names, :ticks, :frame))) titlevals = getindex.(tstyle, (:axisnames, :textcolor, :fontsize, :rotation, :align, :font, :gap)) @@ -333,16 +337,16 @@ function plot!(axis::Axis3D) tvals = getindex.(ticks, (:textcolor, :rotation, :fontsize, :align, :font, :gap)) args = ( getindex.(axis, (:showaxis, :showticks, :showgrid))..., - titlevals..., framevals..., tvals..., axis.padding + titlevals..., framevals..., tvals..., axis.padding, ) onany( draw_axis3d, Observable(textbuffer), Observable(linebuffer), scale(scene), - axis[1], axis.ticks.ranges_labels, Observable(axis.fonts), args...; update=true + axis[1], axis.ticks.ranges_labels, Observable(axis.fonts), args...; update = true ) return axis end function axis3d!(scene::Scene, lims = boundingbox(scene, p -> isaxis(p) || not_in_data_space(p)); kw...) - axis3d!(scene, Attributes(), lims; ticks = (ranges = automatic, labels = automatic), kw...) + return axis3d!(scene, Attributes(), lims; ticks = (ranges = automatic, labels = automatic), kw...) end diff --git a/src/basic_recipes/band.jl b/src/basic_recipes/band.jl index cdb02b8f095..940f897b647 100644 --- a/src/basic_recipes/band.jl +++ b/src/basic_recipes/band.jl @@ -12,16 +12,16 @@ Both bounds can be passed together as `lowerupper`, a vector of intervals. shading = NoShading end -function convert_arguments(::Type{<: Band}, x, ylower, yupper) +function convert_arguments(::Type{<:Band}, x, ylower, yupper) return (Point2{float_type(x, ylower)}.(x, ylower), Point2{float_type(x, yupper)}.(x, yupper)) end -convert_arguments(P::Type{<: Band}, x::AbstractVector{<:Number}, y::AbstractVector{<:Interval}) = +convert_arguments(P::Type{<:Band}, x::AbstractVector{<:Number}, y::AbstractVector{<:Interval}) = convert_arguments(P, x, leftendpoint.(y), rightendpoint.(y)) function band_connect(n) - ns = 1:n-1 - ns2 = n+1:2n-1 + ns = 1:(n - 1) + ns2 = (n + 1):(2n - 1) return [GLTriangleFace.(ns, ns .+ 1, ns2); GLTriangleFace.(ns .+ 1, ns2 .+ 1, ns2)] end @@ -53,7 +53,7 @@ function Makie.plot!(plot::Band) # side to make an even band if length(c) == length(lowerpoints[]) return repeat(to_color(c), 2)::RGBColors - # if there's one color for each band vertex, the colors are used directly + # if there's one color for each band vertex, the colors are used directly elseif length(c) == 2 * length(lowerpoints[]) return to_color(c)::RGBColors else @@ -65,17 +65,17 @@ function Makie.plot!(plot::Band) end attr = Attributes(plot) attr[:color] = meshcolor - mesh!(plot, attr, coordinates, connectivity) + return mesh!(plot, attr, coordinates, connectivity) end function fill_view(x, y1, y2, where::Nothing) - x, y1, y2 + return x, y1, y2 end function fill_view(x, y1, y2, where::Function) - fill_view(x, y1, y2, where.(x, y1, y2)) + return fill_view(x, y1, y2, where.(x, y1, y2)) end -function fill_view(x, y1, y2, bools::AbstractVector{<: Union{Integer, Bool}}) - view(x, bools), view(y1, bools), view(y2, bools) +function fill_view(x, y1, y2, bools::AbstractVector{<:Union{Integer, Bool}}) + return view(x, bools), view(y1, bools), view(y2, bools) end """ @@ -85,7 +85,7 @@ fill the section between 2 lines with the condition `where` """ function fill_between!(scenelike, x, y1, y2; where = nothing, kw_args...) xv, ylow, yhigh = fill_view(x, y1, y2, where) - band!(scenelike, xv, ylow, yhigh; kw_args...) + return band!(scenelike, xv, ylow, yhigh; kw_args...) end export fill_between! diff --git a/src/basic_recipes/barplot.jl b/src/basic_recipes/barplot.jl index ecb4a1a4b45..68dac602b4a 100644 --- a/src/basic_recipes/barplot.jl +++ b/src/basic_recipes/barplot.jl @@ -1,4 +1,4 @@ -bar_label_formatter(value::Number) = string(round(value; digits=3)) +bar_label_formatter(value::Number) = string(round(value; digits = 3)) bar_label_formatter(label::String) = label bar_label_formatter(label::LaTeXString) = label @@ -23,11 +23,11 @@ end # `fillto` is related to `y-axis` transformation only, thus we expect `tf::Tuple` function bar_default_fillto(tf::Tuple, ys, offset, in_y_direction) - _logT = Union{typeof(log), typeof(log2), typeof(log10), Base.Fix1{typeof(log), <: Real}} + _logT = Union{typeof(log), typeof(log2), typeof(log10), Base.Fix1{typeof(log), <:Real}} if in_y_direction && tf[2] isa _logT || (!in_y_direction && tf[1] isa _logT) # x-scale log and !(in_y_direction) is equiavlent to y-scale log in_y_direction # use the minimal non-zero y divided by 2 as lower bound for log scale - smart_fillto = minimum(y -> y<=0 ? oftype(y, Inf) : y, ys) / 2 + smart_fillto = minimum(y -> y <= 0 ? oftype(y, Inf) : y, ys) / 2 return clamp.(ys, smart_fillto, Inf), smart_fillto else return ys, offset @@ -86,14 +86,14 @@ Plots a barplot. label_position = :end end -conversion_trait(::Type{<: BarPlot}) = PointBased() +conversion_trait(::Type{<:BarPlot}) = PointBased() function bar_rectangle(x, y, width, fillto, in_y_direction) # y could be smaller than fillto... ymin = min(fillto, y) ymax = max(fillto, y) w = abs(width) - rect = Rectd(x - (w / 2f0), ymin, w, ymax - ymin) + rect = Rectd(x - (w / 2.0f0), ymin, w, ymax - ymin) return in_y_direction ? rect : flip(rect) end @@ -118,14 +118,14 @@ end scale_width(dodge_gap, n_dodge) = (1 - (n_dodge - 1) * dodge_gap) / n_dodge function shift_dodge(i, dodge_width, dodge_gap) - (dodge_width - 1) / 2 + (i - 1) * (dodge_width + dodge_gap) + return (dodge_width - 1) / 2 + (i - 1) * (dodge_width + dodge_gap) end function stack_from_to_sorted(y) to = cumsum(y) - from = [0.0; to[firstindex(to):end-1]] + from = [0.0; to[firstindex(to):(end - 1)]] - (from = from, to = to) + return (from = from, to = to) end function stack_from_to(i_stack, y) @@ -138,12 +138,12 @@ function stack_from_to(i_stack, y) from, to = stack_from_to_sorted(view(y, perm)) - (from = view(from, inv_perm), to = view(to, inv_perm)) + return (from = view(from, inv_perm), to = view(to, inv_perm)) end function stack_grouped_from_to(i_stack, y, grp) from = Array{Float64}(undef, length(y)) - to = Array{Float64}(undef, length(y)) + to = Array{Float64}(undef, length(y)) groupby = StructArray((; grp...)) grps = StructArrays.finduniquesorted(groupby) @@ -162,19 +162,21 @@ function stack_grouped_from_to(i_stack, y, grp) to[inds] .= fromto.to end - (from = from, to = to) + return (from = from, to = to) end function calculate_bar_label_align(label_align, label_rotation::Real, in_y_direction::Bool, flip::Bool) if label_align == automatic - return angle2align(-label_rotation - !flip * pi + in_y_direction * pi/2) + return angle2align(-label_rotation - !flip * pi + in_y_direction * pi / 2) else return to_align(label_align, "Failed to convert `label_align` $label_align.") end end -function text_attributes(values, in_y_direction, flip_labels_at, color_over_background, color_over_bar, - label_offset, label_rotation, label_align, label_position) +function text_attributes( + values, in_y_direction, flip_labels_at, color_over_background, color_over_bar, + label_offset, label_rotation, label_align, label_position + ) aligns = Vec2d[] offsets = Vec2d[] text_colors = RGBAf[] @@ -215,9 +217,11 @@ function text_attributes(values, in_y_direction, flip_labels_at, color_over_back return aligns, offsets, text_colors end -function barplot_labels(xpositions, ypositions, offset, bar_labels, in_y_direction, flip_labels_at, - color_over_background, color_over_bar, label_formatter, label_offset, label_rotation, - label_align, label_position, fillto) +function barplot_labels( + xpositions, ypositions, offset, bar_labels, in_y_direction, flip_labels_at, + color_over_background, color_over_bar, label_formatter, label_offset, label_rotation, + label_align, label_position, fillto + ) if bar_labels isa Symbol && bar_labels in (:x, :y) bar_labels = map(xpositions, ypositions) do x, y if bar_labels === :x @@ -227,23 +231,25 @@ function barplot_labels(xpositions, ypositions, offset, bar_labels, in_y_directi end end end - if bar_labels isa AbstractVector + return if bar_labels isa AbstractVector if length(bar_labels) == length(xpositions) - attributes = text_attributes(ypositions, in_y_direction, flip_labels_at, color_over_background, - color_over_bar, label_offset, label_rotation, label_align, label_position) + attributes = text_attributes( + ypositions, in_y_direction, flip_labels_at, color_over_background, + color_over_bar, label_offset, label_rotation, label_align, label_position + ) label_pos = broadcast(xpositions, ypositions, offset, bar_labels, label_position, fillto) do x, y, off, l, lpos, fto str = string(label_formatter(l)) p = if in_y_direction if lpos == :end - Point2d(x, y+off) + Point2d(x, y + off) else Point2d(x, 0.5 * (y + fto) + off) end else if lpos == :end - Point2d(y, x+off) + Point2d(y, x + off) else - Point2d(0.5 * (y + fto), x+off) + Point2d(0.5 * (y + fto), x + off) end end return (str, p) @@ -262,15 +268,17 @@ function Makie.plot!(p::BarPlot) if !(eltype(bar_points[]) <: Point2) error("barplot only accepts x/y coordinates. Use `barplot(x, y)` or `barplot(xy::Vector{<:Point2})`. Found: $(bar_points[])") end - labels = Observable(Tuple{Union{String,LaTeXStrings.LaTeXString}, Point2d}[]) + labels = Observable(Tuple{Union{String, LaTeXStrings.LaTeXString}, Point2d}[]) label_aligns = Observable(Vec2d[]) label_offsets = Observable(Vec2d[]) label_colors = Observable(RGBAf[]) - function calculate_bars(xy, fillto, offset, transformation, width, dodge, n_dodge, gap, dodge_gap, stack, - dir, bar_labels, flip_labels_at, label_color, color_over_background, - color_over_bar, label_formatter, label_offset, label_rotation, label_align, label_position) + function calculate_bars( + xy, fillto, offset, transformation, width, dodge, n_dodge, gap, dodge_gap, stack, + dir, bar_labels, flip_labels_at, label_color, color_over_background, + color_over_bar, label_formatter, label_offset, label_rotation, label_align, label_position + ) - in_y_direction = get((y=true, x=false), dir) do + in_y_direction = get((y = true, x = false), dir) do error("Invalid direction $dir. Options are :x and :y.") end @@ -316,18 +324,22 @@ function Makie.plot!(p::BarPlot) if !isnothing(bar_labels) oback = color_over_background === automatic ? label_color : color_over_background obar = color_over_bar === automatic ? label_color : color_over_bar - label_args = barplot_labels(x̂, y, offset, bar_labels, in_y_direction, - flip_labels_at, to_color(oback), to_color(obar), - label_formatter, label_offset, label_rotation, label_align, label_position, fillto) + label_args = barplot_labels( + x̂, y, offset, bar_labels, in_y_direction, + flip_labels_at, to_color(oback), to_color(obar), + label_formatter, label_offset, label_rotation, label_align, label_position, fillto + ) labels[], label_aligns[], label_offsets[], label_colors[] = label_args end return bar_rectangle.(x̂, y .+ offset, barwidth, fillto, in_y_direction) end - bars = lift(calculate_bars, p, p[1], p.fillto, p.offset, p.transformation.transform_func, p.width, p.dodge, p.n_dodge, p.gap, - p.dodge_gap, p.stack, p.direction, p.bar_labels, p.flip_labels_at, - p.label_color, p.color_over_background, p.color_over_bar, p.label_formatter, p.label_offset, p.label_rotation, p.label_align, p.label_position; priority = 1) + bars = lift( + calculate_bars, p, p[1], p.fillto, p.offset, p.transformation.transform_func, p.width, p.dodge, p.n_dodge, p.gap, + p.dodge_gap, p.stack, p.direction, p.bar_labels, p.flip_labels_at, + p.label_color, p.color_over_background, p.color_over_bar, p.label_formatter, p.label_offset, p.label_rotation, p.label_align, p.label_position; priority = 1 + ) poly!( p, bars, color = p.color, colormap = p.colormap, colorscale = p.colorscale, colorrange = p.colorrange, strokewidth = p.strokewidth, strokecolor = p.strokecolor, visible = p.visible, @@ -335,7 +347,7 @@ function Makie.plot!(p::BarPlot) highclip = p.highclip, lowclip = p.lowclip, nan_color = p.nan_color, alpha = p.alpha, ) - if !isnothing(p.bar_labels[]) - text!(p, labels; align=label_aligns, offset=label_offsets, color=label_colors, font=p.label_font, fontsize=p.label_size, rotation=p.label_rotation) + return if !isnothing(p.bar_labels[]) + text!(p, labels; align = label_aligns, offset = label_offsets, color = label_colors, font = p.label_font, fontsize = p.label_size, rotation = p.label_rotation) end end diff --git a/src/basic_recipes/bracket.jl b/src/basic_recipes/bracket.jl index 0ef965c33ee..18b34bb9212 100644 --- a/src/basic_recipes/bracket.jl +++ b/src/basic_recipes/bracket.jl @@ -57,15 +57,17 @@ function plot!(pl::Bracket) textoffset_vec = Observable(Vec2f[]) bp = Observable(BezierPath[]) - text_tuples = Observable(Tuple{Any,Point2f}[]) + text_tuples = Observable(Tuple{Any, Point2f}[]) realtextoffset = lift(pl, pl.textoffset, pl.fontsize) do to, fs return to === automatic ? Float32.(0.75 .* fs) : Float32.(to) end - onany(pl, points, scene.camera.projectionview, pl.model, transform_func(pl), - scene.viewport, pl.offset, pl.width, pl.orientation, realtextoffset, - pl.style, pl.text) do points, _, _, _, _, offset, width, orientation, textoff, style, text + onany( + pl, points, scene.camera.projectionview, pl.model, transform_func(pl), + scene.viewport, pl.offset, pl.width, pl.orientation, realtextoffset, + pl.style, pl.text + ) do points, _, _, _, _, offset, width, orientation, textoff, style, text empty!(bp[]) empty!(textoffset_vec[]) @@ -112,13 +114,17 @@ function plot!(pl::Bracket) end # Avoid scale!() / translate!() / rotate!() to affect these - series!(pl, bp; space = :pixel, solid_color = pl.color, linewidth = pl.linewidth, + series!( + pl, bp; space = :pixel, solid_color = pl.color, linewidth = pl.linewidth, linestyle = pl.linestyle, linecap = pl.linecap, joinstyle = pl.joinstyle, - miter_limit = pl.miter_limit, transformation = Transformation()) - text!(pl, text_tuples, space = :pixel, align = pl.align, offset = textoffset_vec, + miter_limit = pl.miter_limit, transformation = Transformation() + ) + text!( + pl, text_tuples, space = :pixel, align = pl.align, offset = textoffset_vec, fontsize = pl.fontsize, font = pl.font, rotation = autorotations, color = pl.textcolor, - justification = pl.justification, model = Mat4f(I)) - pl + justification = pl.justification, model = Mat4f(I) + ) + return pl end data_limits(pl::Bracket) = mapreduce(ps -> Rect3d([ps...]), union, pl[1][]) @@ -133,11 +139,13 @@ function bracket_bezierpath(::Val{:curly}, p1, p2, d, width) c2 = p12 - width * d c3 = p2 + width * d - b = BezierPath([ - MoveTo(p1), - CurveTo(c1, c2, p12), - CurveTo(c2, c3, p2), - ]) + b = BezierPath( + [ + MoveTo(p1), + CurveTo(c1, c2, p12), + CurveTo(c2, c3, p2), + ] + ) return b, p12 end @@ -147,11 +155,13 @@ function bracket_bezierpath(::Val{:square}, p1, p2, d, width) c1 = p1 + width * d c2 = p2 + width * d - b = BezierPath([ - MoveTo(p1), - LineTo(c1), - LineTo(c2), - LineTo(p2), - ]) + b = BezierPath( + [ + MoveTo(p1), + LineTo(c1), + LineTo(c2), + LineTo(p2), + ] + ) return b, p12 end diff --git a/src/basic_recipes/buffers.jl b/src/basic_recipes/buffers.jl index 8ef95881ab9..f40d7b7702c 100644 --- a/src/basic_recipes/buffers.jl +++ b/src/basic_recipes/buffers.jl @@ -7,14 +7,14 @@ function LinesegmentBuffer( scene::SceneLike, ::Type{Point{N}} = Point{2}; color = RGBAf[], linewidth = Float32[], kw_args... - ) where N - linesegments!( + ) where {N} + return linesegments!( scene, Point{N, Float32}[]; color = color, linewidth = linewidth, kw_args... ) end -function append!(lsb::LineSegments, positions::Vector{Point{N, Float32}}; color = :black, linewidth = 1.0) where N +function append!(lsb::LineSegments, positions::Vector{Point{N, Float32}}; color = :black, linewidth = 1.0) where {N} thickv = same_length_array(positions, linewidth, key"linewidth"()) colorv = same_length_array(positions, color, key"color"()) append!(lsb[1][], positions) @@ -23,8 +23,8 @@ function append!(lsb::LineSegments, positions::Vector{Point{N, Float32}}; color return end -function push!(tb::LineSegments, positions::Point{N, Float32}; kw_args...) where N - append!(tb, [positions]; kw_args...) +function push!(tb::LineSegments, positions::Point{N, Float32}; kw_args...) where {N} + return append!(tb, [positions]; kw_args...) end function start!(lsb::LineSegments) @@ -44,14 +44,14 @@ end function TextBuffer( scene::SceneLike, ::Type{Point{N}} = Point{2}; - rotation = [Quaternionf(0,0,0,1)], - color = RGBAf[RGBAf(0,0,0,0)], + rotation = [Quaternionf(0, 0, 0, 1)], + color = RGBAf[RGBAf(0, 0, 0, 0)], fontsize = Float32[0], font = [defaultfont()], align = [Vec2f(0)], kw_args... - ) where N - annotations!( + ) where {N} + return annotations!( scene, String[" "], [Point{N, Float32}(0)]; rotation = rotation, color = color, @@ -81,17 +81,17 @@ function finish!(tb::Annotations) return end -function push!(tb::Annotations, text::String, position::VecTypes{N}; kw_args...) where N - append!(tb, [(String(text), Point{N, Float32}(position))]; kw_args...) +function push!(tb::Annotations, text::String, position::VecTypes{N}; kw_args...) where {N} + return append!(tb, [(String(text), Point{N, Float32}(position))]; kw_args...) end -function append!(tb::Annotations, text::Vector{String}, positions::Vector{Point{N, Float32}}; kw_args...) where N +function append!(tb::Annotations, text::Vector{String}, positions::Vector{Point{N, Float32}}; kw_args...) where {N} text_positions = convert_arguments(Annotations, text, positions)[1] append!(tb, text_positions; kw_args...) return end -function append!(tb::Annotations, text_positions::Vector{Tuple{String, Point{N, Float32}}}; kw_args...) where N +function append!(tb::Annotations, text_positions::Vector{Tuple{String, Point{N, Float32}}}; kw_args...) where {N} append!(tb[1][], text_positions) kw = Dict(kw_args) for key in (:color, :rotation, :fontsize, :font, :align) diff --git a/src/basic_recipes/contourf.jl b/src/basic_recipes/contourf.jl index 8ae1723e2e4..4e4db42b152 100644 --- a/src/basic_recipes/contourf.jl +++ b/src/basic_recipes/contourf.jl @@ -48,12 +48,12 @@ end # _computed_extendlow # _computed_extendhigh -_get_isoband_levels(levels::Int, mi, ma) = collect(range(Float32(mi), nextfloat(Float32(ma)), length = levels+1)) +_get_isoband_levels(levels::Int, mi, ma) = collect(range(Float32(mi), nextfloat(Float32(ma)), length = levels + 1)) function _get_isoband_levels(levels::AbstractVector{<:Real}, mi, ma) edges = Float32.(levels) @assert issorted(edges) - edges + return edges end conversion_trait(::Type{<:Contourf}) = VertexGrid() @@ -77,8 +77,10 @@ function Makie.plot!(c::Contourf{<:Tuple{<:AbstractVector{<:Real}, <:AbstractVec colorrange = lift(c, c._computed_levels) do levels minimum(levels), maximum(levels) end - computed_colormap = lift(compute_contourf_colormap, c, c._computed_levels, c.colormap, c.extendlow, - c.extendhigh) + computed_colormap = lift( + compute_contourf_colormap, c, c._computed_levels, c.colormap, c.extendlow, + c.extendhigh + ) c.attributes[:_computed_colormap] = computed_colormap lowcolor = Observable{RGBAf}() @@ -103,7 +105,7 @@ function Makie.plot!(c::Contourf{<:Tuple{<:AbstractVector{<:Real}, <:AbstractVec @assert issorted(levels) is_extended_low && pushfirst!(levels, -Inf) is_extended_high && push!(levels, Inf) - lows = levels[1:end-1] + lows = levels[1:(end - 1)] highs = levels[2:end] # zs needs to be transposed to match rest of makie @@ -131,7 +133,8 @@ function Makie.plot!(c::Contourf{<:Tuple{<:AbstractVector{<:Real}, <:AbstractVec # it on a first run! calculate_polys(xs[], ys[], zs[], c._computed_levels[], is_extended_low[], is_extended_high[]) - poly!(c, + return poly!( + c, polys, colormap = c._computed_colormap, colorrange = colorrange, @@ -167,8 +170,9 @@ function _group_polys(points, ids) # check if a single point is contained, saving some computation time containment_matrix = [ p1 != p2 && - PolygonOps.inpolygon(first(p1), p2) == 1 - for p1 in polys_lastdouble, p2 in polys_lastdouble] + PolygonOps.inpolygon(first(p1), p2) == 1 + for p1 in polys_lastdouble, p2 in polys_lastdouble + ] unclassified_polyindices = collect(1:size(containment_matrix, 1)) # @show unclassified_polyindices @@ -217,5 +221,5 @@ function _group_polys(points, ids) unclassified_polyindices = unclassified_polyindices[to_keep] containment_matrix = containment_matrix[to_keep, to_keep] end - groups + return groups end diff --git a/src/basic_recipes/contours.jl b/src/basic_recipes/contours.jl index 3d608dd4fb0..85988287d2b 100644 --- a/src/basic_recipes/contours.jl +++ b/src/basic_recipes/contours.jl @@ -1,6 +1,6 @@ function contour_label_formatter(level::Real)::String lev_short = round(level; digits = 2) - string(isinteger(lev_short) ? round(Int, lev_short) : lev_short) + return string(isinteger(lev_short) ? round(Int, lev_short) : lev_short) end """ @@ -66,17 +66,17 @@ function label_info(lev, vertices, col) mid = ceil(Int, 0.5f0 * length(vertices)) # take 3 pts around half segment pts = (vertices[max(firstindex(vertices), mid - 1)], vertices[mid], vertices[min(mid + 1, lastindex(vertices))]) - ( + return ( lev, map(p -> to_ndim(Point3f, p, lev), Tuple(pts)), col, ) end -function contourlines(::Type{<: Contour}, contours, cols, labels) +function contourlines(::Type{<:Contour}, contours, cols, labels) points = Point2f[] colors = RGBA{Float32}[] - lev_pos_col = Tuple{Float32,NTuple{3,Point2f},RGBA{Float32}}[] + lev_pos_col = Tuple{Float32, NTuple{3, Point2f}, RGBA{Float32}}[] for (color, c) in zip(cols, Contours.levels(contours)) for elem in Contours.lines(c) append!(points, elem.vertices) @@ -85,13 +85,13 @@ function contourlines(::Type{<: Contour}, contours, cols, labels) labels && push!(lev_pos_col, label_info(c.level, elem.vertices, color)) end end - points, colors, lev_pos_col + return points, colors, lev_pos_col end -function contourlines(::Type{<: Contour3d}, contours, cols, labels) +function contourlines(::Type{<:Contour3d}, contours, cols, labels) points = Point3f[] colors = RGBA{Float32}[] - lev_pos_col = Tuple{Float32,NTuple{3,Point3f},RGBA{Float32}}[] + lev_pos_col = Tuple{Float32, NTuple{3, Point3f}, RGBA{Float32}}[] for (color, c) in zip(cols, Contours.levels(contours)) for elem in Contours.lines(c) for p in elem.vertices @@ -102,27 +102,27 @@ function contourlines(::Type{<: Contour3d}, contours, cols, labels) labels && push!(lev_pos_col, label_info(c.level, elem.vertices, color)) end end - points, colors, lev_pos_col + return points, colors, lev_pos_col end -to_levels(x::AbstractVector{<: Number}, cnorm) = x +to_levels(x::AbstractVector{<:Number}, cnorm) = x function to_levels(n::Integer, cnorm) zmin, zmax = cnorm dz = (zmax - zmin) / (n + 1) - range(zmin + dz; step = dz, length = n) + return range(zmin + dz; step = dz, length = n) end -conversion_trait(::Type{<: Contour3d}) = VertexGrid() -conversion_trait(::Type{<: Contour}) = VertexGrid() -conversion_trait(::Type{<:Contour}, x, y, z, ::Union{Function, AbstractArray{<: Number, 3}}) = VolumeLike() -conversion_trait(::Type{<: Contour}, ::AbstractArray{<: Number, 3}) = VolumeLike() +conversion_trait(::Type{<:Contour3d}) = VertexGrid() +conversion_trait(::Type{<:Contour}) = VertexGrid() +conversion_trait(::Type{<:Contour}, x, y, z, ::Union{Function, AbstractArray{<:Number, 3}}) = VolumeLike() +conversion_trait(::Type{<:Contour}, ::AbstractArray{<:Number, 3}) = VolumeLike() -function plot!(plot::Contour{<: Tuple{X, Y, Z, Vol}}) where {X, Y, Z, Vol} +function plot!(plot::Contour{<:Tuple{X, Y, Z, Vol}}) where {X, Y, Z, Vol} x, y, z, volume = plot[1:4] @extract plot (colormap, levels, linewidth, alpha) valuerange = lift(nan_extrema, plot, volume) - cliprange = replace_automatic!(()-> valuerange, plot, :colorrange) + cliprange = replace_automatic!(() -> valuerange, plot, :colorrange) cmap = lift(plot, colormap, levels, alpha, cliprange, valuerange) do _cmap, l, alpha, cliprange, vrange levels = to_levels(l, vrange) nlevels = length(levels) @@ -137,7 +137,7 @@ function plot!(plot::Contour{<: Tuple{X, Y, Z, Vol}}) where {X, Y, Z, Vol} v_interval = cliprange[1] .. cliprange[2] # resample colormap and make the empty area between iso surfaces transparent map(1:N) do i - i01 = (i-1) / (N - 1) + i01 = (i - 1) / (N - 1) c = Makie.interpolated_getindex(cmap, i01) isoval = vrange[1] + (i01 * (vrange[2] - vrange[1])) line = reduce(levels, init = false) do v0, level @@ -168,14 +168,14 @@ function plot!(plot::Contour{<: Tuple{X, Y, Z, Vol}}) where {X, Y, Z, Vol} pop!(attr, :linecap) pop!(attr, :joinstyle) pop!(attr, :miter_limit) - volume!(plot, attr, x, y, z, volume) + return volume!(plot, attr, x, y, z, volume) end color_per_level(color, args...) = color_per_level(to_color(color), args...) color_per_level(color::Colorant, _, _, _, _, levels) = fill(color, length(levels)) color_per_level(colors::AbstractVector, args...) = color_per_level(to_colormap(colors), args...) -function color_per_level(colors::AbstractVector{<: Colorant}, _, _, _, _, levels) +function color_per_level(colors::AbstractVector{<:Colorant}, _, _, _, _, levels) if length(levels) == length(colors) return colors else @@ -188,7 +188,7 @@ end function color_per_level(::Nothing, colormap, colorscale, colorrange, a, levels) cmap = to_colormap(colormap) - map(levels) do level + return map(levels) do level c = interpolated_getindex(cmap, colorscale(level), colorscale.(colorrange)) RGBAf(color(c), alpha(c) * a) end @@ -204,7 +204,7 @@ end # Overload for matrix-like x and y lookups for contours # Just removes the `to_vector` invocation -function contourlines(x::AbstractMatrix{<: Real}, y::AbstractMatrix{<: Real}, z::AbstractMatrix{ET}, levels, level_colors, labels, T) where {ET} +function contourlines(x::AbstractMatrix{<:Real}, y::AbstractMatrix{<:Real}, z::AbstractMatrix{ET}, levels, level_colors, labels, T) where {ET} contours = Contours.contours(x, y, z, convert(Vector{ET}, levels)) return contourlines(T, contours, level_colors, labels) end @@ -214,14 +214,14 @@ function has_changed(old_args, new_args) for (old, new) in zip(old_args, new_args) old != new && return true end - false + return false end -function plot!(plot::T) where T <: Union{Contour, Contour3d} +function plot!(plot::T) where {T <: Union{Contour, Contour3d}} x, y, z = plot[1:3] zrange = lift(nan_extrema, plot, z) levels = lift(plot, plot.levels, zrange) do levels, zrange - if levels isa AbstractVector{<: Number} + if levels isa AbstractVector{<:Number} return levels elseif levels isa Integer to_levels(levels, zrange) @@ -230,7 +230,7 @@ function plot!(plot::T) where T <: Union{Contour, Contour3d} end end - replace_automatic!(()-> zrange, plot, :colorrange) + replace_automatic!(() -> zrange, plot, :colorrange) @extract plot (labels, labelsize, labelfont, labelcolor, labelformatter) args = @extract plot (color, colormap, colorscale, colorrange, alpha) @@ -238,7 +238,7 @@ function plot!(plot::T) where T <: Union{Contour, Contour3d} args = (x, y, z, levels, level_colors, labels) arg_values = map(to_value, args) old_values = map(copy, arg_values) - points, colors, lev_pos_col = Observable.(contourlines(arg_values..., T); ignore_equal_values=true) + points, colors, lev_pos_col = Observable.(contourlines(arg_values..., T); ignore_equal_values = true) onany(plot, args...) do args... # contourlines is expensive enough, that it's worth to copy & check against old values # We need to copy, since the values may get mutated in place @@ -265,9 +265,10 @@ function plot!(plot::T) where T <: Union{Contour, Contour3d} transform_marker = false ) - lift(plot, scene.camera.projectionview, transformationmatrix(plot), scene.viewport, - labels, labelcolor, labelformatter, lev_pos_col - ) do _, _, _, labels, labelcolor, labelformatter, lev_pos_col + lift( + plot, scene.camera.projectionview, transformationmatrix(plot), scene.viewport, + labels, labelcolor, labelformatter, lev_pos_col + ) do _, _, _, labels, labelcolor, labelformatter, lev_pos_col labels || return pos = texts.positions[]; empty!(pos) rot = texts.rotation[]; empty!(rot) @@ -296,12 +297,12 @@ function plot!(plot::T) where T <: Union{Contour, Contour3d} return end - bboxes = lift(plot, labels, texts.text; ignore_equal_values=true) do labels, _ + bboxes = lift(plot, labels, texts.text; ignore_equal_values = true) do labels, _ labels || return return broadcast(texts.plots[1][1].val, texts.positions.val, texts.rotation.val) do gc, pt, rot # drop the depth component of the bounding box for 3D px_pos = project(scene, apply_transform(transform_func(plot), pt, space)) - bb = unchecked_boundingbox(gc, to_ndim(Point3f, px_pos, 0f0), to_rotation(rot)) + bb = unchecked_boundingbox(gc, to_ndim(Point3f, px_pos, 0.0f0), to_rotation(rot)) isfinite_rect(bb) || return Rect2f() Rect2f(bb) end @@ -344,23 +345,23 @@ function plot!(plot::T) where T <: Union{Contour, Contour3d} linecap = plot.linecap, joinstyle = plot.joinstyle, miter_limit = plot.miter_limit, - visible=plot.visible, - transparency=plot.transparency, - overdraw=plot.overdraw, - inspectable=plot.inspectable, - depth_shift=plot.depth_shift, - space=plot.space + visible = plot.visible, + transparency = plot.transparency, + overdraw = plot.overdraw, + inspectable = plot.inspectable, + depth_shift = plot.depth_shift, + space = plot.space ) - plot + return plot end -function data_limits(plot::Contour{<: Tuple{X, Y, Z}}) where {X, Y, Z} +function data_limits(plot::Contour{<:Tuple{X, Y, Z}}) where {X, Y, Z} mini_maxi = extrema_nan.((plot[1][], plot[2][])) mini = Vec3d(first.(mini_maxi)..., 0) maxi = Vec3d(last.(mini_maxi)..., 0) return Rect3d(mini, maxi .- mini) end -function boundingbox(plot::Contour{<: Tuple{X, Y, Z}}, space::Symbol = :data) where {X, Y, Z} +function boundingbox(plot::Contour{<:Tuple{X, Y, Z}}, space::Symbol = :data) where {X, Y, Z} return apply_transform_and_model(plot, data_limits(plot)) end # TODO: should this have a data_limits overload? diff --git a/src/basic_recipes/convenience_functions.jl b/src/basic_recipes/convenience_functions.jl index e54669b9361..05d887f9bc7 100644 --- a/src/basic_recipes/convenience_functions.jl +++ b/src/basic_recipes/convenience_functions.jl @@ -8,7 +8,7 @@ as horizontal colorbars. function showlibrary(lib::Symbol)::Scene cgrads = sort(PlotUtils.cgradients(lib)) PlotUtils.clibrary(lib) - showgradients(cgrads) + return showgradients(cgrads) end @@ -27,20 +27,20 @@ function showgradients( size = (800, length(cgrads) * 84), ) - f = Figure(; size=size) + f = Figure(; size = size) ax = Axis(f[1, 1]) labels = map(enumerate(cgrads)) do (i, cmap) c = to_colormap(cmap) image!( ax, - 0..10, - i..(i+1), - reshape(c, (length(c),1)) + 0 .. 10, + i .. (i + 1), + reshape(c, (length(c), 1)) ) cmapstr = string(cmap) - return ((i + (i + 1))/2, cmapstr) + return ((i + (i + 1)) / 2, cmapstr) end ax.yticks = (first.(labels), last.(labels)) diff --git a/src/basic_recipes/datashader.jl b/src/basic_recipes/datashader.jl index 321d1d75819..a01fce12529 100644 --- a/src/basic_recipes/datashader.jl +++ b/src/basic_recipes/datashader.jl @@ -1,221 +1,165 @@ # originally from https://github.com/cjdoris/ShadeYourData.jl module Aggregation -import Base.Threads: @threads -import Makie: Makie, (..), Rect2, widths -abstract type AggOp end + import Base.Threads: @threads + import Makie: Makie, (..), Rect2, widths + abstract type AggOp end -""" - Canvas(bounds::Rect2; resolution::Tuple{Int,Int}=(800, 800), op=AggCount()) - Canvas(xmin::Number, xmax::Number, ymin::Number, ymax::Number; args...) - -# Example - -```Julia -using Makie -canvas = Canvas(-1, 1, -1, 1; op=AggCount(), resolution=(800, 800)) -aggregate!(canvas, points; point_transform=reverse, method=AggThreads()) -aggregated_values = get_aggregation(canvas; operation=equalize_histogram, local_operation=identity) -# Recipes are defined for canvas as well and incorporate the `get_aggregation`, but `aggregate!` must be called manually. -image!(canvas; operation=equalize_histogram, local_operation=identity, colormap=:viridis, colorrange=(0, 20)) -surface!(canvas; operation=equalize_histogram, local_operation=identity) -``` -""" -mutable struct Canvas - bounds::Rect2{Float64} - resolution::Tuple{Int,Int} - op::AggOp - # temporaries / results - aggbuffer::Vector - pixelbuffer::Vector - data_extrema::Tuple{Float64,Float64} -end - -""" - get_aggregation(canvas::Canvas; operation=equalize_histogram, local_operation=identity, result=similar(canvas.pixelbuffer, canvas.resolution)) - -Basically does `operation(map!(local_operation, result, canvas.pixelbuffer))`, but does the correct reshaping of the flat pixelbuffer and -simplifies passing a local or global operation. -Allocates the result buffer every time and can be made non allocating by passing the correct result buffer. -""" -function get_aggregation(canvas::Canvas; operation=equalize_histogram, local_operation=identity, result=similar(canvas.pixelbuffer, canvas.resolution)) - pix_reshaped = Base.ReshapedArray(canvas.pixelbuffer, canvas.resolution, ()) - # we want to make it easy to set local_operation or operation, without them clashing, while also being able to set both! - if operation === Makie.automatic - postfunc = local_operation === identity ? Makie.equalize_histogram : identity - else - postfunc = operation - end - return postfunc(map!(local_operation, result, pix_reshaped)) -end - -Base.size(c::Canvas) = c.resolution -Base.:(==)(a::Canvas, b::Canvas) = size(a) == size(b) && (a.bounds == b.bounds) && a.op == b.op - -@inline update(a::AggOp, x, args...) = merge(a, x, embed(a, args...)) - -struct AggCount{T} <: AggOp end -AggCount() = AggCount{Int}() -null(::AggCount{T}) where {T} = zero(T) -embed(::AggCount{T}) where {T} = oneunit(T) -merge(::AggCount{T}, x::T, y::T) where {T} = x + y -value(::AggCount{T}, x::T) where {T} = x - -struct AggAny <: AggOp end -null(::AggAny) = false -embed(::AggAny) = true -merge(::AggAny, x::Bool, y::Bool) = x | y -value(::AggAny, x::Bool) = x - -struct AggSum{T} <: AggOp end -AggSum() = AggSum{Float64}() -null(::AggSum{T}) where {T} = zero(T) -embed(::AggSum{T}, x) where {T} = convert(T, x) -merge(::AggSum{T}, x::T, y::T) where {T} = x + y -value(::AggSum{T}, x::T) where {T} = x - -struct AggMean{T} <: AggOp end -AggMean() = AggMean{Float64}() -null(::AggMean{T}) where {T} = (zero(T), zero(T)) -embed(::AggMean{T}, x) where {T} = (convert(T, x), oneunit(T)) -merge(::AggMean{T}, x::Tuple{T,T}, y::Tuple{T,T}) where {T} = (x[1] + y[1], x[2] + y[2]) -value(::AggMean{T}, x::Tuple{T,T}) where {T} = float(x[1]) / float(x[2]) - -abstract type AggMethod end - -struct AggSerial <: AggMethod end -struct AggThreads <: AggMethod end - -function Canvas(xmin::Number, xmax::Number, ymin::Number, ymax::Number; args...) - return Canvas(Rect2(xmin, ymin, xmax - xmin, ymax - ymin); args...) -end - -function Canvas(bounds::Rect2; resolution::Tuple{Int,Int}=(800, 800), op=AggCount()) - xsize, ysize = resolution - n_elements = xsize * ysize - o0 = null(op) - v0 = value(op, o0) - aggbuffer = fill(o0, n_elements) - pixelbuffer = fill(v0, n_elements) - # using ReshapedArray directly like this is not advised, but as it lives only briefly it should be ok - return Canvas(Rect2{Float64}(bounds), resolution, op, aggbuffer, pixelbuffer, (v0, v0)) -end - -n_threads(::AggSerial) = 1 -n_threads(::AggThreads) = Threads.nthreads() - -function Base.resize!(canvas::Canvas, resolution::Tuple{Int,Int}, nthreads=1) - npixel = prod(resolution) - n_elements = npixel * nthreads - length(canvas.pixelbuffer) == npixel && length(canvas.aggbuffer) == n_elements && return false - canvas.resolution = resolution - Base.resize!(canvas.pixelbuffer, npixel) - Base.resize!(canvas.aggbuffer, n_elements) - return true -end - -function change_op!(canvas::Canvas, op::AggOp) - op == canvas.op && return false - o0 = null(op) - v0 = value(op, o0) - if eltype(canvas.aggbuffer) != typeof(o0) - canvas.aggbuffer = fill(o0, size(c.aggbuffer)) - canvas.pixelbuffer = fill(v0, size(c.pixelbuffer)) + """ + Canvas(bounds::Rect2; resolution::Tuple{Int,Int}=(800, 800), op=AggCount()) + Canvas(xmin::Number, xmax::Number, ymin::Number, ymax::Number; args...) + + # Example + + ```Julia + using Makie + canvas = Canvas(-1, 1, -1, 1; op=AggCount(), resolution=(800, 800)) + aggregate!(canvas, points; point_transform=reverse, method=AggThreads()) + aggregated_values = get_aggregation(canvas; operation=equalize_histogram, local_operation=identity) + # Recipes are defined for canvas as well and incorporate the `get_aggregation`, but `aggregate!` must be called manually. + image!(canvas; operation=equalize_histogram, local_operation=identity, colormap=:viridis, colorrange=(0, 20)) + surface!(canvas; operation=equalize_histogram, local_operation=identity) + ``` + """ + mutable struct Canvas + bounds::Rect2{Float64} + resolution::Tuple{Int, Int} + op::AggOp + # temporaries / results + aggbuffer::Vector + pixelbuffer::Vector + data_extrema::Tuple{Float64, Float64} end - return true -end - -using InteractiveUtils -""" - aggregate!(c::Canvas, points; point_transform=identity, method::AggMethod=AggSerial()) + """ + get_aggregation(canvas::Canvas; operation=equalize_histogram, local_operation=identity, result=similar(canvas.pixelbuffer, canvas.resolution)) -Aggregate points into a canvas. The points are transformed by `point_transform` before aggregation. -Method can be `AggSerial()` or `AggThreads()`. -""" -function aggregate!(c::Canvas, points; point_transform=identity, method::AggMethod=AggSerial()) - resize!(c, c.resolution, n_threads(method)) # make sure we have the right size for the method - aggbuffer, pixelbuffer = c.aggbuffer, c.pixelbuffer - fill!(aggbuffer, null(c.op)) - return aggregation_implementation!(method, aggbuffer, pixelbuffer, c, c.op, points, point_transform) -end - -function aggregation_implementation!(::AggSerial, - aggbuffer::AbstractVector, pixelbuffer::AbstractVector, - c::Canvas, op::AggOp, - points, point_transform) - (xmin, ymin), (xmax, ymax) = extrema(c.bounds) - xsize, ysize = size(c) - xwidth, ywidth = widths(c.bounds) - xscale = xsize / (xwidth + eps(xwidth)) - yscale = ysize / (ywidth + eps(ywidth)) - - @assert length(aggbuffer) == xsize * ysize - @assert length(pixelbuffer) == xsize * ysize - @assert eltype(aggbuffer) === typeof(null(op)) "$(eltype(aggbuffer)) !== $(typeof(null(op)))" - - # using ReshapedArray directly like this is not advised, but as it lives only briefly it should be ok - out = Base.ReshapedArray(aggbuffer, (xsize, ysize), ()) - for point in points - p = point_transform(point) - x = p[1] - y = p[2] - if length(p) > 2 # should compile away - z = p[3] + Basically does `operation(map!(local_operation, result, canvas.pixelbuffer))`, but does the correct reshaping of the flat pixelbuffer and + simplifies passing a local or global operation. + Allocates the result buffer every time and can be made non allocating by passing the correct result buffer. + """ + function get_aggregation(canvas::Canvas; operation = equalize_histogram, local_operation = identity, result = similar(canvas.pixelbuffer, canvas.resolution)) + pix_reshaped = Base.ReshapedArray(canvas.pixelbuffer, canvas.resolution, ()) + # we want to make it easy to set local_operation or operation, without them clashing, while also being able to set both! + if operation === Makie.automatic + postfunc = local_operation === identity ? Makie.equalize_histogram : identity + else + postfunc = operation end - xmin ≤ x ≤ xmax || continue - ymin ≤ y ≤ ymax || continue - i = 1 + floor(Int, xscale * (x - xmin)) - j = 1 + floor(Int, yscale * (y - ymin)) - if length(p) == 2 # should compile away - out[i, j] = update(op, out[i, j]) - elseif length(p) == 3 - out[i, j] = update(op, out[i, j], z) + return postfunc(map!(local_operation, result, pix_reshaped)) + end + + Base.size(c::Canvas) = c.resolution + Base.:(==)(a::Canvas, b::Canvas) = size(a) == size(b) && (a.bounds == b.bounds) && a.op == b.op + + @inline update(a::AggOp, x, args...) = merge(a, x, embed(a, args...)) + + struct AggCount{T} <: AggOp end + AggCount() = AggCount{Int}() + null(::AggCount{T}) where {T} = zero(T) + embed(::AggCount{T}) where {T} = oneunit(T) + merge(::AggCount{T}, x::T, y::T) where {T} = x + y + value(::AggCount{T}, x::T) where {T} = x + + struct AggAny <: AggOp end + null(::AggAny) = false + embed(::AggAny) = true + merge(::AggAny, x::Bool, y::Bool) = x | y + value(::AggAny, x::Bool) = x + + struct AggSum{T} <: AggOp end + AggSum() = AggSum{Float64}() + null(::AggSum{T}) where {T} = zero(T) + embed(::AggSum{T}, x) where {T} = convert(T, x) + merge(::AggSum{T}, x::T, y::T) where {T} = x + y + value(::AggSum{T}, x::T) where {T} = x + + struct AggMean{T} <: AggOp end + AggMean() = AggMean{Float64}() + null(::AggMean{T}) where {T} = (zero(T), zero(T)) + embed(::AggMean{T}, x) where {T} = (convert(T, x), oneunit(T)) + merge(::AggMean{T}, x::Tuple{T, T}, y::Tuple{T, T}) where {T} = (x[1] + y[1], x[2] + y[2]) + value(::AggMean{T}, x::Tuple{T, T}) where {T} = float(x[1]) / float(x[2]) + + abstract type AggMethod end + + struct AggSerial <: AggMethod end + struct AggThreads <: AggMethod end + + function Canvas(xmin::Number, xmax::Number, ymin::Number, ymax::Number; args...) + return Canvas(Rect2(xmin, ymin, xmax - xmin, ymax - ymin); args...) + end + + function Canvas(bounds::Rect2; resolution::Tuple{Int, Int} = (800, 800), op = AggCount()) + xsize, ysize = resolution + n_elements = xsize * ysize + o0 = null(op) + v0 = value(op, o0) + aggbuffer = fill(o0, n_elements) + pixelbuffer = fill(v0, n_elements) + # using ReshapedArray directly like this is not advised, but as it lives only briefly it should be ok + return Canvas(Rect2{Float64}(bounds), resolution, op, aggbuffer, pixelbuffer, (v0, v0)) + end + + n_threads(::AggSerial) = 1 + n_threads(::AggThreads) = Threads.nthreads() + + function Base.resize!(canvas::Canvas, resolution::Tuple{Int, Int}, nthreads = 1) + npixel = prod(resolution) + n_elements = npixel * nthreads + length(canvas.pixelbuffer) == npixel && length(canvas.aggbuffer) == n_elements && return false + canvas.resolution = resolution + Base.resize!(canvas.pixelbuffer, npixel) + Base.resize!(canvas.aggbuffer, n_elements) + return true + end + + function change_op!(canvas::Canvas, op::AggOp) + op == canvas.op && return false + o0 = null(op) + v0 = value(op, o0) + if eltype(canvas.aggbuffer) != typeof(o0) + canvas.aggbuffer = fill(o0, size(c.aggbuffer)) + canvas.pixelbuffer = fill(v0, size(c.pixelbuffer)) end + return true end - mini, maxi = Inf, -Inf - map!(pixelbuffer, aggbuffer) do x - final_value = value(op, x) - if isfinite(final_value) - mini = min(final_value, mini) - maxi = max(final_value, maxi) - end - return final_value - end - c.data_extrema = (mini, maxi) - return c -end - -function aggregation_implementation!(::AggThreads, - aggbuffer::AbstractVector, pixelbuffer::AbstractVector, - c::Canvas, op::AggOp, - points, point_transform) - (xmin, ymin), (xmax, ymax) = extrema(c.bounds) - xsize, ysize = size(c) - # by adding eps to width we can use the scaling factor plus floor directly to compute the bin indices - xwidth = xmax - xmin - xscale = xsize / (xwidth + eps(xwidth)) - ywidth = ymax - ymin - yscale = ysize / (ywidth + eps(ywidth)) - # each thread reduces some of the data separately - @assert length(aggbuffer) == Threads.nthreads() * xsize * ysize - @assert length(pixelbuffer) == xsize * ysize - @assert eltype(aggbuffer) === typeof(null(op)) "$(eltype(aggbuffer)) !== $(typeof(null(op)))" - - # using ReshapedArray directly like this is not advised, but as it lives only briefly it should be ok - # https://stackoverflow.com/questions/41781621/resizing-a-matrix/41804908#41804908 - out = Base.ReshapedArray(aggbuffer, (xsize, ysize, Threads.nthreads()), ()) - out2 = Base.ReshapedArray(pixelbuffer, (xsize, ysize), ()) - - n = length(points) - chunks = round.(Int, range(1, n; length=Threads.nthreads() + 1)) - - @threads for t in 1:Threads.nthreads() - from = chunks[t] - to = chunks[t + 1] - @inbounds for idx in from:to - p = point_transform(points[idx]) + using InteractiveUtils + + """ + aggregate!(c::Canvas, points; point_transform=identity, method::AggMethod=AggSerial()) + + Aggregate points into a canvas. The points are transformed by `point_transform` before aggregation. + Method can be `AggSerial()` or `AggThreads()`. + """ + function aggregate!(c::Canvas, points; point_transform = identity, method::AggMethod = AggSerial()) + resize!(c, c.resolution, n_threads(method)) # make sure we have the right size for the method + aggbuffer, pixelbuffer = c.aggbuffer, c.pixelbuffer + fill!(aggbuffer, null(c.op)) + return aggregation_implementation!(method, aggbuffer, pixelbuffer, c, c.op, points, point_transform) + end + + function aggregation_implementation!( + ::AggSerial, + aggbuffer::AbstractVector, pixelbuffer::AbstractVector, + c::Canvas, op::AggOp, + points, point_transform + ) + (xmin, ymin), (xmax, ymax) = extrema(c.bounds) + xsize, ysize = size(c) + xwidth, ywidth = widths(c.bounds) + xscale = xsize / (xwidth + eps(xwidth)) + yscale = ysize / (ywidth + eps(ywidth)) + + @assert length(aggbuffer) == xsize * ysize + @assert length(pixelbuffer) == xsize * ysize + @assert eltype(aggbuffer) === typeof(null(op)) "$(eltype(aggbuffer)) !== $(typeof(null(op)))" + + # using ReshapedArray directly like this is not advised, but as it lives only briefly it should be ok + out = Base.ReshapedArray(aggbuffer, (xsize, ysize), ()) + for point in points + p = point_transform(point) x = p[1] y = p[2] if length(p) > 2 # should compile away @@ -226,43 +170,103 @@ function aggregation_implementation!(::AggThreads, i = 1 + floor(Int, xscale * (x - xmin)) j = 1 + floor(Int, yscale * (y - ymin)) if length(p) == 2 # should compile away - out[i, j, t] = update(op, out[i, j, t]) + out[i, j] = update(op, out[i, j]) elseif length(p) == 3 - out[i, j, t] = update(op, out[i, j, t], z) + out[i, j] = update(op, out[i, j], z) end end - end - # reduce along the thread dimension - mini, maxi = Inf, -Inf - for j in 1:ysize - @inbounds for i in 1:xsize - val = out[i, j, 1] - for t in 2:Threads.nthreads() - val = merge(op, val, out[i, j, t]) - end - # update the value in out2 directly in this loop - final_value = value(op, val) + + mini, maxi = Inf, -Inf + map!(pixelbuffer, aggbuffer) do x + final_value = value(op, x) if isfinite(final_value) mini = min(final_value, mini) maxi = max(final_value, maxi) end - out2[i, j] = final_value + return final_value end + c.data_extrema = (mini, maxi) + return c end - c.data_extrema = (mini, maxi) - return c -end -export AggAny, AggCount, AggMean, AggSum, AggSerial, AggThreads + function aggregation_implementation!( + ::AggThreads, + aggbuffer::AbstractVector, pixelbuffer::AbstractVector, + c::Canvas, op::AggOp, + points, point_transform + ) + (xmin, ymin), (xmax, ymax) = extrema(c.bounds) + xsize, ysize = size(c) + # by adding eps to width we can use the scaling factor plus floor directly to compute the bin indices + xwidth = xmax - xmin + xscale = xsize / (xwidth + eps(xwidth)) + ywidth = ymax - ymin + yscale = ysize / (ywidth + eps(ywidth)) + # each thread reduces some of the data separately + @assert length(aggbuffer) == Threads.nthreads() * xsize * ysize + @assert length(pixelbuffer) == xsize * ysize + @assert eltype(aggbuffer) === typeof(null(op)) "$(eltype(aggbuffer)) !== $(typeof(null(op)))" + + # using ReshapedArray directly like this is not advised, but as it lives only briefly it should be ok + # https://stackoverflow.com/questions/41781621/resizing-a-matrix/41804908#41804908 + out = Base.ReshapedArray(aggbuffer, (xsize, ysize, Threads.nthreads()), ()) + out2 = Base.ReshapedArray(pixelbuffer, (xsize, ysize), ()) + + n = length(points) + chunks = round.(Int, range(1, n; length = Threads.nthreads() + 1)) + + @threads for t in 1:Threads.nthreads() + from = chunks[t] + to = chunks[t + 1] + @inbounds for idx in from:to + p = point_transform(points[idx]) + x = p[1] + y = p[2] + if length(p) > 2 # should compile away + z = p[3] + end + xmin ≤ x ≤ xmax || continue + ymin ≤ y ≤ ymax || continue + i = 1 + floor(Int, xscale * (x - xmin)) + j = 1 + floor(Int, yscale * (y - ymin)) + if length(p) == 2 # should compile away + out[i, j, t] = update(op, out[i, j, t]) + elseif length(p) == 3 + out[i, j, t] = update(op, out[i, j, t], z) + end + end + end + # reduce along the thread dimension + mini, maxi = Inf, -Inf + for j in 1:ysize + @inbounds for i in 1:xsize + val = out[i, j, 1] + for t in 2:Threads.nthreads() + val = merge(op, val, out[i, j, t]) + end + # update the value in out2 directly in this loop + final_value = value(op, val) + if isfinite(final_value) + mini = min(final_value, mini) + maxi = max(final_value, maxi) + end + out2[i, j] = final_value + end + end + c.data_extrema = (mini, maxi) + return c + end + + export AggAny, AggCount, AggMean, AggSum, AggSerial, AggThreads end using ..Aggregation using ..Aggregation: Canvas, change_op!, aggregate! -function equalize_histogram(matrix; nbins=256) - h_eq = StatsBase.fit(StatsBase.Histogram, vec(matrix); nbins=nbins) - h_eq = normalize(h_eq; mode=:density) +function equalize_histogram(matrix; nbins = 256) + h_eq = StatsBase.fit(StatsBase.Histogram, vec(matrix); nbins = nbins) + h_eq = normalize(h_eq; mode = :density) cdf = cumsum(h_eq.weights) cdf = cdf / cdf[end] edg = h_eq.edges[1] @@ -316,11 +320,11 @@ For best performance, use `method=Makie.AggThreads()` and make sure to start jul """ Defaults to `Makie.equalize_histogram` function which gets called on the whole get_aggregation array before display (`operation(final_aggregation_result)`). """ - operation=automatic + operation = automatic """ Function which gets called on each element after the aggregation (`map!(x-> local_operation(x), final_aggregation_result)`). """ - local_operation=identity + local_operation = identity """ Function which gets applied to every point before aggregating it. @@ -363,7 +367,7 @@ end function canvas_obs(p::DataShader, limits::Observable, pixel_area::Observable, op, binsize::Observable) - canvas = Canvas(limits[]; resolution=(widths(pixel_area[])...,), op=op[]) + canvas = Canvas(limits[]; resolution = (widths(pixel_area[])...,), op = op[]) canvas_obs = Observable(canvas) onany(p, limits, pixel_area, binsize, op) do lims, pxarea, binsize, op binsize isa Int || error("Bin factor $binsize is not an Int.") @@ -382,24 +386,24 @@ function canvas_obs(p::DataShader, limits::Observable, pixel_area::Observable, o return canvas_obs end -function Makie.plot!(p::DataShader{<: Tuple{<: AbstractVector{<: Point}}}) +function Makie.plot!(p::DataShader{<:Tuple{<:AbstractVector{<:Point}}}) scene = parent_scene(p) limits = projview_to_2d_limits(p) - viewport = lift(identity, p, scene.viewport; ignore_equal_values=true) + viewport = lift(identity, p, scene.viewport; ignore_equal_values = true) canvas = canvas_obs(p, limits, viewport, p.agg, p.binsize) p._boundingbox = lift(fast_bb, p.points, p.point_transform) on_func = p.async[] ? onany_latest : onany canvas_with_aggregation = Observable(canvas[]) # Canvas that only gets notified after get_aggregation happened p.canvas = canvas_with_aggregation colorrange = Observable(Vec2f(0, 1)) - on(p.colorrange; update=true) do crange + on(p.colorrange; update = true) do crange if !(crange isa Automatic) colorrange[] = Vec2f(crange) end end on_func(p, canvas, p.points, p.point_transform) do canvas, points, f - Aggregation.aggregate!(canvas, points; point_transform=f, method=p.method[]) + Aggregation.aggregate!(canvas, points; point_transform = f, method = p.method[]) canvas_with_aggregation[] = canvas # If not automatic, it will get updated by the above on(p.colorrange) if p.colorrange[] isa Automatic @@ -408,22 +412,25 @@ function Makie.plot!(p::DataShader{<: Tuple{<: AbstractVector{<: Point}}}) return end p.raw_colorrange = colorrange - image!(p, canvas_with_aggregation, p.operation, p.local_operation; - interpolate=p.interpolate, + image!( + p, canvas_with_aggregation, p.operation, p.local_operation; + interpolate = p.interpolate, MakieCore.generic_plot_attributes(p)..., - MakieCore.colormap_attributes(p)...) + MakieCore.colormap_attributes(p)... + ) return p end -function aggregate_categories!(canvases, categories; method=AggThreads()) +function aggregate_categories!(canvases, categories; method = AggThreads()) for (k, canvas) in canvases points = categories[k] - Aggregation.aggregate!(canvas, points; method=method) + Aggregation.aggregate!(canvas, points; method = method) end + return end -Makie.convert_arguments(::Type{<:DataShader}, x::Dict{String,Vector{<:Point2}}) = (x,) +Makie.convert_arguments(::Type{<:DataShader}, x::Dict{String, Vector{<:Point2}}) = (x,) function Makie.convert_arguments(::Type{<:DataShader}, groups::AbstractVector, points::AbstractVector{<:Point2}) if length(groups) != length(points) @@ -431,7 +438,7 @@ function Makie.convert_arguments(::Type{<:DataShader}, groups::AbstractVector, p end categories = Dict{String, Vector{Point2f}}() for (g, p) in zip(groups, points) - gpoints = get!(()-> Point2f[], categories, string(g)) + gpoints = get!(() -> Point2f[], categories, string(g)) push!(gpoints, p) end return (categories,) @@ -440,26 +447,28 @@ end function Makie.plot!(p::DataShader{<:Tuple{Dict{String, Vector{Point{2, Float32}}}}}) scene = parent_scene(p) limits = projview_to_2d_limits(p) - viewport = lift(identity, p, scene.viewport; ignore_equal_values=true) + viewport = lift(identity, p, scene.viewport; ignore_equal_values = true) canvas = canvas_obs(p, limits, viewport, Observable(AggCount{Float32}()), p.binsize) p._boundingbox = lift(p, p.points, p.point_transform) do cats, func rects = map(points -> fast_bb(points, func), values(cats)) return reduce(union, rects) end categories = p.points[] - canvases = Dict(k => Canvas(canvas[].bounds; resolution=canvas[].resolution, op=AggCount{Float32}()) - for (k, v) in categories) + canvases = Dict( + k => Canvas(canvas[].bounds; resolution = canvas[].resolution, op = AggCount{Float32}()) + for (k, v) in categories + ) on_func = p.async[] ? onany_latest : onany canvas_with_aggregation = Observable(canvas[]) # Canvas that only gets notified after get_aggregation happened p.canvas = canvas_with_aggregation - toal_value = Observable(0f0) + toal_value = Observable(0.0f0) on_func(p, canvas, p.points) do canvas, cats for (k, c) in canvases Base.resize!(c, canvas.resolution) c.bounds = canvas.bounds end - aggregate_categories!(canvases, cats; method=p.method[]) + aggregate_categories!(canvases, cats; method = p.method[]) toal_value[] = Float32(maximum(sum(map(x -> x.pixelbuffer, values(canvases))))) return end @@ -470,7 +479,7 @@ function Makie.plot!(p::DataShader{<:Tuple{Dict{String, Vector{Point{2, Float32} for (k, canv) in canvases color = colors[k] cmap = [(color, 0.0), (color, 1.0)] - image!(p, canv, identity, op; colorrange=Vec2f(0, 1), colormap=cmap) + image!(p, canv, identity, op; colorrange = Vec2f(0, 1), colormap = cmap) end return p end @@ -478,8 +487,8 @@ end data_limits(p::DataShader) = p._boundingbox[] boundingbox(p::DataShader, space::Symbol = :data) = apply_transform_and_model(p, p._boundingbox[]) -function convert_arguments(P::Type{<:Union{MeshScatter,Image,Surface,Contour,Contour3d}}, canvas::Canvas, operation=automatic, local_operation=identity) - pixel = Aggregation.get_aggregation(canvas; operation=operation, local_operation=local_operation) +function convert_arguments(P::Type{<:Union{MeshScatter, Image, Surface, Contour, Contour3d}}, canvas::Canvas, operation = automatic, local_operation = identity) + pixel = Aggregation.get_aggregation(canvas; operation = operation, local_operation = local_operation) (xmin, ymin), (xmax, ymax) = extrema(canvas.bounds) return convert_arguments(P, xmin .. xmax, ymin .. ymax, pixel) end @@ -492,12 +501,12 @@ Base.getindex(x::FakePlot, key::Symbol) = getindex(getfield(x, :attributes), key function get_plots(plot::DataShader) return map(collect(plot._categories[])) do (name, color) - return FakePlot(Attributes(; label=name, color=color)) + return FakePlot(Attributes(; label = name, color = color)) end end function legendelements(plot::FakePlot, legend) - return [PolyElement(; color=plot.attributes.color, strokecolor=legend.polystrokecolor, strokewidth=legend.polystrokewidth)] + return [PolyElement(; color = plot.attributes.color, strokecolor = legend.polystrokecolor, strokewidth = legend.polystrokewidth)] end # Sadly we must define the colorbar here and can't use the default fallback, @@ -507,12 +516,13 @@ end function extract_colormap(plot::DataShader) color = lift(x -> x.aggbuffer, plot, plot.canvas) return ColorMapping( - color[], color, plot.colormap, plot.raw_colorrange, + color[], color, plot.colormap, plot.raw_colorrange, plot.colorscale, plot.alpha, plot.highclip, plot.lowclip, - plot.nan_color) + plot.nan_color + ) end function xy_to_rect(x, y) @@ -531,7 +541,7 @@ If the array doesn't support this, it will be converted to an interpolation obje * `method` is the interpolation method used, defaulting to `Interpolations.Linear()`. * `update_while_button_pressed` will update the heatmap while a mouse button is pressed, useful for zooming/panning. Set it to false for e.g. WGLMakie to avoid updating while dragging. """ -struct Resampler{T<:AbstractMatrix{<:Union{Real,Colorant}}} +struct Resampler{T <: AbstractMatrix{<:Union{Real, Colorant}}} data::T max_resolution::Union{Automatic, Bool} update_while_button_pressed::Bool @@ -540,7 +550,7 @@ end using Interpolations: Interpolations using ImageBase: ImageBase -function Resampler(data; resolution=automatic, method=Interpolations.Linear(), update_while_button_pressed=false) +function Resampler(data; resolution = automatic, method = Interpolations.Linear(), update_while_button_pressed = false) # Our interpolation interface is to do matrix(linrange, linrange) # There doesn't seem to be an official trait for this, # so we fall back to just check if this method applies: @@ -558,7 +568,7 @@ function Resampler(data; resolution=automatic, method=Interpolations.Linear(), u end end -const HeatmapShader = Heatmap{<:Tuple{EndPoints{Float32},EndPoints{Float32},<:Resampler}} +const HeatmapShader = Heatmap{<:Tuple{EndPoints{Float32}, EndPoints{Float32}, <:Resampler}} # The things we need to do, to allow the atomic Heatmap plot type to be overloaded as a recipe struct HeatmapShaderConversion <: MakieCore.ConversionTrait end @@ -571,7 +581,7 @@ function conversion_trait(::Type{<:Heatmap}, ::Resampler) end function MakieCore.types_for_plot_arguments(::Type{<:Heatmap}, ::HeatmapShaderConversion) - return Tuple{EndPoints{Float32},EndPoints{Float32},<:Resampler} + return Tuple{EndPoints{Float32}, EndPoints{Float32}, <:Resampler} end function data_limits(p::HeatmapShader) @@ -581,7 +591,7 @@ function data_limits(p::HeatmapShader) return Rect3f(mini, widths) end -function boundingbox(p::HeatmapShader, space::Symbol=:data) +function boundingbox(p::HeatmapShader, space::Symbol = :data) return apply_transform_and_model(p, data_limits(p)) end @@ -637,7 +647,7 @@ function convert_arguments(::Type{Heatmap}, x, y, image::Resampler) end function empty_channel!(channel::Channel) - lock(channel.cond_take) do + return lock(channel.cond_take) do while !isempty(channel) take!(channel) end @@ -669,15 +679,15 @@ function Makie.plot!(p::HeatmapShader) x, y = p.x, p.y max_resolution = lift(p, p.values, scene.viewport) do resampler, viewport res = resampler.max_resolution isa Automatic ? widths(viewport) : - ntuple(x -> resampler.max_resolution, 2) + ntuple(x -> resampler.max_resolution, 2) return max.(res, 512) # Not sure why, but viewport can become (1, 1) end - image = lift(x-> x.data, p, p.values) - image_area = lift(xy_to_rect, x, y; ignore_equal_values=true) + image = lift(x -> x.data, p, p.values) + image_area = lift(xy_to_rect, x, y; ignore_equal_values = true) x_y_overview_image = lift(resample_image, p, x, y, image, max_resolution, image_area) overview_image = lift(last, x_y_overview_image) - colorrange = lift(p, p.colorrange, overview_image; ignore_equal_values=true) do crange, image + colorrange = lift(p, p.colorrange, overview_image; ignore_equal_values = true) do crange, image if eltype(image) <: Number if crange isa Automatic return nan_extrema(image) @@ -692,12 +702,12 @@ function Makie.plot!(p::HeatmapShader) cpa = MakieCore.colormap_attributes(p) # Create an overview image that gets shown behind, so we always see the "big picture" # In case updating the detailed view takes longer - lp = image!(p, x, y, overview_image; gpa..., cpa..., interpolate=p.interpolate, colorrange=colorrange) + lp = image!(p, x, y, overview_image; gpa..., cpa..., interpolate = p.interpolate, colorrange = colorrange) translate!(lp, 0, 0, -1) first_downsample = resample_image(x[], y[], image[], max_resolution[], limits[]) # We hide the image when outside of the limits, but we also want to correctly forward, p.visible - visible = Observable(p.visible[]; ignore_equal_values=true) + visible = Observable(p.visible[]; ignore_equal_values = true) on(p, p.visible) do v visible[] = v return @@ -708,7 +718,7 @@ function Makie.plot!(p::HeatmapShader) first_downsample = EndPoints{Float32}(0, 1), EndPoints{Float32}(0, 1), zeros(Float32, 2, 2) end # Make sure we don't trigger an event if the image/xy stays the same - args = map(arg -> lift(identity, p, arg; ignore_equal_values=true), (x, y, image, max_resolution)) + args = map(arg -> lift(identity, p, arg; ignore_equal_values = true), (x, y, image, max_resolution)) CT = Tuple{typeof.(to_value.(args))..., typeof(limits_slow[])} @@ -716,7 +726,7 @@ function Makie.plot!(p::HeatmapShader) # To make this threadsafe, the observable needs to be triggered from the current thread # So we need another channel for the result (unbuffered, so `put!` blocks while the image is being updated) image_to_obs = Channel{Union{Nothing, typeof(first_downsample)}}(0) - do_resample = Channel{CT}(Inf; spawn=true) do ch + do_resample = Channel{CT}(Inf; spawn = true) do ch for (x, y, image, res, limits) in ch if isempty(ch) # only update if there is no newer image queued resampled = resample_image(x, y, image, res, limits) @@ -736,7 +746,7 @@ function Makie.plot!(p::HeatmapShader) imgp = image!( p, first_downsample...; - gpa..., cpa..., interpolate=p.interpolate, colorrange=colorrange, visible=visible, + gpa..., cpa..., interpolate = p.interpolate, colorrange = colorrange, visible = visible, ) # We need to update the image from the same thread as the one that created it @@ -763,11 +773,11 @@ function Makie.plot!(p::HeatmapShader) return p end -struct Pyramid{T,M<:AbstractMatrix{T}} <: AbstractMatrix{T} +struct Pyramid{T, M <: AbstractMatrix{T}} <: AbstractMatrix{T} data::Vector{M} end -function Pyramid(data::AbstractMatrix; min_resolution=1024, mode=Interpolations.Linear()) +function Pyramid(data::AbstractMatrix; min_resolution = 1024, mode = Interpolations.Linear()) ranges(d) = (LinRange(1, size(data, 1), size(d, 1)), LinRange(1, size(data, 2), size(d, 2))) ET = ImageBase.restrict_eltype(first(data)) resized = convert(Matrix{ET}, data) diff --git a/src/basic_recipes/error_and_rangebars.jl b/src/basic_recipes/error_and_rangebars.jl index 240697f0012..c65a8b2e6e0 100644 --- a/src/basic_recipes/error_and_rangebars.jl +++ b/src/basic_recipes/error_and_rangebars.jl @@ -64,39 +64,41 @@ function convert_arguments(::Type{<:Errorbars}, x::RealOrVec, y::RealOrVec, erro xyerr = broadcast(x, y, error_both) do x, y, e Vec4{T}(x, y, e, e) end - (xyerr,) + return (xyerr,) end RealOrVec function convert_arguments(::Type{<:Errorbars}, x::RealOrVec, y::RealOrVec, error_low::RealOrVec, error_high::RealOrVec) T = float_type(x, y, error_low, error_high) xyerr = broadcast(Vec4{T}, x, y, error_low, error_high) - (xyerr,) + return (xyerr,) end -function convert_arguments(::Type{<:Errorbars}, x::RealOrVec, y::RealOrVec, error_low_high::AbstractVector{<:VecTypes{2, T}}) where T +function convert_arguments(::Type{<:Errorbars}, x::RealOrVec, y::RealOrVec, error_low_high::AbstractVector{<:VecTypes{2, T}}) where {T} T_out = float_type(float_type(x, y), T) xyerr = broadcast(x, y, error_low_high) do x, y, (el, eh) Vec4{T_out}(x, y, el, eh) end - (xyerr,) + return (xyerr,) end -function convert_arguments(::Type{<:Errorbars}, xy::AbstractVector{<:VecTypes{2,T}}, - error_both::RealOrVec) where {T} +function convert_arguments( + ::Type{<:Errorbars}, xy::AbstractVector{<:VecTypes{2, T}}, + error_both::RealOrVec + ) where {T} T_out = float_type(T, float_type(error_both)) xyerr = broadcast(xy, error_both) do (x, y), e Vec4{T_out}(x, y, e, e) end - (xyerr,) + return (xyerr,) end -function convert_arguments(::Type{<:Errorbars}, xy::AbstractVector{<:VecTypes{2, T}}, error_low::RealOrVec, error_high::RealOrVec) where T +function convert_arguments(::Type{<:Errorbars}, xy::AbstractVector{<:VecTypes{2, T}}, error_low::RealOrVec, error_high::RealOrVec) where {T} T_out = float_type(T, float_type(error_low, error_high)) xyerr = broadcast(xy, error_low, error_high) do (x, y), el, eh Vec4{T_out}(x, y, el, eh) end - (xyerr,) + return (xyerr,) end function convert_arguments(::Type{<:Errorbars}, xy::AbstractVector{<:VecTypes{2, T1}}, error_low_high::AbstractVector{<:VecTypes{2, T2}}) where {T1, T2} @@ -104,15 +106,15 @@ function convert_arguments(::Type{<:Errorbars}, xy::AbstractVector{<:VecTypes{2, xyerr = broadcast(xy, error_low_high) do (x, y), (el, eh) Vec4{T_out}(x, y, el, eh) end - (xyerr,) + return (xyerr,) end -function convert_arguments(::Type{<:Errorbars}, xy_error_both::AbstractVector{<:VecTypes{3, T}}) where T +function convert_arguments(::Type{<:Errorbars}, xy_error_both::AbstractVector{<:VecTypes{3, T}}) where {T} T_out = float_type(T) xyerr = broadcast(xy_error_both) do (x, y, e) Vec4{T_out}(x, y, e, e) end - (xyerr,) + return (xyerr,) end ### conversions for rangebars @@ -123,13 +125,15 @@ function convert_arguments(::Type{<:Rangebars}, val::RealOrVec, low::RealOrVec, return (val_low_high,) end -function convert_arguments(::Type{<:Rangebars}, val::RealOrVec, - low_high::AbstractVector{<:VecTypes{2,T}}) where {T} +function convert_arguments( + ::Type{<:Rangebars}, val::RealOrVec, + low_high::AbstractVector{<:VecTypes{2, T}} + ) where {T} T_out = float_type(float_type(val), T) val_low_high = broadcast(val, low_high) do val, (low, high) Vec3{T_out}(val, low, high) end - (val_low_high,) + return (val_low_high,) end Makie.convert_arguments(P::Type{<:Rangebars}, x::AbstractVector{<:Number}, y::AbstractVector{<:Interval}) = @@ -164,7 +168,7 @@ function Makie.plot!(plot::Errorbars{<:Tuple{AbstractVector{<:Vec{4}}}}) return output end - _plot_bars!(plot, linesegpairs, is_in_y_direction) + return _plot_bars!(plot, linesegpairs, is_in_y_direction) end @@ -194,29 +198,33 @@ function Makie.plot!(plot::Rangebars{<:Tuple{AbstractVector{<:Vec{3}}}}) return output end - _plot_bars!(plot, linesegpairs, is_in_y_direction) + return _plot_bars!(plot, linesegpairs, is_in_y_direction) end - function _plot_bars!(plot, linesegpairs, is_in_y_direction) f_if(condition, f, arg) = condition ? f(arg) : arg @extract plot ( whiskerwidth, color, linewidth, linecap, visible, colormap, colorscale, colorrange, - inspectable, transparency) + inspectable, transparency, + ) scene = parent_scene(plot) - whiskers = lift(plot, linesegpairs, scene.camera.projectionview, plot.model, - scene.viewport, transform_func(plot), whiskerwidth) do endpoints, _, _, _, _, whiskerwidth + whiskers = lift( + plot, linesegpairs, scene.camera.projectionview, plot.model, + scene.viewport, transform_func(plot), whiskerwidth + ) do endpoints, _, _, _, _, whiskerwidth screenendpoints = plot_to_screen(plot, endpoints) screenendpoints_shifted_pairs = map(screenendpoints) do sep - (sep .+ f_if(is_in_y_direction[], reverse, Point(0, -whiskerwidth/2)), - sep .+ f_if(is_in_y_direction[], reverse, Point(0, whiskerwidth/2))) + ( + sep .+ f_if(is_in_y_direction[], reverse, Point(0, -whiskerwidth / 2)), + sep .+ f_if(is_in_y_direction[], reverse, Point(0, whiskerwidth / 2)), + ) end return [p for pair in screenendpoints_shifted_pairs for p in pair] @@ -252,7 +260,7 @@ function _plot_bars!(plot, linesegpairs, is_in_y_direction) inspectable = inspectable, transparency = transparency, space = :pixel, model = Mat4f(I) # overwrite scale!() / translate!() / rotate!() ) - plot + return plot end function plot_to_screen(plot, points::AbstractVector) diff --git a/src/basic_recipes/hvlines.jl b/src/basic_recipes/hvlines.jl index 165c0be42e8..53d45a530b7 100644 --- a/src/basic_recipes/hvlines.jl +++ b/src/basic_recipes/hvlines.jl @@ -34,8 +34,9 @@ end function projview_to_2d_limits(plot::AbstractPlot) scene = parent_scene(plot) - lift(plot, f32_conversion_obs(scene), scene.camera.projectionview, ignore_equal_values = true - ) do f32c, pv + return lift( + plot, f32_conversion_obs(scene), scene.camera.projectionview, ignore_equal_values = true + ) do f32c, pv xmin, xmax = minmax((((-1, 1) .- pv[1, 4]) ./ pv[1, 1])...) ymin, ymax = minmax((((-1, 1) .- pv[2, 4]) ./ pv[2, 2])...) origin = Vec2d(xmin, ymin) @@ -78,11 +79,11 @@ function Makie.plot!(p::Union{HLines, VLines}) notify(p[1]) line_attributes = copy(p.attributes) - foreach(key-> delete!(line_attributes, key), [:ymin, :ymax, :xmin, :xmax, :xautolimits, :yautolimits]) + foreach(key -> delete!(line_attributes, key), [:ymin, :ymax, :xmin, :xmax, :xautolimits, :yautolimits]) # Drop transform_func because we handle it manually line_attributes[:transformation] = Transformation(p, transform_func = identity) linesegments!(p, line_attributes, points) - p + return p end function data_limits(p::HLines) @@ -95,4 +96,4 @@ function data_limits(p::VLines) return Rect3d(Point3d(xmin, NaN, 0), Vec3d(xmax - xmin, NaN, 0)) end -boundingbox(p::Union{HLines, VLines}, space::Symbol = :data) = apply_transform_and_model(p, data_limits(p)) \ No newline at end of file +boundingbox(p::Union{HLines, VLines}, space::Symbol = :data) = apply_transform_and_model(p, data_limits(p)) diff --git a/src/basic_recipes/hvspan.jl b/src/basic_recipes/hvspan.jl index 4327badd803..5a6f954b9d7 100644 --- a/src/basic_recipes/hvspan.jl +++ b/src/basic_recipes/hvspan.jl @@ -54,13 +54,13 @@ function Makie.plot!(p::Union{HSpan, VSpan}) if p isa HSpan x_mi = min_x + (max_x - min_x) * mi x_ma = min_x + (max_x - min_x) * ma - low = _apply_y_transform(transf, low) + low = _apply_y_transform(transf, low) high = _apply_y_transform(transf, high) push!(rects[], Rect2d(Point2(x_mi, low), Vec2(x_ma - x_mi, high - low))) elseif p isa VSpan y_mi = min_y + (max_y - min_y) * mi y_ma = min_y + (max_y - min_y) * ma - low = _apply_x_transform(transf, low) + low = _apply_x_transform(transf, low) high = _apply_x_transform(transf, high) push!(rects[], Rect2d(Point2(low, y_mi), Vec2(high - low, y_ma - y_mi))) end @@ -71,12 +71,12 @@ function Makie.plot!(p::Union{HSpan, VSpan}) notify(p[1]) poly_attributes = copy(p.attributes) - foreach(x-> delete!(poly_attributes, x), [:ymin, :ymax, :xmin, :xmax, :xautolimits, :yautolimits]) + foreach(x -> delete!(poly_attributes, x), [:ymin, :ymax, :xmin, :xmax, :xautolimits, :yautolimits]) # we handle transform_func manually poly_attributes[:transformation] = Transformation(p, transform_func = identity) poly!(p, poly_attributes, rects) - p + return p end _apply_x_transform(t::Tuple, v) = apply_transform(t[1], v) diff --git a/src/basic_recipes/makiecore_examples/lines.jl b/src/basic_recipes/makiecore_examples/lines.jl index 5bde21b0c4a..65764fa3681 100644 --- a/src/basic_recipes/makiecore_examples/lines.jl +++ b/src/basic_recipes/makiecore_examples/lines.jl @@ -1,73 +1,73 @@ function attribute_examples(::Type{Lines}) - Dict( + return Dict( :linestyle => [ Example( code = """ - linestyles = [:solid, :dot, :dash, :dashdot, :dashdotdot] - gapstyles = [:normal, :dense, :loose, 10] - fig = Figure() - with_updates_suspended(fig.layout) do - for (i, ls) in enumerate(linestyles) - for (j, gs) in enumerate(gapstyles) - title = gs === :normal ? repr(ls) : "\$((ls, gs))" - ax = Axis(fig[i, j]; title, yautolimitmargin = (0.2, 0.2)) - hidedecorations!(ax) - hidespines!(ax) - linestyle = (ls, gs) - for linewidth in 1:3 - lines!(ax, 1:10, fill(linewidth, 10); linestyle, linewidth) - end + linestyles = [:solid, :dot, :dash, :dashdot, :dashdotdot] + gapstyles = [:normal, :dense, :loose, 10] + fig = Figure() + with_updates_suspended(fig.layout) do + for (i, ls) in enumerate(linestyles) + for (j, gs) in enumerate(gapstyles) + title = gs === :normal ? repr(ls) : "\$((ls, gs))" + ax = Axis(fig[i, j]; title, yautolimitmargin = (0.2, 0.2)) + hidedecorations!(ax) + hidespines!(ax) + linestyle = (ls, gs) + for linewidth in 1:3 + lines!(ax, 1:10, fill(linewidth, 10); linestyle, linewidth) end end end - fig - """ + end + fig + """ ), Example( code = """ - fig = Figure() - patterns = [ - [0, 1, 2], - [0, 20, 22], - [0, 2, 4, 12, 14], - [0, 2, 4, 6, 8, 10, 20], - [0, 1, 2, 4, 6, 9, 12], - [0.0, 4.0, 6.0, 9.5], - ] - ax = Axis(fig[1, 1], yautolimitmargin = (0.2, 0.2)) - for (i, pattern) in enumerate(patterns) - lines!(ax, [-i, -i], linestyle = Linestyle(pattern), linewidth = 4) - text!(ax, (1.5, -i), text = "Linestyle(\$pattern)", - align = (:center, :bottom), offset = (0, 10)) - end - hidedecorations!(ax) - fig - """ + fig = Figure() + patterns = [ + [0, 1, 2], + [0, 20, 22], + [0, 2, 4, 12, 14], + [0, 2, 4, 6, 8, 10, 20], + [0, 1, 2, 4, 6, 9, 12], + [0.0, 4.0, 6.0, 9.5], + ] + ax = Axis(fig[1, 1], yautolimitmargin = (0.2, 0.2)) + for (i, pattern) in enumerate(patterns) + lines!(ax, [-i, -i], linestyle = Linestyle(pattern), linewidth = 4) + text!(ax, (1.5, -i), text = "Linestyle(\$pattern)", + align = (:center, :bottom), offset = (0, 10)) + end + hidedecorations!(ax) + fig + """ ), ], :joinstyle => [ Example( code = """ - fig = Figure() - ax = Axis(fig[1, 1], yautolimitmargin = (0.05, 0.15)) - hidedecorations!(ax) + fig = Figure() + ax = Axis(fig[1, 1], yautolimitmargin = (0.05, 0.15)) + hidedecorations!(ax) - joinstyles = [:miter, :bevel, :round] - for (i, joinstyle) in enumerate(joinstyles) - x = (1:3) .+ 5 * (i - 1) - ys = [[0.5, 3.5, 0.5], [3, 5, 3], [5, 6, 5], [6.5, 7, 6.5]] - for y in ys - lines!(ax, x, y; linewidth = 15, joinstyle, color = :black) - end - text!(ax, x[2], ys[end][2], text = ":\$joinstyle", - align = (:center, :bottom), offset = (0, 15), font = :bold) + joinstyles = [:miter, :bevel, :round] + for (i, joinstyle) in enumerate(joinstyles) + x = (1:3) .+ 5 * (i - 1) + ys = [[0.5, 3.5, 0.5], [3, 5, 3], [5, 6, 5], [6.5, 7, 6.5]] + for y in ys + lines!(ax, x, y; linewidth = 15, joinstyle, color = :black) end + text!(ax, x[2], ys[end][2], text = ":\$joinstyle", + align = (:center, :bottom), offset = (0, 15), font = :bold) + end - text!(ax, 4.5, 4.5, text = "for angles\nbelow miter_limit,\n:miter == :bevel", - align = (:center, :center)) + text!(ax, 4.5, 4.5, text = "for angles\nbelow miter_limit,\n:miter == :bevel", + align = (:center, :center)) - fig - """ + fig + """ ), ], :linecap => [ @@ -121,4 +121,4 @@ function attribute_examples(::Type{Lines}) ), ], ) -end \ No newline at end of file +end diff --git a/src/basic_recipes/makiecore_examples/scatter.jl b/src/basic_recipes/makiecore_examples/scatter.jl index 608f9bc3b06..f36ef1700f0 100644 --- a/src/basic_recipes/makiecore_examples/scatter.jl +++ b/src/basic_recipes/makiecore_examples/scatter.jl @@ -1,91 +1,91 @@ function attribute_examples(::Type{Scatter}) - Dict( + return Dict( :color => [ Example( code = """ - fig = Figure() - kwargs = (; markersize = 30, axis = (; limits = (0, 4, 0, 4))) - scatter(fig[1, 1], 1:3; kwargs..., color = :tomato) - scatter(fig[1, 2], 1:3; kwargs..., color = [RGBf(1, 0, 0), RGBf(0, 1, 0), RGBf(0, 0, 1)]) - scatter(fig[2, 1], 1:3; kwargs..., color = [10, 20, 30]) - scatter(fig[2, 2], 1:3; kwargs..., color = [10, 20, 30], colormap = :plasma) - fig - """ - ) + fig = Figure() + kwargs = (; markersize = 30, axis = (; limits = (0, 4, 0, 4))) + scatter(fig[1, 1], 1:3; kwargs..., color = :tomato) + scatter(fig[1, 2], 1:3; kwargs..., color = [RGBf(1, 0, 0), RGBf(0, 1, 0), RGBf(0, 0, 1)]) + scatter(fig[2, 1], 1:3; kwargs..., color = [10, 20, 30]) + scatter(fig[2, 2], 1:3; kwargs..., color = [10, 20, 30], colormap = :plasma) + fig + """ + ), ], :colormap => [ Example( code = """ - fig = Figure() - kwargs = (; markersize = 30, axis = (; limits = (0, 6, 0, 6))) - scatter(fig[1, 1], 1:5; kwargs..., color = 1:5, colormap = :viridis) - scatter(fig[1, 2], 1:5; kwargs..., color = 1:5, colormap = :plasma) - scatter(fig[2, 1], 1:5; kwargs..., color = 1:5, colormap = Reverse(:viridis)) - scatter(fig[2, 2], 1:5; kwargs..., color = 1:5, colormap = [:tomato, :slategray2]) - fig - """ - ) + fig = Figure() + kwargs = (; markersize = 30, axis = (; limits = (0, 6, 0, 6))) + scatter(fig[1, 1], 1:5; kwargs..., color = 1:5, colormap = :viridis) + scatter(fig[1, 2], 1:5; kwargs..., color = 1:5, colormap = :plasma) + scatter(fig[2, 1], 1:5; kwargs..., color = 1:5, colormap = Reverse(:viridis)) + scatter(fig[2, 2], 1:5; kwargs..., color = 1:5, colormap = [:tomato, :slategray2]) + fig + """ + ), ], :markersize => [ Example( code = """ - fig = Figure() - kwargs = (; marker = Rect, axis = (; limits = (0, 4, 0, 4))) - scatter(fig[1, 1], 1:3; kwargs..., markersize = 30) - scatter(fig[1, 2], 1:3; kwargs..., markersize = (30, 20)) - scatter(fig[2, 1], 1:3; kwargs..., markersize = [10, 20, 30]) - scatter(fig[2, 2], 1:3; kwargs..., markersize = [(10, 20), (20, 30), (40, 30)]) - fig - """ - ) + fig = Figure() + kwargs = (; marker = Rect, axis = (; limits = (0, 4, 0, 4))) + scatter(fig[1, 1], 1:3; kwargs..., markersize = 30) + scatter(fig[1, 2], 1:3; kwargs..., markersize = (30, 20)) + scatter(fig[2, 1], 1:3; kwargs..., markersize = [10, 20, 30]) + scatter(fig[2, 2], 1:3; kwargs..., markersize = [(10, 20), (20, 30), (40, 30)]) + fig + """ + ), ], :marker_offset => [ Example( code = """ - fig = Figure() - scatter(fig[1, 1], [Point2f(0) for _ in 1:5]; marker = Circle, markersize = 30, - marker_offset = [(0, 0), (-50, 0), (0, -50), (50, 0), (0, 50)], - color = [:black, :blue, :green, :red, :orange]) - scatter(fig[1, 2], [Point3f(0) for _ in 1:7]; marker = :ltriangle, markersize = 0.2, markerspace = :data, - marker_offset = Vec3f[(0, 0, 0), (-1, 0, 0), (0, -1, 0), (1, 0, 0), (0, 1, 0), (0, 0, -1), (0, 0, 1)], - color = [:black, :blue, :green, :red, :orange, :cyan, :purple]) - fig - """ - ) + fig = Figure() + scatter(fig[1, 1], [Point2f(0) for _ in 1:5]; marker = Circle, markersize = 30, + marker_offset = [(0, 0), (-50, 0), (0, -50), (50, 0), (0, 50)], + color = [:black, :blue, :green, :red, :orange]) + scatter(fig[1, 2], [Point3f(0) for _ in 1:7]; marker = :ltriangle, markersize = 0.2, markerspace = :data, + marker_offset = Vec3f[(0, 0, 0), (-1, 0, 0), (0, -1, 0), (1, 0, 0), (0, 1, 0), (0, 0, -1), (0, 0, 1)], + color = [:black, :blue, :green, :red, :orange, :cyan, :purple]) + fig + """ + ), ], :rotation => [ Example( code = """ - fig = Figure() - kwargs = (; marker = :utriangle, markersize = 30, axis = (; limits = (0, 4, 0, 4))) - scatter(fig[1, 1], 1:3; kwargs...) - scatter(fig[1, 2], 1:3; kwargs..., rotation = deg2rad(45)) - scatter(fig[1, 3], 1:3; kwargs..., rotation = deg2rad.([0, 45, 90])) - fig - """ - ) + fig = Figure() + kwargs = (; marker = :utriangle, markersize = 30, axis = (; limits = (0, 4, 0, 4))) + scatter(fig[1, 1], 1:3; kwargs...) + scatter(fig[1, 2], 1:3; kwargs..., rotation = deg2rad(45)) + scatter(fig[1, 3], 1:3; kwargs..., rotation = deg2rad.([0, 45, 90])) + fig + """ + ), ], :strokecolor => [ Example( code = """ - fig = Figure() - kwargs = (; markersize = 30, strokewidth = 3) - scatter(fig[1, 1], 1:3; kwargs..., strokecolor = :tomato) - scatter(fig[1, 2], 1:3; kwargs..., strokecolor = [RGBf(1, 0, 0), RGBf(0, 1, 0), RGBf(0, 0, 1)]) - fig - """ - ) + fig = Figure() + kwargs = (; markersize = 30, strokewidth = 3) + scatter(fig[1, 1], 1:3; kwargs..., strokecolor = :tomato) + scatter(fig[1, 2], 1:3; kwargs..., strokecolor = [RGBf(1, 0, 0), RGBf(0, 1, 0), RGBf(0, 0, 1)]) + fig + """ + ), ], :strokewidth => [ Example( code = """ - fig = Figure() - kwargs = (; markersize = 30, strokecolor = :tomato) - scatter(fig[1, 1], 1:3; kwargs..., strokewidth = 3) - scatter(fig[1, 2], 1:3; kwargs..., strokewidth = [0, 3, 6]) - fig - """ - ) + fig = Figure() + kwargs = (; markersize = 30, strokecolor = :tomato) + scatter(fig[1, 1], 1:3; kwargs..., strokewidth = 3) + scatter(fig[1, 2], 1:3; kwargs..., strokewidth = [0, 3, 6]) + fig + """ + ), ], ) -end \ No newline at end of file +end diff --git a/src/basic_recipes/mesh.jl b/src/basic_recipes/mesh.jl index 1e23e64eab2..18f12292e82 100644 --- a/src/basic_recipes/mesh.jl +++ b/src/basic_recipes/mesh.jl @@ -1,7 +1,7 @@ -function plot!(p::Mesh{<: Tuple{<: GeometryBasics.MetaMesh}}) +function plot!(p::Mesh{<:Tuple{<:GeometryBasics.MetaMesh}}) metamesh = p[1][] meshes = GeometryBasics.split_mesh(metamesh.mesh) - + if !haskey(metamesh, :material_names) || !haskey(metamesh, :materials) @error "The given mesh has no :material_names or :materials. Drawing without material information." for (i, m) in enumerate(meshes) @@ -21,19 +21,19 @@ function plot!(p::Mesh{<: Tuple{<: GeometryBasics.MetaMesh}}) end names = metamesh[:material_names] - + for (name, m) in zip(names, meshes) attr = Attributes() material = metamesh[:materials][name] # TODO: Add ambient multiplier # attr[:ambient] = get(material, "ambient", p.attributes[:ambient]) - attr[:diffuse] = get(material, "diffuse", p.attributes[:diffuse]) - attr[:specular] = get(material, "specular", p.attributes[:specular]) + attr[:diffuse] = get(material, "diffuse", p.attributes[:diffuse]) + attr[:specular] = get(material, "specular", p.attributes[:specular]) attr[:shininess] = get(material, "shininess", p.attributes[:shininess]) if haskey(material, "diffuse map") - try + try x = material["diffuse map"] tex = if haskey(x, "image") x["image"] @@ -47,32 +47,33 @@ function plot!(p::Mesh{<: Tuple{<: GeometryBasics.MetaMesh}}) idx = findfirst(f -> lowercase(f) == lowercase(filename), files) if idx === nothing @error "Failed to load texture from material $name - File $filename not found in $path." - fill(RGB{N0f8}(1,0,1), (1,1)) + fill(RGB{N0f8}(1, 0, 1), (1, 1)) else FileIO.load(joinpath(path, files[idx])) end end else - fill(RGB{N0f8}(1,0,1), (1,1)) + fill(RGB{N0f8}(1, 0, 1), (1, 1)) end repeat = get(x, "clamp", false) ? (:clamp_to_edge) : (:repeat) - - attr[:color] = ShaderAbstractions.Sampler(tex; + + attr[:color] = ShaderAbstractions.Sampler( + tex; x_repeat = repeat, mipmap = true, minfilter = :linear_mipmap_linear, magfilter = :linear ) - + scale = Vec2f(get(x, "scale", Vec2f(1))) trans = Vec2f(get(x, "offset", Vec2f(0))) attr[:uv_transform] = ((trans, scale), :mesh) catch e @error "Failed to load texture from material $name: " exception = e end - - # What should we do if no texture is given? - # Should we assume diffuse carries color information if no texture is given? + + # What should we do if no texture is given? + # Should we assume diffuse carries color information if no texture is given? elseif haskey(material, "diffuse") - attr[:color] = RGBAf(1,1,1,1) + attr[:color] = RGBAf(1, 1, 1, 1) else # use Makie default? end diff --git a/src/basic_recipes/pie.jl b/src/basic_recipes/pie.jl index 0e202a85f2d..12e88894c2f 100644 --- a/src/basic_recipes/pie.jl +++ b/src/basic_recipes/pie.jl @@ -28,7 +28,7 @@ convert_arguments(PT::Type{<:Pie}, values::RealVector) = convert_arguments(PT, 0 convert_arguments(PT::Type{<:Pie}, point::VecTypes{2}, values::RealVector) = convert_arguments(PT, point[1], point[2], values) convert_arguments(PT::Type{<:Pie}, ps::AbstractVector{<:VecTypes{2}}, values::RealVector) = convert_arguments(PT, getindex.(ps, 1), getindex.(ps, 2), values) -function convert_arguments(::Type{<:Pie}, xs::Union{Real,RealVector}, ys::Union{Real,RealVector}, values::RealVector) +function convert_arguments(::Type{<:Pie}, xs::Union{Real, RealVector}, ys::Union{Real, RealVector}, values::RealVector) xs = length(xs) == 1 ? fill(only(xs), length(values)) : xs ys = length(ys) == 1 ? fill(only(ys), length(values)) : ys return (float_convert(xs), float_convert(ys), float_convert(values)) @@ -55,7 +55,7 @@ function plot!(plot::Pie) end # create vector of a vector of points for each piece - vertex_arrays = map(boundaries[1:end-1], boundaries[2:end], xs, ys, radius, inner_radius, offset_radius) do sta, en, x, y, r, inner_r, offset_r + vertex_arrays = map(boundaries[1:(end - 1)], boundaries[2:end], xs, ys, radius, inner_radius, offset_radius) do sta, en, x, y, r, inner_r, offset_r x += cos((en + sta) / 2 + offset) * offset_r y += sin((en + sta) / 2 + offset) * offset_r distance = en - sta @@ -89,5 +89,5 @@ function plot!(plot::Pie) visible = plot.visible, transparency = plot.transparency ) - plot + return plot end diff --git a/src/basic_recipes/poly.jl b/src/basic_recipes/poly.jl index 4f41e919c4c..ce8dc9bf2ba 100644 --- a/src/basic_recipes/poly.jl +++ b/src/basic_recipes/poly.jl @@ -1,7 +1,7 @@ const PolyElements = Union{Polygon, MultiPolygon, Circle, Rect, AbstractMesh, VecTypes, AbstractVector{<:VecTypes}} -convert_arguments(::Type{<: Poly}, v::AbstractVector{<: PolyElements}) = (v,) -convert_arguments(::Type{<: Poly}, v::Union{Polygon, MultiPolygon}) = (v,) +convert_arguments(::Type{<:Poly}, v::AbstractVector{<:PolyElements}) = (v,) +convert_arguments(::Type{<:Poly}, v::Union{Polygon, MultiPolygon}) = (v,) function convert_pointlike(args...) @@ -28,10 +28,10 @@ function convert_arguments(::Type{<:Poly}, vertices::AbstractArray, indices::Abs return convert_arguments(Mesh, vertices, indices) end -convert_arguments(::Type{<: Poly}, m::GeometryBasics.Mesh) = (m,) -convert_arguments(::Type{<: Poly}, m::GeometryBasics.GeometryPrimitive) = (m,) +convert_arguments(::Type{<:Poly}, m::GeometryBasics.Mesh) = (m,) +convert_arguments(::Type{<:Poly}, m::GeometryBasics.GeometryPrimitive) = (m,) -function plot!(plot::Poly{<: Tuple{Union{GeometryBasics.Mesh, GeometryPrimitive}}}) +function plot!(plot::Poly{<:Tuple{Union{GeometryBasics.Mesh, GeometryPrimitive}}}) mesh!( plot, plot[1], color = plot.color, @@ -50,44 +50,44 @@ function plot!(plot::Poly{<: Tuple{Union{GeometryBasics.Mesh, GeometryPrimitive} space = plot.space, depth_shift = plot.depth_shift ) - wireframe!( + return wireframe!( plot, plot[1], color = plot.strokecolor, linestyle = plot.linestyle, space = plot.space, linewidth = plot.strokewidth, linecap = plot.linecap, visible = plot.visible, overdraw = plot.overdraw, inspectable = plot.inspectable, transparency = plot.transparency, - colormap = plot.strokecolormap, depth_shift=plot.stroke_depth_shift + colormap = plot.strokecolormap, depth_shift = plot.stroke_depth_shift ) end # Poly conversion -function poly_convert(geometries::AbstractVector, transform_func=identity) +function poly_convert(geometries::AbstractVector, transform_func = identity) isempty(geometries) && return GeometryBasics.SimpleMesh{2, Float64, GLTriangleFace}[] return poly_convert.(geometries, (transform_func,)) end -function poly_convert(geometry::AbstractGeometry{2, T}, transform_func=identity) where {T} - return GeometryBasics.mesh(geometry; pointtype=Point{2,float_type(T)}, facetype=GLTriangleFace) +function poly_convert(geometry::AbstractGeometry{2, T}, transform_func = identity) where {T} + return GeometryBasics.mesh(geometry; pointtype = Point{2, float_type(T)}, facetype = GLTriangleFace) end -poly_convert(meshes::AbstractVector{<:AbstractMesh}, transform_func=identity) = poly_convert.(meshes, (transform_func,)) +poly_convert(meshes::AbstractVector{<:AbstractMesh}, transform_func = identity) = poly_convert.(meshes, (transform_func,)) -function poly_convert(polys::AbstractVector{<:Polygon{N, T}}, transform_func=identity) where {N, T} +function poly_convert(polys::AbstractVector{<:Polygon{N, T}}, transform_func = identity) where {N, T} MeshType = GeometryBasics.SimpleMesh{N, float_type(T), GLTriangleFace} return isempty(polys) ? MeshType[] : poly_convert.(polys, (transform_func,)) end -function poly_convert(multipolygons::AbstractVector{<:MultiPolygon}, transform_func=identity) +function poly_convert(multipolygons::AbstractVector{<:MultiPolygon}, transform_func = identity) return [merge(poly_convert.(multipoly.polygons, (transform_func,))) for multipoly in multipolygons] end -function poly_convert(multipolygon::MultiPolygon, transform_func=identity) +function poly_convert(multipolygon::MultiPolygon, transform_func = identity) return poly_convert.(multipolygon.polygons, (transform_func,)) end -poly_convert(mesh::GeometryBasics.Mesh, transform_func=identity) = mesh +poly_convert(mesh::GeometryBasics.Mesh, transform_func = identity) = mesh -function poly_convert(polygon::Polygon, transform_func=identity) +function poly_convert(polygon::Polygon, transform_func = identity) outer = coordinates(polygon.exterior) # TODO consider applying f32 convert here too. We would need to identify this though... PT = float_type(outer) @@ -106,7 +106,7 @@ function poly_convert(polygon::Polygon, transform_func=identity) return GeometryBasics.Mesh(points_flat, faces) end -function poly_convert(polygon::AbstractVector{<:VecTypes{2, T}}, transform_func=identity) where {T} +function poly_convert(polygon::AbstractVector{<:VecTypes{2, T}}, transform_func = identity) where {T} points = convert(Vector{Point2{float_type(T)}}, polygon) points_transformed = apply_transform(transform_func, points) faces = GeometryBasics.earcut_triangulate([points_transformed]) @@ -114,7 +114,7 @@ function poly_convert(polygon::AbstractVector{<:VecTypes{2, T}}, transform_func= return GeometryBasics.Mesh(points, faces)::GeometryBasics.SimpleMesh{2, float_type(T), GLTriangleFace} end -function poly_convert(polygons::AbstractVector{<:AbstractVector{<:VecTypes}}, transform_func=identity) +function poly_convert(polygons::AbstractVector{<:AbstractVector{<:VecTypes}}, transform_func = identity) return map(polygons) do poly return poly_convert(poly, transform_func) end @@ -138,7 +138,7 @@ function to_lines(meshes::AbstractVector) return line end -function to_lines(polygon::AbstractVector{<: VecTypes}) +function to_lines(polygon::AbstractVector{<:VecTypes}) result = Point2d.(polygon) if !isempty(result) && !(result[1] ≈ result[end]) push!(result, polygon[1]) @@ -146,11 +146,12 @@ function to_lines(polygon::AbstractVector{<: VecTypes}) return result end -function plot!(plot::Poly{<: Tuple{<: Union{Polygon, MultiPolygon, Rect2, Circle, AbstractVector{<: PolyElements}}}}) +function plot!(plot::Poly{<:Tuple{<:Union{Polygon, MultiPolygon, Rect2, Circle, AbstractVector{<:PolyElements}}}}) geometries = plot[1] transform_func = plot.transformation.transform_func meshes = lift(poly_convert, plot, geometries, transform_func) - mesh!(plot, meshes; + mesh!( + plot, meshes; visible = plot.visible, shading = plot.shading, color = plot.color, @@ -159,8 +160,8 @@ function plot!(plot::Poly{<: Tuple{<: Union{Polygon, MultiPolygon, Rect2, Circle colorrange = plot.colorrange, lowclip = plot.lowclip, highclip = plot.highclip, - nan_color=plot.nan_color, - alpha=plot.alpha, + nan_color = plot.nan_color, + alpha = plot.alpha, overdraw = plot.overdraw, fxaa = plot.fxaa, transparency = plot.transparency, @@ -183,7 +184,7 @@ function plot!(plot::Poly{<: Tuple{<: Union{Polygon, MultiPolygon, Rect2, Circle return sc end end - lines!( + return lines!( plot, outline, visible = plot.visible, color = stroke, linestyle = plot.linestyle, alpha = plot.alpha, colormap = plot.strokecolormap, @@ -197,7 +198,7 @@ end # TODO: for Makie v0.22, GeometryBasics v0.5, # switch from AbstractMesh{Polytope{N, T}} to AbstractMesh{N, T} -function plot!(plot::Mesh{<: Tuple{<: AbstractVector{P}}}) where P <: Union{<: AbstractMesh{N, T}, Polygon{N, T}} where {N, T} +function plot!(plot::Mesh{<:Tuple{<:AbstractVector{P}}}) where {P <: Union{<:AbstractMesh{N, T}, Polygon{N, T}}} where {N, T} meshes = plot[1] attrs = Attributes( visible = plot.visible, shading = plot.shading, fxaa = plot.fxaa, @@ -213,7 +214,7 @@ function plot!(plot::Mesh{<: Tuple{<: AbstractVector{P}}}) where P <: Union{<: A depth_shift = plot.depth_shift ) - num_meshes = lift(plot, meshes; ignore_equal_values=true) do meshes + num_meshes = lift(plot, meshes; ignore_equal_values = true) do meshes return Int[length(coordinates(m)) for m in meshes] end @@ -224,7 +225,7 @@ function plot!(plot::Mesh{<: Tuple{<: AbstractVector{P}}}) where P <: Union{<: A lift!(plot, mesh_colors, plot.color, num_meshes) do colors, num_meshes # one mesh per color if colors isa AbstractVector && length(colors) == length(num_meshes) - ccolors = colors isa AbstractArray{<: Number} ? colors : to_color(colors) + ccolors = colors isa AbstractArray{<:Number} ? colors : to_color(colors) result = similar(ccolors, float32type(ccolors), sum(num_meshes)) i = 1 for (cs, len) in zip(ccolors, num_meshes) diff --git a/src/basic_recipes/raincloud.jl b/src/basic_recipes/raincloud.jl index bf5fb74116e..32fee7768de 100644 --- a/src/basic_recipes/raincloud.jl +++ b/src/basic_recipes/raincloud.jl @@ -1,20 +1,20 @@ -#### -#### Helper functions to make the cloud plot! -#### -function cloud_plot_check_args(category_labels, data_array) - length(category_labels) == length(data_array) || DimensionMismatch("Length of category_labels must match with length of data_array") - return nothing -end - -# Allow to globally set jitter RNG for testing -# A bit of a lazy solution, but it doesn't seem to be desirably to -# pass the RNG through the plotting command -const RAINCLOUD_RNG = Ref{Random.AbstractRNG}(Random.GLOBAL_RNG) - -# quick custom function for jitter -rand_localized(min, max) = rand_localized(RAINCLOUD_RNG[], min, max) -rand_localized(RNG::Random.AbstractRNG, min, max) = rand(RNG) * (max - min) .+ min - +#### +#### Helper functions to make the cloud plot! +#### +function cloud_plot_check_args(category_labels, data_array) + length(category_labels) == length(data_array) || DimensionMismatch("Length of category_labels must match with length of data_array") + return nothing +end + +# Allow to globally set jitter RNG for testing +# A bit of a lazy solution, but it doesn't seem to be desirably to +# pass the RNG through the plotting command +const RAINCLOUD_RNG = Ref{Random.AbstractRNG}(Random.GLOBAL_RNG) + +# quick custom function for jitter +rand_localized(min, max) = rand_localized(RAINCLOUD_RNG[], min, max) +rand_localized(RNG::Random.AbstractRNG, min, max) = rand(RNG) * (max - min) .+ min + """ rainclouds!(ax, category_labels, data_array; plot_boxplots=true, plot_clouds=true, kwargs...) @@ -29,309 +29,320 @@ between each. # Keywords -""" -@recipe RainClouds (category_labels, data_array) begin +""" +@recipe RainClouds (category_labels, data_array) begin """ Can take values of `:left`, `:right`, determines where the violin plot will be, relative to the scatter points - """ - side = :left + """ + side = :left """ Orientation of rainclouds (`:vertical` or `:horizontal`) - """ - orientation = :vertical + """ + orientation = :vertical """ Whether or not to center the boxplot on the category. - """ - center_boxplot = true - # Cloud plot + """ + center_boxplot = true + # Cloud plot """ Determines size of violin plot. Corresponds to `width` keyword arg in `violin`. - """ - cloud_width = 0.75 + """ + cloud_width = 0.75 """ Specify values to trim the `violin`. Can be a `Tuple` or a `Function` (e.g. `datalimits=extrema`) - """ - violin_limits = (-Inf, Inf) - # Box Plot Settings + """ + violin_limits = (-Inf, Inf) + # Box Plot Settings """ Width of the boxplot on the category axis. - """ - boxplot_width = 0.1 - "The width of the Q1, Q3 whisker in the boxplot. Value as a portion of the `boxplot_width`." - whiskerwidth = 0.5 - "Determines the stroke width for the outline of the boxplot." - strokewidth = 1.0 + """ + boxplot_width = 0.1 + "The width of the Q1, Q3 whisker in the boxplot. Value as a portion of the `boxplot_width`." + whiskerwidth = 0.5 + "Determines the stroke width for the outline of the boxplot." + strokewidth = 1.0 """ Determines whether or not to have a line for the median value in the boxplot. - """ - show_median = true + """ + show_median = true """ Determines the distance away the boxplot should be placed from the center line when `center_boxplot` is `false`. This is the value used to recentering the boxplot. - """ - boxplot_nudge = 0.075 - - "Distance between elements on the main axis (depending on `orientation`)." - gap = 0.2 - + """ + boxplot_nudge = 0.075 + + "Distance between elements on the main axis (depending on `orientation`)." + gap = 0.2 + """ Size of marker used for the scatter plot. - """ - markersize = 2.0 - + """ + markersize = 2.0 + """ Vector of `Integer` (length of data) of grouping variable to create multiple side-by-side boxes at the same x position - """ - dodge = automatic + """ + dodge = automatic """ The number of categories to dodge (defaults to `maximum(dodge)`) - """ - n_dodge = automatic - "Spacing between dodged boxes." - dodge_gap = 0.01 - - "Whether to show boxplots to summarize distribution of data." - plot_boxplots = true + """ + n_dodge = automatic + "Spacing between dodged boxes." + dodge_gap = 0.01 + + "Whether to show boxplots to summarize distribution of data." + plot_boxplots = true """ Show outliers in the boxplot as points (usually confusing when paired with the scatter plot so the default is to not show them) - """ - show_boxplot_outliers = false + """ + show_boxplot_outliers = false """ [`violin`, `hist`, `nothing`] how to show cloud plots, either as violin or histogram plots, or not at all. - """ - clouds = violin + """ + clouds = violin """ If `clouds=hist`, this passes down the number of bins to the histogram call. - """ - hist_bins = 30 + """ + hist_bins = 30 """ Scatter plot specific. Default value is 0.02 if `plot_boxplots` is true, otherwise `0.075` default. - """ - side_nudge = automatic + """ + side_nudge = automatic """ Determines the width of the scatter-plot bar in category x-axis absolute terms. - """ - jitter_width = 0.05 - + """ + jitter_width = 0.05 + """ A single color, or a vector of colors, one for each point. - """ - color = @inherit patchcolor - cycle = [:color => :patchcolor] -end - -# create_jitter_array(length_data_array; jitter_width = 0.1, clamped_portion = 0.1) -# Returns a array containing random values with a mean of 0, and a values from `-jitter_width/2.0` to `+jitter_width/2.0`, where a portion of a values are clamped right at the edges. -function create_jitter_array(length_data_array; jitter_width = 0.1, clamped_portion = 0.1) - jitter_width < 0 && ArgumentError("`jitter_width` should be positive.") - !(0 <= clamped_portion <= 1) || ArgumentError("`clamped_portion` should be between 0.0 to 1.0") - - # Make base jitter, note base jitter minimum-to-maximum span is 1.0 - base_min, base_max = (-0.5, 0.5) - jitter = [rand_localized(base_min, base_max) for _ in 1:length_data_array] - - # created clamp_min, and clamp_max to clamp a portion of the data - @assert (base_max - base_min) == 1.0 - @assert (base_max + base_min) / 2.0 == 0 - clamp_min = base_min + (clamped_portion / 2.0) - clamp_max = base_max - (clamped_portion / 2.0) - - # clamp if need be - clamp!(jitter, clamp_min, clamp_max) - - # Based on assumptions of clamp_min and clamp_max above - jitter = jitter * (0.5jitter_width / clamp_max) - - return jitter -end - -#### -#### Functions that make the cloud plot -#### -function plot!( - ax::Makie.Axis, P::Type{<: RainClouds}, - allattrs::Attributes, category_labels, data_array) - - plot = plot!(ax.scene, P, allattrs, category_labels, data_array) - - if any(x -> x isa AbstractString, category_labels) - ulabels = unique(category_labels) - if !haskey(allattrs, :orientation) || allattrs.orientation[] === :vertical - ax.xticks = (1:length(ulabels), ulabels) - else - ax.yticks = (1:length(ulabels), ulabels) - end - end - if haskey(allattrs, :title) - ax.title = allattrs.title[] - end - if haskey(allattrs, :xlabel) - ax.xlabel = allattrs.xlabel[] - end - if haskey(allattrs, :ylabel) - ax.ylabel = allattrs.ylabel[] - end - reset_limits!(ax) - return plot -end - -function group_labels(category_labels, data_array) - grouped = Dict{eltype(category_labels), Vector{Int}}() - for (label, data_ix) in zip(category_labels, axes(data_array,1)) - push!(get!(grouped, label, eltype(data_array)[]), data_ix) - end - - return pairs(grouped) -end - -function ungroup_labels(category_labels, data_array) - if eltype(data_array) <: AbstractVector - @warn "Using a nested array for raincloud is deprecated. Read raincloud's documentation and update your usage accordingly." - data_array_ = reduce(vcat, data_array) - category_labels_ = similar(category_labels, length(data_array_)) - ix = 0 - for (i, da) in enumerate(data_array) - category_labels_[axes(da, 1) .+ ix] .= category_labels[i] - ix += size(da, 1) - end - return category_labels_, data_array_ - end - return category_labels, data_array -end - -function convert_arguments(::Type{<: RainClouds}, category_labels, data_array) - cloud_plot_check_args(category_labels, data_array) - return (category_labels, data_array) -end - -function plot!(plot::RainClouds) - category_labels = plot.category_labels[] - data_array = plot.data_array[] - category_labels, data_array = ungroup_labels(category_labels, data_array) - if any(ismissing, data_array) - error("missing values in data not supported. Please filter out any missing values before plotting") - end - - # Checking kwargs, and assigning defaults if they are not in kwargs - # General Settings - # Define where categories should lie - x_positions = if any(x -> x isa AbstractString, category_labels) - labels = unique(category_labels) - pos = Dict(label => i for (i, label) in enumerate(labels)) - [pos[label] for label in category_labels] - else - category_labels - end - - side = plot.side[] - center_boxplot_bool = plot.center_boxplot[] - # Cloud plot - cloud_width = plot.cloud_width[] - cloud_width[] < 0 && ArgumentError("`cloud_width` should be positive.") - - # Box Plot Settings - boxplot_width = plot.boxplot_width[] - whiskerwidth = plot.whiskerwidth[] - strokewidth = plot.strokewidth[] - show_median = plot.show_median[] - boxplot_nudge = plot.boxplot_nudge[] - - plot_boxplots = plot.plot_boxplots[] - clouds = plot.clouds[] - hist_bins = plot.hist_bins[] - - # Scatter Plot defaults dependent on if there is a boxplot - side_scatter_nudge_default = plot_boxplots ? 0.2 : 0.075 - - # Scatter Plot Settings - side_scatter_nudge = plot.side_nudge[] isa Makie.Automatic ? side_scatter_nudge_default : plot.side_nudge[] - side_scatter_nudge < 0 && ArgumentError("`side_nudge` should be positive. Change `side` to :left, :right if you wish.") - jitter_width = plot.jitter_width[] - jitter_width < 0 && ArgumentError("`jitter_width` should be positive.") - markersize = plot.markersize[] - - - # Set-up - if plot.orientation[] === :horizontal - # flip side to when horizontal - side = side === :left ? :right : :left - end - (side === :left) && (side_nudge_direction = 1.0) - (side === :right) && (side_nudge_direction = -1.0) - side_scatter_nudge_with_direction = side_scatter_nudge * side_nudge_direction - side_boxplot_nudge_with_direction = boxplot_nudge * side_nudge_direction - - recenter_to_boxplot_nudge_value = center_boxplot_bool ? side_boxplot_nudge_with_direction : 0.0 - plot_boxplots || (recenter_to_boxplot_nudge_value = 0.0) - # Note: these cloud plots are horizontal - full_width = jitter_width + side_scatter_nudge + - (plot_boxplots ? boxplot_width : 0) + - (!isnothing(clouds) ? 1 + abs(recenter_to_boxplot_nudge_value) : 0) - - final_x_positions, width = compute_x_and_width(x_positions .+ recenter_to_boxplot_nudge_value/2, full_width, - plot.gap[], plot.dodge[], - plot.n_dodge[], plot.dodge_gap[]) - width_ratio = width / full_width - - jitter = create_jitter_array(length(data_array); - jitter_width = jitter_width*width_ratio) - - if !isnothing(clouds) - if clouds === violin - violin!(plot, final_x_positions .- recenter_to_boxplot_nudge_value.*width_ratio, data_array; - show_median=show_median, side=side, width=width_ratio*cloud_width, plot.cycle, - datalimits=plot.violin_limits, plot.color, gap=0, orientation=plot.orientation[]) - elseif clouds === hist - edges = pick_hist_edges(data_array, hist_bins) - # dodge belongs below: it ensure that the histogram groups labels by both dodge - # and category (so there is a separate histogram for each dodge group) - groupings = if plot.dodge[] isa MakieCore.Automatic - category_labels - else - zip(category_labels, plot.dodge[]) - end - for (_, ixs) in group_labels(groupings, data_array) - isempty(ixs) && continue - xoffset = final_x_positions[ixs[1]] - recenter_to_boxplot_nudge_value - hist!(plot, view(data_array, ixs); offset=xoffset, - scale_to=(side === :left ? -1 : 1)*cloud_width*width_ratio, bins=edges, - # yes, we really do want :x when orientation is :vertical - # an :x directed histogram has a vertical orientation - direction=plot.orientation[] === :vertical ? :x : :y, - color=getuniquevalue(plot.color[], ixs)) - end - else - error("cloud attribute accepts (violin, hist, nothing), but not: $(clouds)") - end - end - - scatter_x = final_x_positions .+ side_scatter_nudge_with_direction.*width_ratio .+ - jitter .- recenter_to_boxplot_nudge_value.*width_ratio - if plot.orientation[] === :vertical - scatter!(plot, scatter_x, data_array; markersize=markersize, plot.color, plot.cycle) - else - scatter!(plot, data_array, scatter_x; markersize=markersize, plot.color, plot.cycle) - end - - if plot_boxplots - boxplot!(plot, final_x_positions .+ side_boxplot_nudge_with_direction.*width_ratio .- - recenter_to_boxplot_nudge_value.*width_ratio, - data_array; - plot.orientation, - strokewidth=strokewidth, - whiskerwidth=whiskerwidth*width_ratio, - width=boxplot_width*width_ratio, - markersize=markersize, - show_outliers=plot.show_boxplot_outliers[], - color=plot.color, - cycle=plot.cycle) - end - - return plot -end + """ + color = @inherit patchcolor + cycle = [:color => :patchcolor] +end + +# create_jitter_array(length_data_array; jitter_width = 0.1, clamped_portion = 0.1) +# Returns a array containing random values with a mean of 0, and a values from `-jitter_width/2.0` to `+jitter_width/2.0`, where a portion of a values are clamped right at the edges. +function create_jitter_array(length_data_array; jitter_width = 0.1, clamped_portion = 0.1) + jitter_width < 0 && ArgumentError("`jitter_width` should be positive.") + !(0 <= clamped_portion <= 1) || ArgumentError("`clamped_portion` should be between 0.0 to 1.0") + + # Make base jitter, note base jitter minimum-to-maximum span is 1.0 + base_min, base_max = (-0.5, 0.5) + jitter = [rand_localized(base_min, base_max) for _ in 1:length_data_array] + + # created clamp_min, and clamp_max to clamp a portion of the data + @assert (base_max - base_min) == 1.0 + @assert (base_max + base_min) / 2.0 == 0 + clamp_min = base_min + (clamped_portion / 2.0) + clamp_max = base_max - (clamped_portion / 2.0) + + # clamp if need be + clamp!(jitter, clamp_min, clamp_max) + + # Based on assumptions of clamp_min and clamp_max above + jitter = jitter * (0.5jitter_width / clamp_max) + + return jitter +end + +#### +#### Functions that make the cloud plot +#### +function plot!( + ax::Makie.Axis, P::Type{<:RainClouds}, + allattrs::Attributes, category_labels, data_array + ) + + plot = plot!(ax.scene, P, allattrs, category_labels, data_array) + + if any(x -> x isa AbstractString, category_labels) + ulabels = unique(category_labels) + if !haskey(allattrs, :orientation) || allattrs.orientation[] === :vertical + ax.xticks = (1:length(ulabels), ulabels) + else + ax.yticks = (1:length(ulabels), ulabels) + end + end + if haskey(allattrs, :title) + ax.title = allattrs.title[] + end + if haskey(allattrs, :xlabel) + ax.xlabel = allattrs.xlabel[] + end + if haskey(allattrs, :ylabel) + ax.ylabel = allattrs.ylabel[] + end + reset_limits!(ax) + return plot +end + +function group_labels(category_labels, data_array) + grouped = Dict{eltype(category_labels), Vector{Int}}() + for (label, data_ix) in zip(category_labels, axes(data_array, 1)) + push!(get!(grouped, label, eltype(data_array)[]), data_ix) + end + + return pairs(grouped) +end + +function ungroup_labels(category_labels, data_array) + if eltype(data_array) <: AbstractVector + @warn "Using a nested array for raincloud is deprecated. Read raincloud's documentation and update your usage accordingly." + data_array_ = reduce(vcat, data_array) + category_labels_ = similar(category_labels, length(data_array_)) + ix = 0 + for (i, da) in enumerate(data_array) + category_labels_[axes(da, 1) .+ ix] .= category_labels[i] + ix += size(da, 1) + end + return category_labels_, data_array_ + end + return category_labels, data_array +end + +function convert_arguments(::Type{<:RainClouds}, category_labels, data_array) + cloud_plot_check_args(category_labels, data_array) + return (category_labels, data_array) +end + +function plot!(plot::RainClouds) + category_labels = plot.category_labels[] + data_array = plot.data_array[] + category_labels, data_array = ungroup_labels(category_labels, data_array) + if any(ismissing, data_array) + error("missing values in data not supported. Please filter out any missing values before plotting") + end + + # Checking kwargs, and assigning defaults if they are not in kwargs + # General Settings + # Define where categories should lie + x_positions = if any(x -> x isa AbstractString, category_labels) + labels = unique(category_labels) + pos = Dict(label => i for (i, label) in enumerate(labels)) + [pos[label] for label in category_labels] + else + category_labels + end + + side = plot.side[] + center_boxplot_bool = plot.center_boxplot[] + # Cloud plot + cloud_width = plot.cloud_width[] + cloud_width[] < 0 && ArgumentError("`cloud_width` should be positive.") + + # Box Plot Settings + boxplot_width = plot.boxplot_width[] + whiskerwidth = plot.whiskerwidth[] + strokewidth = plot.strokewidth[] + show_median = plot.show_median[] + boxplot_nudge = plot.boxplot_nudge[] + + plot_boxplots = plot.plot_boxplots[] + clouds = plot.clouds[] + hist_bins = plot.hist_bins[] + + # Scatter Plot defaults dependent on if there is a boxplot + side_scatter_nudge_default = plot_boxplots ? 0.2 : 0.075 + + # Scatter Plot Settings + side_scatter_nudge = plot.side_nudge[] isa Makie.Automatic ? side_scatter_nudge_default : plot.side_nudge[] + side_scatter_nudge < 0 && ArgumentError("`side_nudge` should be positive. Change `side` to :left, :right if you wish.") + jitter_width = plot.jitter_width[] + jitter_width < 0 && ArgumentError("`jitter_width` should be positive.") + markersize = plot.markersize[] + + + # Set-up + if plot.orientation[] === :horizontal + # flip side to when horizontal + side = side === :left ? :right : :left + end + (side === :left) && (side_nudge_direction = 1.0) + (side === :right) && (side_nudge_direction = -1.0) + side_scatter_nudge_with_direction = side_scatter_nudge * side_nudge_direction + side_boxplot_nudge_with_direction = boxplot_nudge * side_nudge_direction + + recenter_to_boxplot_nudge_value = center_boxplot_bool ? side_boxplot_nudge_with_direction : 0.0 + plot_boxplots || (recenter_to_boxplot_nudge_value = 0.0) + # Note: these cloud plots are horizontal + full_width = jitter_width + side_scatter_nudge + + (plot_boxplots ? boxplot_width : 0) + + (!isnothing(clouds) ? 1 + abs(recenter_to_boxplot_nudge_value) : 0) + + final_x_positions, width = compute_x_and_width( + x_positions .+ recenter_to_boxplot_nudge_value / 2, full_width, + plot.gap[], plot.dodge[], + plot.n_dodge[], plot.dodge_gap[] + ) + width_ratio = width / full_width + + jitter = create_jitter_array( + length(data_array); + jitter_width = jitter_width * width_ratio + ) + + if !isnothing(clouds) + if clouds === violin + violin!( + plot, final_x_positions .- recenter_to_boxplot_nudge_value .* width_ratio, data_array; + show_median = show_median, side = side, width = width_ratio * cloud_width, plot.cycle, + datalimits = plot.violin_limits, plot.color, gap = 0, orientation = plot.orientation[] + ) + elseif clouds === hist + edges = pick_hist_edges(data_array, hist_bins) + # dodge belongs below: it ensure that the histogram groups labels by both dodge + # and category (so there is a separate histogram for each dodge group) + groupings = if plot.dodge[] isa MakieCore.Automatic + category_labels + else + zip(category_labels, plot.dodge[]) + end + for (_, ixs) in group_labels(groupings, data_array) + isempty(ixs) && continue + xoffset = final_x_positions[ixs[1]] - recenter_to_boxplot_nudge_value + hist!( + plot, view(data_array, ixs); offset = xoffset, + scale_to = (side === :left ? -1 : 1) * cloud_width * width_ratio, bins = edges, + # yes, we really do want :x when orientation is :vertical + # an :x directed histogram has a vertical orientation + direction = plot.orientation[] === :vertical ? :x : :y, + color = getuniquevalue(plot.color[], ixs) + ) + end + else + error("cloud attribute accepts (violin, hist, nothing), but not: $(clouds)") + end + end + + scatter_x = final_x_positions .+ side_scatter_nudge_with_direction .* width_ratio .+ + jitter .- recenter_to_boxplot_nudge_value .* width_ratio + if plot.orientation[] === :vertical + scatter!(plot, scatter_x, data_array; markersize = markersize, plot.color, plot.cycle) + else + scatter!(plot, data_array, scatter_x; markersize = markersize, plot.color, plot.cycle) + end + + if plot_boxplots + boxplot!( + plot, final_x_positions .+ side_boxplot_nudge_with_direction .* width_ratio .- + recenter_to_boxplot_nudge_value .* width_ratio, + data_array; + plot.orientation, + strokewidth = strokewidth, + whiskerwidth = whiskerwidth * width_ratio, + width = boxplot_width * width_ratio, + markersize = markersize, + show_outliers = plot.show_boxplot_outliers[], + color = plot.color, + cycle = plot.cycle + ) + end + + return plot +end diff --git a/src/basic_recipes/scatterlines.jl b/src/basic_recipes/scatterlines.jl index abec787d200..b3eec03d82f 100644 --- a/src/basic_recipes/scatterlines.jl +++ b/src/basic_recipes/scatterlines.jl @@ -29,10 +29,10 @@ Plots `scatter` markers and `lines` between them. cycle = [:color] end -conversion_trait(::Type{<: ScatterLines}) = PointBased() +conversion_trait(::Type{<:ScatterLines}) = PointBased() -function plot!(p::Plot{scatterlines, <:NTuple{N, Any}}) where N +function plot!(p::Plot{scatterlines, <:NTuple{N, Any}}) where {N} # markercolor is the same as linecolor if left automatic real_markercolor = Observable{Any}() @@ -54,7 +54,8 @@ function plot!(p::Plot{scatterlines, <:NTuple{N, Any}}) where N mcol === automatic ? col : mcol end - lines!(p, p[1:N]...; + lines!( + p, p[1:N]...; color = p.color, linestyle = p.linestyle, linewidth = p.linewidth, @@ -66,7 +67,8 @@ function plot!(p::Plot{scatterlines, <:NTuple{N, Any}}) where N colorrange = p.colorrange, inspectable = p.inspectable ) - scatter!(p, p[1:N]...; + return scatter!( + p, p[1:N]...; color = real_markercolor, strokecolor = p.strokecolor, strokewidth = p.strokewidth, diff --git a/src/basic_recipes/series.jl b/src/basic_recipes/series.jl index af5d14734d8..dc8ecd757b7 100644 --- a/src/basic_recipes/series.jl +++ b/src/basic_recipes/series.jl @@ -9,54 +9,62 @@ Curves can be: If any of `marker`, `markersize`, `markercolor`, `strokecolor` or `strokewidth` is set != nothing, a scatterplot is added. """ -@recipe Series (curves::AbstractVector{<:Union{BezierPath,AbstractVector{<:Point}}},) begin - linewidth=2 - color=:lighttest - solid_color=nothing - labels=nothing - linestyle=:solid +@recipe Series (curves::AbstractVector{<:Union{BezierPath, AbstractVector{<:Point}}},) begin + linewidth = 2 + color = :lighttest + solid_color = nothing + labels = nothing + linestyle = :solid linecap = @inherit linecap joinstyle = @inherit joinstyle miter_limit = @inherit miter_limit - marker=nothing - markersize=nothing - markercolor=automatic - strokecolor=nothing - strokewidth=nothing + marker = nothing + markersize = nothing + markercolor = automatic + strokecolor = nothing + strokewidth = nothing space = :data end replace_missing(x) = ismissing(x) ? NaN : x -function convert_arguments(T::Type{<: Series}, y::RealMatrix) - convert_arguments(T, 1:size(y, 2), y) +function convert_arguments(T::Type{<:Series}, y::RealMatrix) + return convert_arguments(T, 1:size(y, 2), y) end -function convert_arguments(::Type{<: Series}, x::RealVector, ys::RealMatrix) +function convert_arguments(::Type{<:Series}, x::RealVector, ys::RealMatrix) T = float_type(x, ys) - return (map(1:size(ys, 1)) do i - Point2{T}.(replace_missing.(x), replace_missing.(view(ys, i, :))) - end,) + return ( + map(1:size(ys, 1)) do i + Point2{T}.(replace_missing.(x), replace_missing.(view(ys, i, :))) + end, + ) end -function convert_arguments(::Type{<:Series}, - arg::AbstractVector{<:Tuple{X,Y}}) where {X<:RealVector,Y<:RealVector} +function convert_arguments( + ::Type{<:Series}, + arg::AbstractVector{<:Tuple{X, Y}} + ) where {X <: RealVector, Y <: RealVector} # TODO: is this problematic with varying tuple types? - return (map(arg) do (x, y) - T = float_type(x, y) - Point2{T}.(replace_missing.(x), replace_missing.(y)) - end,) + return ( + map(arg) do (x, y) + T = float_type(x, y) + Point2{T}.(replace_missing.(x), replace_missing.(y)) + end, + ) end -function convert_arguments(T::Type{<:Series}, arg::Tuple{<:RealVector,<:RealVector}) +function convert_arguments(T::Type{<:Series}, arg::Tuple{<:RealVector, <:RealVector}) return convert_arguments(T, [arg]) end -function convert_arguments(::Type{<: Series}, arg::AbstractVector{<: AbstractVector{<:Point2}}) - return (map(arg) do points - T = float_type(points) - T.(replace_missing.(first.(points)), replace_missing.(last.(points))) - end,) +function convert_arguments(::Type{<:Series}, arg::AbstractVector{<:AbstractVector{<:Point2}}) + return ( + map(arg) do points + T = float_type(points) + T.(replace_missing.(first.(points)), replace_missing.(last.(points))) + end, + ) end function plot!(plot::Series) @@ -73,23 +81,28 @@ function plot!(plot::Series) end for i in 1:nseries - label = lift(l-> isnothing(l) ? "series $(i)" : l[i], plot, labels) - positions = lift(c-> c[i], plot, curves) - series_color = lift(c-> c isa AbstractVector ? c[i] : c, plot, colors) - series_linestyle = lift(ls-> ls isa AbstractVector ? ls[i] : ls, plot, linestyle) + label = lift(l -> isnothing(l) ? "series $(i)" : l[i], plot, labels) + positions = lift(c -> c[i], plot, curves) + series_color = lift(c -> c isa AbstractVector ? c[i] : c, plot, colors) + series_linestyle = lift(ls -> ls isa AbstractVector ? ls[i] : ls, plot, linestyle) if !isempty(scatter) mcolor = plot.markercolor - markercolor = lift((mc, sc)-> mc == automatic ? sc : mc, plot, mcolor, series_color) - scatterlines!(plot, positions; - linewidth=linewidth, linecap = plot.linecap, joinstyle = joinstyle, - miter_limit = miter_limit, color=series_color, markercolor=series_color, - label=label[], scatter..., space = space, linestyle = series_linestyle) + markercolor = lift((mc, sc) -> mc == automatic ? sc : mc, plot, mcolor, series_color) + scatterlines!( + plot, positions; + linewidth = linewidth, linecap = plot.linecap, joinstyle = joinstyle, + miter_limit = miter_limit, color = series_color, markercolor = series_color, + label = label[], scatter..., space = space, linestyle = series_linestyle + ) else - lines!(plot, positions; linewidth=linewidth, linecap = plot.linecap, - joinstyle = joinstyle, miter_limit = miter_limit, color=series_color, - label=label, space = space, linestyle = series_linestyle) + lines!( + plot, positions; linewidth = linewidth, linecap = plot.linecap, + joinstyle = joinstyle, miter_limit = miter_limit, color = series_color, + label = label, space = space, linestyle = series_linestyle + ) end end + return end function Makie.get_plots(plot::Series) diff --git a/src/basic_recipes/spy.jl b/src/basic_recipes/spy.jl index 24b78f23150..f4bc12f54e5 100644 --- a/src/basic_recipes/spy.jl +++ b/src/basic_recipes/spy.jl @@ -64,11 +64,11 @@ function data_limits(plot::Spy) return Rect3d(Point3d(xmin, ymin, 0), Vec3d(xmax - xmin, ymax - ymin, 0)) end -function boundingbox(p::Spy, space::Symbol=:data) +function boundingbox(p::Spy, space::Symbol = :data) return apply_transform_and_model(p, data_limits(p)) end -function convert_arguments(::Type{<:Spy}, matrix::AbstractMatrix{T}) where T +function convert_arguments(::Type{<:Spy}, matrix::AbstractMatrix{T}) where {T} Tr = Makie.float_type(T) return convert_arguments(Spy, Tr.((0, size(matrix, 1))), Tr.((0, size(matrix, 2))), matrix) end @@ -97,9 +97,9 @@ function Makie.plot!(p::Spy) msize end end - index_map = Observable(Dict{Int, Tuple{Int, Int}}(); ignore_equal_values=true) + index_map = Observable(Dict{Int, Tuple{Int, Int}}(); ignore_equal_values = true) p._index_map = index_map - xyc = lift(p, p.z; ignore_equal_values=true) do z + xyc = lift(p, p.z; ignore_equal_values = true) do z x, y, color = SparseArrays.findnz(z) index_map[] = Dict(enumerate(zip(x, y))) return (x, y, color, size(z)) @@ -126,7 +126,8 @@ function Makie.plot!(p::Spy) MakieCore.generic_plot_attributes(p)... ) - lines!(p, rect, + return lines!( + p, rect, color = p.framecolor, linewidth = p.framesize, visible = p.framevisible, diff --git a/src/basic_recipes/stairs.jl b/src/basic_recipes/stairs.jl index 68a3331b7b7..1eb017ffd46 100644 --- a/src/basic_recipes/stairs.jl +++ b/src/basic_recipes/stairs.jl @@ -18,14 +18,14 @@ end conversion_trait(::Type{<:Stairs}) = PointBased() -function plot!(p::Stairs{<:Tuple{<:AbstractVector{T}}}) where T <: Point2 +function plot!(p::Stairs{<:Tuple{<:AbstractVector{T}}}) where {T <: Point2} points = p[1] steppoints = lift(p, points, p.step) do points, step if step === :pre s_points = Vector{T}(undef, length(points) * 2 - 1) s_points[1] = point = points[1] - for i in 1:length(points)-1 + for i in 1:(length(points) - 1) nextpoint = points[i + 1] s_points[2i] = T(point[1], nextpoint[2]) s_points[2i + 1] = nextpoint @@ -35,8 +35,8 @@ function plot!(p::Stairs{<:Tuple{<:AbstractVector{T}}}) where T <: Point2 elseif step === :post s_points = Vector{T}(undef, length(points) * 2 - 1) s_points[1] = point = points[1] - for i in 1:length(points)-1 - nextpoint = points[i+1] + for i in 1:(length(points) - 1) + nextpoint = points[i + 1] s_points[2i] = T(nextpoint[1], point[2]) s_points[2i + 1] = nextpoint point = nextpoint @@ -45,8 +45,8 @@ function plot!(p::Stairs{<:Tuple{<:AbstractVector{T}}}) where T <: Point2 elseif step === :center s_points = Vector{T}(undef, length(points) * 2) s_points[1] = point = points[1] - for i in 1:length(points)-1 - nextpoint = points[i+1] + for i in 1:(length(points) - 1) + nextpoint = points[i + 1] halfx = (point[1] + nextpoint[1]) / 2 s_points[2i] = T(halfx, point[2]) s_points[2i + 1] = T(halfx, nextpoint[2]) @@ -60,5 +60,5 @@ function plot!(p::Stairs{<:Tuple{<:AbstractVector{T}}}) where T <: Point2 end lines!(p, shared_attributes(p, Lines), steppoints) - p + return p end diff --git a/src/basic_recipes/stem.jl b/src/basic_recipes/stem.jl index 91ab22462ef..4778522f69c 100644 --- a/src/basic_recipes/stem.jl +++ b/src/basic_recipes/stem.jl @@ -38,10 +38,10 @@ end conversion_trait(::Type{<:Stem}) = PointBased() -trunkpoint(stempoint::P, offset::Number) where P <: Point2 = P(stempoint[1], offset) -trunkpoint(stempoint::P, offset::Point2) where P <: Point2 = P(offset...) -trunkpoint(stempoint::P, offset::Number) where P <: Point3 = P(stempoint[1], stempoint[2], offset) -trunkpoint(stempoint::P, offset::Point3) where P <: Point3 = P(offset...) +trunkpoint(stempoint::P, offset::Number) where {P <: Point2} = P(stempoint[1], offset) +trunkpoint(stempoint::P, offset::Point2) where {P <: Point2} = P(offset...) +trunkpoint(stempoint::P, offset::Number) where {P <: Point3} = P(stempoint[1], stempoint[2], offset) +trunkpoint(stempoint::P, offset::Point3) where {P <: Point3} = P(offset...) function plot!(s::Stem{<:Tuple{<:AbstractVector{<:Point}}}) @@ -53,7 +53,8 @@ function plot!(s::Stem{<:Tuple{<:AbstractVector{<:Point}}}) trunkpoints = lift(st -> last.(st), s, stemtuples) - lines!(s, trunkpoints, + lines!( + s, trunkpoints, linewidth = s.trunkwidth, color = s.trunkcolor, colormap = s.trunkcolormap, @@ -61,8 +62,10 @@ function plot!(s::Stem{<:Tuple{<:AbstractVector{<:Point}}}) colorrange = s.trunkcolorrange, visible = s.visible, linestyle = s.trunklinestyle, - inspectable = s.inspectable) - linesegments!(s, stemtuples, + inspectable = s.inspectable + ) + linesegments!( + s, stemtuples, linewidth = s.stemwidth, color = s.stemcolor, colormap = s.stemcolormap, @@ -70,8 +73,10 @@ function plot!(s::Stem{<:Tuple{<:AbstractVector{<:Point}}}) colorrange = s.stemcolorrange, visible = s.visible, linestyle = s.stemlinestyle, - inspectable = s.inspectable) - scatter!(s, s[1], + inspectable = s.inspectable + ) + scatter!( + s, s[1], color = s.color, colormap = s.colormap, colorscale = s.colorscale, @@ -81,6 +86,7 @@ function plot!(s::Stem{<:Tuple{<:AbstractVector{<:Point}}}) strokecolor = s.strokecolor, strokewidth = s.strokewidth, visible = s.visible, - inspectable = s.inspectable) - s + inspectable = s.inspectable + ) + return s end diff --git a/src/basic_recipes/streamplot.jl b/src/basic_recipes/streamplot.jl index 17602262e26..4675a220138 100644 --- a/src/basic_recipes/streamplot.jl +++ b/src/basic_recipes/streamplot.jl @@ -1,4 +1,3 @@ - """ streamplot(f::function, xinterval, yinterval; color = norm, kwargs...) @@ -39,13 +38,13 @@ See the function `Makie.streamplot_impl` for implementation details. MakieCore.mixin_generic_plot_attributes()... end -function convert_arguments(::Type{<: StreamPlot}, f::Function, xrange, yrange) +function convert_arguments(::Type{<:StreamPlot}, f::Function, xrange, yrange) xmin, xmax = extrema(xrange) ymin, ymax = extrema(yrange) return (f, Rect(xmin, ymin, xmax - xmin, ymax - ymin)) end -function convert_arguments(::Type{<: StreamPlot}, f::Function, xrange, yrange, zrange) +function convert_arguments(::Type{<:StreamPlot}, f::Function, xrange, yrange, zrange) xmin, xmax = extrema(xrange) ymin, ymax = extrema(yrange) zmin, zmax = extrema(zrange) @@ -54,7 +53,7 @@ function convert_arguments(::Type{<: StreamPlot}, f::Function, xrange, yrange, z return (f, Rect(mini, maxi .- mini)) end -function convert_arguments(::Type{<: StreamPlot}, f::Function, limits::Rect) +function convert_arguments(::Type{<:StreamPlot}, f::Function, limits::Rect) return (f, limits) end @@ -79,14 +78,14 @@ Links: [Quasirandom sequences](http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/) """ -function streamplot_impl(CallType, f, limits::Rect{N, T}, resolutionND, stepsize, maxsteps=500, dens=1.0, color_func = norm) where {N, T} +function streamplot_impl(CallType, f, limits::Rect{N, T}, resolutionND, stepsize, maxsteps = 500, dens = 1.0, color_func = norm) where {N, T} resolution = to_ndim(Vec{N, Int}, resolutionND, last(resolutionND)) mask = trues(resolution...) # unvisited squares arrow_pos = Point{N, Float32}[] arrow_dir = Vec{N, Float32}[] line_points = Point{N, Float32}[] - _cfunc = x-> to_color(color_func(x)) - ColorType = typeof(_cfunc(Point{N,Float32}(0.0))) + _cfunc = x -> to_color(color_func(x)) + ColorType = typeof(_cfunc(Point{N, Float32}(0.0))) line_colors = ColorType[] colors = ColorType[] dt = Point{N, Float32}(stepsize) @@ -98,20 +97,24 @@ function streamplot_impl(CallType, f, limits::Rect{N, T}, resolutionND, stepsize # see http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/ ϕ = (MathConstants.φ, 1.324717957244746, 1.2207440846057596)[N] - acoeff = ϕ.^(-(1:N)) + acoeff = ϕ .^ (-(1:N)) n_points = 0 # count visited squares ind = 0 # index of low discrepancy sequence - while n_points < prod(resolution)*min(one(dens), dens) # fill up to 100*dens% of mask + while n_points < prod(resolution) * min(one(dens), dens) # fill up to 100*dens% of mask # next index from low discrepancy sequence - c = CartesianIndex(ntuple(N) do i - j = ceil(Int, ((0.5 + acoeff[i]*ind) % 1)*resolution[i]) - clamp(j, 1, size(mask, i)) - end) + c = CartesianIndex( + ntuple(N) do i + j = ceil(Int, ((0.5 + acoeff[i] * ind) % 1) * resolution[i]) + clamp(j, 1, size(mask, i)) + end + ) ind += 1 if mask[c] - x0 = Point{N}(ntuple(N) do i - first(r[i]) + (c[i] - 0.5) * step(r[i]) - end) + x0 = Point{N}( + ntuple(N) do i + first(r[i]) + (c[i] - 0.5) * step(r[i]) + end + ) point = apply_f(x0, CallType) if !(point isa Point2 || point isa Point3) error("Function passed to streamplot must return Point2 or Point3") @@ -178,7 +181,7 @@ function plot!(p::StreamPlot) lines!( p, - lift(x->x[3], p, data), + lift(x -> x[3], p, data), color = lift(last, p, data), linestyle = p.linestyle, linecap = p.linecap, @@ -226,11 +229,11 @@ function plot!(p::StreamPlot) end end - scatterfun(N)( + return scatterfun(N)( p, lift(first, p, data); - markersize=arrow_size, rotation=rotations, - color=lift(x -> x[4], p, data), + markersize = arrow_size, rotation = rotations, + color = lift(x -> x[4], p, data), marker = lift((ah, q) -> arrow_head(N, ah, q), p, p.arrow_head, p.quality), colormap_args..., generic_plot_attributes... diff --git a/src/basic_recipes/text.jl b/src/basic_recipes/text.jl index a033fadeaef..bc2491cd564 100644 --- a/src/basic_recipes/text.jl +++ b/src/basic_recipes/text.jl @@ -1,5 +1,5 @@ function check_textsize_deprecation(@nospecialize(dictlike)) - if haskey(dictlike, :textsize) + return if haskey(dictlike, :textsize) throw(ArgumentError("`textsize` has been renamed to `fontsize` in Makie v0.19. Please change all occurrences of `textsize` to `fontsize` or revert back to an earlier version.")) end end @@ -7,7 +7,7 @@ end # conversion stopper for previous methods convert_arguments(::Type{<:Text}, gcs::AbstractVector{<:GlyphCollection}) = (gcs,) convert_arguments(::Type{<:Text}, gc::GlyphCollection) = (gc,) -convert_arguments(::Type{<:Text}, vec::AbstractVector{<:Tuple{<:Any,<:Point}}) = (vec,) +convert_arguments(::Type{<:Text}, vec::AbstractVector{<:Tuple{<:Any, <:Point}}) = (vec,) convert_arguments(::Type{<:Text}, strings::AbstractVector{<:AbstractString}) = (strings,) convert_arguments(::Type{<:Text}, string::AbstractString) = (string,) # Fallback to PointBased @@ -17,10 +17,10 @@ convert_arguments(::Type{<:Text}, args...) = convert_arguments(PointBased(), arg function plot!(plot::Text) positions = plot[1] # attach a function to any text that calculates the glyph layout and stores it - glyphcollections = Observable(GlyphCollection[]; ignore_equal_values=true) - linesegs = Observable(Point2f[]; ignore_equal_values=true) - linewidths = Observable(Float32[]; ignore_equal_values=true) - linecolors = Observable(RGBAf[]; ignore_equal_values=true) + glyphcollections = Observable(GlyphCollection[]; ignore_equal_values = true) + linesegs = Observable(Point2f[]; ignore_equal_values = true) + linewidths = Observable(Float32[]; ignore_equal_values = true) + linecolors = Observable(RGBAf[]; ignore_equal_values = true) lineindices = Ref(Int[]) if !haskey(plot, :text) attributes(plot)[:text] = plot[2] @@ -30,10 +30,12 @@ function plot!(plot::Text) color_scaled = calc_color isa ColorMapping ? calc_color.color_scaled : plot.color cmap = calc_color isa ColorMapping ? calc_color.colormap : plot.colormap - onany(plot, plot.text, plot.fontsize, plot.font, plot.fonts, plot.align, - plot.rotation, plot.justification, plot.lineheight, color_scaled, cmap, - plot.strokecolor, plot.strokewidth, plot.word_wrap_width, plot.offset) do str, - ts, f, fs, al, rot, jus, lh, cs, cmap, scol, swi, www, offs + onany( + plot, plot.text, plot.fontsize, plot.font, plot.fonts, plot.align, + plot.rotation, plot.justification, plot.lineheight, color_scaled, cmap, + plot.strokecolor, plot.strokewidth, plot.word_wrap_width, plot.offset + ) do str, + ts, f, fs, al, rot, jus, lh, cs, cmap, scol, swi, www, offs ts = to_fontsize(ts) f = to_font(fs, f) @@ -73,12 +75,14 @@ function plot!(plot::Text) linesegs[] = lsegs end - linesegs_shifted = Observable(Point2f[]; ignore_equal_values=true) + linesegs_shifted = Observable(Point2f[]; ignore_equal_values = true) sc = parent_scene(plot) - onany(plot, linesegs, positions, sc.camera.projectionview, sc.viewport, f32_conversion_obs(sc), - transform_func_obs(sc), get(plot, :space, :data)) do segs, pos, _, _, _, transf, space + onany( + plot, linesegs, positions, sc.camera.projectionview, sc.viewport, f32_conversion_obs(sc), + transform_func_obs(sc), get(plot, :space, :data) + ) do segs, pos, _, _, _, transf, space pos_transf = plot_to_screen(plot, pos) linesegs_shifted[] = map(segs, lineindices[]) do seg, index seg + attr_broadcast_getindex(pos_transf, index) @@ -101,7 +105,7 @@ function plot!(plot::Text) pop!(t.attributes, :fonts) pop!(t.attributes, :text) linesegments!(plot, linesegs_shifted; linewidth = linewidths, color = linecolors, space = :pixel) - plot + return plot end to_offset(v::VecTypes) = Vec2f(v) @@ -109,12 +113,14 @@ to_offset(v::AbstractVector) = map(to_offset, v) function _get_glyphcollection_and_linesegments(str::AbstractString, index, ts, f, fs, al, rot, jus, lh, col, scol, swi, www, offs) gc = layout_text(string(str), ts, f, fs, al, rot, jus, lh, col, scol, swi, www) - gc, Point2f[], Float32[], RGBAf[], Int[] + return gc, Point2f[], Float32[], RGBAf[], Int[] end function _get_glyphcollection_and_linesegments(latexstring::LaTeXString, index, ts, f, fs, al, rot, jus, lh, col, scol, swi, www, offs) - tex_elements, glyphcollections, offset = texelems_and_glyph_collection(latexstring, ts, - al[1], al[2], rot, col, scol, swi, www) + tex_elements, glyphcollections, offset = texelems_and_glyph_collection( + latexstring, ts, + al[1], al[2], rot, col, scol, swi, www + ) linesegs = Point2f[] linewidths = Float32[] @@ -138,18 +144,17 @@ function _get_glyphcollection_and_linesegments(latexstring::LaTeXString, index, end end - glyphcollections, linesegs, linewidths, linecolors, lineindices + return glyphcollections, linesegs, linewidths, linecolors, lineindices end function plot!(plot::Text{<:Tuple{<:AbstractString}}) attrs = copy(plot.attributes) pop!(attrs, :calculated_colors) text!(plot, plot.position; attrs..., text = plot[1]) - plot + return plot end - # TODO: is this necessary? there seems to be a recursive loop with the above # function without these two interceptions, but I didn't need it before merging # everything into the monorepo... @@ -160,7 +165,7 @@ function plot!(plot::Text{<:Tuple{<:AbstractArray{<:AbstractString}}}) attrs = copy(plot.attributes) pop!(attrs, :calculated_colors) text!(plot, plot.position; attrs..., text = plot[1]) - plot + return plot end # overload text plotting for a vector of tuples of a string and a point each @@ -170,7 +175,7 @@ function plot!(plot::Text{<:Tuple{<:AbstractArray{<:Tuple{<:Any, <:Point}}}}) strings = Observable{Vector{Any}}(first.(strings_and_positions[])) positions = Observable( - Point3d[to_ndim(Point3d, last(x), 0) for x in strings_and_positions[]] # avoid Any for zero elements + Point3d[to_ndim(Point3d, last(x), 0) for x in strings_and_positions[]] # avoid Any for zero elements ) attrs = plot.attributes @@ -195,11 +200,13 @@ function plot!(plot::Text{<:Tuple{<:AbstractArray{<:Tuple{<:Any, <:Point}}}}) return end - plot + return plot end -function texelems_and_glyph_collection(str::LaTeXString, fontscale_px, halign, valign, - rotation, color, strokecolor, strokewidth, word_wrap_width) +function texelems_and_glyph_collection( + str::LaTeXString, fontscale_px, halign, valign, + rotation, color, strokecolor, strokewidth, word_wrap_width + ) rot = convert_attribute(rotation, key"rotation"()) @@ -229,7 +236,7 @@ function texelems_and_glyph_collection(str::LaTeXString, fontscale_px, halign, v if word_wrap_width > 0 last_space_idx = 0 last_newline_idx = 1 - newline_offset = Point3f(basepositions[1][1], 0f0, 0) + newline_offset = Point3f(basepositions[1][1], 0.0f0, 0) for i in eachindex(texchars) basepositions[i] -= newline_offset @@ -238,12 +245,12 @@ function texelems_and_glyph_collection(str::LaTeXString, fontscale_px, halign, v if last_space_idx != 0 && right_pos > word_wrap_width section_offset = basepositions[last_space_idx + 1][1] lineheight = maximum((height(bb) for bb in bboxes[last_newline_idx:last_space_idx])) - last_newline_idx = last_space_idx+1 + last_newline_idx = last_space_idx + 1 newline_offset += Point3f(section_offset, lineheight, 0) # TODO: newlines don't really need to represented at all? # chars[last_space_idx] = '\n' - for j in last_space_idx+1:i + for j in (last_space_idx + 1):i basepositions[j] -= Point3f(section_offset, lineheight, 0) end end @@ -255,13 +262,13 @@ function texelems_and_glyph_collection(str::LaTeXString, fontscale_px, halign, v end bb = isempty(bboxes) ? BBox(0, 0, 0, 0) : begin - mapreduce(union, zip(bboxes, basepositions)) do (b, pos) - Rect2f(Rect3f(b) + pos) + mapreduce(union, zip(bboxes, basepositions)) do (b, pos) + Rect2f(Rect3f(b) + pos) + end end - end xshift = get_xshift(minimum(bb)[1], maximum(bb)[1], halign) - yshift = get_yshift(minimum(bb)[2], maximum(bb)[2], valign, default=0f0) + yshift = get_yshift(minimum(bb)[2], maximum(bb)[2], valign, default = 0.0f0) shift = Vec3f(xshift, yshift, 0) positions = basepositions .- Ref(shift) @@ -279,32 +286,32 @@ function texelems_and_glyph_collection(str::LaTeXString, fontscale_px, halign, v strokewidth ) - all_els, pre_align_gl, Point2f(xshift, yshift) + return all_els, pre_align_gl, Point2f(xshift, yshift) end iswhitespace(l::LaTeXString) = iswhitespace(replace(l.s, '$' => "")) struct RichText type::Symbol - children::Vector{Union{RichText,String}} + children::Vector{Union{RichText, String}} attributes::Dict{Symbol, Any} function RichText(type::Symbol, children...; kwargs...) - cs = Union{RichText,String}[children...] + cs = Union{RichText, String}[children...] typeof(cs) - new(type, cs, Dict(kwargs)) + return new(type, cs, Dict(kwargs)) end end function Base.String(r::RichText) fn(io, x::RichText) = foreach(x -> fn(io, x), x.children) fn(io, s::String) = print(io, s) - sprint() do io + return sprint() do io fn(io, r) end end function Base.show(io::IO, ::MIME"text/plain", r::RichText) - print(io, "RichText: \"$(String(r))\"") + return print(io, "RichText: \"$(String(r))\"") end """ @@ -344,7 +351,7 @@ export rich, subscript, superscript, subsup, left_subsup function _get_glyphcollection_and_linesegments(rt::RichText, index, ts, f, fset, al, rot, jus, lh, col, scol, swi, www, offs) gc = layout_text(rt, ts, f, fset, al, rot, jus, lh, col) - gc, Point2f[], Float32[], RGBAf[], Int[] + return gc, Point2f[], Float32[], RGBAf[], Int[] end struct GlyphState @@ -368,31 +375,35 @@ struct GlyphInfo end # Copy constructor, to overwrite a field -function GlyphInfo(gi::GlyphInfo; - glyph=gi.glyph, - font=gi.font, - origin=gi.origin, - extent=gi.extent, - size=gi.size, - rotation=gi.rotation, - color=gi.color, - strokecolor=gi.strokecolor, - strokewidth=gi.strokewidth) - - return GlyphInfo(glyph, - font, - origin, - extent, - size, - rotation, - color, - strokecolor, - strokewidth) +function GlyphInfo( + gi::GlyphInfo; + glyph = gi.glyph, + font = gi.font, + origin = gi.origin, + extent = gi.extent, + size = gi.size, + rotation = gi.rotation, + color = gi.color, + strokecolor = gi.strokecolor, + strokewidth = gi.strokewidth + ) + + return GlyphInfo( + glyph, + font, + origin, + extent, + size, + rotation, + color, + strokecolor, + strokewidth + ) end function GlyphCollection(v::Vector{GlyphInfo}) - GlyphCollection( + return GlyphCollection( [i.glyph for i in v], [i.font for i in v], [Point3f(i.origin..., 0) for i in v], @@ -433,7 +444,7 @@ function apply_lineheight!(lines, lh) l = line[j] ox, oy = l.origin # TODO: Lineheight - l = GlyphInfo(l; origin=Point2f(ox, oy - (i - 1) * 20)) + l = GlyphInfo(l; origin = Point2f(ox, oy - (i - 1) * 20)) line[j] = l end end @@ -441,7 +452,7 @@ function apply_lineheight!(lines, lh) end function max_x_advance(glyph_infos::Vector{GlyphInfo})::Float32 - return maximum(glyph_infos; init=0.0f0) do ginfo + return maximum(glyph_infos; init = 0.0f0) do ginfo ginfo.origin[1] + ginfo.extent.hadvance * ginfo.size[1] end end @@ -466,8 +477,8 @@ function apply_alignment_and_justification!(lines, ju, al) top_y = max_y_ascender(lines[1]) bottom_y = min_y_descender(lines[end]) - al_offset_x = get_xshift(0f0, max_x, al[1]; default=0f0) - al_offset_y = get_yshift(bottom_y, top_y, al[2]; default=0f0) + al_offset_x = get_xshift(0.0f0, max_x, al[1]; default = 0.0f0) + al_offset_y = get_yshift(bottom_y, top_y, al[2]; default = 0.0f0) fju = float_justification(ju, al) @@ -485,10 +496,10 @@ end function float_justification(ju, al)::Float32 halign = al[1] - float_justification = if ju === automatic - get_xshift(0f0, 1f0, halign) + return float_justification = if ju === automatic + get_xshift(0.0f0, 1.0f0, halign) else - get_xshift(0f0, 1f0, ju; default=ju) # errors if wrong symbol is used + get_xshift(0.0f0, 1.0f0, ju; default = ju) # errors if wrong symbol is used end end @@ -534,7 +545,7 @@ end function right_align!(line1::Vector{GlyphInfo}, line2::Vector{GlyphInfo}) isempty(line1) || isempty(line2) && return xmax1, xmax2 = map((line1, line2)) do line - maximum(line; init = 0f0) do ginfo + maximum(line; init = 0.0f0) do ginfo GlyphInfo ginfo.origin[1] + ginfo.size[1] * (ginfo.extent.ink_bounding_box.origin[1] + ginfo.extent.ink_bounding_box.widths[1]) end @@ -561,17 +572,19 @@ function process_rt_node!(lines, gs::GlyphState, s::String, _) gi = FreeTypeAbstraction.glyph_index(bestfont, char) gext = GlyphExtent(bestfont, char) ori = Point2f(x, y) - push!(lines[end], GlyphInfo( - gi, - bestfont, - ori, - gext, - gs.size, - to_rotation(0), - gs.color, - RGBAf(0, 0, 0, 0), - 0f0, - )) + push!( + lines[end], GlyphInfo( + gi, + bestfont, + ori, + gext, + gs.size, + to_rotation(0), + gs.color, + RGBAf(0, 0, 0, 0), + 0.0f0, + ) + ) x = x + gext.hadvance * gs.size[1] end end @@ -587,7 +600,7 @@ function new_glyphstate(gs::GlyphState, rt::RichText, ::Val{:sup}, fonts) att = rt.attributes fontsize = _get_fontsize(att, gs.size * 0.66) offset = _get_offset(att, Vec2f(0)) .* fontsize - GlyphState( + return GlyphState( gs.x + offset[1], gs.baseline + 0.4 * gs.size[2] + offset[2], fontsize, @@ -600,7 +613,7 @@ function new_glyphstate(gs::GlyphState, rt::RichText, ::Val{:span}, fonts) att = rt.attributes fontsize = _get_fontsize(att, gs.size) offset = _get_offset(att, Vec2f(0)) .* fontsize - GlyphState( + return GlyphState( gs.x + offset[1], gs.baseline + offset[2], fontsize, @@ -613,7 +626,7 @@ function new_glyphstate(gs::GlyphState, rt::RichText, ::Val{:sub}, fonts) att = rt.attributes fontsize = _get_fontsize(att, gs.size * 0.66) offset = _get_offset(att, Vec2f(0)) .* fontsize - GlyphState( + return GlyphState( gs.x + offset[1], gs.baseline - 0.25 * gs.size[2] + offset[2], fontsize, @@ -625,7 +638,7 @@ end function new_glyphstate(gs::GlyphState, rt::RichText, ::Val{:subsup_sub}, fonts) att = rt.attributes fontsize = _get_fontsize(att, gs.size * 0.66) - GlyphState( + return GlyphState( gs.x, gs.baseline - 0.25 * gs.size[2], fontsize, @@ -636,7 +649,7 @@ end function new_glyphstate(gs::GlyphState, rt::RichText, ::Val{:subsup_sup}, fonts) att = rt.attributes fontsize = _get_fontsize(att, gs.size * 0.66) - GlyphState( + return GlyphState( gs.x, gs.baseline + 0.4 * gs.size[2], fontsize, @@ -647,20 +660,20 @@ end iswhitespace(r::RichText) = iswhitespace(String(r)) -function get_xshift(lb, ub, align; default=0.5f0) +function get_xshift(lb, ub, align; default = 0.5f0) if align isa Symbol - align = align === :left ? 0.0f0 : - align === :center ? 0.5f0 : - align === :right ? 1.0f0 : default + align = align === :left ? 0.0f0 : + align === :center ? 0.5f0 : + align === :right ? 1.0f0 : default end - lb * (1-align) + ub * align |> Float32 + return lb * (1 - align) + ub * align |> Float32 end -function get_yshift(lb, ub, align; default=0.5f0) +function get_yshift(lb, ub, align; default = 0.5f0) if align isa Symbol align = align === :bottom ? 0.0f0 : - align === :center ? 0.5f0 : - align === :top ? 1.0f0 : default + align === :center ? 0.5f0 : + align === :top ? 1.0f0 : default end - lb * (1-align) + ub * align |> Float32 + return lb * (1 - align) + ub * align |> Float32 end diff --git a/src/basic_recipes/timeseries.jl b/src/basic_recipes/timeseries.jl index 7409047fac5..8ac1e310d95 100644 --- a/src/basic_recipes/timeseries.jl +++ b/src/basic_recipes/timeseries.jl @@ -28,9 +28,11 @@ end signal2point(signal::Number, start) = Point2f(time() - start, signal) signal2point(signal::Point2, start) = signal -signal2point(signal, start) = error(""" Signal needs to be of type Number or Point. -Found: $(typeof(signal)) -""") +signal2point(signal, start) = error( + """ Signal needs to be of type Number or Point. + Found: $(typeof(signal)) + """ +) function Makie.plot!(plot::TimeSeries) @@ -47,5 +49,5 @@ function Makie.plot!(plot::TimeSeries) buffer = points[] points[] = buff_ref end - plot + return plot end diff --git a/src/basic_recipes/tooltip.jl b/src/basic_recipes/tooltip.jl index 41ab8affd49..66eebfd5ae4 100644 --- a/src/basic_recipes/tooltip.jl +++ b/src/basic_recipes/tooltip.jl @@ -43,7 +43,7 @@ Creates a tooltip pointing at `position` displaying the given `string "Sets the color of the tooltip outline." outline_color = :black "Sets the linewidth of the tooltip outline." - outline_linewidth = 2f0 + outline_linewidth = 2.0f0 "Sets the linestyle of the tooltip outline." outline_linestyle = nothing @@ -51,17 +51,17 @@ Creates a tooltip pointing at `position` displaying the given `string inspectable = false end -function convert_arguments(::Type{<: Tooltip}, x::Real, y::Real, str::AbstractString) +function convert_arguments(::Type{<:Tooltip}, x::Real, y::Real, str::AbstractString) return (Point2{float_type(x, y)}(x, y), str) end -function convert_arguments(::Type{<: Tooltip}, x::Real, y::Real) +function convert_arguments(::Type{<:Tooltip}, x::Real, y::Real) return (Point2{float_type(x, y)}(x, y),) end function plot!(plot::Tooltip{<:Tuple{<:VecTypes, <:AbstractString}}) - plot.attributes[:text] = plot[2] + plot.attributes[:text] = plot[2] tooltip!(plot, plot[1]; plot.attributes...) - plot + return plot end @@ -69,8 +69,9 @@ function plot!(p::Tooltip{<:Tuple{<:VecTypes}}) # TODO align scene = parent_scene(p) px_pos = map( - p, p[1], scene.camera.projectionview, p.model, transform_func(p), - p.space, scene.viewport) do pos, _, model, tf, space, viewport + p, p[1], scene.camera.projectionview, p.model, transform_func(p), + p.space, scene.viewport + ) do pos, _, model, tf, space, viewport # Adjusted from error_and_rangebars spvm = clip_to_space(scene.camera, :pixel) * space_to_clip(scene.camera, space) * model @@ -89,11 +90,11 @@ function plot!(p::Tooltip{<:Tuple{<:VecTypes}}) if placement === :left return Vec2f(-o - r - ts, b - align * (b + t)) elseif placement === :right - return Vec2f( o + l + ts, b - align * (b + t)) + return Vec2f(o + l + ts, b - align * (b + t)) elseif placement in (:below, :down, :bottom) return Vec2f(l - align * (l + r), -o - t - ts) elseif placement in (:above, :up, :top) - return Vec2f(l - align * (l + r), o + b + ts) + return Vec2f(l - align * (l + r), o + b + ts) else @error "Tooltip placement $placement invalid. Assuming :above" return Vec2f(0, o + b + ts) @@ -128,11 +129,11 @@ function plot!(p::Tooltip{<:Tuple{<:VecTypes}}) # TODO react to glyphcollection instead bbox = map( - p, px_pos, p.text, text_align, text_offset, textpadding, p.align - ) do p, s, _, o, pad, align + p, px_pos, p.text, text_align, text_offset, textpadding, p.align + ) do p, s, _, o, pad, align bb = string_boundingbox(tp) + to_ndim(Vec3f, o, 0) l, r, b, t = pad - return Rect3f(origin(bb) .- (l, b, 0), widths(bb) .+ (l+r, b+t, 0)) + return Rect3f(origin(bb) .- (l, b, 0), widths(bb) .+ (l + r, b + t, 0)) end # Text background mesh @@ -152,34 +153,34 @@ function plot!(p::Tooltip{<:Tuple{<:VecTypes}}) r, t = (l, b) .+ (w, h) if placement === :left return Point3f[ - (r, b + align * h + 0.5s, z), - (r + s, b + align * h, z), - (r, b + align * h - 0.5s, z), + (r, b + align * h + 0.5s, z), + (r + s, b + align * h, z), + (r, b + align * h - 0.5s, z), ] elseif placement === :right return Point3f[ - (l, b + align * h - 0.5s, z), - (l-s, b + align * h, z), - (l, b + align * h + 0.5s, z), + (l, b + align * h - 0.5s, z), + (l - s, b + align * h, z), + (l, b + align * h + 0.5s, z), ] elseif placement in (:below, :down, :bottom) return Point3f[ - (l + align * w - 0.5s, t, z), - (l + align * w, t+s, z), - (l + align * w + 0.5s, t, z), + (l + align * w - 0.5s, t, z), + (l + align * w, t + s, z), + (l + align * w + 0.5s, t, z), ] elseif placement in (:above, :up, :top) return Point3f[ - (l + align * w + 0.5s, b, z), - (l + align * w, b-s, z), - (l + align * w - 0.5s, b, z), + (l + align * w + 0.5s, b, z), + (l + align * w, b - s, z), + (l + align * w - 0.5s, b, z), ] else @error "Tooltip placement $placement invalid. Assuming :above" return Point3f[ - (l + align * w + 0.5s, b, z), - (l + align * w, b-s, z), - (l + align * w - 0.5s, b, z), + (l + align * w + 0.5s, b, z), + (l + align * w, b - s, z), + (l + align * w - 0.5s, b, z), ] end end @@ -207,43 +208,43 @@ function plot!(p::Tooltip{<:Tuple{<:VecTypes}}) shift = if placement === :left Vec2f[ (l, b), (l, t), (r, t), - (r, b + align * h + 0.5s), + (r, b + align * h + 0.5s), (r + s, b + align * h), - (r, b + align * h - 0.5s), - (r, b), (l, b) + (r, b + align * h - 0.5s), + (r, b), (l, b), ] elseif placement === :right Vec2f[ (r, b), (l, b), - (l, b + align * h - 0.5s), - (l-s, b + align * h), - (l, b + align * h + 0.5s), - (l, t), (r, t), (r, b) + (l, b + align * h - 0.5s), + (l - s, b + align * h), + (l, b + align * h + 0.5s), + (l, t), (r, t), (r, b), ] elseif placement in (:below, :down, :bottom) Vec2f[ (l, b), (l, t), (l + align * w - 0.5s, t), - (l + align * w, t+s), + (l + align * w, t + s), (l + align * w + 0.5s, t), - (r, t), (r, b), (l, b) + (r, t), (r, b), (l, b), ] elseif placement in (:above, :up, :top) Vec2f[ (l, b), (l, t), (r, t), (r, b), (l + align * w + 0.5s, b), - (l + align * w, b-s), + (l + align * w, b - s), (l + align * w - 0.5s, b), - (l, b) + (l, b), ] else @error "Tooltip placement $placement invalid. Assuming :above" Vec2f[ (l, b), (l, t), (r, t), (r, b), (l + align * w + 0.5s, b), - (l + align * w, b-s), + (l + align * w, b - s), (l + align * w - 0.5s, b), - (l, b) + (l, b), ] end @@ -252,7 +253,7 @@ function plot!(p::Tooltip{<:Tuple{<:VecTypes}}) lp = lines!( p, outline, - color = p.outline_color, space = :pixel, miter_limit = pi/18, + color = p.outline_color, space = :pixel, miter_limit = pi / 18, linewidth = p.outline_linewidth, linestyle = p.outline_linestyle, transparency = p.transparency, visible = p.visible, overdraw = p.overdraw, depth_shift = p.depth_shift, diff --git a/src/basic_recipes/tricontourf.jl b/src/basic_recipes/tricontourf.jl index 9a7384f9ff3..7e6b5edb2ce 100644 --- a/src/basic_recipes/tricontourf.jl +++ b/src/basic_recipes/tricontourf.jl @@ -57,8 +57,10 @@ function Makie.used_attributes(::Type{<:Tricontourf}, ::AbstractVector{<:Real}, return (:triangulation,) end -function Makie.convert_arguments(::Type{<:Tricontourf}, x::AbstractVector{<:Real}, y::AbstractVector{<:Real}, z::AbstractVector{<:Real}; - triangulation=DelaunayTriangulation()) +function Makie.convert_arguments( + ::Type{<:Tricontourf}, x::AbstractVector{<:Real}, y::AbstractVector{<:Real}, z::AbstractVector{<:Real}; + triangulation = DelaunayTriangulation() + ) T = float_type(x, y, z) z = elconvert(T, z) points = [elconvert(T, x)'; elconvert(T, y)'] @@ -85,16 +87,16 @@ function compute_contourf_colormap(levels, cmap, elow, ehigh) _cmap = to_colormap(cmap) if elow === :auto && ehigh !== :auto - cm_base = cgrad(_cmap, n + 1; categorical=true)[2:end] - cm = cgrad(cm_base, levels_scaled; categorical=true) + cm_base = cgrad(_cmap, n + 1; categorical = true)[2:end] + cm = cgrad(cm_base, levels_scaled; categorical = true) elseif ehigh === :auto && elow !== :auto - cm_base = cgrad(_cmap, n + 1; categorical=true)[1:(end - 1)] - cm = cgrad(cm_base, levels_scaled; categorical=true) + cm_base = cgrad(_cmap, n + 1; categorical = true)[1:(end - 1)] + cm = cgrad(cm_base, levels_scaled; categorical = true) elseif ehigh === :auto && elow === :auto - cm_base = cgrad(_cmap, n + 2; categorical=true)[2:(end - 1)] - cm = cgrad(cm_base, levels_scaled; categorical=true) + cm_base = cgrad(_cmap, n + 2; categorical = true)[2:(end - 1)] + cm = cgrad(cm_base, levels_scaled; categorical = true) else - cm = cgrad(_cmap, levels_scaled; categorical=true) + cm = cgrad(_cmap, levels_scaled; categorical = true) end return cm end @@ -127,8 +129,10 @@ function Makie.plot!(c::Tricontourf{<:Tuple{<:DelTri.Triangulation, <:AbstractVe end colorrange = lift(extrema_nan, c, c._computed_levels) - computed_colormap = lift(compute_contourf_colormap, c, c._computed_levels, c.colormap, c.extendlow, - c.extendhigh) + computed_colormap = lift( + compute_contourf_colormap, c, c._computed_levels, c.colormap, c.extendlow, + c.extendhigh + ) c.attributes[:_computed_colormap] = computed_colormap lowcolor = Observable{RGBAf}() @@ -157,7 +161,7 @@ function Makie.plot!(c::Tricontourf{<:Tuple{<:DelTri.Triangulation, <:AbstractVe @assert issorted(levels) is_extended_low && pushfirst!(levels, -Inf) is_extended_high && push!(levels, Inf) - lows = levels[1:end-1] + lows = levels[1:(end - 1)] highs = levels[2:end] xs = [DelTri.getx(p) for p in DelTri.each_point(triangulation)] # each_point preserves indices @@ -191,7 +195,8 @@ function Makie.plot!(c::Tricontourf{<:Tuple{<:DelTri.Triangulation, <:AbstractVe # it on a first run! calculate_polys(tri[], zs[], c._computed_levels[], is_extended_low[], is_extended_high[]) - poly!(c, + return poly!( + c, polys, colormap = c._computed_colormap, colorscale = c.colorscale, @@ -214,17 +219,17 @@ end # FIXME: TriplotBase augments levels so here the implementation is just repeated without that step function filled_tricontours(x, y, z, t, levels) m = TriplotBase.TriMesh(x, y, t) - filled_tricontours(m, z, levels) + return filled_tricontours(m, z, levels) end function filled_tricontours(m::TriplotBase.TriMesh, z, levels) @assert issorted(levels) nlevels = length(levels) filled_contours = TriplotBase.FilledContour{eltype(levels)}[] - for i=1:nlevels-1 + for i in 1:(nlevels - 1) lower = levels[i] - upper = levels[i+1] + upper = levels[i + 1] push!(filled_contours, TriplotBase.generate_filled_contours(m, z, lower, upper)) end - filled_contours + return filled_contours end diff --git a/src/basic_recipes/triplot.jl b/src/basic_recipes/triplot.jl index fa1135fd091..28dbe1dcc25 100644 --- a/src/basic_recipes/triplot.jl +++ b/src/basic_recipes/triplot.jl @@ -8,62 +8,62 @@ Plots a triangulation based on the provided position or `Triangulation` from Del @recipe Triplot (triangles,) begin # Toggles "Determines whether to plot the individual points. Note that this will only plot points included in the triangulation." - show_points=false + show_points = false "Determines whether to plot the convex hull." - show_convex_hull=false + show_convex_hull = false "Determines whether to plot the ghost edges." - show_ghost_edges=false + show_ghost_edges = false "Determines whether to plot the constrained edges." - show_constrained_edges=false + show_constrained_edges = false "Determines whether to recompute the representative points for the ghost edge orientation. Note that this will mutate `tri.representative_point_list` directly." - recompute_centers=false + recompute_centers = false # Mesh settings "Sets the size of the points." - markersize= @inherit markersize + markersize = @inherit markersize "Sets the shape of the points." - marker= @inherit marker + marker = @inherit marker "Sets the color of the points." - markercolor= @inherit markercolor + markercolor = @inherit markercolor "Sets the color of triangle edges." - strokecolor= @inherit patchstrokecolor + strokecolor = @inherit patchstrokecolor "Sets the linewidth of triangle edges." - strokewidth=1 + strokewidth = 1 "Sets the linestyle of triangle edges." - linestyle=:solid + linestyle = :solid "Sets the color of the triangles." - triangle_color= :transparent + triangle_color = :transparent linecap = @inherit linecap joinstyle = @inherit joinstyle miter_limit = @inherit miter_limit # Convex hull settings "Sets the color of the convex hull." - convex_hull_color=:red + convex_hull_color = :red "Sets the linestyle of the convex hull." - convex_hull_linestyle=:dash + convex_hull_linestyle = :dash "Sets the width of the convex hull." - convex_hull_linewidth= @inherit linewidth + convex_hull_linewidth = @inherit linewidth # Ghost edge settings "Sets the color of the ghost edges." - ghost_edge_color=:blue + ghost_edge_color = :blue "Sets the linestyle of the ghost edges." - ghost_edge_linestyle= @inherit linestyle + ghost_edge_linestyle = @inherit linestyle "Sets the width of the ghost edges." - ghost_edge_linewidth= @inherit linewidth + ghost_edge_linewidth = @inherit linewidth "Sets the extension factor for the rectangle that the exterior ghost edges are extended onto." - ghost_edge_extension_factor=0.1 + ghost_edge_extension_factor = 0.1 "Sets the bounding box for truncating ghost edges which can be a `Rect2` (or `BBox`) or a tuple of the form `(xmin, xmax, ymin, ymax)`. By default, the rectangle will be given by `[a - eΔx, b + eΔx] × [c - eΔy, d + eΔy]` where `e` is the `ghost_edge_extension_factor`, `Δx = b - a` and `Δy = d - c` are the lengths of the sides of the rectangle, and `[a, b] × [c, d]` is the bounding box of the points in the triangulation." - bounding_box=automatic + bounding_box = automatic # Constrained edge settings "Sets the color of the constrained edges." - constrained_edge_color=:magenta + constrained_edge_color = :magenta "Sets the linestyle of the constrained edges." - constrained_edge_linestyle= @inherit linestyle + constrained_edge_linestyle = @inherit linestyle "Sets the width of the constrained edges." - constrained_edge_linewidth= @inherit linewidth + constrained_edge_linewidth = @inherit linewidth end function get_all_triangulation_points!(points, tri) @@ -103,13 +103,17 @@ function get_triangulation_ghost_edges!(ghost_edges, extent, tri, bounding_box) sizehint!(ghost_edges, 2DelTri.num_ghost_edges(tri)) if bounding_box === automatic if DelTri.has_boundary_nodes(tri) - xmin, xmax, ymin, ymax = DelTri.polygon_bounds(DelTri.get_points(tri), - DelTri.get_boundary_nodes(tri), - Val(true)) + xmin, xmax, ymin, ymax = DelTri.polygon_bounds( + DelTri.get_points(tri), + DelTri.get_boundary_nodes(tri), + Val(true) + ) else - xmin, xmax, ymin, ymax = DelTri.polygon_bounds(DelTri.get_points(tri), - DelTri.get_convex_hull_vertices(tri), - Val(true)) + xmin, xmax, ymin, ymax = DelTri.polygon_bounds( + DelTri.get_points(tri), + DelTri.get_convex_hull_vertices(tri), + Val(true) + ) end Δx = xmax - xmin Δy = ymax - ymin @@ -184,7 +188,7 @@ function Makie.plot!(p::Triplot{<:Tuple{<:Vector{<:Point}}}) return DelTri.triangulate(transformed, randomise = false) end - attr[:transformation] = Transformation(p.transformation; transform_func=identity) + attr[:transformation] = Transformation(p.transformation; transform_func = identity) triplot!(p, attr, tri) return end @@ -214,25 +218,39 @@ function Makie.plot!(p::Triplot{<:Tuple{<:DelTri.Triangulation}}) p.show_convex_hull[] && get_triangulation_convex_hull!(convex_hull_2f[], tri) p.show_constrained_edges[] && get_triangulation_constrained_edges!(constrained_edges_2f[], tri) - foreach(notify, - (points_2f, present_points_2f, triangles_3f, ghost_edges_2f, convex_hull_2f, - constrained_edges_2f)) + foreach( + notify, + ( + points_2f, present_points_2f, triangles_3f, ghost_edges_2f, convex_hull_2f, + constrained_edges_2f, + ) + ) return nothing end onany(update_plot, p, p[1]) update_plot(p[1][]) - poly!(p, points_2f, triangles_3f; strokewidth=p.strokewidth, strokecolor=p.strokecolor, - color=p.triangle_color, linestyle=p.linestyle) - linesegments!(p, ghost_edges_2f; color=p.ghost_edge_color, linewidth=p.ghost_edge_linewidth, - linecap=p.linecap, linestyle=p.ghost_edge_linestyle, xautolimits=false, yautolimits=false) - lines!(p, convex_hull_2f; color=p.convex_hull_color, linewidth=p.convex_hull_linewidth, - linecap = p.linecap, joinstyle = p.joinstyle, miter_limit = p.miter_limit, - linestyle=p.convex_hull_linestyle, depth_shift=-1.0f-5) - linesegments!(p, constrained_edges_2f; color=p.constrained_edge_color, depth_shift=-2.0f-5, - linecap=p.linecap, linewidth=p.constrained_edge_linewidth, linestyle=p.constrained_edge_linestyle) - scatter!(p, present_points_2f; markersize=p.markersize, color=p.markercolor, - strokecolor=p.strokecolor, marker=p.marker, visible=p.show_points, depth_shift=-3.0f-5) + poly!( + p, points_2f, triangles_3f; strokewidth = p.strokewidth, strokecolor = p.strokecolor, + color = p.triangle_color, linestyle = p.linestyle + ) + linesegments!( + p, ghost_edges_2f; color = p.ghost_edge_color, linewidth = p.ghost_edge_linewidth, + linecap = p.linecap, linestyle = p.ghost_edge_linestyle, xautolimits = false, yautolimits = false + ) + lines!( + p, convex_hull_2f; color = p.convex_hull_color, linewidth = p.convex_hull_linewidth, + linecap = p.linecap, joinstyle = p.joinstyle, miter_limit = p.miter_limit, + linestyle = p.convex_hull_linestyle, depth_shift = -1.0f-5 + ) + linesegments!( + p, constrained_edges_2f; color = p.constrained_edge_color, depth_shift = -2.0f-5, + linecap = p.linecap, linewidth = p.constrained_edge_linewidth, linestyle = p.constrained_edge_linestyle + ) + scatter!( + p, present_points_2f; markersize = p.markersize, color = p.markercolor, + strokecolor = p.strokecolor, marker = p.marker, visible = p.show_points, depth_shift = -3.0f-5 + ) return p end diff --git a/src/basic_recipes/volumeslices.jl b/src/basic_recipes/volumeslices.jl index 31c4d5557cd..6f0800684e0 100644 --- a/src/basic_recipes/volumeslices.jl +++ b/src/basic_recipes/volumeslices.jl @@ -1,4 +1,3 @@ - """ VolumeSlices @@ -28,11 +27,11 @@ function Makie.plot!(plot::VolumeSlices) mx, Mx = extrema(x) my, My = extrema(y) mz, Mz = extrema(z) - Rect3(mx, my, mz, Mx-mx, My-my, Mz-mz) + Rect3(mx, my, mz, Mx - mx, My - my, Mz - mz) end axes = :x, :y, :z - for (ax, p, r, (X, Y)) ∈ zip(axes, (:yz, :xz, :xy), (x, y, z), ((y, z), (x, z), (x, y))) + for (ax, p, r, (X, Y)) in zip(axes, (:yz, :xz, :xy), (x, y, z), ((y, z), (x, z), (x, y))) plot[Symbol(:heatmap_, p)] = hmap = heatmap!( plot, attr, X, Y, zeros(length(X[]), length(Y[])) ) @@ -48,5 +47,5 @@ function Makie.plot!(plot::VolumeSlices) linesegments!(plot, bbox, color = bbox_color, visible = bbox_visible, inspectable = false) - plot + return plot end diff --git a/src/basic_recipes/voronoiplot.jl b/src/basic_recipes/voronoiplot.jl index 7588a5a6ddb..64316c6f5f5 100644 --- a/src/basic_recipes/voronoiplot.jl +++ b/src/basic_recipes/voronoiplot.jl @@ -11,28 +11,28 @@ DelaunayTriangulation.jl. """ @recipe Voronoiplot (vorn,) begin "Determines whether to plot the individual generators." - show_generators=true - smooth=false + show_generators = true + smooth = false # Point settings "Sets the size of the points." - markersize= @inherit markersize + markersize = @inherit markersize "Sets the shape of the points." - marker= @inherit marker + marker = @inherit marker "Sets the color of the points." - markercolor= @inherit markercolor + markercolor = @inherit markercolor # Polygon settings "Sets the strokecolor of the polygons." - strokecolor= @inherit patchstrokecolor + strokecolor = @inherit patchstrokecolor "Sets the width of the polygon stroke." - strokewidth=1.0 + strokewidth = 1.0 "Sets the color of the polygons. If `automatic`, the polygons will be individually colored according to the colormap." - color=automatic + color = automatic "Sets the extension factor for the unbounded edges, used in `DelaunayTriangulation.polygon_bounds`." - unbounded_edge_extension_factor=0.1 + unbounded_edge_extension_factor = 0.1 "Sets the clipping area for the generated polygons which can be a `Rect2` (or `BBox`), `Tuple` with entries `(xmin, xmax, ymin, ymax)` or as a `Circle`. Anything outside the specified area will be removed. If the `clip` is not set it is automatically determined using `unbounded_edge_extension_factor` as a `Rect`." - clip=automatic + clip = automatic MakieCore.mixin_colormap_attributes()... end @@ -141,8 +141,10 @@ function plot!(p::Voronoiplot{<:Tuple{<:Vector{<:Point{N}}}}) where {N} end # Default to circular clip for polar transformed data - attr[:clip] = map(p, pop!(attr, :clip), p.unbounded_edge_extension_factor, - transform_func_obs(p), ps) do bb, ext, tf, ps + attr[:clip] = map( + p, pop!(attr, :clip), p.unbounded_edge_extension_factor, + transform_func_obs(p), ps + ) do bb, ext, tf, ps if bb === automatic && tf isa Polar rscaled = maximum(p -> p[1 + tf.theta_as_x], ps) * (1 + ext) return Circle(Point2f(0), rscaled) @@ -150,7 +152,7 @@ function plot!(p::Voronoiplot{<:Tuple{<:Vector{<:Point{N}}}}) where {N} return bb end end - attr[:transformation] = Transformation(p.transformation; transform_func=identity) + attr[:transformation] = Transformation(p.transformation; transform_func = identity) return voronoiplot!(p, attr, vorn) end @@ -178,8 +180,10 @@ function plot!(p::Voronoiplot{<:Tuple{<:DelTri.VoronoiTessellation}}) cs = [i for i in DelTri.each_point_index(DelTri.get_triangulation(vorn)) if DelTri.has_polygon(vorn, i)] return cs elseif color isa AbstractArray - @assert(length(color) == DelTri.num_points(DelTri.get_triangulation(vorn)), - "Color vector must have the same length as the number of generators, including any not yet in the tessellation.") + @assert( + length(color) == DelTri.num_points(DelTri.get_triangulation(vorn)), + "Color vector must have the same length as the number of generators, including any not yet in the tessellation." + ) return [color[i] for i in DelTri.each_generator(vorn)] # this matches the polygon order else return color # constant color @@ -191,7 +195,7 @@ function plot!(p::Voronoiplot{<:Tuple{<:DelTri.VoronoiTessellation}}) bbox = nothing elseif p.clip[] === automatic extent = p.unbounded_edge_extension_factor[] - bbox = DelTri.polygon_bounds(vorn, extent; include_polygon_vertices=false) + bbox = DelTri.polygon_bounds(vorn, extent; include_polygon_vertices = false) else bbox = p.clip[] end @@ -202,23 +206,27 @@ function plot!(p::Voronoiplot{<:Tuple{<:DelTri.VoronoiTessellation}}) onany(update_plot, p, p[1]) update_plot(p[1][]) - poly!(p, polygons; - strokecolor=p.strokecolor, - strokewidth=p.strokewidth, - color=p._calculated_colors, - colormap=p.colormap, - colorscale=p.colorscale, - colorrange=p.colorrange, - lowclip=p.lowclip, - highclip=p.highclip, - nan_color=p.nan_color) - - scatter!(p, generators_2f; - markersize=p.markersize, - marker=p.marker, - color=p.markercolor, - visible=p.show_generators, - depth_shift=-2.0f-5) + poly!( + p, polygons; + strokecolor = p.strokecolor, + strokewidth = p.strokewidth, + color = p._calculated_colors, + colormap = p.colormap, + colorscale = p.colorscale, + colorrange = p.colorrange, + lowclip = p.lowclip, + highclip = p.highclip, + nan_color = p.nan_color + ) + + scatter!( + p, generators_2f; + markersize = p.markersize, + marker = p.marker, + color = p.markercolor, + visible = p.show_generators, + depth_shift = -2.0f-5 + ) return p end diff --git a/src/basic_recipes/voxels.jl b/src/basic_recipes/voxels.jl index 448df0c4ccd..6a962a38482 100644 --- a/src/basic_recipes/voxels.jl +++ b/src/basic_recipes/voxels.jl @@ -1,22 +1,26 @@ -function Makie.convert_arguments(T::Type{<:Voxels}, chunk::Array{<: Real, 3}) - X, Y, Z = map(x-> (-0.5*x, 0.5*x), size(chunk)) +function Makie.convert_arguments(T::Type{<:Voxels}, chunk::Array{<:Real, 3}) + X, Y, Z = map(x -> (-0.5 * x, 0.5 * x), size(chunk)) return convert_arguments(T, X, Y, Z, chunk) end -function convert_arguments(T::Type{<:Voxels}, xs, ys, zs, chunk::Array{<: Real, 3}) +function convert_arguments(T::Type{<:Voxels}, xs, ys, zs, chunk::Array{<:Real, 3}) xi = Float32.(to_endpoints(xs)) yi = Float32.(to_endpoints(ys)) zi = Float32.(to_endpoints(zs)) return convert_arguments(T, xi, yi, zi, chunk) end -function convert_arguments(::Type{<:Voxels}, xs::EndPoints, ys::EndPoints, zs::EndPoints, - chunk::Array{<:Real,3}) +function convert_arguments( + ::Type{<:Voxels}, xs::EndPoints, ys::EndPoints, zs::EndPoints, + chunk::Array{<:Real, 3} + ) return (xs, ys, zs, Array{UInt8, 3}(undef, to_ndim(Vec3{Int}, size(chunk), 1)...)) end -function convert_arguments(::Type{<:Voxels}, xs::EndPoints, ys::EndPoints, - zs::EndPoints, chunk::Array{UInt8,3}) +function convert_arguments( + ::Type{<:Voxels}, xs::EndPoints, ys::EndPoints, + zs::EndPoints, chunk::Array{UInt8, 3} + ) return (xs, ys, zs, chunk) end @@ -29,8 +33,8 @@ function calculated_attributes!(::Type{<:Voxels}, plot) c = to_color(color[i]) output[i] = RGBAf(Colors.color(c), Colors.alpha(c) * a) end - for i in min(255, length(color))+1 : 255 - output[i] = RGBAf(0,0,0,0) + for i in (min(255, length(color)) + 1):255 + output[i] = RGBAf(0, 0, 0, 0) end elseif color isa AbstractArray output = similar(color, RGBAf) @@ -107,7 +111,7 @@ function local_update(plot::Voxels, is, js, ks) mini, maxi = apply_scale(plot.colorscale[], plot._limits[]) input = plot.args[end][] for k in ks, j in js, i in is - idx = i + _size[1] * ((j-1) + _size[2] * (k-1)) + idx = i + _size[1] * ((j - 1) + _size[2] * (k - 1)) _update_voxel(plot.converted[end].val, input, idx, plot.is_air[], plot.colorscale[], mini, maxi) end plot._local_update[] = (is, js, ks) @@ -221,9 +225,9 @@ function voxel_positions(p::Voxels) _size = size(voxel_id) step = (maxi .- mini) ./ _size return [ - Point3f(mini .+ step .* (i-0.5, j-0.5, k-0.5)) - for k in 1:_size[3] for j in 1:_size[2] for i in 1:_size[1] - if voxel_id[i, j, k] !== 0x00 + Point3f(mini .+ step .* (i - 0.5, j - 0.5, k - 0.5)) + for k in 1:_size[3] for j in 1:_size[2] for i in 1:_size[1] + if voxel_id[i, j, k] !== 0x00 ] end diff --git a/src/basic_recipes/waterfall.jl b/src/basic_recipes/waterfall.jl index 7387442e788..45a635a6e98 100644 --- a/src/basic_recipes/waterfall.jl +++ b/src/basic_recipes/waterfall.jl @@ -7,21 +7,21 @@ to each other. """ @recipe Waterfall (x, y) begin color = @inherit patchcolor - dodge=automatic - n_dodge=automatic - gap=0.2 - dodge_gap=0.03 - width=automatic - cycle=[:color => :patchcolor] - stack=automatic - show_direction=false - marker_pos=:utriangle - marker_neg=:dtriangle - direction_color= @inherit backgroundcolor - show_final=false - final_color=plot_color(:grey90, 0.5) - final_gap=automatic - final_dodge_gap=0 + dodge = automatic + n_dodge = automatic + gap = 0.2 + dodge_gap = 0.03 + width = automatic + cycle = [:color => :patchcolor] + stack = automatic + show_direction = false + marker_pos = :utriangle + marker_neg = :dtriangle + direction_color = @inherit backgroundcolor + show_final = false + final_color = plot_color(:grey90, 0.5) + final_gap = automatic + final_dodge_gap = 0 end conversion_trait(::Type{<:Waterfall}) = PointBased() @@ -37,14 +37,14 @@ function Makie.plot!(p::Waterfall) xy = similar(xy) fillto = similar(x) final = similar(xy) - groupby = StructArray(; grp=i_group) + groupby = StructArray(; grp = i_group) for (grp, inds) in StructArrays.finduniquesorted(groupby) fromto = stack_from_to_final(i_stack[inds], y[inds]) fillto[inds] .= fromto.from xy[inds] .= Point2f.(x[inds], fromto.to) final[inds] .= Point2f.(x[inds], fromto.final) end - return (xy=xy, fillto=fillto, final=final) + return (xy = xy, fillto = fillto, final = final) end fromto = lift(stack_bars, p, p[1], p.dodge, p.stack) @@ -54,10 +54,10 @@ function Makie.plot!(p::Waterfall) barplot!( p, lift(x -> x.final, p, fromto); - dodge=p.dodge, - color=p.final_color, - dodge_gap=p.final_dodge_gap, - gap=final_gap, + dodge = p.dodge, + color = p.final_color, + dodge_gap = p.final_dodge_gap, + gap = final_gap, ) end @@ -75,21 +75,21 @@ function Makie.plot!(p::Waterfall) p, lift(x -> x.xy, p, fromto); bar_attrs..., - fillto=lift(x -> x.fillto, p, fromto), - stack=automatic, + fillto = lift(x -> x.fillto, p, fromto), + stack = automatic, ) if p.show_direction[] function direction_markers( - fromto, - marker_pos, - marker_neg, - width, - gap, - dodge, - n_dodge, - dodge_gap, - ) + fromto, + marker_pos, + marker_neg, + width, + gap, + dodge, + n_dodge, + dodge_gap, + ) xs = first( compute_x_and_width(first.(fromto.xy), width, gap, dodge, n_dodge, dodge_gap) ) @@ -108,7 +108,7 @@ function Makie.plot!(p::Waterfall) push!(shapes, marker_pos) end end - return (xy=xy, shapes=shapes) + return (xy = xy, shapes = shapes) end markers = lift( @@ -127,8 +127,9 @@ function Makie.plot!(p::Waterfall) scatter!( p, lift(x -> x.xy, p, markers); - marker=lift(x -> x.shapes, p, markers), - color=p.direction_color) + marker = lift(x -> x.shapes, p, markers), + color = p.direction_color + ) end return p @@ -139,5 +140,5 @@ function stack_from_to_final(i_stack, y) perm = sortperm(i_stack) # sort by i_stack inv_perm = sortperm(order[perm]) # restore original order from, to = stack_from_to_sorted(view(y, perm)) - return (from=view(from, inv_perm), to=view(to, inv_perm), final=last(to)) + return (from = view(from, inv_perm), to = view(to, inv_perm), final = last(to)) end diff --git a/src/basic_recipes/wireframe.jl b/src/basic_recipes/wireframe.jl index 73c7114d2e2..df9e46abb3d 100644 --- a/src/basic_recipes/wireframe.jl +++ b/src/basic_recipes/wireframe.jl @@ -1,15 +1,15 @@ -function convert_arguments(::Type{<: Wireframe}, x::AbstractVector, y::AbstractVector, z::AbstractMatrix) - (ngrid(x, y)..., z) +function convert_arguments(::Type{<:Wireframe}, x::AbstractVector, y::AbstractVector, z::AbstractMatrix) + return (ngrid(x, y)..., z) end xvector(x::AbstractVector, len) = x -xvector(x::ClosedInterval, len) = range(minimum(x), stop=maximum(x), length=len) +xvector(x::ClosedInterval, len) = range(minimum(x), stop = maximum(x), length = len) xvector(x::AbstractMatrix, len) = x yvector(x, len) = xvector(x, len)' yvector(x::AbstractMatrix, len) = x -function plot!(plot::Wireframe{<: Tuple{<: Any, <: Any, <: AbstractMatrix}}) +function plot!(plot::Wireframe{<:Tuple{<:Any, <:Any, <:AbstractMatrix}}) points_faces = lift(plot, plot[1:3]...) do x, y, z M, N = size(z) points = vec(Point3f.(xvector(x, M), yvector(y, N), z)) @@ -18,10 +18,10 @@ function plot!(plot::Wireframe{<: Tuple{<: Any, <: Any, <: AbstractMatrix}}) faces = decompose(LineFace{GLIndex}, Tessellation(Rect2(0, 0, 1, 1), (M, N))) connect(points, faces) end - linesegments!(plot, Attributes(plot), points_faces) + return linesegments!(plot, Attributes(plot), points_faces) end -function plot!(plot::Wireframe{Tuple{T}}) where T +function plot!(plot::Wireframe{Tuple{T}}) where {T} points = lift(plot, plot[1]) do g # get the point representation of the geometry indices = decompose(LineFace{GLIndex}, g) @@ -33,5 +33,5 @@ function plot!(plot::Wireframe{Tuple{T}}) where T return connect(points, indices) end end - linesegments!(plot, Attributes(plot), points) + return linesegments!(plot, Attributes(plot), points) end diff --git a/src/bezier.jl b/src/bezier.jl index a8a61391801..c6233c0f57a 100644 --- a/src/bezier.jl +++ b/src/bezier.jl @@ -48,8 +48,8 @@ bezier curve to point `p`, with the control point `c`. The curve is converted in curve internally. """ quadratic_curve_to(x0, y0, cx1, cy1, p1, p2) = CurveTo( - x0 + 2/3 * (cx1 - x0), y0 + 2/3 * (cy1 - y0), - p1 + 2/3 * (cx1 - p1), p2 + 2/3 * (cy1 - p2), + x0 + 2 / 3 * (cx1 - x0), y0 + 2 / 3 * (cy1 - y0), + p1 + 2 / 3 * (cx1 - p1), p2 + 2 / 3 * (cy1 - p2), p1, p2 ) @@ -80,8 +80,10 @@ struct EllipticalArc a2::Float64 end -EllipticalArc(cx, cy, r1, r2, angle, a1, a2) = EllipticalArc(Point2d(cx, cy), - r1, r2, angle, a1, a2) +EllipticalArc(cx, cy, r1, r2, angle, a1, a2) = EllipticalArc( + Point2d(cx, cy), + r1, r2, angle, a1, a2 +) """ ClosePath() @@ -95,7 +97,7 @@ const PathCommand = Union{MoveTo, LineTo, CurveTo, EllipticalArc, ClosePath} # For hashing with crc32c function Base.write(io::IO, command::PathCommand) - write(io, Ref(command)) + return write(io, Ref(command)) end function bbox(commands::Vector{PathCommand}) @@ -117,7 +119,7 @@ end function elliptical_arc_to_beziers(arc::EllipticalArc) delta_a = abs(arc.a2 - arc.a1) n_beziers = ceil(Int, delta_a / 0.5pi) - angles = range(arc.a1, arc.a2; length=n_beziers + 1) + angles = range(arc.a1, arc.a2; length = n_beziers + 1) startpoint = Point2d(cos(arc.a1), sin(arc.a1)) curves = map(angles[1:(end - 1)], angles[2:end]) do start, stop @@ -135,7 +137,7 @@ function elliptical_arc_to_beziers(arc::EllipticalArc) return translate(path, arc.c) end -bbox(p, x::Union{LineTo,CurveTo}) = bbox(segment(p, x)) +bbox(p, x::Union{LineTo, CurveTo}) = bbox(segment(p, x)) function bbox(p, e::EllipticalArc) return bbox(elliptical_arc_to_beziers(e)) end @@ -150,8 +152,10 @@ end function point_at_angle(e::EllipticalArc, theta) M = abs(e.r1) * cos(theta) N = abs(e.r2) * sin(theta) - return Point2d(e.c[1] + cos(e.angle) * M - sin(e.angle) * N, - e.c[2] + sin(e.angle) * M + cos(e.angle) * N) + return Point2d( + e.c[1] + cos(e.angle) * M - sin(e.angle) * N, + e.c[2] + sin(e.angle) * M + cos(e.angle) * N + ) end function cleanup_bbox(bb::Rect2) @@ -200,7 +204,7 @@ fast_stable_hash(x::BezierPath) = x.hash Base.:(==)(b1::BezierPath, b2::BezierPath) = b1.commands == b2.commands Base.broadcastable(b::BezierPath) = Ref(b) -function Base.:+(pc::P, p::Point2) where P <: PathCommand +function Base.:+(pc::P, p::Point2) where {P <: PathCommand} fnames = fieldnames(P) return P(map(f -> getfield(pc, f) + p, fnames)...) end @@ -231,9 +235,9 @@ function scale(e::EllipticalArc, v::VecTypes{2}) elseif x < 0 && y > 0 pi - e.angle, -e.a1, -e.a2 else - pi - e.angle, pi-e.a1, pi-e.a2 + pi - e.angle, pi - e.a1, pi - e.a2 end - EllipticalArc(e.c .* v, e.r1 * abs(x), e.r2 * abs(y), ang, a1, a2) + return EllipticalArc(e.c .* v, e.r1 * abs(x), e.r2 * abs(y), ang, a1, a2) end rotmatrix2d(a) = Mat2(cos(a), sin(a), -sin(a), cos(a)) @@ -242,13 +246,13 @@ rotate(c::ClosePath, a) = c rotate(l::LineTo, a) = LineTo(rotmatrix2d(a) * l.p) function rotate(c::CurveTo, a) m = rotmatrix2d(a) - CurveTo(m * c.c1, m * c.c2, m *c.p) + return CurveTo(m * c.c1, m * c.c2, m * c.p) end function rotate(e::EllipticalArc, a) m = rotmatrix2d(a) newc = m * e.c newangle = e.angle + a - EllipticalArc(newc, e.r1, e.r2, newangle, e.a1, e.a2) + return EllipticalArc(newc, e.r1, e.r2, newangle, e.a1, e.a2) end rotate(b::BezierPath, a) = BezierPath(PathCommand[rotate(c::PathCommand, a) for c in b.commands]) @@ -271,7 +275,7 @@ function fit_to_bbox(b::BezierPath, bb_target::Rect2; keep_aspect = true) end function fit_to_unit_square(b::BezierPath, keep_aspect = true) - fit_to_bbox(b, Rect2((0.0, 0.0), (1.0, 1.0)), keep_aspect = keep_aspect) + return fit_to_bbox(b, Rect2((0.0, 0.0), (1.0, 1.0)), keep_aspect = keep_aspect) end Base.:+(pc::EllipticalArc, p::Point2) = EllipticalArc(pc.c + p, pc.r1, pc.r2, pc.angle, pc.a1, pc.a2) @@ -282,25 +286,32 @@ Base.:+(bp::BezierPath, p::Point2) = BezierPath(bp.commands .+ Ref(p)) function bezier_ngon(n, radius, angle) - points = [radius * Point2d(cos(a + angle), sin(a + angle)) - for a in range(0, 2pi, length = n+1)[1:end-1]] - BezierPath([ - MoveTo(points[1]); - LineTo.(@view points[2:end]); - ClosePath() - ]) + points = [ + radius * Point2d(cos(a + angle), sin(a + angle)) + for a in range(0, 2pi, length = n + 1)[1:(end - 1)] + ] + return BezierPath( + [ + MoveTo(points[1]); + LineTo.(@view points[2:end]); + ClosePath() + ] + ) end function bezier_star(n, inner_radius, outer_radius, angle) points = [ (isodd(i) ? outer_radius : inner_radius) * Point2d(cos(a + angle), sin(a + angle)) - for (i, a) in enumerate(range(0, 2pi, length = 2n+1)[1:end-1])] - BezierPath([ - MoveTo(points[1]); - LineTo.(points[2:end]); - ClosePath() - ]) + for (i, a) in enumerate(range(0, 2pi, length = 2n + 1)[1:(end - 1)]) + ] + return BezierPath( + [ + MoveTo(points[1]); + LineTo.(points[2:end]); + ClosePath() + ] + ) end function BezierPath(poly::Polygon{N, T}) where {N, T} @@ -389,7 +400,7 @@ function parse_bezier_commands(svg) commands = PathCommand[] lastcomm = nothing function lastp() - if isnothing(lastcomm) + return if isnothing(lastcomm) Point2d(0, 0) else c = commands[end] @@ -426,27 +437,27 @@ function parse_bezier_commands(svg) end if comm == "M" - x, y = parse.(Float64, args[i+1:i+2]) + x, y = parse.(Float64, args[(i + 1):(i + 2)]) push!(commands, MoveTo(Point2d(x, y))) i += 3 elseif comm == "m" - x, y = parse.(Float64, args[i+1:i+2]) + x, y = parse.(Float64, args[(i + 1):(i + 2)]) push!(commands, MoveTo(Point2d(x, y) + lastp())) i += 3 elseif comm == "L" - x, y = parse.(Float64, args[i+1:i+2]) + x, y = parse.(Float64, args[(i + 1):(i + 2)]) push!(commands, LineTo(Point2d(x, y))) i += 3 elseif comm == "l" - x, y = parse.(Float64, args[i+1:i+2]) + x, y = parse.(Float64, args[(i + 1):(i + 2)]) push!(commands, LineTo(Point2d(x, y) + lastp())) i += 3 elseif comm == "H" - x = parse(Float64, args[i+1]) + x = parse(Float64, args[i + 1]) push!(commands, LineTo(Point2d(x, lastp()[2]))) i += 2 elseif comm == "h" - x = parse(Float64, args[i+1]) + x = parse(Float64, args[i + 1]) push!(commands, LineTo(Point2d(x, 0) + lastp())) i += 2 elseif comm == "Z" @@ -456,66 +467,74 @@ function parse_bezier_commands(svg) push!(commands, ClosePath()) i += 1 elseif comm == "C" - x1, y1, x2, y2, x3, y3 = parse.(Float64, args[i+1:i+6]) + x1, y1, x2, y2, x3, y3 = parse.(Float64, args[(i + 1):(i + 6)]) push!(commands, CurveTo(Point2d(x1, y1), Point2d(x2, y2), Point2d(x3, y3))) i += 7 elseif comm == "c" - x1, y1, x2, y2, x3, y3 = parse.(Float64, args[i+1:i+6]) + x1, y1, x2, y2, x3, y3 = parse.(Float64, args[(i + 1):(i + 6)]) l = lastp() push!(commands, CurveTo(Point2d(x1, y1) + l, Point2d(x2, y2) + l, Point2d(x3, y3) + l)) i += 7 elseif comm == "S" - x1, y1, x2, y2 = parse.(Float64, args[i+1:i+4]) + x1, y1, x2, y2 = parse.(Float64, args[(i + 1):(i + 4)]) prev = commands[end] reflected = prev.p + (prev.p - prev.c2) push!(commands, CurveTo(reflected, Point2d(x1, y1), Point2d(x2, y2))) i += 5 elseif comm == "s" - x1, y1, x2, y2 = parse.(Float64, args[i+1:i+4]) + x1, y1, x2, y2 = parse.(Float64, args[(i + 1):(i + 4)]) prev = commands[end] reflected = prev.p + (prev.p - prev.c2) l = lastp() push!(commands, CurveTo(reflected, Point2d(x1, y1) + l, Point2d(x2, y2) + l)) i += 5 elseif comm == "A" - args[i+1:i+7] - r1, r2 = parse.(Float64, args[i+1:i+2]) - angle = parse(Float64, args[i+3]) - large_arc_flag, sweep_flag = parse.(Bool, args[i+4:i+5]) - x2, y2 = parse.(Float64, args[i+6:i+7]) + args[(i + 1):(i + 7)] + r1, r2 = parse.(Float64, args[(i + 1):(i + 2)]) + angle = parse(Float64, args[i + 3]) + large_arc_flag, sweep_flag = parse.(Bool, args[(i + 4):(i + 5)]) + x2, y2 = parse.(Float64, args[(i + 6):(i + 7)]) x1, y1 = lastp() - push!(commands, EllipticalArc(x1, y1, x2, y2, r1, r2, - angle, large_arc_flag, sweep_flag)) + push!( + commands, EllipticalArc( + x1, y1, x2, y2, r1, r2, + angle, large_arc_flag, sweep_flag + ) + ) i += 8 elseif comm == "a" - r1, r2 = parse.(Float64, args[i+1:i+2]) - angle = parse(Float64, args[i+3]) - large_arc_flag, sweep_flag = parse.(Bool, args[i+4:i+5]) + r1, r2 = parse.(Float64, args[(i + 1):(i + 2)]) + angle = parse(Float64, args[i + 3]) + large_arc_flag, sweep_flag = parse.(Bool, args[(i + 4):(i + 5)]) x1, y1 = lastp() - x2, y2 = parse.(Float64, args[i+6:i+7]) .+ (x1, y1) - - push!(commands, EllipticalArc(x1, y1, x2, y2, r1, r2, - angle, large_arc_flag, sweep_flag)) + x2, y2 = parse.(Float64, args[(i + 6):(i + 7)]) .+ (x1, y1) + + push!( + commands, EllipticalArc( + x1, y1, x2, y2, r1, r2, + angle, large_arc_flag, sweep_flag + ) + ) i += 8 elseif comm == "v" - dy = parse(Float64, args[i+1]) + dy = parse(Float64, args[i + 1]) l = lastp() push!(commands, LineTo(Point2d(l[1], l[2] + dy))) i += 2 elseif comm == "V" - y = parse(Float64, args[i+1]) + y = parse(Float64, args[i + 1]) l = lastp() push!(commands, LineTo(Point2d(l[1], y))) i += 2 elseif comm == "Q" x0, y0 = lastp() - x1, y1, x2, y2 = parse.(Float64, args[i+1:i+4]) + x1, y1, x2, y2 = parse.(Float64, args[(i + 1):(i + 4)]) push!(commands, quadratic_curve_to(x0, y0, x1, y1, x2, y2)) i += 5 elseif comm == "q" x0, y0 = lastp() - x1, y1, x2, y2 = parse.(Float64, args[i+1:i+4]) + x1, y1, x2, y2 = parse.(Float64, args[(i + 1):(i + 4)]) push!(commands, quadratic_curve_to(x0, y0, x1 + x0, y1 + y0, x2 + x0, y2 + y0)) i += 5 else @@ -529,7 +548,7 @@ function parse_bezier_commands(svg) end - commands + return commands end """ @@ -578,7 +597,7 @@ function EllipticalArc(x1, y1, x2, y2, rx, ry, ϕ, largearc::Bool, sweepflag::Bo Δθ_pre end - EllipticalArc(c, rx, ry, ϕ, θ1, θ1 + Δθ) + return EllipticalArc(c, rx, ry, ϕ, θ1, θ1 + Δθ) end ################################################### @@ -623,15 +642,15 @@ end ftvec(p) = FT_Vector(round(Int, p[1]), round(Int, p[2])) function convert_command(m::MoveTo) - true, 1, ftvec.([m.p]), [FT_Curve_Tag_On] + return true, 1, ftvec.([m.p]), [FT_Curve_Tag_On] end function convert_command(l::LineTo) - false, 1, ftvec.([l.p]), [FT_Curve_Tag_On] + return false, 1, ftvec.([l.p]), [FT_Curve_Tag_On] end function convert_command(c::CurveTo) - false, 3, ftvec.([c.c1, c.c2, c.p]), [FT_Curve_Tag_Cubic, FT_Curve_Tag_Cubic, FT_Curve_Tag_On] + return false, 3, ftvec.([c.c1, c.c2, c.p]), [FT_Curve_Tag_Cubic, FT_Curve_Tag_Cubic, FT_Curve_Tag_On] end function render_path(path, bitmap_size_px = 256) @@ -710,7 +729,7 @@ function replace_nonfreetype_commands(path) end i += 1 end - newpath + return newpath end @@ -794,9 +813,13 @@ segment(p, c::CurveTo) = BezierSegment(p, c.c1, c.c2, c.p) const BezierCircle = let r = 0.47 # sqrt(1/pi) - BezierPath([MoveTo(Point(r, 0.0)), - EllipticalArc(Point(0.0, 0), r, r, 0.0, 0.0, 2pi), - ClosePath()]) + BezierPath( + [ + MoveTo(Point(r, 0.0)), + EllipticalArc(Point(0.0, 0), r, r, 0.0, 0.0, 2pi), + ClosePath(), + ] + ) end const BezierUTriangle = let @@ -808,10 +831,14 @@ const BezierUTriangle = let p2 = Point2d(-w / 2, -h / 2) p3 = Point2d(w / 2, -h / 2) centroid = (p1 + p2 + p3) / 3 - bp = BezierPath([MoveTo(p1 - centroid), - LineTo(p2 - centroid), - LineTo(p3 - centroid), - ClosePath()]) + bp = BezierPath( + [ + MoveTo(p1 - centroid), + LineTo(p2 - centroid), + LineTo(p3 - centroid), + ClosePath(), + ] + ) end const BezierLTriangle = rotate(BezierUTriangle, pi / 2) @@ -820,11 +847,15 @@ const BezierRTriangle = rotate(BezierUTriangle, 3pi / 2) const BezierSquare = let r = 0.95 * sqrt(pi) / 2 / 2 # this gives a little less area as the r=0.5 circle - BezierPath([MoveTo(Point2d(r, -r)), - LineTo(Point2d(r, r)), - LineTo(Point2d(-r, r)), - LineTo(Point2d(-r, -r)), - ClosePath()]) + BezierPath( + [ + MoveTo(Point2d(r, -r)), + LineTo(Point2d(r, r)), + LineTo(Point2d(-r, r)), + LineTo(Point2d(-r, -r)), + ClosePath(), + ] + ) end const BezierCross = let @@ -833,14 +864,20 @@ const BezierCross = let ri = 0.166 #r * (1 - cutfraction) first_three = Point2d[(r, ri), (ri, ri), (ri, r)] - all = (x -> reduce(vcat, x))(map(0:(pi / 2):(3pi / 2)) do a - m = Mat2d(sin(a), cos(a), cos(a), -sin(a)) - return Ref(m) .* first_three - end) - - BezierPath([MoveTo(all[1]), - LineTo.(all[2:end])..., - ClosePath()]) + all = (x -> reduce(vcat, x))( + map(0:(pi / 2):(3pi / 2)) do a + m = Mat2d(sin(a), cos(a), cos(a), -sin(a)) + return Ref(m) .* first_three + end + ) + + BezierPath( + [ + MoveTo(all[1]), + LineTo.(all[2:end])..., + ClosePath(), + ] + ) end const BezierX = rotate(BezierCross, pi / 4) diff --git a/src/camera/camera.jl b/src/camera/camera.jl index 96c3a458a5e..7255065c275 100644 --- a/src/camera/camera.jl +++ b/src/camera/camera.jl @@ -1,13 +1,15 @@ function Base.copy(x::Camera) - Camera(ntuple(10) do i - getfield(x, i) - end...) + return Camera( + ntuple(10) do i + getfield(x, i) + end... + ) end function Base.:(==)(a::Camera, b::Camera) - to_value(a.view) == to_value(b.view) && - to_value(a.projection) == to_value(b.projection) && - to_value(a.resolution) == to_value(b.resolution) + return to_value(a.view) == to_value(b.view) && + to_value(a.projection) == to_value(b.projection) && + to_value(a.resolution) == to_value(b.resolution) end function Base.show(io::IO, camera::Camera) @@ -19,7 +21,7 @@ function Base.show(io::IO, camera::Camera) println(io, " projectionview: ", camera.projectionview[]) println(io, " resolution: ", camera.resolution[]) println(io, " eyeposition: ", camera.eyeposition[]) - println(io, " view direction: ", camera.view_direction[]) + return println(io, " view direction: ", camera.view_direction[]) end function disconnect!(c::Camera) @@ -48,7 +50,7 @@ struct CameraLift{F, Args} end function (cl::CameraLift{F, Args})(val) where {F, Args} - cl.f(map(to_value, cl.args)...) + return cl.f(map(to_value, cl.args)...) end """ @@ -57,12 +59,12 @@ end When mapping over observables for the camera, we store them in the `steering_node` vector, to make it easier to disconnect the camera steering signals later! """ -function Observables.on(f, camera::Camera, observables::AbstractObservable...; priority=0) +function Observables.on(f, camera::Camera, observables::AbstractObservable...; priority = 0) # PriorityObservables don't implement on_any, because that would replace # the method in Observables. CameraLift acts as a workaround for now. cl = CameraLift(f, observables) for n in observables - obs = on(cl, n, priority=priority) + obs = on(cl, n, priority = priority) push!(camera.steering_nodes, obs) end return f @@ -83,7 +85,7 @@ function Camera(viewport) view, proj, proj_view, - lift(a-> Vec2f(widths(a)), viewport), + lift(a -> Vec2f(widths(a)), viewport), Observable(Vec3f(0, 0, -1)), Observable(Vec3f(1)), Observable(Vec3f(0, 1, 0)), @@ -98,7 +100,7 @@ function set_proj_view!(camera::Camera, projection, view) # But nobody should do that, right? # GLMakie uses map on view camera.view[] = view - camera.projection[] = projection + return camera.projection[] = projection end is_mouseinside(x, target) = is_mouseinside(get_scene(x), target) diff --git a/src/camera/camera2d.jl b/src/camera/camera2d.jl index f352e99cb91..eb9e25e15a8 100644 --- a/src/camera/camera2d.jl +++ b/src/camera/camera2d.jl @@ -44,7 +44,7 @@ function cam2d!(scene::SceneLike; kw_args...) correct_ratio!(scene, cam) selection_rect!(scene, cam, cam_attributes.selectionbutton) cameracontrols!(scene, cam) - cam + return cam end get_space(::Camera2D) = :data @@ -76,7 +76,7 @@ function update_cam!(scene::Scene, cam::Camera2D, area3d::Rect) area = Rect2d(area3d) area = positive_widths(area) # ignore rects with width almost 0 - any(x-> x ≈ 0.0, widths(area)) && return + any(x -> x ≈ 0.0, widths(area)) && return pa = viewport(scene)[] px_wh = normalize(widths(pa)) @@ -91,7 +91,7 @@ function update_cam!(scene::Scene, cam::Camera2D, area3d::Rect) newwh = s .* widths(area) cam.area[] = Rect2d(minimum(area), newwh) end - update_cam!(scene, cam) + return update_cam!(scene, cam) end function update_cam!(scene::SceneLike, cam::Camera2D) @@ -107,7 +107,7 @@ function update_cam!(scene::SceneLike, cam::Camera2D) end function correct_ratio!(scene, cam) - on(camera(scene), viewport(scene)) do area + return on(camera(scene), viewport(scene)) do area neww = widths(area) change = neww .- cam.last_area[] if !(change ≈ Vec(0.0, 0.0)) @@ -150,7 +150,7 @@ function add_pan!(scene::SceneLike, cam::Camera2D) return Consume(false) end - on( + return on( camera(scene), Observable.((scene, cam, startpos, drag_active))..., e.mouseposition @@ -170,7 +170,7 @@ end function add_zoom!(scene::SceneLike, cam::Camera2D) e = events(scene) - on(camera(scene), e.scroll) do x + return on(camera(scene), e.scroll) do x @extractvalue cam (zoomspeed, zoombutton, area) zoom = Float64(x[2]) if zoom != 0 && ispressed(scene, zoombutton) && is_mouseinside(scene) @@ -216,7 +216,7 @@ function selection_rect!(scene, cam, key) scene_unscaled, rect[], linestyle = :dot, - linewidth = 2f0, + linewidth = 2.0f0, color = (:black, 0.4), visible = false ) @@ -315,7 +315,7 @@ function add_restriction!(cam, window, rarea::Rect2, minwidths::Vec) end return end - restrict_action + return restrict_action end struct PixelCamera <: AbstractCamera end @@ -332,7 +332,7 @@ get_space(::UpdatePixelCam) = :pixel function (cam::UpdatePixelCam)(window_size) w, h = Float64.(widths(window_size)) projection = orthographicprojection(0.0, w, 0.0, h, cam.near, cam.far) - set_proj_view!(cam.camera, projection, Mat4d(I)) + return set_proj_view!(cam.camera, projection, Mat4d(I)) end """ @@ -342,7 +342,7 @@ Creates a pixel camera for the given `scene`. This means that the positional data of a plot will be interpreted in pixel units. This camera does not feature controls. """ -function campixel!(scene::Scene; nearclip=-10_000.0, farclip=10_000.0) +function campixel!(scene::Scene; nearclip = -10_000.0, farclip = 10_000.0) disconnect!(camera(scene)) camera(scene).view_direction[] = Vec3f(0, 0, -1) update_once = Observable(false) @@ -365,14 +365,14 @@ get_space(::RelativeCamera) = :relative Creates a camera for the given `scene` which maps the scene area to a 0..1 by 0..1 range. This camera does not feature controls. """ -function cam_relative!(scene::Scene; nearclip=-10_000.0, farclip=10_000.0) +function cam_relative!(scene::Scene; nearclip = -10_000.0, farclip = 10_000.0) disconnect!(camera(scene)) camera(scene).view_direction[] = Vec3f(0, 0, -1) projection = orthographicprojection(0.0, 1.0, 0.0, 1.0, nearclip, farclip) set_proj_view!(camera(scene), projection, Mat4d(I)) cam = RelativeCamera() cameracontrols!(scene, cam) - cam + return cam end # disconnect!(::Makie.PixelCamera) = nothing diff --git a/src/camera/camera3d.jl b/src/camera/camera3d.jl index 93a73a41ff3..9fe34a3652c 100644 --- a/src/camera/camera3d.jl +++ b/src/camera/camera3d.jl @@ -117,29 +117,29 @@ function Camera3D(scene::Scene; kwargs...) controls = Attributes( # Keyboard controls # Translations - up_key = Keyboard.r, - down_key = Keyboard.f, - left_key = Keyboard.a, - right_key = Keyboard.d, - forward_key = Keyboard.w, - backward_key = Keyboard.s, + up_key = Keyboard.r, + down_key = Keyboard.f, + left_key = Keyboard.a, + right_key = Keyboard.d, + forward_key = Keyboard.w, + backward_key = Keyboard.s, # Zooms - zoom_in_key = Keyboard.u, - zoom_out_key = Keyboard.o, + zoom_in_key = Keyboard.u, + zoom_out_key = Keyboard.o, increase_fov_key = Keyboard.b, decrease_fov_key = Keyboard.n, # Rotations - pan_left_key = Keyboard.j, + pan_left_key = Keyboard.j, pan_right_key = Keyboard.l, - tilt_up_key = Keyboard.i, + tilt_up_key = Keyboard.i, tilt_down_key = Keyboard.k, - roll_clockwise_key = Keyboard.e, + roll_clockwise_key = Keyboard.e, roll_counterclockwise_key = Keyboard.q, # Mouse controls translation_button = Mouse.right, - rotation_button = Mouse.left, - scroll_mod = true, - reposition_button = Keyboard.left_alt & Mouse.left, + rotation_button = Mouse.left, + scroll_mod = true, + reposition_button = Keyboard.left_alt & Mouse.left, # Shared controls fix_x_key = Keyboard.x, fix_y_key = Keyboard.y, @@ -186,8 +186,8 @@ function Camera3D(scene::Scene; kwargs...) # Semi-Internal - view matrix get(overwrites, :eyeposition, Observable(Vec3d(3, 3, 3))), - get(overwrites, :lookat, Observable(Vec3d(0, 0, 0))), - get(overwrites, :upvector, Observable(Vec3d(0, 0, 1))), + get(overwrites, :lookat, Observable(Vec3d(0, 0, 0))), + get(overwrites, :upvector, Observable(Vec3d(0, 0, 1))), # Semi-Internal - projection matrix get(overwrites, :fov, Observable(45.0)), @@ -235,7 +235,7 @@ function Camera3D(scene::Scene; kwargs...) # reset on(camera(scene), events(scene).keyboardbutton, events(scene).mousebutton, priority = 1) do ke, me if cam.selected[] && ispressed(scene, controls[:reset][]) && - (ke.action == Keyboard.press || me.action == Mouse.press) + (ke.action == Keyboard.press || me.action == Mouse.press) # center keeps the rotation of the camera so we reset that here # might make sense to keep user set lookat, upvector, eyeposition # around somewhere for this? @@ -250,7 +250,7 @@ function Camera3D(scene::Scene; kwargs...) update_cam!(scene, cam) - cam + return cam end # These imitate the old camera @@ -278,7 +278,7 @@ function deselect_all_cameras!(scene) for child in scene.children deselect_all_cameras!(child) end - nothing + return nothing end @@ -287,32 +287,33 @@ end ################################################################################ - function on_pulse(scene, cam::Camera3D, timestep) @extractvalue cam.controls ( right_key, left_key, up_key, down_key, backward_key, forward_key, tilt_up_key, tilt_down_key, pan_left_key, pan_right_key, roll_counterclockwise_key, roll_clockwise_key, - zoom_out_key, zoom_in_key, increase_fov_key, decrease_fov_key + zoom_out_key, zoom_in_key, increase_fov_key, decrease_fov_key, ) - if !ispressed(scene, right_key | left_key | up_key | down_key | backward_key | forward_key | - tilt_up_key | tilt_down_key | pan_left_key | pan_right_key | roll_counterclockwise_key | - roll_clockwise_key | zoom_out_key | zoom_in_key | increase_fov_key | decrease_fov_key) - + if !ispressed( + scene, right_key | left_key | up_key | down_key | backward_key | forward_key | + tilt_up_key | tilt_down_key | pan_left_key | pan_right_key | roll_counterclockwise_key | + roll_clockwise_key | zoom_out_key | zoom_in_key | increase_fov_key | decrease_fov_key + ) + return end @extractvalue cam.settings ( - keyboard_translationspeed, keyboard_rotationspeed, keyboard_zoomspeed, projectiontype + keyboard_translationspeed, keyboard_rotationspeed, keyboard_zoomspeed, projectiontype, ) # translation - right = ispressed(scene, right_key) - left = ispressed(scene, left_key) - up = ispressed(scene, up_key) - down = ispressed(scene, down_key) - backward = ispressed(scene, backward_key) - forward = ispressed(scene, forward_key) + right = ispressed(scene, right_key) + left = ispressed(scene, left_key) + up = ispressed(scene, up_key) + down = ispressed(scene, down_key) + backward = ispressed(scene, backward_key) + forward = ispressed(scene, forward_key) translating = right || left || up || down || backward || forward if translating @@ -336,12 +337,12 @@ function on_pulse(scene, cam::Camera3D, timestep) end # rotation - up = ispressed(scene, tilt_up_key) - down = ispressed(scene, tilt_down_key) - left = ispressed(scene, pan_left_key) - right = ispressed(scene, pan_right_key) + up = ispressed(scene, tilt_up_key) + down = ispressed(scene, tilt_down_key) + left = ispressed(scene, pan_left_key) + right = ispressed(scene, pan_right_key) counterclockwise = ispressed(scene, roll_counterclockwise_key) - clockwise = ispressed(scene, roll_clockwise_key) + clockwise = ispressed(scene, roll_clockwise_key) rotating = up || down || left || right || counterclockwise || clockwise if rotating @@ -354,11 +355,11 @@ function on_pulse(scene, cam::Camera3D, timestep) # zoom zoom_out = ispressed(scene, zoom_out_key) - zoom_in = ispressed(scene, zoom_in_key) + zoom_in = ispressed(scene, zoom_in_key) zooming = zoom_out || zoom_in if zooming - zoom_step = (1.0 + keyboard_zoomspeed * timestep) ^ (zoom_out - zoom_in) + zoom_step = (1.0 + keyboard_zoomspeed * timestep)^(zoom_out - zoom_in) _zoom!(scene, cam, zoom_step, false, false) end @@ -368,7 +369,7 @@ function on_pulse(scene, cam::Camera3D, timestep) fov_adjustment = fov_inc || fov_dec if fov_adjustment - step = (1 + keyboard_zoomspeed * timestep) ^ (fov_inc - fov_dec) + step = (1 + keyboard_zoomspeed * timestep)^(fov_inc - fov_dec) cam.fov[] = clamp(cam.fov[] * step, 0.1, 179.0) end @@ -386,7 +387,7 @@ function add_mouse_controls!(scene, cam::Camera3D) @extract cam.controls (translation_button, rotation_button, reposition_button, scroll_mod) @extract cam.settings ( mouse_translationspeed, mouse_rotationspeed, mouse_zoomspeed, - cad, projectiontype, zoom_shift_lookat + cad, projectiontype, zoom_shift_lookat, ) last_mousepos = RefValue(Vec2d(0, 0)) @@ -396,7 +397,7 @@ function add_mouse_controls!(scene, cam::Camera3D) function compute_diff(delta) if projectiontype[] == Perspective - # TODO wrong scaling? :( + # TODO wrong scaling? :( ynorm = 2 * norm(cam.lookat[] - cam.eyeposition[]) * tand(0.5 * cam.fov[]) return ynorm / size(scene, 2) * delta else @@ -418,7 +419,7 @@ function add_mouse_controls!(scene, cam::Camera3D) dragging[] = (true, false) return Consume(true) end - # drag stop & repostion + # drag stop & repostion elseif event.action == Mouse.release consume = false @@ -480,9 +481,9 @@ function add_mouse_controls!(scene, cam::Camera3D) end #zoom - on(camera(scene), e.scroll) do scroll + return on(camera(scene), e.scroll) do scroll if is_mouseinside(scene) && ispressed(scene, scroll_mod[]) - zoom_step = (1.0 + 0.1 * mouse_zoomspeed[]) ^ -scroll[2] + zoom_step = (1.0 + 0.1 * mouse_zoomspeed[])^-scroll[2] zoom!(scene, cam, zoom_step, cad[], zoom_shift_lookat[]) return Consume(true) end @@ -509,7 +510,7 @@ pressed the translation will be restricted to act in these directions. function translate_cam!(scene, cam::Camera3D, t::VecTypes) _translate_cam!(scene, cam, t) update_cam!(scene, cam) - nothing + return nothing end """ @@ -523,10 +524,10 @@ Note that this method reacts to `fix_x_key` etc and `fixed_axis`. The former restrict the rotation around a specific axis when a given key is pressed. The latter keeps the camera y axis fixed as the data space z axis. """ -function rotate_cam!(scene, cam::Camera3D, angles::VecTypes, from_mouse=false) +function rotate_cam!(scene, cam::Camera3D, angles::VecTypes, from_mouse = false) _rotate_cam!(scene, cam, angles, from_mouse) update_cam!(scene, cam) - nothing + return nothing end @@ -545,7 +546,7 @@ the same screen space position. function zoom!(scene, cam::Camera3D, zoom_step, cad = false, zoom_shift_lookat = false) _zoom!(scene, cam, zoom_step, cad, zoom_shift_lookat) update_cam!(scene, cam) - nothing + return nothing end @@ -577,7 +578,7 @@ function _translate_cam!(scene, cam::Camera3D, t) end -function _rotate_cam!(scene, cam::Camera3D, angles::VecTypes, from_mouse=false) +function _rotate_cam!(scene, cam::Camera3D, angles::VecTypes, from_mouse = false) @extractvalue cam.controls (fix_x_key, fix_y_key, fix_z_key) @extractvalue cam.settings (fixed_axis, circular_rotation, rotation_center) @@ -681,7 +682,7 @@ function _zoom!(scene, cam::Camera3D, zoom_step, cad = false, zoom_shift_lookat scale = norm(viewdir) * tand(0.5 * cam.fov[]) end - cam.lookat[] = lookat + scale * shift + cam.lookat[] = lookat + scale * shift cam.eyeposition[] = lookat - zoom_step * viewdir + scale * shift else # just zoom in/out @@ -731,7 +732,7 @@ function update_cam!(scene::Scene, cam::Camera3D) set_proj_view!(camera(scene), proj, view) scene.camera.eyeposition[] = Vec3f(cam.eyeposition[]) scene.camera.upvector[] = upvector - scene.camera.view_direction[] = Vec3f(normalize(cam.lookat[] - cam.eyeposition[])) + return scene.camera.view_direction[] = Vec3f(normalize(cam.lookat[] - cam.eyeposition[])) end @@ -772,9 +773,9 @@ end # Update camera position via camera Position & Orientation function update_cam!(scene::Scene, camera::Camera3D, eyeposition::VecTypes, lookat::VecTypes, up::VecTypes = camera.upvector[]) - camera.lookat[] = Vec3d(lookat) + camera.lookat[] = Vec3d(lookat) camera.eyeposition[] = Vec3d(eyeposition) - camera.upvector[] = Vec3d(up) + camera.upvector[] = Vec3d(up) update_cam!(scene, camera) return end @@ -796,9 +797,9 @@ function update_cam!( sp, cp = sincos(phi) v = Vec3d(ct * cp, ct * sp, st) u = Vec3d(-st * cp, -st * sp, ct) - camera.lookat[] = center + camera.lookat[] = center camera.eyeposition[] = center .+ radius * v - camera.upvector[] = u + camera.upvector[] = u update_cam!(scene, camera) return end @@ -807,9 +808,9 @@ end function show_cam(scene) cam = cameracontrols(scene) println("cam=cameracontrols(scene)") - println("cam.eyeposition[] = ", round.(cam.eyeposition[], digits=2)) - println("cam.lookat[] = ", round.(cam.lookat[], digits=2)) - println("cam.upvector[] = ", round.(cam.upvector[], digits=2)) - println("cam.fov[] = ", round.(cam.fov[], digits=2)) + println("cam.eyeposition[] = ", round.(cam.eyeposition[], digits = 2)) + println("cam.lookat[] = ", round.(cam.lookat[], digits = 2)) + println("cam.upvector[] = ", round.(cam.upvector[], digits = 2)) + println("cam.fov[] = ", round.(cam.fov[], digits = 2)) return end diff --git a/src/camera/old_camera3d.jl b/src/camera/old_camera3d.jl index b6753dda83a..58311d5e9da 100644 --- a/src/camera/old_camera3d.jl +++ b/src/camera/old_camera3d.jl @@ -1,4 +1,3 @@ - @enum ProjectionEnum Perspective Orthographic struct OldCamera3D <: AbstractCamera @@ -50,7 +49,7 @@ function old_cam3d_cad!(scene::Scene; kw_args...) # update cam when screen ratio changes update_cam!(scene, cam) end - cam + return cam end get_space(::OldCamera3D) = :data @@ -88,7 +87,7 @@ function old_cam3d_turntable!(scene::Scene; kw_args...) # update cam when screen ratio changes update_cam!(scene, cam) end - cam + return cam end """ @@ -109,19 +108,19 @@ function projection_switch( wh::Rect2, fov::T, near::T, far::T, projectiontype::ProjectionEnum, zoom::T - ) where T <: Real + ) where {T <: Real} aspect = T((/)(widths(wh)...)) h = T(tan(fov / 360.0 * pi) * near) w = T(h * aspect) projectiontype == Perspective && return frustum(-w, w, -h, h, near, far) h, w = h * zoom, w * zoom - orthographicprojection(-w, w, -h, h, near, far) + return orthographicprojection(-w, w, -h, h, near, far) end function rotate_cam( theta::Vec{3, T}, cam_right::Vec{3, T}, cam_up::Vec{3, T}, cam_dir::Vec{3, T} - ) where T + ) where {T} rotation = Quaternion{T}(0, 0, 0, 1) if !all(isfinite.(theta)) # We can only rotate for finite values @@ -140,7 +139,7 @@ function rotate_cam( if theta[3] != 0 rotation *= qrotation(cam_dir, theta[3]) end - rotation + return rotation end # TODO switch button and key because this is the wrong order @@ -176,11 +175,11 @@ function add_translation!(scene, cam, key, button, zoom_shift_lookat::Bool) return Consume(false) end - on(camera(scene), scene.events.scroll) do scroll + return on(camera(scene), scene.events.scroll) do scroll if ispressed(scene, button[]) && is_mouseinside(scene) cam_res = Vec2d(widths(scene)) mouse_pos_normalized = mouseposition_px(scene) ./ cam_res - mouse_pos_normalized = 2*mouse_pos_normalized .- 1.0 + mouse_pos_normalized = 2 * mouse_pos_normalized .- 1.0 zoom_step = scroll[2] zoom!(scene, mouse_pos_normalized, zoom_step, zoom_shift_lookat) return Consume(true) @@ -213,7 +212,7 @@ function add_rotation!(scene, cam, button, key, fixed_axis::Bool) return Consume(false) end - on(camera(scene), e.mouseposition) do mp + return on(camera(scene), e.mouseposition) do mp if dragging[] && ispressed(scene, key[]) mousepos = screen_relative(scene, mp) rot_scaling = cam.rotationspeed[] * (e.window_dpi[] * 0.005) @@ -270,8 +269,8 @@ function zoom!(scene, point::VecTypes, zoom_step, shift_lookat::Bool) # split zoom into two components: # the offset perpendicular to `eyeposition - lookat`, based on mouse offset ~ ray_dir # the offset parallel to `eyeposition - lookat` ~ dir - ray_eye = inv(scene.camera.projection[]) * Vec4d(point[1],point[2],0,0) - ray_eye = Vec4d(ray_eye[Vec(1, 2)]...,0,0) + ray_eye = inv(scene.camera.projection[]) * Vec4d(point[1], point[2], 0, 0) + ray_eye = Vec4d(ray_eye[Vec(1, 2)]..., 0, 0) ray_dir = Vec3d((inv(scene.camera.view[]) * ray_eye)) dir = eyeposition - lookat @@ -281,8 +280,8 @@ function zoom!(scene, point::VecTypes, zoom_step, shift_lookat::Bool) if projectiontype == Perspective ray_dir *= norm(dir) end - cam.eyeposition[] = eyeposition + (ray_dir - dir) * (1.0 - 0.9 ^ zoom_step) - cam.lookat[] = lookat + (1.0 - 0.9 ^ zoom_step) * ray_dir + cam.eyeposition[] = eyeposition + (ray_dir - dir) * (1.0 - 0.9^zoom_step) + cam.lookat[] = lookat + (1.0 - 0.9^zoom_step) * ray_dir else # Rotations need more extreme eyeposition shifts step = zoom_step @@ -293,7 +292,7 @@ function zoom!(scene, point::VecTypes, zoom_step, shift_lookat::Bool) end end - update_cam!(scene, cam) + return update_cam!(scene, cam) end """ @@ -335,7 +334,7 @@ function update_cam!(scene::Scene, cam::OldCamera3D) set_proj_view!(camera(scene), proj, view) scene.camera.eyeposition[] = Vec3f(cam.eyeposition[]) scene.camera.upvector[] = Vec3f(cam.upvector[]) - scene.camera.view_direction[] = Vec3f(normalize(cam.lookat[] - cam.eyeposition[])) + return scene.camera.view_direction[] = Vec3f(normalize(cam.lookat[] - cam.eyeposition[])) end function update_cam!(scene::Scene, camera::OldCamera3D, area3d::Rect) @@ -346,9 +345,9 @@ function update_cam!(scene::Scene, camera::OldCamera3D, area3d::Rect) middle = maximum(bb) - half_width old_dir = normalize(eyeposition .- lookat) camera.lookat[] = middle - neweyepos = middle .+ (1.2*norm(width) .* old_dir) + neweyepos = middle .+ (1.2 * norm(width) .* old_dir) camera.eyeposition[] = neweyepos - camera.upvector[] = Vec3d(0,0,1) + camera.upvector[] = Vec3d(0, 0, 1) camera.near[] = 0.1 * norm(widths(bb)) camera.far[] = 3.0 * norm(widths(bb)) update_cam!(scene, camera) diff --git a/src/camera/projection_math.jl b/src/camera/projection_math.jl index 7fb24056f4c..e3a877e8554 100644 --- a/src/camera/projection_math.jl +++ b/src/camera/projection_math.jl @@ -1,10 +1,10 @@ -function scalematrix(s::Vec{3, T}) where T +function scalematrix(s::Vec{3, T}) where {T} T0, T1 = zero(T), one(T) - Mat{4}( - s[1],T0, T0, T0, - T0, s[2],T0, T0, - T0, T0, s[3],T0, - T0, T0, T0, T1, + return Mat{4}( + s[1], T0, T0, T0, + T0, s[2], T0, T0, + T0, T0, s[3], T0, + T0, T0, T0, T1, ) end @@ -12,13 +12,13 @@ translationmatrix_x(x::T) where {T} = translationmatrix(Vec{3, T}(x, 0, 0)) translationmatrix_y(y::T) where {T} = translationmatrix(Vec{3, T}(0, y, 0)) translationmatrix_z(z::T) where {T} = translationmatrix(Vec{3, T}(0, 0, z)) -function translationmatrix(t::Vec{3, T}) where T +function translationmatrix(t::Vec{3, T}) where {T} T0, T1 = zero(T), one(T) - Mat{4}( - T1, T0, T0, T0, - T0, T1, T0, T0, - T0, T0, T1, T0, - t[1],t[2],t[3],T1, + return Mat{4}( + T1, T0, T0, T0, + T0, T1, T0, T0, + T0, T0, T1, T0, + t[1], t[2], t[3], T1, ) end @@ -27,17 +27,17 @@ rotate(::Type{T}, angle::Number, axis::Vec{3}) where {T} = rotate(T(angle), conv function rotationmatrix_x(angle::Number) T0, T1 = (0, 1) - Mat{4}( + return Mat{4}( T1, T0, T0, T0, T0, cos(angle), sin(angle), T0, - T0, -sin(angle), cos(angle), T0, + T0, -sin(angle), cos(angle), T0, T0, T0, T0, T1 ) end function rotationmatrix_y(angle::Number) T0, T1 = (0, 1) - Mat{4}( - cos(angle), T0, -sin(angle), T0, + return Mat{4}( + cos(angle), T0, -sin(angle), T0, T0, T1, T0, T0, sin(angle), T0, cos(angle), T0, T0, T0, T0, T1 @@ -45,9 +45,9 @@ function rotationmatrix_y(angle::Number) end function rotationmatrix_z(angle::Number) T0, T1 = (0, 1) - Mat{4}( + return Mat{4}( cos(angle), sin(angle), T0, T0, - -sin(angle), cos(angle), T0, T0, + -sin(angle), cos(angle), T0, T0, T0, T0, T1, T0, T0, T0, T0, T1 ) @@ -76,8 +76,8 @@ end M : array View frustum matrix (4x4). """ -function frustum(left::T, right::T, bottom::T, top::T, znear::T, zfar::T) where T - (right == left || bottom == top || znear == zfar) && return Mat{4,4,T}(I) +function frustum(left::T, right::T, bottom::T, top::T, znear::T, zfar::T) where {T} + (right == left || bottom == top || znear == zfar) && return Mat{4, 4, T}(I) T0, T1, T2 = zero(T), one(T), T(2) return Mat{4}( T2 * znear / (right - left), T0, T0, T0, @@ -94,7 +94,7 @@ the y-axis (measured in degrees), the specified `aspect` ratio, and near and far clipping planes `znear`, `zfar`. Optionally specify the element type `T` of the matrix. """ -function perspectiveprojection(fovy::T, aspect::T, znear::T, zfar::T) where T +function perspectiveprojection(fovy::T, aspect::T, znear::T, zfar::T) where {T} (znear == zfar) && error("znear ($znear) must be different from tfar ($zfar)") h = T(tan(fovy / 360.0 * pi) * znear) w = T(h * aspect) @@ -103,22 +103,22 @@ end function perspectiveprojection( ::Type{T}, fovy::Number, aspect::Number, znear::Number, zfar::Number - ) where T - perspectiveprojection(T(fovy), T(aspect), T(znear), T(zfar)) + ) where {T} + return perspectiveprojection(T(fovy), T(aspect), T(znear), T(zfar)) end """ `proj = perspectiveprojection([T], rect, fov, near, far)` defines the projection ratio in terms of the rectangular view size `rect` rather than the aspect ratio. """ -function perspectiveprojection(wh::Rect2, fov::T, near::T, far::T) where T - perspectiveprojection(fov, T(wh.w/wh.h), near, far) +function perspectiveprojection(wh::Rect2, fov::T, near::T, far::T) where {T} + return perspectiveprojection(fov, T(wh.w / wh.h), near, far) end function perspectiveprojection( ::Type{T}, wh::Rect2, fov::Number, near::Number, far::Number - ) where T - perspectiveprojection(T(fov), T(wh.w/wh.h), T(near), T(far)) + ) where {T} + return perspectiveprojection(T(fov), T(wh.w / wh.h), T(near), T(far)) end """ @@ -129,72 +129,73 @@ the component of `up` that is perpendicular to the vector pointing from `eyeposition` to `lookat` will be used. All inputs must be supplied as 3-vectors. """ -function lookat(eyePos::Vec{3, T}, lookAt::Vec{3, T}, up::Vec{3, T}) where T +function lookat(eyePos::Vec{3, T}, lookAt::Vec{3, T}, up::Vec{3, T}) where {T} return lookat_basis(eyePos, lookAt, up) * translationmatrix(-eyePos) end -function lookat_basis(eyePos::Vec{3, T}, lookAt::Vec{3, T}, up::Vec{3, T}) where T - zaxis = normalize(eyePos-lookAt) - xaxis = normalize(cross(up, zaxis)) - yaxis = normalize(cross(zaxis, xaxis)) +function lookat_basis(eyePos::Vec{3, T}, lookAt::Vec{3, T}, up::Vec{3, T}) where {T} + zaxis = normalize(eyePos - lookAt) + xaxis = normalize(cross(up, zaxis)) + yaxis = normalize(cross(zaxis, xaxis)) T0, T1 = zero(T), one(T) return Mat{4}( xaxis[1], yaxis[1], zaxis[1], T0, xaxis[2], yaxis[2], zaxis[2], T0, xaxis[3], yaxis[3], zaxis[3], T0, - T0, T0, T0, T1 + T0, T0, T0, T1 ) end -function lookat(::Type{T}, eyePos::Vec{3}, lookAt::Vec{3}, up::Vec{3}) where T - lookat(Vec{3,T}(eyePos), Vec{3,T}(lookAt), Vec{3,T}(up)) +function lookat(::Type{T}, eyePos::Vec{3}, lookAt::Vec{3}, up::Vec{3}) where {T} + return lookat(Vec{3, T}(eyePos), Vec{3, T}(lookAt), Vec{3, T}(up)) end -function orthographicprojection(wh::Rect2, near::T, far::T) where T +function orthographicprojection(wh::Rect2, near::T, far::T) where {T} w, h = widths(wh) - orthographicprojection(zero(T), T(w), zero(T), T(h), near, far) + return orthographicprojection(zero(T), T(w), zero(T), T(h), near, far) end function orthographicprojection( ::Type{T}, wh::Rect2, near::Number, far::Number - ) where T - orthographicprojection(wh, T(near), T(far)) + ) where {T} + return orthographicprojection(wh, T(near), T(far)) end function orthographicprojection( left::T, right::T, bottom::T, top::T, znear::T, zfar::T - ) where T - (right==left || bottom==top || znear==zfar) && return Mat{4,4,T}(I) + ) where {T} + (right == left || bottom == top || znear == zfar) && return Mat{4, 4, T}(I) T0, T1, T2 = zero(T), one(T), T(2) - Mat{4}( - T2/(right-left), T0, T0, T0, - T0, T2/(top-bottom), T0, T0, - T0, T0, -T2/(zfar-znear), T0, - -(right+left)/(right-left), -(top+bottom)/(top-bottom), -(zfar+znear)/(zfar-znear), T1 + return Mat{4}( + T2 / (right - left), T0, T0, T0, + T0, T2 / (top - bottom), T0, T0, + T0, T0, -T2 / (zfar - znear), T0, + -(right + left) / (right - left), -(top + bottom) / (top - bottom), -(zfar + znear) / (zfar - znear), T1 ) end -function orthographicprojection(::Type{T}, - left ::Number, right::Number, - bottom::Number, top ::Number, - znear ::Number, zfar ::Number - ) where T - orthographicprojection( - T(left), T(right), +function orthographicprojection( + ::Type{T}, + left::Number, right::Number, + bottom::Number, top::Number, + znear::Number, zfar::Number + ) where {T} + return orthographicprojection( + T(left), T(right), T(bottom), T(top), - T(znear), T(zfar) + T(znear), T(zfar) ) end mutable struct Pivot{T} - origin ::Vec{3, T} - xaxis ::Vec{3, T} - yaxis ::Vec{3, T} - zaxis ::Vec{3, T} - rotation ::Quaternion - translation ::Vec{3, T} - scale ::Vec{3, T} + origin::Vec{3, T} + xaxis::Vec{3, T} + yaxis::Vec{3, T} + zaxis::Vec{3, T} + rotation::Quaternion + translation::Vec{3, T} + scale::Vec{3, T} end GeometryBasics.origin(p::Pivot) = p.origin @@ -202,30 +203,30 @@ GeometryBasics.origin(p::Pivot) = p.origin rotationmatrix4(q::Quaternion{T}) where {T} = Mat4{T}(q) function transformationmatrix(p::Pivot) - translationmatrix(p.origin) * #go to origin - rotationmatrix4(p.rotation) * #apply rotation - translationmatrix(-p.origin)* # go back to origin - translationmatrix(p.translation) #apply translation + return translationmatrix(p.origin) * #go to origin + rotationmatrix4(p.rotation) * #apply rotation + translationmatrix(-p.origin) * # go back to origin + translationmatrix(p.translation) #apply translation end function transformationmatrix(translation, scale) T = eltype(translation) T0, T1 = zero(T), one(T) return Mat{4}( - scale[1],T0, T0, T0, - T0, scale[2],T0, T0, - T0, T0, scale[3],T0, + scale[1], T0, T0, T0, + T0, scale[2], T0, T0, + T0, T0, scale[3], T0, translation[1], translation[2], translation[3], T1 ) end -function transformationmatrix(translation, scale, rotation::Quaternion{T}) where T +function transformationmatrix(translation, scale, rotation::Quaternion{T}) where {T} trans_scale = transformationmatrix(translation, scale) rotation = Mat4{T}(rotation) - trans_scale*rotation + return trans_scale * rotation end -function is_translation_scale_matrix(mat::Mat4{T}) where T +function is_translation_scale_matrix(mat::Mat4{T}) where {T} # Checks that matrix has form: (* being any number) # * 0 0 * # 0 * 0 * @@ -233,9 +234,9 @@ function is_translation_scale_matrix(mat::Mat4{T}) where T # 0 0 0 1 T0 = zero(T) return (mat[2, 1] == T0) && (mat[3, 1] == T0) && (mat[4, 1] == T0) && - (mat[1, 2] == T0) && (mat[3, 2] == T0) && (mat[4, 2] == T0) && - (mat[1, 3] == T0) && (mat[2, 3] == T0) && (mat[4, 3] == T0) && - (mat[4, 4] == one(T)) + (mat[1, 2] == T0) && (mat[3, 2] == T0) && (mat[4, 2] == T0) && + (mat[1, 3] == T0) && (mat[2, 3] == T0) && (mat[4, 3] == T0) && + (mat[4, 4] == one(T)) end """ @@ -247,9 +248,9 @@ created with matching order, i.e. `transform = translation_matrix * scale_matrix * rotation_matrix`. The model matrix created by `Transformation` is one such matrix. """ -function decompose_translation_scale_rotation_matrix(model::Mat4{T}) where T - trans = Vec3{T}(model[Vec(1,2,3), 4]) - m33 = model[Vec(1,2,3), Vec(1,2,3)] +function decompose_translation_scale_rotation_matrix(model::Mat4{T}) where {T} + trans = Vec3{T}(model[Vec(1, 2, 3), 4]) + m33 = model[Vec(1, 2, 3), Vec(1, 2, 3)] if m33[1, 2] ≈ m33[1, 3] ≈ m33[2, 3] ≈ 0 scale = Vec3{T}(diag(m33)) rot = Quaternion{T}(0, 0, 0, 1) @@ -293,9 +294,9 @@ extraction of the rotation component. This still works if a rotation is involved and requires the same order of operations, i.e. `transform = translation_matrix * scale_matrix * rotation_matrix`. """ -function decompose_translation_scale_matrix(model::Mat4{T}) where T - trans = Vec3{T}(model[Vec(1,2,3), 4]) - m33 = model[Vec(1,2,3), Vec(1,2,3)] +function decompose_translation_scale_matrix(model::Mat4{T}) where {T} + trans = Vec3{T}(model[Vec(1, 2, 3), 4]) + m33 = model[Vec(1, 2, 3), Vec(1, 2, 3)] if m33[1, 2] ≈ m33[1, 3] ≈ m33[2, 3] ≈ 0 scale = Vec3{T}(diag(m33)) return trans, scale @@ -307,7 +308,7 @@ function decompose_translation_scale_matrix(model::Mat4{T}) where T end #Calculate rotation between two vectors -function rotation(u::Vec{3, T}, v::Vec{3, T}) where T +function rotation(u::Vec{3, T}, v::Vec{3, T}) where {T} # It is important that the inputs are of equal length when # calculating the half-way vector. u, v = normalize(u), normalize(v) @@ -315,10 +316,10 @@ function rotation(u::Vec{3, T}, v::Vec{3, T}) where T # in this case will be (0, 0, 0), which cannot be normalized. if (u == -v) # 180 degree rotation around any orthogonal vector - other = (abs(dot(u, Vec{3, T}(1,0,0))) < 1.0) ? Vec{3, T}(1,0,0) : Vec{3, T}(0,1,0) + other = (abs(dot(u, Vec{3, T}(1, 0, 0))) < 1.0) ? Vec{3, T}(1, 0, 0) : Vec{3, T}(0, 1, 0) return qrotation(normalize(cross(u, other)), T(180)) end - half = normalize(u+v) + half = normalize(u + v) return Quaternion(cross(u, half)..., dot(u, half)) end @@ -358,7 +359,7 @@ function _to_world( prj_view_inv::Mat4, cam_res::StaticVector ) where {N, T} - to_world(Point(p), prj_view_inv, cam_res) .- + return to_world(Point(p), prj_view_inv, cam_res) .- to_world(zeros(Point{N, T}), prj_view_inv, cam_res) end @@ -368,7 +369,7 @@ function project(matrix::Mat4{T1}, p::VT, dim4::Real = 1.0) where {N, T1 <: Real T = promote_type(Float32, T1, T2) p = to_ndim(Vec4{T}, to_ndim(Vec3{T}, p, 0.0), dim4) p = matrix * p - to_ndim(VT, p, 0.0) + return to_ndim(VT, p, 0.0) end function project(scene::Scene, point::VecTypes) @@ -378,8 +379,8 @@ function project(scene::Scene, point::VecTypes) # Which would be semi breaking at this point though, I suppose return project( cam.projectionview[] * - f32_convert_matrix(scene.float32convert, :data) * - transformationmatrix(scene)[], + f32_convert_matrix(scene.float32convert, :data) * + transformationmatrix(scene)[], Vec2f(widths(area)), Point(point) ) @@ -399,21 +400,21 @@ end # TODO: consider warning here to discourage risky functions function project_point2(mat4::Mat4{T1}, point2::Point2{T2}) where {T1, T2} T = promote_type(Float32, T1, T2) - Point2{T2}(mat4 * to_ndim(Point4{T}, to_ndim(Point3{T}, point2, 0), 1)) + return Point2{T2}(mat4 * to_ndim(Point4{T}, to_ndim(Point3{T}, point2, 0), 1)) end # TODO: consider warning here to discourage risky functions -function transform(model::Mat4{T1}, x::VT) where {T1, VT<:VecTypes} +function transform(model::Mat4{T1}, x::VT) where {T1, VT <: VecTypes} T = promote_type(Float32, T1, eltype(VT)) # TODO: no w = 1? Is this meant to skip translations? x4d = to_ndim(Vec4{T}, x, 0.0) - to_ndim(VT, model * x4d, 0.0) + return to_ndim(VT, model * x4d, 0.0) end ################################################################################ # project between different coordinate systems/spaces -function space_to_clip(cam::Camera, space::Symbol, projectionview::Bool=true) +function space_to_clip(cam::Camera, space::Symbol, projectionview::Bool = true) if is_data_space(space) return projectionview ? cam.projectionview[] : cam.projection[] elseif space == :eye @@ -448,7 +449,7 @@ end function get_space(scene::Scene) space = get_space(cameracontrols(scene))::Symbol - space === :data ? (:data,) : (:data, space) + return space === :data ? (:data,) : (:data, space) end get_space(::AbstractCamera) = :data # TODO: Should this be less specialized? ScenePlot? AbstractPlot? @@ -458,7 +459,7 @@ is_space_compatible(a, b) = is_space_compatible(get_space(a), get_space(b)) is_space_compatible(a::Symbol, b::Symbol) = a === b is_space_compatible(a::Symbol, b::Union{Tuple, Vector}) = a in b function is_space_compatible(a::Union{Tuple, Vector}, b::Union{Tuple, Vector}) - any(x -> is_space_compatible(x, b), a) + return any(x -> is_space_compatible(x, b), a) end is_space_compatible(a::Union{Tuple, Vector}, b::Symbol) = is_space_compatible(b, a) diff --git a/src/colorsampler.jl b/src/colorsampler.jl index cffb5a9ab68..45ee09bf3fe 100644 --- a/src/colorsampler.jl +++ b/src/colorsampler.jl @@ -13,7 +13,7 @@ const NoScaling = Scaling{typeof(identity), Nothing} struct Sampler{N, V} <: AbstractArray{RGBAf, 1} # the colors to sample from! - colors::AbstractArray{T, N} where T + colors::AbstractArray{T, N} where {T} # or an array of values, which are used to index into colors via interpolation! values::V # additional alpha that gets multiplied @@ -43,7 +43,7 @@ end Like getindex, but accepts values between 0..1 for `value` and interpolates those to the full range of `cmap`. """ -function interpolated_getindex(cmap::AbstractArray{T}, i01::AbstractFloat) where T +function interpolated_getindex(cmap::AbstractArray{T}, i01::AbstractFloat) where {T} isfinite(i01) || error("Looking up a non-finite or NaN value in a colormap is undefined.") i1len = (i01 * (length(cmap) - 1)) + 1 down = floor(Int, i1len) @@ -87,7 +87,7 @@ function Base.getindex(sampler::Sampler, i)::RGBAf return RGBAf(color(c), alpha(c) * sampler.alpha) end -function Base.getindex(sampler::Sampler{2, <: AbstractVector{Vec2f}}, i)::RGBAf +function Base.getindex(sampler::Sampler{2, <:AbstractVector{Vec2f}}, i)::RGBAf uv = sampler.values[i] colors = sampler.colors # indexing confirming to OpenGL uv indexing @@ -98,13 +98,17 @@ function Base.getindex(sampler::Sampler{2, <: AbstractVector{Vec2f}}, i)::RGBAf return RGBAf(color(c), alpha(c) * sampler.alpha) end -function sampler(cmap::Union{Symbol, String}, n::Int = 20; - scaling=Scaling(), alpha=1.0, interpolation=Linear) +function sampler( + cmap::Union{Symbol, String}, n::Int = 20; + scaling = Scaling(), alpha = 1.0, interpolation = Linear + ) return sampler(cmap, LinRange(0, 1, n); scaling = scaling, alpha = alpha, interpolation = interpolation) end -function sampler(cmap::Union{Symbol, String}, values::AbstractVector{<: AbstractFloat}; - scaling=Scaling(), alpha=1.0, interpolation=Linear) +function sampler( + cmap::Union{Symbol, String}, values::AbstractVector{<:AbstractFloat}; + scaling = Scaling(), alpha = 1.0, interpolation = Linear + ) cs = PlotUtils.get_colorscheme(cmap) @@ -113,26 +117,32 @@ function sampler(cmap::Union{Symbol, String}, values::AbstractVector{<: Abstract return Sampler(colors, values, alpha, interpolation, scaling) end -function sampler(cmap::Vector{<: Colorant}, values::AbstractVector{<: AbstractFloat}; - scaling=Scaling(), alpha=1.0, interpolation=Linear) +function sampler( + cmap::Vector{<:Colorant}, values::AbstractVector{<:AbstractFloat}; + scaling = Scaling(), alpha = 1.0, interpolation = Linear + ) return Sampler(RGBAf.(cmap), values, alpha, interpolation, scaling) end -function sampler(cmap::AbstractVector, values, crange; - alpha=1.0, interpolation=Linear) +function sampler( + cmap::AbstractVector, values, crange; + alpha = 1.0, interpolation = Linear + ) return Sampler(to_color.(cmap), values, alpha, interpolation, Scaling(identity, crange)) end # uv texture sampler -function sampler(cmap::Matrix{<: Colorant}, uv::AbstractVector{Vec2f}; - alpha=1.0, interpolation=Linear) +function sampler( + cmap::Matrix{<:Colorant}, uv::AbstractVector{Vec2f}; + alpha = 1.0, interpolation = Linear + ) return Sampler(cmap, uv, alpha, interpolation, Scaling()) end apply_scale(scale::AbstractObservable, x) = lift(apply_scale, scale, x) -apply_scale(::Union{Nothing,typeof(identity)}, x) = x # noop +apply_scale(::Union{Nothing, typeof(identity)}, x) = x # noop apply_scale(scale, x) = broadcast(scale, x) -function numbers_to_colors(numbers::Union{AbstractArray{<:Number},Number}, primitive) +function numbers_to_colors(numbers::Union{AbstractArray{<:Number}, Number}, primitive) colormap = get_attribute(primitive, :colormap)::Vector{RGBAf} _colorrange = get_attribute(primitive, :colorrange)::Union{Nothing, Vec2f} colorscale = get_attribute(primitive, :colorscale) @@ -146,16 +156,18 @@ function numbers_to_colors(numbers::Union{AbstractArray{<:Number},Number}, primi lowclip = get_attribute(primitive, :lowclip)::RGBAf highclip = get_attribute(primitive, :highclip)::RGBAf - nan_color = get_attribute(primitive, :nan_color, RGBAf(0,0,0,0))::RGBAf + nan_color = get_attribute(primitive, :nan_color, RGBAf(0, 0, 0, 0))::RGBAf return numbers_to_colors(numbers, colormap, colorscale, colorrange, lowclip, highclip, nan_color) end -function numbers_to_colors(numbers::Union{AbstractArray{<:Number, N},Number}, - colormap, colorscale, colorrange::Vec2, - lowclip::Union{Automatic,RGBAf}, - highclip::Union{Automatic,RGBAf}, - nan_color::RGBAf)::Union{Array{RGBAf, N},RGBAf} where {N} +function numbers_to_colors( + numbers::Union{AbstractArray{<:Number, N}, Number}, + colormap, colorscale, colorrange::Vec2, + lowclip::Union{Automatic, RGBAf}, + highclip::Union{Automatic, RGBAf}, + nan_color::RGBAf + )::Union{Array{RGBAf, N}, RGBAf} where {N} cmin, cmax = colorrange scaled_cmin = apply_scale(colorscale, cmin) scaled_cmax = apply_scale(colorscale, cmax) @@ -172,7 +184,8 @@ function numbers_to_colors(numbers::Union{AbstractArray{<:Number, N},Number}, return interpolated_getindex( colormap, scaled_number, - (scaled_cmin, scaled_cmax)) + (scaled_cmin, scaled_cmax) + ) end end @@ -186,7 +199,7 @@ end @enum ColorMappingType categorical banded continuous -struct ColorMapping{N,T<:AbstractArray{<:Number,N},T2<:AbstractArray{<:Number,N}} +struct ColorMapping{N, T <: AbstractArray{<:Number, N}, T2 <: AbstractArray{<:Number, N}} # The pure color values from the plot this colormapping is associated to # Will be always an array of numbers color::Observable{T} @@ -198,7 +211,7 @@ struct ColorMapping{N,T<:AbstractArray{<:Number,N},T2<:AbstractArray{<:Number,N} # The 0-1 scaled values from crange, which describe the colormapping mapping::Observable{Union{Nothing, Vector{Float64}}} - colorrange::Observable{Vec{2,Float64}} + colorrange::Observable{Vec{2, Float64}} lowclip::Observable{Union{Automatic, RGBAf}} # Defaults to first color in colormap highclip::Observable{Union{Automatic, RGBAf}} # Defaults to last color in colormap @@ -256,10 +269,11 @@ function _colormapping( @nospecialize(lowclip), @nospecialize(highclip), @nospecialize(nan_color), - color_mapping_type) where {V <: AbstractArray{T, N}} where {N, T} - map_colors = Observable(RGBAf[]; ignore_equal_values=true) - raw_colormap = Observable(RGBAf[]; ignore_equal_values=true) - mapping = Observable{Union{Nothing,Vector{Float64}}}(nothing; ignore_equal_values=true) + color_mapping_type + ) where {V <: AbstractArray{T, N}} where {N, T} + map_colors = Observable(RGBAf[]; ignore_equal_values = true) + raw_colormap = Observable(RGBAf[]; ignore_equal_values = true) + mapping = Observable{Union{Nothing, Vector{Float64}}}(nothing; ignore_equal_values = true) colorscale = convert(Observable{Function}, colorscale) colorscale.ignore_equal_values = true @@ -281,22 +295,22 @@ function _colormapping( onany(update_colors, colormap, alpha) update_colors(colormap[], alpha[]) - _lowclip = Observable{Union{Automatic,RGBAf}}(automatic; ignore_equal_values=true) - on(lowclip; update=true) do lc - _lowclip[] = lc isa Union{Nothing,Automatic} ? automatic : to_color(lc) + _lowclip = Observable{Union{Automatic, RGBAf}}(automatic; ignore_equal_values = true) + on(lowclip; update = true) do lc + _lowclip[] = lc isa Union{Nothing, Automatic} ? automatic : to_color(lc) return end - _highclip = Observable{Union{Automatic,RGBAf}}(automatic; ignore_equal_values=true) - on(highclip; update=true) do hc - _highclip[] = hc isa Union{Nothing,Automatic} ? automatic : to_color(hc) + _highclip = Observable{Union{Automatic, RGBAf}}(automatic; ignore_equal_values = true) + on(highclip; update = true) do hc + _highclip[] = hc isa Union{Nothing, Automatic} ? automatic : to_color(hc) return end - colorrange = lift(color_tight, colorrange; ignore_equal_values=true) do color, crange + colorrange = lift(color_tight, colorrange; ignore_equal_values = true) do color, crange return crange isa Automatic ? Vec2{Float64}(distinct_extrema_nan(color)) : Vec2{Float64}(crange) end - colorrange_scaled = lift(colorrange, colorscale; ignore_equal_values=true) do range, scale + colorrange_scaled = lift(colorrange, colorscale; ignore_equal_values = true) do range, scale return Vec2f(apply_scale(scale, range)) end @@ -310,20 +324,22 @@ function _colormapping( color_scaled[] = scaled end end - CT = ColorMapping{N,V,typeof(color_scaled[])} - - return CT(color_tight, - map_colors, - raw_colormap, - colorscale, - mapping, - colorrange, - _lowclip, - _highclip, - lift(to_color, nan_color), - color_mapping_type, - colorrange_scaled, - color_scaled) + CT = ColorMapping{N, V, typeof(color_scaled[])} + + return CT( + color_tight, + map_colors, + raw_colormap, + colorscale, + mapping, + colorrange, + _lowclip, + _highclip, + lift(to_color, nan_color), + color_mapping_type, + colorrange_scaled, + color_scaled + ) end function ColorMapping( @@ -336,7 +352,8 @@ function ColorMapping( @nospecialize(lowclip), @nospecialize(highclip), @nospecialize(nan_color), - color_mapping_type=lift(colormapping_type, colormap; ignore_equal_values=true)) where {N} + color_mapping_type = lift(colormapping_type, colormap; ignore_equal_values = true) + ) where {N} T = _array_value_type(color) color_tight = Observable{T}(color) @@ -347,14 +364,18 @@ function ColorMapping( color_tight[] = new_colors end end - # color_tight.ignore_equal_values = true - _colormapping(color_tight, colors_obs, colormap, colorrange, - colorscale, alpha, lowclip, highclip, nan_color, color_mapping_type) + # color_tight.ignore_equal_values = true + return _colormapping( + color_tight, colors_obs, colormap, colorrange, + colorscale, alpha, lowclip, highclip, nan_color, color_mapping_type + ) end function assemble_colors(c::AbstractArray{<:Number}, @nospecialize(color), @nospecialize(plot)) - return ColorMapping(c, color, plot.colormap, plot.colorrange, plot.colorscale, plot.alpha, plot.lowclip, - plot.highclip, plot.nan_color) + return ColorMapping( + c, color, plot.colormap, plot.colorrange, plot.colorscale, plot.alpha, plot.lowclip, + plot.highclip, plot.nan_color + ) end function to_color(c::ColorMapping) @@ -362,14 +383,16 @@ function to_color(c::ColorMapping) end function Base.get(c::ColorMapping, value::Number) - return numbers_to_colors([value], c.colormap[], c.scale[], c.colorrange_scaled[], lowclip(c)[], - highclip(c)[], c.nan_color[])[1] + return numbers_to_colors( + [value], c.colormap[], c.scale[], c.colorrange_scaled[], lowclip(c)[], + highclip(c)[], c.nan_color[] + )[1] end function assemble_colors(colortype, color, plot) return lift(plot, color, plot.alpha) do color, a if a < 1.0 - return broadcast(c-> RGBAf(Colors.color(c), Colors.alpha(c) * a), to_color(color)) + return broadcast(c -> RGBAf(Colors.color(c), Colors.alpha(c) * a), to_color(color)) else return to_color(color) end @@ -379,8 +402,10 @@ end function assemble_colors(::Number, color, plot) plot.colorrange[] isa Automatic && error("Cannot determine a colorrange automatically for single number color value. Pass an explicit colorrange.") cm = assemble_colors([color[]], lift(x -> [x], color), plot) - return lift((args...)-> numbers_to_colors(args...)[1], cm.color_scaled, cm.colormap, identity, cm.colorrange_scaled, cm.lowclip, cm.highclip, - cm.nan_color) + return lift( + (args...) -> numbers_to_colors(args...)[1], cm.color_scaled, cm.colormap, identity, cm.colorrange_scaled, cm.lowclip, cm.highclip, + cm.nan_color + ) end highclip(cmap::ColorMapping) = lift((cm, hc) -> hc isa Automatic ? last(cm) : hc, cmap.colormap, cmap.highclip) diff --git a/src/conversions.jl b/src/conversions.jl index 410fb34f71b..3fe4419318e 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -1,7 +1,7 @@ ################################################################################ # Type Conversions # ################################################################################ -const RangeLike = Union{AbstractVector,ClosedInterval,Tuple{Real,Real}} +const RangeLike = Union{AbstractVector, ClosedInterval, Tuple{Real, Real}} function convert_arguments(CT::ConversionTrait, args...) expanded = expand_dimensions(CT, args...) @@ -44,7 +44,7 @@ end # same for points function convert_single_argument(a::AbstractArray{<:Union{Missing, <:Point{N, PT}}}) where {N, PT} T = float_type(PT) - return Point{N,T}[ismissing(x) ? Point{N,T}(NaN) : Point{N,T}(x) for x in a] + return Point{N, T}[ismissing(x) ? Point{N, T}(NaN) : Point{N, T}(x) for x in a] end function convert_single_argument(a::AbstractArray{Any}) @@ -53,7 +53,7 @@ function convert_single_argument(a::AbstractArray{Any}) end # Leave concretely typed vectors alone (AbstractArray{<:Union{Missing, <:Real}} also dispatches for `Vector{Float32}`) -convert_single_argument(a::AbstractArray{T}) where {T<:Real} = a +convert_single_argument(a::AbstractArray{T}) where {T <: Real} = a convert_single_argument(a::AbstractArray{<:Point{N, T}}) where {N, T} = a convert_single_argument(a::OffsetArray{<:Point}) = OffsetArrays.no_offset_view(a) @@ -77,10 +77,10 @@ end function convert_arguments(::PointBased, position::VecTypes{N, T}) where {N, T <: Real} _T = @isdefined(T) ? T : Float64 - return ([Point{N,float_type(_T)}(position)],) + return ([Point{N, float_type(_T)}(position)],) end -function convert_arguments(::PointBased, positions::AbstractVector{<: VecTypes{N, T}}) where {N, T <: Real} +function convert_arguments(::PointBased, positions::AbstractVector{<:VecTypes{N, T}}) where {N, T <: Real} # VecTypes{N, T} will have T undefined if tuple has different number types _T = @isdefined(T) ? T : Float64 if !(N in (2, 3)) @@ -90,12 +90,12 @@ function convert_arguments(::PointBased, positions::AbstractVector{<: VecTypes{N end function convert_arguments(T::PointBased, positions::OffsetVector) - return convert_arguments(T, OffsetArrays.no_offset_view(positions)) + return convert_arguments(T, OffsetArrays.no_offset_view(positions)) end -function convert_arguments(::PointBased, positions::SubArray{<: VecTypes, 1}) +function convert_arguments(::PointBased, positions::SubArray{<:VecTypes, 1}) # TODO figure out a good subarray solution - (positions,) + return (positions,) end """ @@ -104,12 +104,12 @@ spanning z over the grid spanned by x y """ function convert_arguments(::PointBased, x::RealArray, y::RealVector, z::RealMatrix) T = float_type(x, y, z) - (vec(Point{3, T}.(x, y', z)),) + return (vec(Point{3, T}.(x, y', z)),) end function convert_arguments(::PointBased, x::RealVector, y::RealVector, z::RealVector) T = float_type(x, y, z) - return (Point{3,T}.(x, y, z),) + return (Point{3, T}.(x, y, z),) end @@ -126,12 +126,12 @@ from `x`, `y`, and `z`. """ function convert_arguments(::PointBased, x::RealArray, y::RealMatrix, z::RealMatrix) T = float_type(x, y, z) - (vec(Point{3, T}.(x, y, z)),) + return (vec(Point{3, T}.(x, y, z)),) end function convert_arguments(::PointBased, x::RealVector, y::RealVector) - return (Point{2,float_type(x, y)}.(x, y),) + return (Point{2, float_type(x, y)}.(x, y),) end """ @@ -145,7 +145,7 @@ function convert_arguments(p::PointBased, x::GeometryPrimitive{Dim, T}) where {D end function convert_arguments(::PointBased, pos::RealMatrix) - (to_vertices(pos),) + return (to_vertices(pos),) end @@ -168,7 +168,7 @@ Takes an input `Rect` `x` and decomposes it to points. `P` is the plot Type (it is optional). """ -function convert_arguments(P::PointBased, x::Rect2{T}) where T +function convert_arguments(P::PointBased, x::Rect2{T}) where {T} return convert_arguments(P, decompose(Point2{float_type(T)}, x)) end @@ -185,13 +185,13 @@ function convert_arguments(::PointBased, rect::Rect3{T}) where {T} return (decompose(Point3{float_type(T)}, rect),) end -function convert_arguments(P::Type{<: LineSegments}, rect::Rect3{T}) where {T} +function convert_arguments(P::Type{<:LineSegments}, rect::Rect3{T}) where {T} f = GeometryBasics.remove_duplicates(decompose(LineFace{Int}, rect)) p = connect(decompose(Point3{float_type(T)}, rect), f) return convert_arguments(P, p) end -function convert_arguments(::Type{<: Lines}, rect::Rect3{T}) where {T} +function convert_arguments(::Type{<:Lines}, rect::Rect3{T}) where {T} PT = Point3{float_type(T)} points = decompose(PT, rect) push!(points, PT(NaN)) # use to seperate linesegments @@ -212,7 +212,7 @@ end Takes an input `Array{LineString}` or a `MultiLineString` and decomposes it to points. """ -function convert_arguments(PB::PointBased, linestring::Union{AbstractVector{<:LineString{N, T}}, MultiLineString{N, T}, AbstractVector{<:MultiLineString{N,T}}}) where {N, T} +function convert_arguments(PB::PointBased, linestring::Union{AbstractVector{<:LineString{N, T}}, MultiLineString{N, T}, AbstractVector{<:MultiLineString{N, T}}}) where {N, T} T_out = float_type(T) arr = Point{N, T_out}[]; n = length(linestring) for idx in 1:n @@ -254,7 +254,7 @@ end Takes an input `Array{Polygon}` or a `MultiPolygon` and decomposes it to points. """ function convert_arguments(PB::PointBased, mp::Union{Array{<:Polygon{N, T}}, MultiPolygon{N, T}}) where {N, T} - arr = Point{N,float_type(T)}[] + arr = Point{N, float_type(T)}[] n = length(mp) for idx in 1:n converted = convert_arguments(PB, mp[idx])[1] # this should always be a Tuple{<: Vector{Point}} @@ -273,7 +273,7 @@ function convert_arguments(::PointBased, b::BezierPath) last_moveto = false function poly3(t, p0, p1, p2, p3) - Point2d((1-t)^3 .* p0 .+ t*p1*(3*(1-t)^2) + p2*(3*(1-t)*t^2) .+ p3*t^3) + return Point2d((1 - t)^3 .* p0 .+ t * p1 * (3 * (1 - t)^2) + p2 * (3 * (1 - t) * t^2) .+ p3 * t^3) end for command in b2.commands @@ -308,7 +308,7 @@ end # GridBased # ################################################################################ -function edges(v::AbstractVector{T}) where T +function edges(v::AbstractVector{T}) where {T} T_out = float_type(T) l = length(v) if l == 1 @@ -317,9 +317,9 @@ function edges(v::AbstractVector{T}) where T # Equivalent to # mids = 0.5 .* (v[1:end-1] .+ v[2:end]) # borders = [2v[1] - mids[1]; mids; 2v[end] - mids[end]] - borders = T_out[0.5 * (v[max(1, i)] + v[min(end, i+1)]) for i in 0:length(v)] + borders = T_out[0.5 * (v[max(1, i)] + v[min(end, i + 1)]) for i in 0:length(v)] borders[1] = 2borders[1] - borders[2] - borders[end] = 2borders[end] - borders[end-1] + borders[end] = 2borders[end] - borders[end - 1] return borders end end @@ -342,8 +342,10 @@ whether they represent edges or centers of the heatmap bins. If they are centers, convert to edges. Convert eltypes to `Float32` and return outputs as a `Tuple`. """ -function convert_arguments(ct::GridBased, x::AbstractVecOrMat{<:Real}, y::AbstractVecOrMat{<:Real}, - z::AbstractMatrix{<:Union{Real,Colorant}}) +function convert_arguments( + ct::GridBased, x::AbstractVecOrMat{<:Real}, y::AbstractVecOrMat{<:Real}, + z::AbstractMatrix{<:Union{Real, Colorant}} + ) nx, ny, nz = adjust_axes(ct, x, y, z) return (float_convert(nx), float_convert(ny), el32convert(nz)) end @@ -356,16 +358,18 @@ convert_arguments(ct::VertexGrid, x::RealMatrix, y::RealMatrix) = convert_argume Takes one or two ClosedIntervals `x` and `y` and converts them to closed ranges with size(z, 1/2). """ -function convert_arguments(P::GridBased, x::RangeLike, y::RangeLike, z::AbstractMatrix{<: Union{Real, Colorant}}) - convert_arguments(P, to_linspace(x, size(z, 1)), to_linspace(y, size(z, 2)), z) +function convert_arguments(P::GridBased, x::RangeLike, y::RangeLike, z::AbstractMatrix{<:Union{Real, Colorant}}) + return convert_arguments(P, to_linspace(x, size(z, 1)), to_linspace(y, size(z, 2)), z) end -function convert_arguments(::VertexGrid, x::EndPointsLike, y::EndPointsLike, - z::AbstractMatrix{<:Union{Real,Colorant}}) +function convert_arguments( + ::VertexGrid, x::EndPointsLike, y::EndPointsLike, + z::AbstractMatrix{<:Union{Real, Colorant}} + ) return (to_linspace(x, size(z, 1)), to_linspace(y, size(z, 2)), el32convert(z)) end -function to_endpoints(x::Tuple{<:Real,<:Real}) +function to_endpoints(x::Tuple{<:Real, <:Real}) T = float_type(x...) return EndPoints(T.(x)) end @@ -377,13 +381,17 @@ function to_endpoints(x, dim) return to_endpoints(x) end -function convert_arguments(::GridBased, x::EndPointsLike, y::EndPointsLike, - z::AbstractMatrix{<:Union{Real,Colorant}}) +function convert_arguments( + ::GridBased, x::EndPointsLike, y::EndPointsLike, + z::AbstractMatrix{<:Union{Real, Colorant}} + ) return (to_endpoints(x), to_endpoints(y), el32convert(z)) end -function convert_arguments(::CellGrid, x::EndPoints, y::EndPoints, - z::AbstractMatrix{<:Union{Real,Colorant}}) +function convert_arguments( + ::CellGrid, x::EndPoints, y::EndPoints, + z::AbstractMatrix{<:Union{Real, Colorant}} + ) return (x, y, el32convert(z)) end @@ -393,8 +401,10 @@ function get_step(x::EndPoints, n) return step(range(x...; length = n)) end -function convert_arguments(::CellGrid, x::EndPointsLike, y::EndPointsLike, - z::AbstractMatrix{<:Union{Real,Colorant}}) +function convert_arguments( + ::CellGrid, x::EndPointsLike, y::EndPointsLike, + z::AbstractMatrix{<:Union{Real, Colorant}} + ) xe = to_endpoints(x) ye = to_endpoints(y) @@ -412,14 +422,16 @@ function convert_arguments(::CellGrid, x::EndPointsLike, y::EndPointsLike, end function print_range_warning(side::String, value) - @warn "Encountered an `AbstractVector` with value $value on side $side in `convert_arguments` for the `ImageLike` trait. + return @warn "Encountered an `AbstractVector` with value $value on side $side in `convert_arguments` for the `ImageLike` trait. Using an `AbstractVector` to specify one dimension of an `ImageLike` is deprecated because `ImageLike` sides always need exactly two values, start and stop. Use interval notation `start .. stop` or a two-element tuple `(start, stop)` instead." end -function convert_arguments(::ImageLike, xs::RangeLike, ys::RangeLike, - data::AbstractMatrix{<:Union{Real,Colorant}}) +function convert_arguments( + ::ImageLike, xs::RangeLike, ys::RangeLike, + data::AbstractMatrix{<:Union{Real, Colorant}} + ) x = to_endpoints(xs, "x") y = to_endpoints(ys, "y") return (x, y, el32convert(data)) @@ -468,8 +480,10 @@ end # VolumeLike # ################################################################################ -function convert_arguments(::VolumeLike, x::RangeLike, y::RangeLike, z::RangeLike, - data::RealArray{3}) +function convert_arguments( + ::VolumeLike, x::RangeLike, y::RangeLike, z::RangeLike, + data::RealArray{3} + ) return (to_endpoints(x, "x"), to_endpoints(y, "y"), to_endpoints(z, "z"), el32convert(data)) end @@ -481,14 +495,14 @@ Takes 3 `AbstractVector` `x`, `y`, and `z` and the `AbstractMatrix` `i`, and put `P` is the plot Type (it is optional). """ function convert_arguments(::VolumeLike, x::RealVector, y::RealVector, z::RealVector, i::RealArray{3}) - (to_endpoints(x, "x"), to_endpoints(y, "y"), to_endpoints(z, "z"), el32convert(i)) + return (to_endpoints(x, "x"), to_endpoints(y, "y"), to_endpoints(z, "z"), el32convert(i)) end ################################################################################ # <:Lines # ################################################################################ -function convert_arguments(::Type{<: Lines}, x::Rect2{T}) where T +function convert_arguments(::Type{<:Lines}, x::Rect2{T}) where {T} points = decompose(Point2{float_type(T)}, x) return (points[[1, 2, 3, 4, 1]],) end @@ -501,11 +515,11 @@ end Accepts a Vector of Pair of Points (e.g. `[Point(0, 0) => Point(1, 1), ...]`) to encode e.g. linesegments or directions. """ -function convert_arguments(::Type{<: LineSegments}, positions::AbstractVector{E}) where E <: Union{Pair{A, A}, Tuple{A, A}} where A <: VecTypes{N, T} where {N, T} - return (float_convert(reinterpret(Point{N,T}, positions)),) +function convert_arguments(::Type{<:LineSegments}, positions::AbstractVector{E}) where {E <: Union{Pair{A, A}, Tuple{A, A}}} where {A <: VecTypes{N, T}} where {N, T} + return (float_convert(reinterpret(Point{N, T}, positions)),) end -function convert_arguments(::Type{<: LineSegments}, x::Rect2{T}) where T +function convert_arguments(::Type{<:LineSegments}, x::Rect2{T}) where {T} points = decompose(Point2{float_type(T)}, x) return (points[[1, 2, 2, 3, 3, 4, 4, 1]],) end @@ -524,7 +538,7 @@ function convert_arguments( T::Type{<:Mesh}, x::RealVector, y::RealVector, z::RealVector ) - convert_arguments(T, Point3{float_type(x, y, z)}.(x, y, z)) + return convert_arguments(T, Point3{float_type(x, y, z)}.(x, y, z)) end """ convert_arguments(Mesh, xyz::AbstractVector)::GLNormalMesh @@ -536,7 +550,7 @@ function convert_arguments( MT::Type{<:Mesh}, xyz::AbstractVector ) - faces = connect(UInt32.(0:length(xyz)-1), GLTriangleFace) + faces = connect(UInt32.(0:(length(xyz) - 1)), GLTriangleFace) # TODO support faceview natively return convert_arguments(MT, xyz, collect(faces)) end @@ -555,34 +569,36 @@ end function convert_arguments( ::Type{<:Mesh}, - meshes::AbstractVector{<: Union{AbstractMesh, AbstractPolygon}} + meshes::AbstractVector{<:Union{AbstractMesh, AbstractPolygon}} ) # TODO: clear faceviews return (meshes,) end function convert_arguments(MT::Type{<:Mesh}, xyz::AbstractPolygon) - m = GeometryBasics.mesh(xyz; pointtype=float_type(xyz), facetype=GLTriangleFace) + m = GeometryBasics.mesh(xyz; pointtype = float_type(xyz), facetype = GLTriangleFace) return convert_arguments(MT, m) end # TODO GeometryBasics can't deal with this directly for Integer Points? function convert_arguments( MT::Type{<:Mesh}, - xyz::AbstractVector{<: Point{2}} + xyz::AbstractVector{<:Point{2}} ) ps = float_convert(xyz) - m = GeometryBasics.mesh(ps; pointtype=eltype(ps), facetype=GLTriangleFace) + m = GeometryBasics.mesh(ps; pointtype = eltype(ps), facetype = GLTriangleFace) return convert_arguments(MT, m) end function convert_arguments(::Type{<:Mesh}, geom::GeometryPrimitive{N, T}) where {N, T <: Real} # we convert to UV mesh as default, because otherwise the uv informations get lost # - we can still drop them, but we can't add them later on - m = GeometryBasics.expand_faceviews(GeometryBasics.uv_normal_mesh( - geom; pointtype = Point{N, float_type(T)}, - uvtype = Vec2f, normaltype = Vec3f, facetype = GLTriangleFace - )) + m = GeometryBasics.expand_faceviews( + GeometryBasics.uv_normal_mesh( + geom; pointtype = Point{N, float_type(T)}, + uvtype = Vec2f, normaltype = Vec3f, facetype = GLTriangleFace + ) + ) return (m,) end @@ -593,7 +609,7 @@ Takes real vectors x, y, z and constructs a triangle mesh out of those, using th faces in `indices`, which can be integers (every 3 -> one triangle), or GeometryBasics.NgonFace{N, <: Integer}. """ function convert_arguments( - T::Type{<: Mesh}, + T::Type{<:Mesh}, x::RealVector, y::RealVector, z::RealVector, indices::AbstractVector ) @@ -639,8 +655,10 @@ function convert_arguments(::Type{<:Arrows}, x::RealVector, y::RealVector, f::Fu return (vec(points), vec(f_out)) end -function convert_arguments(::Type{<:Arrows}, x::RealVector, y::RealVector, z::RealVector, - f::Function) +function convert_arguments( + ::Type{<:Arrows}, x::RealVector, y::RealVector, z::RealVector, + f::Function + ) points = [Point3{float_type(x, y, z)}(x, y, z) for x in x, y in y, z in z] f_out = Vec3{float_type(x, y, z)}.(f.(points)) return (vec(points), vec(f_out)) @@ -675,7 +693,7 @@ function convert_arguments(P::Type{<:AbstractPlot}, i::AbstractInterval, f::Func return convert_arguments(P, x, y) end -function convert_arguments(P::Type{<:Union{Band,Rangebars}}, i::AbstractInterval, f::Function) +function convert_arguments(P::Type{<:Union{Band, Rangebars}}, i::AbstractInterval, f::Function) # f() returns interval for these plottypes x, y = PlotUtils.adapted_grid(x -> mean(f(x)), endpoints(i)) return convert_arguments(P, x, f.(x)) @@ -683,12 +701,12 @@ end # OffsetArrays conversions function convert_arguments(sl::GridBased, wm::OffsetArray) - x1, y1 = wm.offsets .+ 1 - nx, ny = size(wm) - x = range(x1, length = nx) - y = range(y1, length = ny) - v = parent(wm) - return convert_arguments(sl, x, y, v) + x1, y1 = wm.offsets .+ 1 + nx, ny = size(wm) + x = range(x1, length = nx) + y = range(y1, length = ny) + v = parent(wm) + return convert_arguments(sl, x, y, v) end ################################################################################ @@ -705,7 +723,7 @@ function elconvert(::Type{T1}, x::AbstractArray{T2, N}) where {T1, T2, N} return convert(AbstractArray{T1, N}, x) end -function elconvert(::Type{T}, x::AbstractArray{<: Union{Missing, <:Real}}) where {T} +function elconvert(::Type{T}, x::AbstractArray{<:Union{Missing, <:Real}}) where {T} return map(x) do elem return (ismissing(elem) ? T(NaN) : convert(T, elem)) end @@ -720,15 +738,15 @@ float_type(::Type{Float64}) = Float64 float_type(::Type{Float32}) = Float32 float_type(::Type{Bool}) = Float32 float_type(::Type{<:Real}) = Float64 -float_type(::Type{<:Union{Int8,UInt8,Int16,UInt16}}) = Float32 +float_type(::Type{<:Union{Int8, UInt8, Int16, UInt16}}) = Float32 float_type(::Type{<:Union{Float16}}) = Float32 -float_type(::Type{Point{N,T}}) where {N,T} = Point{N,float_type(T)} -float_type(::Type{Vec{N,T}}) where {N,T} = Vec{N,float_type(T)} -float_type(::Type{NTuple{N, T}}) where {N,T} = Point{N,float_type(T)} -float_type(::Type{Tuple{T1, T2}}) where {T1,T2} = Point2{promote_type(float_type(T1), float_type(T2))} -float_type(::Type{Tuple{T1, T2, T3}}) where {T1,T2,T3} = Point3{promote_type(float_type(T1), float_type(T2), float_type(T3))} +float_type(::Type{Point{N, T}}) where {N, T} = Point{N, float_type(T)} +float_type(::Type{Vec{N, T}}) where {N, T} = Vec{N, float_type(T)} +float_type(::Type{NTuple{N, T}}) where {N, T} = Point{N, float_type(T)} +float_type(::Type{Tuple{T1, T2}}) where {T1, T2} = Point2{promote_type(float_type(T1), float_type(T2))} +float_type(::Type{Tuple{T1, T2, T3}}) where {T1, T2, T3} = Point3{promote_type(float_type(T1), float_type(T2), float_type(T3))} float_type(::Type{Union{Missing, T}}) where {T} = float_type(T) -float_type(::Type{Union{Nothing,T}}) where {T} = float_type(T) +float_type(::Type{Union{Nothing, T}}) where {T} = float_type(T) float_type(::Type{ClosedInterval{T}}) where {T} = ClosedInterval{T} float_type(::Type{ClosedInterval}) = ClosedInterval{Float32} float_type(::AbstractArray{T}) where {T} = float_type(T) @@ -739,25 +757,25 @@ float_convert(x::AbstractArray{Float32}) = x float_convert(x::AbstractArray{Float64}) = x float_convert(x::AbstractArray) = elconvert(float_type(x), x) float_convert(x::Observable) = lift(float_convert, x) -float_convert(x::AbstractArray{<:Union{Missing, T}}) where {T<:Real} = elconvert(float_type(T), x) +float_convert(x::AbstractArray{<:Union{Missing, T}}) where {T <: Real} = elconvert(float_type(T), x) float32type(::Type{<:Real}) = Float32 -float32type(::Type{Point{N,T}}) where {N,T} = Point{N,float32type(T)} -float32type(::Type{Vec{N,T}}) where {N,T} = Vec{N,float32type(T)} +float32type(::Type{Point{N, T}}) where {N, T} = Point{N, float32type(T)} +float32type(::Type{Vec{N, T}}) where {N, T} = Vec{N, float32type(T)} # We may want to always use UInt8 for colors? float32type(::Type{<:RGB{N0f8}}) = RGB{N0f8} float32type(::Type{<:RGBA{N0f8}}) = RGBA{N0f8} float32type(::Type{<:RGB}) = RGB{Float32} -float32type(::Type{<: RGBA}) = RGBA{Float32} -float32type(::Type{<: Colorant}) = RGBA{Float32} -float32type(::AbstractArray{T}) where T = float32type(T) +float32type(::Type{<:RGBA}) = RGBA{Float32} +float32type(::Type{<:Colorant}) = RGBA{Float32} +float32type(::AbstractArray{T}) where {T} = float32type(T) float32type(::T) where {T} = float32type(T) el32convert(x::ClosedInterval) = Float32(minimum(x)) .. Float32(maximum(x)) el32convert(x::AbstractArray) = elconvert(float32type(x), x) -el32convert(x::AbstractArray{T}) where {T<:Real} = elconvert(float32type(T), x) -el32convert(x::AbstractArray{<:Union{Missing,T}}) where {T<:Real} = elconvert(float32type(T), x) +el32convert(x::AbstractArray{T}) where {T <: Real} = elconvert(float32type(T), x) +el32convert(x::AbstractArray{<:Union{Missing, T}}) where {T <: Real} = elconvert(float32type(T), x) el32convert(x::AbstractArray{Float32}) = x el32convert(x::Observable) = lift(el32convert, x) el32convert(x) = convert(float32type(x), x) @@ -780,17 +798,17 @@ function to_triangles(x::AbstractVector{Int}) end function to_triangles(idx0::AbstractVector{UInt32}) - reinterpret(GLTriangleFace, idx0) + return reinterpret(GLTriangleFace, idx0) end -function to_triangles(faces::AbstractVector{TriangleFace{T}}) where T - elconvert(GLTriangleFace, faces) +function to_triangles(faces::AbstractVector{TriangleFace{T}}) where {T} + return elconvert(GLTriangleFace, faces) end -function to_triangles(faces::AbstractMatrix{T}) where T <: Integer +function to_triangles(faces::AbstractMatrix{T}) where {T <: Integer} @assert size(faces, 2) == 3 return broadcast(1:size(faces, 1), 3) do fidx, n - GLTriangleFace(ntuple(i-> faces[fidx, i], n)) + GLTriangleFace(ntuple(i -> faces[fidx, i], n)) end end @@ -809,19 +827,19 @@ Converts a representation of vertices `v` to its canonical representation as a - if `v` has 2 or 3 rows, it will treat each column as a vertex, - otherwise if `v` has 2 or 3 columns, it will treat each row as a vertex. """ -function to_vertices(verts::AbstractVector{<: VecTypes{3, T}}) where T +function to_vertices(verts::AbstractVector{<:VecTypes{3, T}}) where {T} T_out = float_type(T) vert3 = T != T_out ? map(Point3{T_out}, verts) : verts return reinterpret(Point3{T_out}, vert3) end -function to_vertices(verts::AbstractVector{<: VecTypes{N, T}}) where {N, T} +function to_vertices(verts::AbstractVector{<:VecTypes{N, T}}) where {N, T} return map(Point{N, float_type(T)}, verts) end -function to_vertices(verts::AbstractMatrix{T}) where {T<:Real} +function to_vertices(verts::AbstractMatrix{T}) where {T <: Real} T_out = float_type(T) - if size(verts, 1) in (2, 3) + return if size(verts, 1) in (2, 3) to_vertices(verts, T_out, Val(1), Val(size(verts, 1))) elseif size(verts, 2) in (2, 3) to_vertices(verts, T_out, Val(2), Val(size(verts, 2))) @@ -834,12 +852,12 @@ function to_vertices(verts::AbstractMatrix{T}, ::Type{Tout}, ::Val{1}, ::Val{N}) if T == Tout && N == 3 return reinterpret(Point{N, T}, elconvert(T, vec(verts))) else - return Point{N,Tout}[ntuple(j -> Tout(verts[j, i]), N) for i in 1:size(verts, 2)] + return Point{N, Tout}[ntuple(j -> Tout(verts[j, i]), N) for i in 1:size(verts, 2)] end end -function to_vertices(verts::AbstractMatrix{T}, ::Type{Tout}, ::Val{2}, ::Val{N}) where {T<:Real, Tout, N} - return Point{N, Tout}[ntuple(j-> Tout(verts[i, j]), N) for i in 1:size(verts, 1)] +function to_vertices(verts::AbstractMatrix{T}, ::Type{Tout}, ::Val{2}, ::Val{N}) where {T <: Real, Tout, N} + return Point{N, Tout}[ntuple(j -> Tout(verts[i, j]), N) for i in 1:size(verts, 1)] end @@ -855,7 +873,7 @@ function tryrange(F::AbstractArray, vec) rets = [tryrange(f, vec) for f in F] # get the preferred for each maxind = maximum(indexin(rets, vec)) # get the last attempt that succeeded (most likely to fit all) rets .= [tryrange(f, vec[maxind:maxind]) for f in F] # ensure that all functions compute there - rets[1] + return rets[1] end function tryrange(F, vec) @@ -870,17 +888,11 @@ function tryrange(F, vec) end - - - ################################################################################ # Attribute conversions # ################################################################################ - - - convert_attribute(x, key::Key, ::Key) = convert_attribute(x, key) convert_attribute(s::SceneLike, x, key::Key, ::Key) = convert_attribute(s, x, key) convert_attribute(s::SceneLike, x, key::Key) = convert_attribute(x, key) @@ -899,9 +911,9 @@ convert_attribute(p::Nothing, ::key"lowclip") = p convert_attribute(p, ::key"nan_color") = to_color(p) struct Palette - colors::Vector{RGBA{Float32}} - i::Ref{Int} - Palette(colors) = new(to_color.(colors), zero(Int)) + colors::Vector{RGBA{Float32}} + i::Ref{Int} + Palette(colors) = new(to_color.(colors), zero(Int)) end Palette(name::Union{String, Symbol}, n = 8) = Palette(categorical_colors(name, n)) @@ -919,9 +931,9 @@ to_color(c::VecTypes{4}) = RGBAf(c[1], c[2], c[3], c[4]) to_color(c::Symbol) = to_color(string(c)) to_color(c::String) = parse(RGBA{Float32}, c) to_color(c::AbstractArray) = to_color.(c) -to_color(c::AbstractArray{<: Colorant, N}) where N = convert(Array{RGBAf, N}, c) +to_color(c::AbstractArray{<:Colorant, N}) where {N} = convert(Array{RGBAf, N}, c) to_color(p::AbstractPattern) = p -function to_color(c::Tuple{<: Any, <: Number}) +function to_color(c::Tuple{<:Any, <:Number}) col = to_color(c[1]) return RGBAf(Colors.color(col), alpha(col) * c[2]) end @@ -966,7 +978,7 @@ convert_attribute(::Automatic, ::key"uv_transform", ::key"image") = Mat{2, 3, Fl convert_attribute(x::Vector, k::key"uv_transform") = convert_attribute.(x, (k,)) convert_attribute(x, k::key"uv_transform") = convert_attribute(uv_transform(x), k) -convert_attribute(x::Mat3f, ::key"uv_transform") = x[Vec(1,2), Vec(1,2,3)] +convert_attribute(x::Mat3f, ::key"uv_transform") = x[Vec(1, 2), Vec(1, 2, 3)] convert_attribute(x::Mat{2, 3, Float32}, ::key"uv_transform") = x convert_attribute(x::Nothing, ::key"uv_transform") = x @@ -1005,8 +1017,8 @@ Creates a 3x3 uv transformation matrix based on the given translation and scale or rotation angle (around z axis). """ uv_transform(x::Tuple{VecTypes{2, <:Real}, VecTypes{2, <:Real}}) = uv_transform(x[1], x[2]) -uv_transform(scale::VecTypes{2, <: Real}) = uv_transform(Vec2f(0), scale) -function uv_transform(translation::VecTypes{2, <: Real}, scale::VecTypes{2, <: Real}) +uv_transform(scale::VecTypes{2, <:Real}) = uv_transform(Vec2f(0), scale) +function uv_transform(translation::VecTypes{2, <:Real}, scale::VecTypes{2, <:Real}) return Mat3f( scale[1], 0, 0, 0, scale[2], 0, @@ -1015,7 +1027,7 @@ function uv_transform(translation::VecTypes{2, <: Real}, scale::VecTypes{2, <: R end function uv_transform(angle::Real) return Mat3f( - cos(angle), sin(angle), 0, + cos(angle), sin(angle), 0, -sin(angle), cos(angle), 0, 0, 0, 1 ) @@ -1036,23 +1048,23 @@ Creates a 3x3 uv transformation matrix from a given named action. They assume function uv_transform(action::Symbol) # TODO: do some explicitly named operations if action == :rotr90 - return Mat3f(0,-1,0, 1,0,0, 0,1,1) + return Mat3f(0, -1, 0, 1, 0, 0, 0, 1, 1) elseif action == :rotl90 - return Mat3f(0,1,0, -1,0,0, 1,0,1) + return Mat3f(0, 1, 0, -1, 0, 0, 1, 0, 1) elseif action == :rot180 - return Mat3f(-1,0,0, 0,-1,0, 1,1,1) + return Mat3f(-1, 0, 0, 0, -1, 0, 1, 1, 1) elseif action in (:swap_xy, :transpose) - return Mat3f(0,1,0, 1,0,0, 0,0,1) + return Mat3f(0, 1, 0, 1, 0, 0, 0, 0, 1) elseif action in (:flip_x, :invert_x) - return Mat3f(-1,0,0, 0,1,0, 1,0,1) + return Mat3f(-1, 0, 0, 0, 1, 0, 1, 0, 1) elseif action in (:flip_y, :invert_y) - return Mat3f(1,0,0, 0,-1,0, 0,1,1) + return Mat3f(1, 0, 0, 0, -1, 0, 0, 1, 1) elseif action in (:flip_xy, :invert_xy) - return Mat3f(-1,0,0, 0,-1,0, 1,1,1) + return Mat3f(-1, 0, 0, 0, -1, 0, 1, 1, 1) elseif action in (:meshscatter, :mesh, :image, :surface) M = convert_attribute(automatic, key"uv_transform"(), Key{action}()) - return Mat3f(M[1,1], M[2,1], 0, M[1,2], M[2,2], 0, M[1,3], M[2,3], 1) - # elseif action == :surface + return Mat3f(M[1, 1], M[2, 1], 0, M[1, 2], M[2, 2], 0, M[1, 3], M[2, 3], 1) + # elseif action == :surface # return Mat3f(I) else error("Transformation :$action not recognized.") @@ -1112,7 +1124,7 @@ const GapType = Union{Real, Symbol, Tuple, AbstractVector} # A `Symbol` equal to `:dash`, `:dot`, `:dashdot`, `:dashdotdot` to_linestyle(ls::Union{Symbol, AbstractString}) = line_pattern(ls, :normal) -function to_linestyle(ls::Tuple{<:Union{Symbol, AbstractString}, <: GapType}) +function to_linestyle(ls::Tuple{<:Union{Symbol, AbstractString}, <:GapType}) return line_pattern(ls[1], ls[2]) end @@ -1156,7 +1168,7 @@ function line_diff_pattern(ls_str::AbstractString, gaps::GapType = :normal) pattern = Float64[] for i in 1:length(ls_str) curr_char = ls_str[i] - next_char = i == lastindex(ls_str) ? ls_str[firstindex(ls_str)] : ls_str[i+1] + next_char = i == lastindex(ls_str) ? ls_str[firstindex(ls_str)] : ls_str[i + 1] # push dash or dot if curr_char == '-' push!(pattern, dash) @@ -1170,7 +1182,7 @@ function line_diff_pattern(ls_str::AbstractString, gaps::GapType = :normal) push!(pattern, dash_gap) end end - pattern + return pattern end "Checks if the linestyle format provided as a string contains only dashes and dots" @@ -1178,17 +1190,17 @@ function check_line_pattern(ls_str) isnothing(match(r"^[.-]+$", ls_str)) && throw(ArgumentError("If you provide a string as linestyle, it must only consist of dashes (-) and dots (.)")) - nothing + return nothing end function convert_gaps(gaps::GapType) error_msg = "You provided the gaps modifier $gaps when specifying the linestyle. The modifier must be one of the symbols `:normal`, `:dense` or `:loose`, a real number or a tuple of two real numbers." if gaps isa Symbol gaps in [:normal, :dense, :loose] || throw(ArgumentError(error_msg)) - dot_gaps = (normal = 2, dense = 1, loose = 4) + dot_gaps = (normal = 2, dense = 1, loose = 4) dash_gaps = (normal = 3, dense = 2, loose = 6) - dot_gap = getproperty(dot_gaps, gaps) + dot_gap = getproperty(dot_gaps, gaps) dash_gap = getproperty(dash_gaps, gaps) elseif gaps isa Real dot_gap = gaps @@ -1251,9 +1263,9 @@ function miter_angle_to_distance(angle, directed = false) end -convert_attribute(c::Tuple{<: Number, <: Number}, ::key"position") = Point2f(c[1], c[2]) -convert_attribute(c::Tuple{<: Number, <: Number, <: Number}, ::key"position") = Point3f(c) -convert_attribute(c::VecTypes{N}, ::key"position") where N = Point{N, Float32}(c) +convert_attribute(c::Tuple{<:Number, <:Number}, ::key"position") = Point2f(c[1], c[2]) +convert_attribute(c::Tuple{<:Number, <:Number, <:Number}, ::key"position") = Point3f(c) +convert_attribute(c::VecTypes{N}, ::key"position") where {N} = Point{N, Float32}(c) """ to_align(align[, error_prefix]) @@ -1306,9 +1318,9 @@ if it fails to do so. valign2num(v::Real, error_msg = "") = Float32(v) function valign2num(v::Symbol, error_msg = "Invalid valign $v. Valid values are <:Real, :bottom, :top, and :center.") if v === :top - return 1f0 + return 1.0f0 elseif v === :bottom - return 0f0 + return 0.0f0 elseif v === :center return 0.5f0 else @@ -1352,7 +1364,7 @@ A font can either be specified by a file path, such as "folder/with/fonts/font.o or by a (partial) name such as "Helvetica", "Helvetica Bold" etc. """ function to_font(str::String) - lock(FONT_CACHE_LOCK) do + return lock(FONT_CACHE_LOCK) do return get!(FONT_CACHE, str) do # load default fonts without font search to avoid latency if str == "default" || str == "TeX Gyre Heros Makie" @@ -1363,13 +1375,13 @@ function to_font(str::String) return load_font(assetpath("fonts", "TeXGyreHerosMakie-Italic.otf")) elseif str == "TeX Gyre Heros Makie Bold Italic" return load_font(assetpath("fonts", "TeXGyreHerosMakie-BoldItalic.otf")) - # load fonts directly if they are given as font paths + # load fonts directly if they are given as font paths elseif isfile(str) return load_font(str) end # for all other cases, search for the best match on the system fontpath = assetpath("fonts") - font = FreeTypeAbstraction.findfont(str; additional_fonts=fontpath) + font = FreeTypeAbstraction.findfont(str; additional_fonts = fontpath) if font === nothing @warn("Could not find font $str, using TeX Gyre Heros Makie") return to_font("TeX Gyre Heros Makie") @@ -1405,8 +1417,8 @@ to_font(fonts::Attributes, x) = to_font(x) to_rotation(s::Quaternionf) = s to_rotation(s::Quaternion) = Quaternionf(s.data...) -function to_rotation(s::VecTypes{N}) where N - if N == 4 +function to_rotation(s::VecTypes{N}) where {N} + return if N == 4 Quaternionf(s...) elseif N == 3 rotation_between(Vec3f(0, 0, 1), to_ndim(Vec3f, s, 0.0)) @@ -1420,34 +1432,38 @@ end to_rotation(s::Tuple{VecTypes, Number}) = qrotation(to_ndim(Vec3f, s[1], 0.0), s[2]) to_rotation(angle::Number) = qrotation(Vec3f(0, 0, 1), angle) to_rotation(r::AbstractVector) = to_rotation.(r) -to_rotation(r::AbstractVector{<: Quaternionf}) = r +to_rotation(r::AbstractVector{<:Quaternionf}) = r convert_attribute(x, ::key"colorrange") = to_colorrange(x) to_colorrange(x) = isnothing(x) ? nothing : Vec2f(x) convert_attribute(x, ::key"fontsize") = to_fontsize(x) to_fontsize(x::Number) = Float32(x) -to_fontsize(x::AbstractVector{T}) where T <: Number = el32convert(x) +to_fontsize(x::AbstractVector{T}) where {T <: Number} = el32convert(x) to_fontsize(x::Vec2) = Vec2f(x) -to_fontsize(x::AbstractVector{T}) where T <: Vec2 = Vec2f.(x) +to_fontsize(x::AbstractVector{T}) where {T <: Vec2} = Vec2f.(x) convert_attribute(x, ::key"linewidth") = to_linewidth(x) to_linewidth(x) = Float32(x) to_linewidth(x::AbstractVector) = el32convert(x) # ColorBrewer colormaps that support only 8 colors require special handling on the backend, so we show them here. -const colorbrewer_8color_names = String.([ - :Accent, - :Dark2, - :Pastel2, - :Set2 -]) - -const plotutils_names = String.(union( - keys(PlotUtils.ColorSchemes.colorschemes), - keys(PlotUtils.COLORSCHEME_ALIASES), - keys(PlotUtils.MISC_COLORSCHEMES) -)) +const colorbrewer_8color_names = String.( + [ + :Accent, + :Dark2, + :Pastel2, + :Set2, + ] +) + +const plotutils_names = String.( + union( + keys(PlotUtils.ColorSchemes.colorschemes), + keys(PlotUtils.COLORSCHEME_ALIASES), + keys(PlotUtils.MISC_COLORSCHEMES) + ) +) const all_gradient_names = Set(vcat(plotutils_names, colorbrewer_8color_names)) @@ -1461,6 +1477,7 @@ function available_gradients() for name in sort(collect(all_gradient_names)) println(" ", name) end + return end @@ -1472,7 +1489,7 @@ to_colormap(cm, categories::Integer) = error("`to_colormap(cm, categories)` is d Creates categorical colors and tries to match `categories`. Will error if color scheme doesn't contain enough categories. Will drop the n last colors, if request less colors than contained in scheme. """ -function categorical_colors(cols::AbstractVector{<: Colorant}, categories::Integer) +function categorical_colors(cols::AbstractVector{<:Colorant}, categories::Integer) if length(cols) < categories error("Not enough colors for number of categories. Categories: $(categories), colors: $(length(cols))") end @@ -1485,7 +1502,7 @@ end function categorical_colors(cs::Union{String, Symbol}, categories::Integer) cs_string = string(cs) - if cs_string in all_gradient_names + return if cs_string in all_gradient_names if haskey(ColorBrewer.colorSchemes, cs_string) return to_colormap(ColorBrewer.palette(cs_string, categories)) else @@ -1513,16 +1530,15 @@ to_colormap(r::Reverse) = reverse(to_colormap(r.data)) to_colormap(cs::ColorScheme) = to_colormap(cs.colors) - """ to_colormap(b::AbstractVector) An `AbstractVector{T}` with any object that `to_color` accepts. """ to_colormap(cm::AbstractVector)::Vector{RGBAf} = map(to_color, cm) -to_colormap(cm::AbstractVector{<: Colorant}) = convert(Vector{RGBAf}, cm) +to_colormap(cm::AbstractVector{<:Colorant}) = convert(Vector{RGBAf}, cm) -function to_colormap(cs::Tuple{<: Union{Reverse, Symbol, AbstractString}, Real})::Vector{RGBAf} +function to_colormap(cs::Tuple{<:Union{Reverse, Symbol, AbstractString}, Real})::Vector{RGBAf} cmap = to_colormap(cs[1]) return RGBAf.(color.(cmap), alpha.(cmap) .* cs[2]) # We need to rework this to conform to the backend interface. end @@ -1535,7 +1551,7 @@ For now, we support gradients from `PlotUtils` natively. """ function to_colormap(cs::Union{String, Symbol})::Vector{RGBAf} cs_string = string(cs) - if cs_string in all_gradient_names + return if cs_string in all_gradient_names if cs_string in colorbrewer_8color_names # special handling for 8 color only return to_colormap(ColorBrewer.palette(cs_string, 8)) else @@ -1584,9 +1600,11 @@ function convert_attribute(value::Union{Symbol, String}, k::key"algorithm") :indexedabsorption => IndexedAbsorptionRGBA, :additive => AdditiveRGBA, ) - convert_attribute(get(vals, Symbol(value)) do - error("$value is not a valid volume algorithm. It must be one of $(keys(vals))") - end, k) + return convert_attribute( + get(vals, Symbol(value)) do + error("$value is not a valid volume algorithm. It must be one of $(keys(vals))") + end, k + ) end #= @@ -1629,221 +1647,513 @@ This would create different hashes, making the caching in the texture atlas fail See: https://github.com/MakieOrg/Makie.jl/pull/3394 =# -const DEFAULT_MARKER_MAP = Dict(:+ => BezierPath([Makie.MoveTo([0.1245, 0.375]), - Makie.LineTo([0.1245, 0.1245]), - Makie.LineTo([0.375, 0.1245]), - Makie.LineTo([0.375, -0.12449999999999999]), - Makie.LineTo([0.1245, -0.1245]), - Makie.LineTo([0.12450000000000003, -0.375]), - Makie.LineTo([-0.12449999999999997, -0.375]), - Makie.LineTo([-0.12449999999999999, -0.12450000000000003]), - Makie.LineTo([-0.375, -0.12450000000000006]), - Makie.LineTo([-0.375, 0.12449999999999994]), - Makie.LineTo([-0.12450000000000003, 0.12449999999999999]), - Makie.LineTo([-0.12450000000000007, 0.37499999999999994]), - Makie.ClosePath()]), - :diamond => BezierPath([Makie.MoveTo([0.4464931614186469, - -5.564531862779532e-17]), - Makie.LineTo([2.10398220755128e-17, - 0.4464931614186469]), - Makie.LineTo([-0.4464931614186469, - 5.564531862779532e-17]), - Makie.LineTo([-2.10398220755128e-17, - -0.4464931614186469]), - Makie.ClosePath()]), - :star4 => BezierPath([Makie.MoveTo([2.7554554183166277e-17, - 0.44999999999999996]), - Makie.LineTo([-0.13258251920342445, - 0.13258251920342445]), - Makie.LineTo([-0.44999999999999996, - 5.5109108366332553e-17]), - Makie.LineTo([-0.13258251920342445, - -0.13258251920342445]), - Makie.LineTo([-8.266365659379842e-17, - -0.44999999999999996]), - Makie.LineTo([0.13258251920342445, - -0.13258251920342445]), - Makie.LineTo([0.44999999999999996, - -1.1021821673266511e-16]), - Makie.LineTo([0.13258251920342445, 0.13258251920342445]), - Makie.ClosePath()]), - :star8 => BezierPath([Makie.MoveTo([2.7554554183166277e-17, - 0.44999999999999996]), - Makie.LineTo([-0.09471414797008038, 0.2286601772904396]), - Makie.LineTo([-0.31819804608821867, - 0.31819804608821867]), - Makie.LineTo([-0.2286601772904396, 0.09471414797008038]), - Makie.LineTo([-0.44999999999999996, - 5.5109108366332553e-17]), - Makie.LineTo([-0.2286601772904396, - -0.09471414797008038]), - Makie.LineTo([-0.31819804608821867, - -0.31819804608821867]), - Makie.LineTo([-0.09471414797008038, - -0.2286601772904396]), - Makie.LineTo([-8.266365659379842e-17, - -0.44999999999999996]), - Makie.LineTo([0.09471414797008038, -0.2286601772904396]), - Makie.LineTo([0.31819804608821867, - -0.31819804608821867]), - Makie.LineTo([0.2286601772904396, -0.09471414797008038]), - Makie.LineTo([0.44999999999999996, - -1.1021821673266511e-16]), - Makie.LineTo([0.2286601772904396, 0.09471414797008038]), - Makie.LineTo([0.31819804608821867, 0.31819804608821867]), - Makie.LineTo([0.09471414797008038, 0.2286601772904396]), - Makie.ClosePath()]), - :star6 => BezierPath([Makie.MoveTo([2.7554554183166277e-17, - 0.44999999999999996]), - Makie.LineTo([-0.11249999999999999, 0.1948557123541832]), - Makie.LineTo([-0.3897114247083664, 0.22499999999999998]), - Makie.LineTo([-0.22499999999999998, - 2.7554554183166277e-17]), - Makie.LineTo([-0.3897114247083664, - -0.22499999999999998]), - Makie.LineTo([-0.11249999999999999, - -0.1948557123541832]), - Makie.LineTo([-8.266365659379842e-17, - -0.44999999999999996]), - Makie.LineTo([0.11249999999999999, -0.1948557123541832]), - Makie.LineTo([0.3897114247083664, -0.22499999999999998]), - Makie.LineTo([0.22499999999999998, - -5.5109108366332553e-17]), - Makie.LineTo([0.3897114247083664, 0.22499999999999998]), - Makie.LineTo([0.11249999999999999, 0.1948557123541832]), - Makie.ClosePath()]), - :rtriangle => BezierPath([Makie.MoveTo([0.485, -8.909305463796994e-17]), - Makie.LineTo([-0.24249999999999994, 0.36375]), - Makie.LineTo([-0.2425000000000001, - -0.36374999999999996]), - Makie.ClosePath()]), - :x => BezierPath([Makie.MoveTo([-0.1771302486872301, 0.35319983720268056]), - Makie.LineTo([1.39759596452057e-17, 0.17606958851545035]), - Makie.LineTo([0.17713024868723018, 0.3531998372026805]), - Makie.LineTo([0.3531998372026805, 0.17713024868723012]), - Makie.LineTo([0.17606958851545035, -1.025465786723834e-17]), - Makie.LineTo([0.3531998372026805, -0.17713024868723015]), - Makie.LineTo([0.17713024868723015, -0.3531998372026805]), - Makie.LineTo([1.1151998010815531e-17, -0.17606958851545035]), - Makie.LineTo([-0.17713024868723015, -0.3531998372026805]), - Makie.LineTo([-0.35319983720268044, -0.17713024868723018]), - Makie.LineTo([-0.17606958851545035, - -1.4873299788782892e-17]), - Makie.LineTo([-0.3531998372026805, 0.1771302486872301]), - Makie.ClosePath()]), - :circle => BezierPath([Makie.MoveTo([0.3525, 0.0]), - EllipticalArc([0.0, 0.0], 0.3525, 0.3525, 0.0, 0.0, - 6.283185307179586), Makie.ClosePath()]), - :pentagon => BezierPath([Makie.MoveTo([2.2962128485971897e-17, 0.375]), - Makie.LineTo([-0.35664620250463486, - 0.11588137596845627]), - Makie.LineTo([-0.22041946649551392, - -0.30338137596845627]), - Makie.LineTo([0.22041946649551392, - -0.30338137596845627]), - Makie.LineTo([0.35664620250463486, - 0.11588137596845627]), - Makie.ClosePath()]), - :vline => BezierPath([Makie.MoveTo([0.063143668438509, -0.315718342192545]), - Makie.LineTo([0.063143668438509, 0.315718342192545]), - Makie.LineTo([-0.063143668438509, 0.315718342192545]), - Makie.LineTo([-0.063143668438509, -0.315718342192545]), - Makie.ClosePath()]), - :cross => BezierPath([Makie.MoveTo([0.1245, 0.375]), - Makie.LineTo([0.1245, 0.1245]), - Makie.LineTo([0.375, 0.1245]), - Makie.LineTo([0.375, -0.12449999999999999]), - Makie.LineTo([0.1245, -0.1245]), - Makie.LineTo([0.12450000000000003, -0.375]), - Makie.LineTo([-0.12449999999999997, -0.375]), - Makie.LineTo([-0.12449999999999999, - -0.12450000000000003]), - Makie.LineTo([-0.375, -0.12450000000000006]), - Makie.LineTo([-0.375, 0.12449999999999994]), - Makie.LineTo([-0.12450000000000003, - 0.12449999999999999]), - Makie.LineTo([-0.12450000000000007, - 0.37499999999999994]), - Makie.ClosePath()]), - :xcross => BezierPath([Makie.MoveTo([-0.1771302486872301, - 0.35319983720268056]), - Makie.LineTo([1.39759596452057e-17, - 0.17606958851545035]), - Makie.LineTo([0.17713024868723018, 0.3531998372026805]), - Makie.LineTo([0.3531998372026805, 0.17713024868723012]), - Makie.LineTo([0.17606958851545035, - -1.025465786723834e-17]), - Makie.LineTo([0.3531998372026805, - -0.17713024868723015]), - Makie.LineTo([0.17713024868723015, - -0.3531998372026805]), - Makie.LineTo([1.1151998010815531e-17, - -0.17606958851545035]), - Makie.LineTo([-0.17713024868723015, - -0.3531998372026805]), - Makie.LineTo([-0.35319983720268044, - -0.17713024868723018]), - Makie.LineTo([-0.17606958851545035, - -1.4873299788782892e-17]), - Makie.LineTo([-0.3531998372026805, 0.1771302486872301]), - Makie.ClosePath()]), - :rect => BezierPath([Makie.MoveTo([0.315718342192545, -0.315718342192545]), - Makie.LineTo([0.315718342192545, 0.315718342192545]), - Makie.LineTo([-0.315718342192545, 0.315718342192545]), - Makie.LineTo([-0.315718342192545, -0.315718342192545]), - Makie.ClosePath()]), - :ltriangle => BezierPath([Makie.MoveTo([-0.485, 2.969768487932331e-17]), - Makie.LineTo([0.2425, -0.36375]), - Makie.LineTo([0.24250000000000005, 0.36375]), - Makie.ClosePath()]), - :dtriangle => BezierPath([Makie.MoveTo([-0.0, -0.485]), - Makie.LineTo([0.36375, 0.24250000000000002]), - Makie.LineTo([-0.36375, 0.24250000000000002]), - Makie.ClosePath()]), - :utriangle => BezierPath([Makie.MoveTo([0.0, 0.485]), - Makie.LineTo([-0.36375, -0.24250000000000002]), - Makie.LineTo([0.36375, -0.24250000000000002]), - Makie.ClosePath()]), - :star5 => BezierPath([Makie.MoveTo([2.7554554183166277e-17, - 0.44999999999999996]), - Makie.LineTo([-0.12343490123748782, - 0.16989357054233553]), - Makie.LineTo([-0.4279754430055618, 0.13905765116214752]), - Makie.LineTo([-0.19972187340259556, - -0.06489357054233552]), - Makie.LineTo([-0.2645033597946167, -0.3640576511621475]), - Makie.LineTo([-3.8576373077105933e-17, - -0.21000000000000002]), - Makie.LineTo([0.2645033597946167, -0.3640576511621475]), - Makie.LineTo([0.19972187340259556, - -0.06489357054233552]), - Makie.LineTo([0.4279754430055618, 0.13905765116214752]), - Makie.LineTo([0.12343490123748782, 0.16989357054233553]), - Makie.ClosePath()]), - :octagon => BezierPath([Makie.MoveTo([2.2962128485971897e-17, 0.375]), - Makie.LineTo([-0.2651650384068489, - 0.2651650384068489]), - Makie.LineTo([-0.375, 4.5924256971943795e-17]), - Makie.LineTo([-0.2651650384068489, - -0.2651650384068489]), - Makie.LineTo([-6.888638049483202e-17, -0.375]), - Makie.LineTo([0.2651650384068489, - -0.2651650384068489]), - Makie.LineTo([0.375, -9.184851394388759e-17]), - Makie.LineTo([0.2651650384068489, 0.2651650384068489]), - Makie.ClosePath()]), - :hline => BezierPath([Makie.MoveTo([0.315718342192545, -0.063143668438509]), - Makie.LineTo([0.315718342192545, 0.063143668438509]), - Makie.LineTo([-0.315718342192545, 0.063143668438509]), - Makie.LineTo([-0.315718342192545, -0.063143668438509]), - Makie.ClosePath()]), - :hexagon => BezierPath([Makie.MoveTo([2.2962128485971897e-17, 0.375]), - Makie.LineTo([-0.32475952059030533, 0.1875]), - Makie.LineTo([-0.32475952059030533, -0.1875]), - Makie.LineTo([-6.888638049483202e-17, -0.375]), - Makie.LineTo([0.32475952059030533, -0.1875]), - Makie.LineTo([0.32475952059030533, 0.1875]), - Makie.ClosePath()])) +const DEFAULT_MARKER_MAP = Dict( + :+ => BezierPath( + [ + Makie.MoveTo([0.1245, 0.375]), + Makie.LineTo([0.1245, 0.1245]), + Makie.LineTo([0.375, 0.1245]), + Makie.LineTo([0.375, -0.12449999999999999]), + Makie.LineTo([0.1245, -0.1245]), + Makie.LineTo([0.12450000000000003, -0.375]), + Makie.LineTo([-0.12449999999999997, -0.375]), + Makie.LineTo([-0.12449999999999999, -0.12450000000000003]), + Makie.LineTo([-0.375, -0.12450000000000006]), + Makie.LineTo([-0.375, 0.12449999999999994]), + Makie.LineTo([-0.12450000000000003, 0.12449999999999999]), + Makie.LineTo([-0.12450000000000007, 0.37499999999999994]), + Makie.ClosePath(), + ] + ), + :diamond => BezierPath( + [ + Makie.MoveTo( + [ + 0.4464931614186469, + -5.564531862779532e-17, + ] + ), + Makie.LineTo( + [ + 2.10398220755128e-17, + 0.4464931614186469, + ] + ), + Makie.LineTo( + [ + -0.4464931614186469, + 5.564531862779532e-17, + ] + ), + Makie.LineTo( + [ + -2.10398220755128e-17, + -0.4464931614186469, + ] + ), + Makie.ClosePath(), + ] + ), + :star4 => BezierPath( + [ + Makie.MoveTo( + [ + 2.7554554183166277e-17, + 0.44999999999999996, + ] + ), + Makie.LineTo( + [ + -0.13258251920342445, + 0.13258251920342445, + ] + ), + Makie.LineTo( + [ + -0.44999999999999996, + 5.5109108366332553e-17, + ] + ), + Makie.LineTo( + [ + -0.13258251920342445, + -0.13258251920342445, + ] + ), + Makie.LineTo( + [ + -8.266365659379842e-17, + -0.44999999999999996, + ] + ), + Makie.LineTo( + [ + 0.13258251920342445, + -0.13258251920342445, + ] + ), + Makie.LineTo( + [ + 0.44999999999999996, + -1.1021821673266511e-16, + ] + ), + Makie.LineTo([0.13258251920342445, 0.13258251920342445]), + Makie.ClosePath(), + ] + ), + :star8 => BezierPath( + [ + Makie.MoveTo( + [ + 2.7554554183166277e-17, + 0.44999999999999996, + ] + ), + Makie.LineTo([-0.09471414797008038, 0.2286601772904396]), + Makie.LineTo( + [ + -0.31819804608821867, + 0.31819804608821867, + ] + ), + Makie.LineTo([-0.2286601772904396, 0.09471414797008038]), + Makie.LineTo( + [ + -0.44999999999999996, + 5.5109108366332553e-17, + ] + ), + Makie.LineTo( + [ + -0.2286601772904396, + -0.09471414797008038, + ] + ), + Makie.LineTo( + [ + -0.31819804608821867, + -0.31819804608821867, + ] + ), + Makie.LineTo( + [ + -0.09471414797008038, + -0.2286601772904396, + ] + ), + Makie.LineTo( + [ + -8.266365659379842e-17, + -0.44999999999999996, + ] + ), + Makie.LineTo([0.09471414797008038, -0.2286601772904396]), + Makie.LineTo( + [ + 0.31819804608821867, + -0.31819804608821867, + ] + ), + Makie.LineTo([0.2286601772904396, -0.09471414797008038]), + Makie.LineTo( + [ + 0.44999999999999996, + -1.1021821673266511e-16, + ] + ), + Makie.LineTo([0.2286601772904396, 0.09471414797008038]), + Makie.LineTo([0.31819804608821867, 0.31819804608821867]), + Makie.LineTo([0.09471414797008038, 0.2286601772904396]), + Makie.ClosePath(), + ] + ), + :star6 => BezierPath( + [ + Makie.MoveTo( + [ + 2.7554554183166277e-17, + 0.44999999999999996, + ] + ), + Makie.LineTo([-0.11249999999999999, 0.1948557123541832]), + Makie.LineTo([-0.3897114247083664, 0.22499999999999998]), + Makie.LineTo( + [ + -0.22499999999999998, + 2.7554554183166277e-17, + ] + ), + Makie.LineTo( + [ + -0.3897114247083664, + -0.22499999999999998, + ] + ), + Makie.LineTo( + [ + -0.11249999999999999, + -0.1948557123541832, + ] + ), + Makie.LineTo( + [ + -8.266365659379842e-17, + -0.44999999999999996, + ] + ), + Makie.LineTo([0.11249999999999999, -0.1948557123541832]), + Makie.LineTo([0.3897114247083664, -0.22499999999999998]), + Makie.LineTo( + [ + 0.22499999999999998, + -5.5109108366332553e-17, + ] + ), + Makie.LineTo([0.3897114247083664, 0.22499999999999998]), + Makie.LineTo([0.11249999999999999, 0.1948557123541832]), + Makie.ClosePath(), + ] + ), + :rtriangle => BezierPath( + [ + Makie.MoveTo([0.485, -8.909305463796994e-17]), + Makie.LineTo([-0.24249999999999994, 0.36375]), + Makie.LineTo( + [ + -0.2425000000000001, + -0.36374999999999996, + ] + ), + Makie.ClosePath(), + ] + ), + :x => BezierPath( + [ + Makie.MoveTo([-0.1771302486872301, 0.35319983720268056]), + Makie.LineTo([1.39759596452057e-17, 0.17606958851545035]), + Makie.LineTo([0.17713024868723018, 0.3531998372026805]), + Makie.LineTo([0.3531998372026805, 0.17713024868723012]), + Makie.LineTo([0.17606958851545035, -1.025465786723834e-17]), + Makie.LineTo([0.3531998372026805, -0.17713024868723015]), + Makie.LineTo([0.17713024868723015, -0.3531998372026805]), + Makie.LineTo([1.1151998010815531e-17, -0.17606958851545035]), + Makie.LineTo([-0.17713024868723015, -0.3531998372026805]), + Makie.LineTo([-0.35319983720268044, -0.17713024868723018]), + Makie.LineTo( + [ + -0.17606958851545035, + -1.4873299788782892e-17, + ] + ), + Makie.LineTo([-0.3531998372026805, 0.1771302486872301]), + Makie.ClosePath(), + ] + ), + :circle => BezierPath( + [ + Makie.MoveTo([0.3525, 0.0]), + EllipticalArc( + [0.0, 0.0], 0.3525, 0.3525, 0.0, 0.0, + 6.283185307179586 + ), Makie.ClosePath(), + ] + ), + :pentagon => BezierPath( + [ + Makie.MoveTo([2.2962128485971897e-17, 0.375]), + Makie.LineTo( + [ + -0.35664620250463486, + 0.11588137596845627, + ] + ), + Makie.LineTo( + [ + -0.22041946649551392, + -0.30338137596845627, + ] + ), + Makie.LineTo( + [ + 0.22041946649551392, + -0.30338137596845627, + ] + ), + Makie.LineTo( + [ + 0.35664620250463486, + 0.11588137596845627, + ] + ), + Makie.ClosePath(), + ] + ), + :vline => BezierPath( + [ + Makie.MoveTo([0.063143668438509, -0.315718342192545]), + Makie.LineTo([0.063143668438509, 0.315718342192545]), + Makie.LineTo([-0.063143668438509, 0.315718342192545]), + Makie.LineTo([-0.063143668438509, -0.315718342192545]), + Makie.ClosePath(), + ] + ), + :cross => BezierPath( + [ + Makie.MoveTo([0.1245, 0.375]), + Makie.LineTo([0.1245, 0.1245]), + Makie.LineTo([0.375, 0.1245]), + Makie.LineTo([0.375, -0.12449999999999999]), + Makie.LineTo([0.1245, -0.1245]), + Makie.LineTo([0.12450000000000003, -0.375]), + Makie.LineTo([-0.12449999999999997, -0.375]), + Makie.LineTo( + [ + -0.12449999999999999, + -0.12450000000000003, + ] + ), + Makie.LineTo([-0.375, -0.12450000000000006]), + Makie.LineTo([-0.375, 0.12449999999999994]), + Makie.LineTo( + [ + -0.12450000000000003, + 0.12449999999999999, + ] + ), + Makie.LineTo( + [ + -0.12450000000000007, + 0.37499999999999994, + ] + ), + Makie.ClosePath(), + ] + ), + :xcross => BezierPath( + [ + Makie.MoveTo( + [ + -0.1771302486872301, + 0.35319983720268056, + ] + ), + Makie.LineTo( + [ + 1.39759596452057e-17, + 0.17606958851545035, + ] + ), + Makie.LineTo([0.17713024868723018, 0.3531998372026805]), + Makie.LineTo([0.3531998372026805, 0.17713024868723012]), + Makie.LineTo( + [ + 0.17606958851545035, + -1.025465786723834e-17, + ] + ), + Makie.LineTo( + [ + 0.3531998372026805, + -0.17713024868723015, + ] + ), + Makie.LineTo( + [ + 0.17713024868723015, + -0.3531998372026805, + ] + ), + Makie.LineTo( + [ + 1.1151998010815531e-17, + -0.17606958851545035, + ] + ), + Makie.LineTo( + [ + -0.17713024868723015, + -0.3531998372026805, + ] + ), + Makie.LineTo( + [ + -0.35319983720268044, + -0.17713024868723018, + ] + ), + Makie.LineTo( + [ + -0.17606958851545035, + -1.4873299788782892e-17, + ] + ), + Makie.LineTo([-0.3531998372026805, 0.1771302486872301]), + Makie.ClosePath(), + ] + ), + :rect => BezierPath( + [ + Makie.MoveTo([0.315718342192545, -0.315718342192545]), + Makie.LineTo([0.315718342192545, 0.315718342192545]), + Makie.LineTo([-0.315718342192545, 0.315718342192545]), + Makie.LineTo([-0.315718342192545, -0.315718342192545]), + Makie.ClosePath(), + ] + ), + :ltriangle => BezierPath( + [ + Makie.MoveTo([-0.485, 2.969768487932331e-17]), + Makie.LineTo([0.2425, -0.36375]), + Makie.LineTo([0.24250000000000005, 0.36375]), + Makie.ClosePath(), + ] + ), + :dtriangle => BezierPath( + [ + Makie.MoveTo([-0.0, -0.485]), + Makie.LineTo([0.36375, 0.24250000000000002]), + Makie.LineTo([-0.36375, 0.24250000000000002]), + Makie.ClosePath(), + ] + ), + :utriangle => BezierPath( + [ + Makie.MoveTo([0.0, 0.485]), + Makie.LineTo([-0.36375, -0.24250000000000002]), + Makie.LineTo([0.36375, -0.24250000000000002]), + Makie.ClosePath(), + ] + ), + :star5 => BezierPath( + [ + Makie.MoveTo( + [ + 2.7554554183166277e-17, + 0.44999999999999996, + ] + ), + Makie.LineTo( + [ + -0.12343490123748782, + 0.16989357054233553, + ] + ), + Makie.LineTo([-0.4279754430055618, 0.13905765116214752]), + Makie.LineTo( + [ + -0.19972187340259556, + -0.06489357054233552, + ] + ), + Makie.LineTo([-0.2645033597946167, -0.3640576511621475]), + Makie.LineTo( + [ + -3.8576373077105933e-17, + -0.21000000000000002, + ] + ), + Makie.LineTo([0.2645033597946167, -0.3640576511621475]), + Makie.LineTo( + [ + 0.19972187340259556, + -0.06489357054233552, + ] + ), + Makie.LineTo([0.4279754430055618, 0.13905765116214752]), + Makie.LineTo([0.12343490123748782, 0.16989357054233553]), + Makie.ClosePath(), + ] + ), + :octagon => BezierPath( + [ + Makie.MoveTo([2.2962128485971897e-17, 0.375]), + Makie.LineTo( + [ + -0.2651650384068489, + 0.2651650384068489, + ] + ), + Makie.LineTo([-0.375, 4.5924256971943795e-17]), + Makie.LineTo( + [ + -0.2651650384068489, + -0.2651650384068489, + ] + ), + Makie.LineTo([-6.888638049483202e-17, -0.375]), + Makie.LineTo( + [ + 0.2651650384068489, + -0.2651650384068489, + ] + ), + Makie.LineTo([0.375, -9.184851394388759e-17]), + Makie.LineTo([0.2651650384068489, 0.2651650384068489]), + Makie.ClosePath(), + ] + ), + :hline => BezierPath( + [ + Makie.MoveTo([0.315718342192545, -0.063143668438509]), + Makie.LineTo([0.315718342192545, 0.063143668438509]), + Makie.LineTo([-0.315718342192545, 0.063143668438509]), + Makie.LineTo([-0.315718342192545, -0.063143668438509]), + Makie.ClosePath(), + ] + ), + :hexagon => BezierPath( + [ + Makie.MoveTo([2.2962128485971897e-17, 0.375]), + Makie.LineTo([-0.32475952059030533, 0.1875]), + Makie.LineTo([-0.32475952059030533, -0.1875]), + Makie.LineTo([-6.888638049483202e-17, -0.375]), + Makie.LineTo([0.32475952059030533, -0.1875]), + Makie.LineTo([0.32475952059030533, 0.1875]), + Makie.ClosePath(), + ] + ) +) function default_marker_map() return DEFAULT_MARKER_MAP @@ -1859,6 +2169,7 @@ function available_marker_symbols() for (k, v) in default_marker_map() println(" :", k) end + return end """ @@ -1886,8 +2197,8 @@ to_spritemarker(marker::AbstractVector) = map(to_spritemarker, marker) to_spritemarker(marker::AbstractVector{Char}) = marker # Don't dispatch to the above! to_spritemarker(x::FastPixel) = x to_spritemarker(x::Circle) = x -to_spritemarker(::Type{<: Circle}) = Circle -to_spritemarker(::Type{<: Rect}) = Rect +to_spritemarker(::Type{<:Circle}) = Circle +to_spritemarker(::Type{<:Rect}) = Rect to_spritemarker(x::Rect) = x to_spritemarker(b::BezierPath) = b to_spritemarker(b::Polygon) = BezierPath(b) @@ -1908,12 +2219,12 @@ to_spritemarker(marker::Char) = marker """ Matrix of AbstractFloat will be interpreted as a distancefield (negative numbers outside shape, positive inside) """ -to_spritemarker(marker::Matrix{<: AbstractFloat}) = el32convert(marker) +to_spritemarker(marker::Matrix{<:AbstractFloat}) = el32convert(marker) """ Any AbstractMatrix{<: Colorant} or other image type """ -to_spritemarker(marker::AbstractMatrix{<: Colorant}) = marker +to_spritemarker(marker::AbstractMatrix{<:Colorant}) = marker """ A `Symbol` - Available options can be printed with `available_marker_symbols()` @@ -1928,16 +2239,14 @@ function to_spritemarker(marker::Symbol) end - - convert_attribute(value, ::key"marker", ::key"scatter") = to_spritemarker(value) convert_attribute(value, ::key"isovalue", ::key"volume") = Float32(value) convert_attribute(value, ::key"isorange", ::key"volume") = Float32(value) -convert_attribute(value, ::key"gap", ::key"voxels") = ifelse(value <= 0.01, 0f0, Float32(value)) +convert_attribute(value, ::key"gap", ::key"voxels") = ifelse(value <= 0.01, 0.0f0, Float32(value)) function convert_attribute(value::Symbol, ::key"marker", ::key"meshscatter") if value === :Sphere - return normal_mesh(Sphere(Point3f(0), 1f0)) + return normal_mesh(Sphere(Point3f(0), 1.0f0)) else error("Unsupported marker: $(value)") end @@ -1956,22 +2265,26 @@ convert_attribute(value, ::key"backlight") = Float32(value) # SAMPLER overloads convert_attribute(s::ShaderAbstractions.Sampler{RGBAf}, k::key"color") = s -function convert_attribute(s::ShaderAbstractions.Sampler{T,N}, k::key"color") where {T,N} - return ShaderAbstractions.Sampler(el32convert(s.data); minfilter=s.minfilter, magfilter=s.magfilter, - x_repeat=s.repeat[1], y_repeat=s.repeat[min(2, N)], - z_repeat=s.repeat[min(3, N)], - anisotropic=s.anisotropic, color_swizzel=s.color_swizzel) +function convert_attribute(s::ShaderAbstractions.Sampler{T, N}, k::key"color") where {T, N} + return ShaderAbstractions.Sampler( + el32convert(s.data); minfilter = s.minfilter, magfilter = s.magfilter, + x_repeat = s.repeat[1], y_repeat = s.repeat[min(2, N)], + z_repeat = s.repeat[min(3, N)], + anisotropic = s.anisotropic, color_swizzel = s.color_swizzel + ) end -function el32convert(x::ShaderAbstractions.Sampler{T,N}) where {T,N} +function el32convert(x::ShaderAbstractions.Sampler{T, N}) where {T, N} T32 = float32type(T) T32 === T && return x data = el32convert(x.data) - return ShaderAbstractions.Sampler{T32,N,typeof(data)}(data, x.minfilter, x.magfilter, - x.repeat, - x.anisotropic, - x.color_swizzel, - ShaderAbstractions.ArrayUpdater(data, x.updates.update)) + return ShaderAbstractions.Sampler{T32, N, typeof(data)}( + data, x.minfilter, x.magfilter, + x.repeat, + x.anisotropic, + x.color_swizzel, + ShaderAbstractions.ArrayUpdater(data, x.updates.update) + ) end to_color(sampler::ShaderAbstractions.Sampler) = el32convert(sampler) @@ -1985,4 +2298,4 @@ GeometryBasics.collect_with_eltype(::Type{T}, vec::ShaderAbstractions.Buffer{T}) # Used in Label, maybe useful elsewhere? to_lrbt_padding(x::Real) = Vec4f(x) to_lrbt_padding(xy::VecTypes{2}) = Vec4f(xy[1], xy[1], xy[2], xy[2]) -to_lrbt_padding(pad::VecTypes{4}) = to_ndim(Vec4f, pad, 0) \ No newline at end of file +to_lrbt_padding(pad::VecTypes{4}) = to_ndim(Vec4f, pad, 0) diff --git a/src/deprecated.jl b/src/deprecated.jl index e03088ea41e..e5d61064c53 100644 --- a/src/deprecated.jl +++ b/src/deprecated.jl @@ -3,13 +3,13 @@ ## function DiscreteSurface(args...; kwargs...) - @warn "Makie.DiscreteSurface() is deprecated, use Makie.CellGrid() instead" maxlog=1 - CellGrid(args...; kwargs...) + @warn "Makie.DiscreteSurface() is deprecated, use Makie.CellGrid() instead" maxlog = 1 + return CellGrid(args...; kwargs...) end function ContinuousSurface(args...; kwargs...) - @warn "Makie.ContinuousSurface() is deprecated, use Makie.VertexGrid() instead" maxlog=1 - VertexGrid(args...; kwargs...) + @warn "Makie.ContinuousSurface() is deprecated, use Makie.VertexGrid() instead" maxlog = 1 + return VertexGrid(args...; kwargs...) end function Base.getproperty(scene::Scene, field::Symbol) @@ -23,6 +23,6 @@ end @deprecate pixelarea viewport true function Combined(args...; kwargs...) - @warn "Makie.Combined() is deprecated, use Makie.Plot() instead" maxlog=1 - Plot(args...; kwargs...) + @warn "Makie.Combined() is deprecated, use Makie.Plot() instead" maxlog = 1 + return Plot(args...; kwargs...) end diff --git a/src/dim-converts/categorical-integration.jl b/src/dim-converts/categorical-integration.jl index 8d9d7936e74..b31e4275f67 100644 --- a/src/dim-converts/categorical-integration.jl +++ b/src/dim-converts/categorical-integration.jl @@ -29,23 +29,25 @@ struct CategoricalConversion <: AbstractDimConversion # I've run into problems with OrderedCollections.jl # Which seems to be the only ordered set/dict implementation # It's another dependency as well, so right now we just use vectors - sets::Vector{Pair{String,Vector{Any}}} - category_to_int::Observable{Dict{Any,Int}} - int_to_category::Vector{Pair{Int,Any}} - sortby::Union{Nothing,Function} + sets::Vector{Pair{String, Vector{Any}}} + category_to_int::Observable{Dict{Any, Int}} + int_to_category::Vector{Pair{Int, Any}} + sortby::Union{Nothing, Function} end -function CategoricalConversion(; sortby=nothing) - return CategoricalConversion(Pair{String,Vector{Any}}[], - Observable(Dict{Any,Int}(); ignore_equal_values=true), - Pair{Int,Any}[], - sortby) +function CategoricalConversion(; sortby = nothing) + return CategoricalConversion( + Pair{String, Vector{Any}}[], + Observable(Dict{Any, Int}(); ignore_equal_values = true), + Pair{Int, Any}[], + sortby + ) end expand_dimensions(::PointBased, y::Categorical) = (keys(y.values), y) needs_tick_update_observable(conversion::CategoricalConversion) = conversion.category_to_int MakieCore.should_dim_convert(::Type{Categorical}) = true -create_dim_conversion(::Type{Categorical}) = CategoricalConversion(; sortby=identity) +create_dim_conversion(::Type{Categorical}) = CategoricalConversion(; sortby = identity) function recalculate_categories!(conversion::CategoricalConversion) all_categories = [] @@ -54,7 +56,7 @@ function recalculate_categories!(conversion::CategoricalConversion) end unique!(all_categories) if !isnothing(conversion.sortby) - sort!(all_categories; by=conversion.sortby) + sort!(all_categories; by = conversion.sortby) end empty!(conversion.category_to_int[]) empty!(conversion.int_to_category) @@ -85,7 +87,7 @@ end function dict_setindex!(dict, key, value) idx = findfirst(x -> x[1] == key, dict) - if isnothing(idx) + return if isnothing(idx) push!(dict, key => value) else dict[idx] = key => value @@ -121,7 +123,7 @@ function convert_dim_observable(conversion::CategoricalConversion, values_obs::O # so we introduce a placeholder observable that gets triggered when an update is needed # outside of category_to_int updating update_needed = Observable(nothing) - f = on(values_obs; update=true) do values + f = on(values_obs; update = true) do values new_values = unique!(Any[get_values(values)...]) if new_values != prev_values dict_setindex!(conversion.sets, values_obs.id, new_values) diff --git a/src/dim-converts/dates-integration.jl b/src/dim-converts/dates-integration.jl index b8d51646481..1152dc3b404 100644 --- a/src/dim-converts/dates-integration.jl +++ b/src/dim-converts/dates-integration.jl @@ -48,8 +48,8 @@ struct DateTimeConversion <: AbstractDimConversion # Second entry in tuple is a value we use to normalize the number range, # so that they fit into float32 type::Observable{DataType} - function DateTimeConversion(type=Automatic) - obs = Observable{DataType}(type; ignore_equal_values=true) + function DateTimeConversion(type = Automatic) + obs = Observable{DataType}(type; ignore_equal_values = true) return new(obs) end end @@ -104,7 +104,7 @@ function get_ticks(conversion::DateTimeConversion, ticks, scale, formatter, vmin k_min = 2 k_max = 3 end - conversion, dates = PlotUtils.optimize_datetime_ticks(vmin, vmax; k_min=k_min, k_max=k_max) + conversion, dates = PlotUtils.optimize_datetime_ticks(vmin, vmax; k_min = k_min, k_max = k_max) return conversion, dates else # TODO implement proper ticks for Time Date diff --git a/src/dim-converts/dim-converts.jl b/src/dim-converts/dim-converts.jl index bedb297883d..91935507083 100644 --- a/src/dim-converts/dim-converts.jl +++ b/src/dim-converts/dim-converts.jl @@ -3,10 +3,10 @@ abstract type AbstractDimConversion end struct NoDimConversion <: AbstractDimConversion end struct DimConversions - conversions::NTuple{3,Observable{Union{Nothing,AbstractDimConversion}}} + conversions::NTuple{3, Observable{Union{Nothing, AbstractDimConversion}}} function DimConversions() conversions = map((1, 2, 3)) do i - Observable{Union{Nothing,AbstractDimConversion}}(nothing) + Observable{Union{Nothing, AbstractDimConversion}}(nothing) end return new(conversions) end @@ -19,7 +19,7 @@ function Base.getindex(conversions::DimConversions, i::Int) end function Base.setindex!(conversions::DimConversions, value::Observable, i::Int) - on(value; update=true) do val + return on(value; update = true) do val conversions[i] = val end end @@ -66,7 +66,7 @@ end # get_ticks needs overloading for Dim Conversion # Which gets ignored for no conversion/nothing -function get_ticks(::Union{Nothing,NoDimConversion}, ticks, scale, formatter, vmin, vmax) +function get_ticks(::Union{Nothing, NoDimConversion}, ticks, scale, formatter, vmin, vmax) return get_ticks(ticks, scale, formatter, vmin, vmax) end @@ -132,12 +132,14 @@ function connect_conversions!(new_conversions::DimConversions, ax::AbstractAxis) end end end + return end function connect_conversions!(conversions::DimConversions, new_conversions::DimConversions) for i in 1:3 conversions[i] = new_conversions.conversions[i] end + return end # If axis conversion has global state which needs an update of the tick values, @@ -194,7 +196,7 @@ end function convert_dim_observable(conversions::DimConversions, dim::Int, value::Observable, deregister) conversion = conversions[dim] - if !(conversion isa Union{Nothing,NoDimConversion}) + if !(conversion isa Union{Nothing, NoDimConversion}) return convert_dim_observable(conversion, value, deregister) end c = dim_conversion_from_args(value[]) diff --git a/src/dim-converts/unitful-integration.jl b/src/dim-converts/unitful-integration.jl index 89ac5627520..9d77ac3350d 100644 --- a/src/dim-converts/unitful-integration.jl +++ b/src/dim-converts/unitful-integration.jl @@ -2,7 +2,7 @@ using Dates, Observables import Unitful using Unitful: Quantity, @u_str, uconvert, ustrip -const SupportedUnits = Union{Period,Unitful.Quantity,Unitful.Units} +const SupportedUnits = Union{Period, Unitful.Quantity, Unitful.Units} expand_dimensions(::PointBased, y::AbstractVector{<:SupportedUnits}) = (keys(y), y) create_dim_conversion(::Type{<:SupportedUnits}) = UnitfulConversion() @@ -18,8 +18,8 @@ base_unit(::Unitful.FreeUnits{U, DimT, nothing}) where {DimT, U} = U[1] base_unit(x::Unitful.Unit) = x base_unit(x::Period) = base_unit(Quantity(x)) -unit_string(::Type{T}) where T <: Unitful.AbstractQuantity = string(Unitful.unit(T)) -unit_string(unit::Type{<: Unitful.FreeUnits}) = string(unit()) +unit_string(::Type{T}) where {T <: Unitful.AbstractQuantity} = string(Unitful.unit(T)) +unit_string(unit::Type{<:Unitful.FreeUnits}) = string(unit()) unit_string(unit::Unitful.FreeUnits) = string(unit) unit_string(unit::Unitful.Unit) = string(unit) unit_string(::Union{Number, Nothing}) = "" @@ -30,7 +30,7 @@ unit_string_long(::Unitful.Unit{Sym, D}) where {Sym, D} = string(Sym) is_compound_unit(x::Period) = is_compound_unit(Quantity(x)) is_compound_unit(::Quantity{T, D, U}) where {T, D, U} = is_compound_unit(U) is_compound_unit(::Unitful.FreeUnits{U}) where {U} = length(U) != 1 -is_compound_unit(::Type{<: Unitful.FreeUnits{U}}) where {U} = length(U) != 1 +is_compound_unit(::Type{<:Unitful.FreeUnits{U}}) where {U} = length(U) != 1 function eltype_extrema(values) isempty(values) && return (eltype(values), nothing) @@ -105,12 +105,12 @@ end unit_convert(::Automatic, x) = x -function unit_convert(unit::T, x::AbstractArray) where T <: Union{Type{<:Unitful.AbstractQuantity}, Unitful.FreeUnits, Unitful.Unit} +function unit_convert(unit::T, x::AbstractArray) where {T <: Union{Type{<:Unitful.AbstractQuantity}, Unitful.FreeUnits, Unitful.Unit}} return unit_convert.(Ref(unit), x) end # We always convert to preferred unit! -function unit_convert(unit::T, value) where T <: Union{Type{<:Unitful.AbstractQuantity}, Unitful.FreeUnits, Unitful.Unit} +function unit_convert(unit::T, value) where {T <: Union{Type{<:Unitful.AbstractQuantity}, Unitful.FreeUnits, Unitful.Unit}} conv = uconvert(to_free_unit(unit, value), value) return Float64(ustrip(conv)) end @@ -150,8 +150,8 @@ struct UnitfulConversion <: AbstractDimConversion extrema::Dict{String, Tuple{Any, Any}} end -function UnitfulConversion(unit=automatic; units_in_label=true) - extrema = Dict{String,Tuple{Any,Any}}() +function UnitfulConversion(unit = automatic; units_in_label = true) + extrema = Dict{String, Tuple{Any, Any}}() return UnitfulConversion(unit, unit isa Automatic, units_in_label, extrema) end @@ -176,7 +176,7 @@ function update_extrema!(conversion::UnitfulConversion, value_obs::Observable) else new_unit = best_unit(imini, imaxi) end - if new_unit != conversion.unit[] + return if new_unit != conversion.unit[] conversion.unit[] = new_unit end end @@ -210,7 +210,7 @@ function get_ticks(conversion::UnitfulConversion, ticks, scale, formatter, vmin, end function convert_dim_observable(conversion::UnitfulConversion, value_obs::Observable, deregister) - result = map(conversion.unit, value_obs; ignore_equal_values=true) do unit, values + result = map(conversion.unit, value_obs; ignore_equal_values = true) do unit, values if !isempty(values) # try if conversion works, to through error if not! # Is there a function for this to check in Unitful? diff --git a/src/display.jl b/src/display.jl index 336c6028922..995045f3681 100644 --- a/src/display.jl +++ b/src/display.jl @@ -25,7 +25,7 @@ end Adds a screen to the scene and registered a clean up event when screen closes. Also, makes sure that always just one screen is active for on scene. """ -function push_screen!(scene::Scene, screen::T) where {T<:MakieScreen} +function push_screen!(scene::Scene, screen::T) where {T <: MakieScreen} if !(screen in scene.current_screens) # If screen isn't already part of this scene, we make sure # that the screen only has one screen per type @@ -49,7 +49,7 @@ Removes screen from scene and cleans up screen function delete_screen!(scene::Scene, screen::MakieScreen) delete!(screen, scene) empty!(screen) - filter!(x-> x !== screen, scene.current_screens) + filter!(x -> x !== screen, scene.current_screens) return end @@ -66,7 +66,7 @@ function set_screen_config!(backend::Module, new_values) return backend_defaults end -function merge_screen_config(::Type{Config}, config::Dict) where Config +function merge_screen_config(::Type{Config}, config::Dict) where {Config} backend = parentmodule(Config) key = nameof(backend) backend_defaults = CURRENT_DEFAULT_THEME[key] @@ -92,8 +92,8 @@ Only case Makie always shows the plot inside the plotpane is when using VSCode e If you want to always force inlining the plot into the plotpane, set `inline!(true)` (E.g. when run in the VSCode REPL). In other cases `inline!(true/false)` won't do anything. """ -function inline!(inline=automatic) - ALWAYS_INLINE_PLOTS[] = inline +function inline!(inline = automatic) + return ALWAYS_INLINE_PLOTS[] = inline end wait_for_display(screen) = nothing @@ -127,17 +127,21 @@ see `?Backend.Screen` or `Base.doc(Backend.Screen)` for applicable options. `backend` accepts Makie backend modules, e.g.: `backend = GLMakie`, `backend = CairoMakie`, etc. """ -function Base.display(figlike::FigureLike; backend=current_backend(), - inline=ALWAYS_INLINE_PLOTS[], update = true, screen_config...) +function Base.display( + figlike::FigureLike; backend = current_backend(), + inline = ALWAYS_INLINE_PLOTS[], update = true, screen_config... + ) config = Dict{Symbol, Any}(screen_config) if ismissing(backend) - error(""" - No backend available! - Make sure to also `import/using` a backend (GLMakie, CairoMakie, WGLMakie). + error( + """ + No backend available! + Make sure to also `import/using` a backend (GLMakie, CairoMakie, WGLMakie). - If you imported GLMakie, it may have not built correctly. - In that case, try `]build GLMakie` and watch out for any warnings. - """) + If you imported GLMakie, it may have not built correctly. + In that case, try `]build GLMakie` and watch out for any warnings. + """ + ) end # We show inline if explicitly requested or if automatic and we can actually show something inline! @@ -174,7 +178,7 @@ is_displayed(screen::MakieScreen, scene::Scene) = screen in scene.current_screen # Backends overload display(::Backend.Screen, scene::Scene), while Makie overloads the below, # so that they don't need to worry # about stuff like `update_state_before_display!` -function Base.display(screen::MakieScreen, figlike::FigureLike; update=true, display_attributes...) +function Base.display(screen::MakieScreen, figlike::FigureLike; update = true, display_attributes...) scene = get_scene(figlike) update && update_state_before_display!(figlike) display(screen, get_scene(figlike); display_attributes...) @@ -193,7 +197,7 @@ end # VScode doesn't catch that method error. const MIME_TO_TRICK_VSCODE = MIME"application/vnd.julia-vscode.diagnostics" -function _backend_showable(mime::MIME{SYM}) where SYM +function _backend_showable(mime::MIME{SYM}) where {SYM} if ALWAYS_INLINE_PLOTS[] == false if mime isa MIME_TO_TRICK_VSCODE return true @@ -215,7 +219,8 @@ const WEB_MIMES = ( MIME"text/html", MIME"application/vnd.webio.application+html", MIME"application/prs.juno.plotpane+html", - MIME"juliavscode/html") + MIME"juliavscode/html", +) backend_showable(@nospecialize(screen), @nospecialize(mime)) = false @@ -234,7 +239,7 @@ function backend_show(backend, io::IO, ::MIME"text/plain", scene::Scene) end function Base.show(io::IO, ::MIME"text/plain", scene::Scene) - show(io, scene) + return show(io, scene) end # VSCode per default displays an object as markdown as well. @@ -244,7 +249,7 @@ function Base.show(io::IO, m::MIME"text/markdown", fig::FigureLike) throw(MethodError(show, io, m, fig)) end -function Base.show(io::IO, m::MIME, figlike::FigureLike; backend = current_backend(), update=true) +function Base.show(io::IO, m::MIME, figlike::FigureLike; backend = current_backend(), update = true) if ALWAYS_INLINE_PLOTS[] == false && m isa MIME_TO_TRICK_VSCODE # We use this mime to display the figure in a window here. # See declaration of MIME_TO_TRICK_VSCODE for more info @@ -254,7 +259,7 @@ function Base.show(io::IO, m::MIME, figlike::FigureLike; backend = current_backe scene = get_scene(figlike) # get current screen the scene is already displayed on, or create a new screen update && update_state_before_display!(figlike) - screen = getscreen(backend, scene, Dict(:visible=>false), io, m) + screen = getscreen(backend, scene, Dict(:visible => false), io, m) backend_show(screen, io, m, scene) return screen end @@ -269,7 +274,7 @@ format2mime(::Type{FileIO.format"TEX"}) = MIME("application/x-tex") format2mime(::Type{FileIO.format"EPS"}) = MIME("application/postscript") format2mime(::Type{FileIO.format"HTML"}) = MIME("text/html") -filetype(::FileIO.File{F}) where F = F +filetype(::FileIO.File{F}) where {F} = F # Allow format to be overridden with first argument """ @@ -301,7 +306,7 @@ Save a `Scene` with the specified filename and format. function FileIO.save( filename::String, fig::FigureLike; args... ) - FileIO.save(FileIO.query(filename), fig; args...) + return FileIO.save(FileIO.query(filename), fig; args...) end function FileIO.save( @@ -313,13 +318,15 @@ function FileIO.save( screen_config... ) if ismissing(backend) - error(""" - No backend available! - Make sure to also `import/using` a backend (GLMakie, CairoMakie, WGLMakie). + error( + """ + No backend available! + Make sure to also `import/using` a backend (GLMakie, CairoMakie, WGLMakie). - If you imported GLMakie, it may have not built correctly. - In that case, try `]build GLMakie` and watch out for any warnings. - """) + If you imported GLMakie, it may have not built correctly. + In that case, try `]build GLMakie` and watch out for any warnings. + """ + ) end scene = get_scene(fig) if resolution !== nothing @@ -354,7 +361,7 @@ function FileIO.save( end catch e # So, if open(io-> error(...), "w"), the file will get created, but not removed... - isfile(filename) && rm(filename; force=true) + isfile(filename) && rm(filename; force = true) rethrow(e) end end @@ -376,12 +383,12 @@ function jl_to_gl_format(image) n = first(ind1) + last(ind1) for i in ind1 @simd for j in ind2 - @inbounds bufc[j, n-i] = image[i, j] + @inbounds bufc[j, n - i] = image[i, j] end end return bufc else - reverse!(image; dims=1) + reverse!(image; dims = 1) return PermutedDimsArray(image, (2, 1)) end end @@ -404,7 +411,7 @@ function apply_screen_config! end Gets the current screen a scene is associated with. Returns nothing if not yet displayed on a screen. """ -function getscreen(scene::Scene, backend=current_backend()) +function getscreen(scene::Scene, backend = current_backend()) isempty(scene.current_screens) && return nothing # stop search idx = findfirst(scene.current_screens) do screen parentmodule(typeof(screen)) === backend @@ -414,7 +421,7 @@ function getscreen(scene::Scene, backend=current_backend()) return scene.current_screens[idx] end -getscreen(scene::SceneLike, backend=current_backend()) = getscreen(get_scene(scene), backend) +getscreen(scene::SceneLike, backend = current_backend()) = getscreen(get_scene(scene), backend) function getscreen(backend::Union{Missing, Module}, scene::Scene, _config::Dict, args...) screen = getscreen(scene, backend) @@ -428,10 +435,12 @@ function getscreen(backend::Union{Missing, Module}, scene::Scene, _config::Dict, return new_screen end if ismissing(backend) - error(""" + error( + """ You have not loaded a backend. Please load one (`using GLMakie` or `using CairoMakie`) before trying to render a Scene. - """) + """ + ) else return backend.Screen(scene, config, args...) end @@ -463,12 +472,12 @@ or RGBA. - `screen_config`: Backend dependent, look up via `?Backend.Screen`/`Base.doc(Backend.Screen)` - `update=true`: resets/updates limits. Set to false, if you want to preserver camera movements. """ -function colorbuffer(fig::FigureLike, format::ImageStorageFormat = JuliaNative; update=true, backend = current_backend(), screen_config...) +function colorbuffer(fig::FigureLike, format::ImageStorageFormat = JuliaNative; update = true, backend = current_backend(), screen_config...) scene = get_scene(fig) update && update_state_before_display!(fig) # if already has a screen, use their visibility value, if no screen, returns false visible = isvisible(getscreen(scene)) - config = Dict{Symbol,Any}(screen_config) + config = Dict{Symbol, Any}(screen_config) get!(config, :visible, visible) get!(config, :start_renderloop, false) screen = getscreen(backend, scene, config) diff --git a/src/documentation/docstringextension.jl b/src/documentation/docstringextension.jl index 25d991af9d4..710884b1728 100644 --- a/src/documentation/docstringextension.jl +++ b/src/documentation/docstringextension.jl @@ -12,7 +12,7 @@ const ATTRIBUTES = DocThemer() function DocStringExtensions.format(::DocThemer, buf, doc) binding = doc.data[:binding] |> Docs.resolve - help_attributes(buf, binding; extended=true) + return help_attributes(buf, binding; extended = true) end ############################################################ @@ -41,7 +41,7 @@ function DocStringExtensions.format(::DocInstances, buf, doc) end # print the Markdown table into the buffer - show(buf, Markdown.MD(Markdown.Table(rows, [:l, :l]))) + return show(buf, Markdown.MD(Markdown.Table(rows, [:l, :l]))) end # """ diff --git a/src/documentation/documentation.jl b/src/documentation/documentation.jl index f9879545d95..1a99e216d15 100644 --- a/src/documentation/documentation.jl +++ b/src/documentation/documentation.jl @@ -14,20 +14,20 @@ Use the optional `extended = true` keyword argument to see more details. """ help(func; kw_args...) = help(stdout, func; kw_args...) #defaults to STDOUT -function help(io::IO, input::Type{T}; extended = false) where T <: AbstractPlot +function help(io::IO, input::Type{T}; extended = false) where {T <: AbstractPlot} buffer = IOBuffer() _help(buffer, input; extended = extended) - Markdown.parse(String(take!(buffer))) + return Markdown.parse(String(take!(buffer))) end function help(io::IO, input::Function; extended = false) buffer = IOBuffer() _help(buffer, to_type(input); extended = extended) - Markdown.parse(String(take!(buffer))) + return Markdown.parse(String(take!(buffer))) end # Internal help functions -function _help(io::IO, input::Type{T}; extended = false) where T <: AbstractPlot +function _help(io::IO, input::Type{T}; extended = false) where {T <: AbstractPlot} func = to_func(input) str = to_string(input) @@ -42,14 +42,14 @@ function _help(io::IO, input::Type{T}; extended = false) where T <: AbstractPlot # Keyword arguments help_attributes(io, input; extended = extended) - if extended + return if extended println(io, "You can see usage examples of `$func` by running:\n") println(io, "`example_database($func)`\n") end end function _help(io::IO, input::Function; extended = false) - _help(io, to_type(input); extended = extended) + return _help(io, to_type(input); extended = extended) end """ help_arguments([io], func) @@ -67,7 +67,7 @@ function help_arguments(io::IO, x::Function) println(io, " ", "(Vector, Vector)") println(io, " ", "(Vector, Vector, Vector)") println(io, " ", "(Matrix)") - println(io, "```") + return println(io, "```") end """ @@ -104,7 +104,7 @@ usage: """ help_attributes(x; kw...) = help_attributes(stdout, x; kw...) -function help_attributes(io::IO, Typ::Type{T}; extended = false) where T <: AbstractPlot +function help_attributes(io::IO, Typ::Type{T}; extended = false) where {T <: AbstractPlot} # get and sort list of attributes from function (using Scatter as an example) # this is a symbolic dictionary, with symbols as the keys attributes = default_theme(nothing, Typ) @@ -148,14 +148,14 @@ function help_attributes(io::IO, Typ::Type{T}; extended = false) where T <: Abst end end end - println(io, "```") + return println(io, "```") end function help_attributes(io::IO, func::Function; extended = false) - help_attributes(io, to_type(func); extended = extended) + return help_attributes(io, to_type(func); extended = extended) end -function help_attributes(io::IO, Typ::Type{T}; extended = false) where T <: Axis3D +function help_attributes(io::IO, Typ::Type{T}; extended = false) where {T <: Axis3D} if extended println(io, "OldAxis attributes and their defaults for `$Typ` are: \n") else @@ -164,7 +164,7 @@ function help_attributes(io::IO, Typ::Type{T}; extended = false) where T <: Axis attributes = default_theme(nothing, Typ) println(io, "```") print_rec(io, attributes, 1; extended = extended) - println(io, "```") + return println(io, "```") end # ========================================================== @@ -174,8 +174,8 @@ end Maps the input of a Type name to its corresponding function. """ -function to_func(Typ::Type{<: AbstractPlot{F}}) where F - F +function to_func(Typ::Type{<:AbstractPlot{F}}) where {F} + return F end to_func(func::Function) = func @@ -188,7 +188,7 @@ Maps the input of a function name to its corresponding Type. """ to_type(func::Function) = Plot{func} -to_type(Typ::Type{T}) where T <: AbstractPlot = Typ +to_type(Typ::Type{T}) where {T <: AbstractPlot} = Typ """ to_string(func) @@ -196,10 +196,10 @@ to_type(Typ::Type{T}) where T <: AbstractPlot = Typ Turns the input of a function name or plot Type into a string. """ function to_string(func::Function) - str = string(typeof(func).name.mt.name) + return str = string(typeof(func).name.mt.name) end -to_string(Typ::Type{T}) where T <: AbstractPlot = to_string(to_func(Typ)) +to_string(Typ::Type{T}) where {T <: AbstractPlot} = to_string(to_func(Typ)) to_string(s::Symbol) = string(s) to_string(s::String) = s @@ -213,7 +213,7 @@ Use the optional `extended = true` keyword argument to see more details. """ function print_rec(io::IO, dict, indent::Int = 1; extended = false) for (k, v) in dict - print(io, " "^(indent*4), k) + print(io, " "^(indent * 4), k) if isa(to_value(v), Makie.Attributes) print(io, ": ") println(io) @@ -229,4 +229,5 @@ function print_rec(io::IO, dict, indent::Int = 1; extended = false) println(io, v) end end + return end diff --git a/src/event-recorder.jl b/src/event-recorder.jl index 6eb489c804d..060d2c427c6 100644 --- a/src/event-recorder.jl +++ b/src/event-recorder.jl @@ -1,4 +1,3 @@ - """ record_events(f, scene::Scene, path::String) @@ -7,18 +6,18 @@ for `scene` and serializes them to `path`. """ function record_events(f, scene::Scene, path::String) display(scene) - result = Vector{Pair{Float64,Pair{Symbol,Any}}}() + result = Vector{Pair{Float64, Pair{Symbol, Any}}}() for field in fieldnames(Events) # These are not Observables (field === :mousebuttonstate || field === :keyboardstate) && continue - on(getfield(scene.events, field); priority=typemax(Int)) do value + on(getfield(scene.events, field); priority = typemax(Int)) do value value = isa(value, Set) ? copy(value) : value push!(result, time() => (field => value)) return Consume(false) end end f() - open(path, "w") do io + return open(path, "w") do io return serialize(io, result) end end @@ -32,7 +31,7 @@ Replays the serialized events recorded with `record_events` in `path` in `scene` replay_events(scene::Scene, path::String) = replay_events(() -> nothing, scene, path) function replay_events(f, scene::Scene, path::String) events = open(io -> deserialize(io), path) - sort!(events; by=first) + sort!(events; by = first) for i in 1:length(events) t1, (field, value) = events[i] (field === :mousebuttonstate || field === :keyboardstate) && continue @@ -50,6 +49,7 @@ function replay_events(f, scene::Scene, path::String) end end end + return end struct RecordEvents diff --git a/src/ffmpeg-util.jl b/src/ffmpeg-util.jl index a328632b070..b66cad25218 100644 --- a/src/ffmpeg-util.jl +++ b/src/ffmpeg-util.jl @@ -36,10 +36,10 @@ means `n` repetitions (i.e. the video is played `n+1` times) when supported by b struct VideoStreamOptions format::String framerate::Int - compression::Union{Nothing,Int} - profile::Union{Nothing,String} - pixel_format::Union{Nothing,String} - loop::Union{Nothing,Int} + compression::Union{Nothing, Int} + profile::Union{Nothing, String} + pixel_format::Union{Nothing, String} + loop::Union{Nothing, Int} loglevel::String input::String @@ -47,7 +47,8 @@ struct VideoStreamOptions function VideoStreamOptions( format::AbstractString, framerate::Real, compression, profile, - pixel_format, loop, loglevel::String, input::String, rawvideo::Bool=true) + pixel_format, loop, loglevel::String, input::String, rawvideo::Bool = true + ) if !isa(framerate, Integer) @warn "The given framefrate is not a subtype of `Integer`, and will be rounded to the nearest integer. To suppress this warning, provide an integer as the framerate." @@ -66,18 +67,22 @@ struct VideoStreamOptions (loop === nothing) && (loop = 0) # items are name, value, allowed_formats - allowed_kwargs = [("compression", compression, ("mp4", "webm")), - ("profile", profile, ("mp4",)), - ("pixel_format", pixel_format, ("mp4",))] + allowed_kwargs = [ + ("compression", compression, ("mp4", "webm")), + ("profile", profile, ("mp4",)), + ("pixel_format", pixel_format, ("mp4",)), + ] for (name, value, allowed_formats) in allowed_kwargs if !(format in allowed_formats) && value !== nothing - @warn("""`$name`, with value $(repr(value)) + @warn( + """`$name`, with value $(repr(value)) was passed as a keyword argument to `record` or `VideoStream`, which only has an effect when the output video's format is one of: $(collect(allowed_formats)). But the actual video format was $(repr(format)). Keyword arg `$name` will be ignored. - """) + """ + ) end end @@ -85,15 +90,18 @@ struct VideoStreamOptions error("file needs to be \"pipe:0\" or a valid file path") end - loglevels = Set([ - "quiet", - "panic", - "fatal", - "error", - "warning", - "info", - "verbose", - "debug"]) + loglevels = Set( + [ + "quiet", + "panic", + "fatal", + "error", + "warning", + "info", + "verbose", + "debug", + ] + ) if !(loglevel in loglevels) error("loglevel needs to be one of $(loglevels)") @@ -102,11 +110,11 @@ struct VideoStreamOptions end end -function VideoStreamOptions(; format="mp4", framerate=24, compression=nothing, profile=nothing, pixel_format=nothing, loop=nothing, loglevel="quiet", input="pipe:0", rawvideo=true) +function VideoStreamOptions(; format = "mp4", framerate = 24, compression = nothing, profile = nothing, pixel_format = nothing, loop = nothing, loglevel = "quiet", input = "pipe:0", rawvideo = true) return VideoStreamOptions(format, framerate, compression, profile, pixel_format, loop, loglevel, input, rawvideo) end -function to_ffmpeg_cmd(vso::VideoStreamOptions, xdim::Integer=0, ydim::Integer=0) +function to_ffmpeg_cmd(vso::VideoStreamOptions, xdim::Integer = 0, ydim::Integer = 0) # explanation of ffmpeg args. note that the order of args is important; args pertaining # to the input have to go before -i and args pertaining to the output have to go after. # -y: "yes", overwrite any existing without confirmation @@ -247,16 +255,18 @@ $(Base.doc(VideoStreamOptions)) * `filter_ticks`: When true, tick events other than `tick.state = Makie.OneTimeRenderTick` are removed until `save()` is called or the VideoStream object gets deleted. """ -function VideoStream(fig::FigureLike; - format="mp4", framerate=24, compression=nothing, profile=nothing, pixel_format=nothing, loop=nothing, - loglevel="quiet", visible=false, update=true, filter_ticks=true, - backend=current_backend(), screen_config...) +function VideoStream( + fig::FigureLike; + format = "mp4", framerate = 24, compression = nothing, profile = nothing, pixel_format = nothing, loop = nothing, + loglevel = "quiet", visible = false, update = true, filter_ticks = true, + backend = current_backend(), screen_config... + ) dir = mktempdir() path = joinpath(dir, "$(gensym(:video)).$(format)") scene = get_scene(fig) update && update_state_before_display!(fig) - config = Dict{Symbol,Any}(screen_config) + config = Dict{Symbol, Any}(screen_config) get!(config, :visible, visible) get!(config, :start_renderloop, false) screen = getscreen(backend, scene, config, GLNative) @@ -277,7 +287,7 @@ function VideoStream(fig::FigureLike; tick_controller = TickController(fig, 1.0 / vso.framerate, filter_ticks) result = VideoStream(process.in, process, screen, tick_controller, buffer, abspath(path), vso) finalizer(result) do x - @async rm(x.path; force=true) + @async rm(x.path; force = true) stop!(x.tick_controller) end return result @@ -321,7 +331,7 @@ function save(path::String, io::VideoStream; video_options...) # Maybe warn? convert_video(io.path, path; video_options...) else - cp(io.path, path; force=true) + cp(io.path, path; force = true) end return path end @@ -329,12 +339,12 @@ end function convert_video(input_path, output_path; video_options...) p, typ = splitext(output_path) format = lstrip(typ, '.') - vso = VideoStreamOptions(; format=format, input=input_path, rawvideo=false, video_options...) + vso = VideoStreamOptions(; format = format, input = input_path, rawvideo = false, video_options...) cmd = to_ffmpeg_cmd(vso) return run(`$(FFMPEG_jll.ffmpeg()) $cmd $output_path`) end -function extract_frames(video, frame_folder; loglevel="quiet") +function extract_frames(video, frame_folder; loglevel = "quiet") path = joinpath(frame_folder, "frame%04d.png") - run(`$(FFMPEG_jll.ffmpeg()) -loglevel $(loglevel) -i $video -y $path`) + return run(`$(FFMPEG_jll.ffmpeg()) -loglevel $(loglevel) -i $video -y $path`) end diff --git a/src/figureplotting.jl b/src/figureplotting.jl index b90f52852f1..1c5efd18383 100644 --- a/src/figureplotting.jl +++ b/src/figureplotting.jl @@ -17,17 +17,21 @@ Base.iterate(ap::AxisPlot, args...) = iterate((ap.axis, ap.plot), args...) get_scene(ap::AxisPlot) = get_scene(ap.axis.scene) function _validate_nt_like_keyword(@nospecialize(kw), name) - if !(kw isa NamedTuple || kw isa AbstractDict{Symbol} || kw isa Attributes) - throw(ArgumentError(""" - The $name keyword argument received an unexpected value $(repr(kw)). - The $name keyword expects a collection of Symbol => value pairs, such as NamedTuple, Attributes, or AbstractDict{Symbol}. - The most common cause of this error is trying to create a one-element NamedTuple like (key = value) which instead creates a variable `key` with value `value`. - Write (key = value,) or (; key = value) instead.""")) + return if !(kw isa NamedTuple || kw isa AbstractDict{Symbol} || kw isa Attributes) + throw( + ArgumentError( + """ + The $name keyword argument received an unexpected value $(repr(kw)). + The $name keyword expects a collection of Symbol => value pairs, such as NamedTuple, Attributes, or AbstractDict{Symbol}. + The most common cause of this error is trying to create a one-element NamedTuple like (key = value) which instead creates a variable `key` with value `value`. + Write (key = value,) or (; key = value) instead.""" + ) + ) end end function _disallow_keyword(kw, attributes) - if haskey(attributes, kw) + return if haskey(attributes, kw) throw(ArgumentError("You cannot pass `$kw` as a keyword argument to this plotting function. Note that `axis` can only be passed to non-mutating plotting functions (not ending with a `!`) that implicitly create an axis, and `figure` only to those that implicitly create a `Figure`.")) end end @@ -37,8 +41,10 @@ end struct FigureOnly end -function args_preferred_axis(::Type{<:Union{Wireframe,Surface,Contour3d}}, x::AbstractArray, y::AbstractArray, - z::AbstractArray) +function args_preferred_axis( + ::Type{<:Union{Wireframe, Surface, Contour3d}}, x::AbstractArray, y::AbstractArray, + z::AbstractArray + ) return all(x -> z[1] ≈ x, z) ? Axis : LScene end @@ -54,13 +60,13 @@ function args_preferred_axis(@nospecialize(args...)) end args_preferred_axis(::AbstractVector, ::AbstractVector, ::AbstractVector, ::Function) = LScene -args_preferred_axis(::AbstractArray{T,3}) where {T} = LScene +args_preferred_axis(::AbstractArray{T, 3}) where {T} = LScene -function args_preferred_axis(::AbstractVector{<:Union{AbstractGeometry{DIM},GeometryBasics.Mesh{DIM}}}) where {DIM} +function args_preferred_axis(::AbstractVector{<:Union{AbstractGeometry{DIM}, GeometryBasics.Mesh{DIM}}}) where {DIM} return DIM === 2 ? Axis : LScene end -function args_preferred_axis(::Union{AbstractGeometry{DIM},GeometryBasics.Mesh{DIM}}) where {DIM} +function args_preferred_axis(::Union{AbstractGeometry{DIM}, GeometryBasics.Mesh{DIM}}) where {DIM} return DIM === 2 ? Axis : LScene end @@ -69,9 +75,9 @@ args_preferred_axis(::AbstractVector{<:Point2}) = Axis preferred_axis_type(::Volume) = LScene -preferred_axis_type(::Union{Image,Heatmap}) = Axis +preferred_axis_type(::Union{Image, Heatmap}) = Axis -function preferred_axis_type(p::Plot{F}) where F +function preferred_axis_type(p::Plot{F}) where {F} # Otherwise, we check the arguments input_args = map(to_value, p.args) result = args_preferred_axis(Plot{F}, input_args...) @@ -83,11 +89,11 @@ function preferred_axis_type(p::Plot{F}) where F end to_dict(dict::Dict) = convert(Dict{Symbol, Any}, dict) -to_dict(nt::NamedTuple) = Dict{Symbol,Any}(pairs(nt)) +to_dict(nt::NamedTuple) = Dict{Symbol, Any}(pairs(nt)) to_dict(attr::Attributes) = attributes(attr) function extract_attributes(dictlike, key) - dictlike = pop!(dictlike, key, Dict{Symbol,Any}()) + dictlike = pop!(dictlike, key, Dict{Symbol, Any}()) _validate_nt_like_keyword(dictlike, key) return to_dict(dictlike) end @@ -137,9 +143,9 @@ E.g.: `plot!(fig[1, 1][1, 1], 1:4)` which needs an axis to exist at f[1, 1][1, 1 """ function MakieCore.create_axis_like!(attributes::Dict, gsp::GridSubposition) _disallow_keyword(:figure, attributes) - layout = GridLayoutBase.get_layout_at!(gsp.parent; createmissing=false) + layout = GridLayoutBase.get_layout_at!(gsp.parent; createmissing = false) gp = layout[gsp.rows, gsp.cols, gsp.side] - c = contents(gp; exact=true) + c = contents(gp; exact = true) if !(length(c) == 1 && can_be_current_axis(c[1])) error("There is not just one axis at $(gp).") end @@ -173,7 +179,7 @@ E.g.: `plot!(fig[1, 1], 1:4)` which requires an axis to exist at `f[1, 1]`. """ function MakieCore.create_axis_like!(attributes::Dict, gp::GridPosition) _disallow_keyword(:figure, attributes) - c = contents(gp; exact=true) + c = contents(gp; exact = true) if !(length(c) == 1 && can_be_current_axis(c[1])) error("There needs to be a single axis-like object at $(gp.span), $(gp.side) to plot into.\nUse a non-mutating plotting command to create an axis implicitly.") end @@ -182,7 +188,7 @@ function MakieCore.create_axis_like!(attributes::Dict, gp::GridPosition) return ax end -function create_axis_like(::AbstractPlot, ::Dict, ::Union{Scene,AbstractAxis}) +function create_axis_like(::AbstractPlot, ::Dict, ::Union{Scene, AbstractAxis}) return error("Plotting into an axis without `!` (e.g. `scatter` instead of `scatter!`)") end @@ -216,14 +222,16 @@ function create_axis_like(plot::AbstractPlot, attributes::Dict, gp::GridPosition isnothing(plot) && return nothing _disallow_keyword(:figure, attributes) figure = get_top_parent(gp) - c = contents(gp; exact=true) + c = contents(gp; exact = true) if !isempty(c) - error(""" - You have used the non-mutating plotting syntax with a GridPosition, which requires an empty GridLayout slot to create an axis in, but there are already the following objects at this layout position: - $(c) - If you meant to plot into an axis at this position, use the plotting function with `!` (e.g. `func!` instead of `func`). - If you really want to place an axis on top of other blocks, make your intention clear and create it manually. - """) + error( + """ + You have used the non-mutating plotting syntax with a GridPosition, which requires an empty GridLayout slot to create an axis in, but there are already the following objects at this layout position: + $(c) + If you meant to plot into an axis at this position, use the plotting function with `!` (e.g. `func!` instead of `func`). + If you really want to place an axis on top of other blocks, make your intention clear and create it manually. + """ + ) end ax = create_axis_for_plot(figure, plot, attributes) if isnothing(ax) # For FigureSpec @@ -244,17 +252,19 @@ E.g.: `plot(fig[1, 1][1, 1], 1:4)` which creates an Axis at f[1, 1][1, 1]. function create_axis_like(plot::AbstractPlot, attributes::Dict, gsp::GridSubposition) isnothing(plot) && return nothing _disallow_keyword(:figure, attributes) - GridLayoutBase.get_layout_at!(gsp.parent; createmissing=true) - c = contents(gsp; exact=true) + GridLayoutBase.get_layout_at!(gsp.parent; createmissing = true) + c = contents(gsp; exact = true) if !isempty(c) - error(""" - You have used the non-mutating plotting syntax with a GridSubposition, which requires an empty GridLayout slot to create an axis in, but there are already the following objects at this layout position: + error( + """ + You have used the non-mutating plotting syntax with a GridSubposition, which requires an empty GridLayout slot to create an axis in, but there are already the following objects at this layout position: - $(c) + $(c) - If you meant to plot into an axis at this position, use the plotting function with `!` (e.g. `func!` instead of `func`). - If you really want to place an axis on top of other blocks, make your intention clear and create it manually. - """) + If you meant to plot into an axis at this position, use the plotting function with `!` (e.g. `func!` instead of `func`). + If you really want to place an axis on top of other blocks, make your intention clear and create it manually. + """ + ) end figure = get_top_parent(gsp) @@ -278,12 +288,14 @@ function update_state_before_display!(f::Figure) end @inline plot_args(args...) = (nothing, args) -@inline function plot_args(a::Union{Figure,AbstractAxis,Scene,Plot,GridSubposition,GridPosition}, - args...) +@inline function plot_args( + a::Union{Figure, AbstractAxis, Scene, Plot, GridSubposition, GridPosition}, + args... + ) return (a, args) end function fig_keywords!(kws) - figkws = Dict{Symbol,Any}() + figkws = Dict{Symbol, Any}() if haskey(kws, :axis) figkws[:axis] = pop!(kws, :axis) end @@ -304,7 +316,7 @@ default_plot_func(::typeof(plot), args) = plotfunc(plottype(map(to_value, args). if haskey(figkws, :axis) ax_kw = figkws[:axis] _validate_nt_like_keyword(ax_kw, :axis) - if any(x-> x in [:dim1_conversion, :dim2_conversion, :dim3_conversion], keys(ax_kw)) + if any(x -> x in [:dim1_conversion, :dim2_conversion, :dim3_conversion], keys(ax_kw)) conversions = get_conversions(ax_kw) if haskey(attributes, :dim_conversions) connect_conversions!(attributes[:dim_conversions], conversions) @@ -335,7 +347,7 @@ end # This enables convert_arguments(::Type{<:AbstractPlot}, ::X) -> FigureSpec # Which skips axis creation # TODO, what to return for the dynamically created axes? -const PlotSpecPlot = Plot{plot, Tuple{<: GridLayoutSpec}} +const PlotSpecPlot = Plot{plot, Tuple{<:GridLayoutSpec}} get_conversions(scene::Scene) = scene.conversions get_conversions(fig::Figure) = get_conversions(fig.scene) @@ -343,27 +355,35 @@ get_conversions(fig::Figure) = get_conversions(fig.scene) @noinline function MakieCore._create_plot!(F, attributes::Dict, args...) if length(args) > 0 if args[1] isa FigureAxisPlot - throw(ArgumentError(""" - Tried plotting with `$(F)!` into a `FigureAxisPlot` object, this is not allowed. + throw( + ArgumentError( + """ + Tried plotting with `$(F)!` into a `FigureAxisPlot` object, this is not allowed. - The `FigureAxisPlot` object is returned by plotting functions not ending in `!` like `lines(...)` or `scatter(...)`. + The `FigureAxisPlot` object is returned by plotting functions not ending in `!` like `lines(...)` or `scatter(...)`. - It contains the new `Figure`, the new axis object, for example an `Axis`, `LScene` or `Axis3`, and the new plot object. It exists just as a convenience because returning it displays the contained figure. For all further operations, you should split it into its parts instead. This way, it is clear which of its components you are targeting. + It contains the new `Figure`, the new axis object, for example an `Axis`, `LScene` or `Axis3`, and the new plot object. It exists just as a convenience because returning it displays the contained figure. For all further operations, you should split it into its parts instead. This way, it is clear which of its components you are targeting. - You can do this with the destructuring syntax `fig, ax, plt = some_plot(...)` and then continue, for example with `$(F)!(ax, ...)`. - """)) + You can do this with the destructuring syntax `fig, ax, plt = some_plot(...)` and then continue, for example with `$(F)!(ax, ...)`. + """ + ) + ) end if args[1] isa AxisPlot - throw(ArgumentError(""" - Tried plotting with `$(F)!` into an `AxisPlot` object, this is not allowed. + throw( + ArgumentError( + """ + Tried plotting with `$(F)!` into an `AxisPlot` object, this is not allowed. - The `AxisPlot` object is returned by plotting functions not ending in `!` with - a `GridPosition` as the first argument, like `lines(fig[1, 2], ...)` or `scatter(fig[1, 2], ...)`. + The `AxisPlot` object is returned by plotting functions not ending in `!` with + a `GridPosition` as the first argument, like `lines(fig[1, 2], ...)` or `scatter(fig[1, 2], ...)`. - It contains the new axis object, for example an `Axis`, `LScene` or `Axis3`, and the new plot object. For all further operations, you should split it into its parts instead. This way, it is clear which of its components you are targeting. + It contains the new axis object, for example an `Axis`, `LScene` or `Axis3`, and the new plot object. For all further operations, you should split it into its parts instead. This way, it is clear which of its components you are targeting. - You can do this with the destructuring syntax `ax, plt = some_plot(fig[1, 2], ...)` and then continue, for example with `$(F)!(ax, ...)`. - """)) + You can do this with the destructuring syntax `ax, plt = some_plot(fig[1, 2], ...)` and then continue, for example with `$(F)!(ax, ...)`. + """ + ) + ) end end figarg, pargs = plot_args(args...) @@ -407,7 +427,6 @@ end plot!(fa::FigureAxis, plot) = plot!(fa.axis, plot) - function plot!(ax::AbstractAxis, plot::AbstractPlot) plot!(ax.scene, plot) if !isnothing(get_conversions(plot)) diff --git a/src/figures.jl b/src/figures.jl index 8b362084331..26c994da26b 100644 --- a/src/figures.jl +++ b/src/figures.jl @@ -30,7 +30,6 @@ get_scene(gp::GridLayoutBase.GridPosition) = get_scene(get_figure(gp)) get_scene(gp::GridLayoutBase.GridSubposition) = get_scene(get_figure(gp)) - const CURRENT_FIGURE = Ref{Union{Nothing, Figure}}(nothing) const CURRENT_FIGURE_LOCK = Base.ReentrantLock() @@ -40,7 +39,7 @@ const CURRENT_FIGURE_LOCK = Base.ReentrantLock() Returns the current active figure (or the last figure created). Returns `nothing` if there is no current active figure. """ -current_figure() = lock(()-> CURRENT_FIGURE[], CURRENT_FIGURE_LOCK) +current_figure() = lock(() -> CURRENT_FIGURE[], CURRENT_FIGURE_LOCK) """ current_figure!(fig) @@ -67,11 +66,11 @@ function current_axis!(fig::Figure, ax) error("This axis' parent is not the given figure") end fig.current_axis[] = ax - ax + return ax end function current_axis!(fig::Figure, ::Nothing) - fig.current_axis[] = nothing + return fig.current_axis[] = nothing end """ @@ -89,7 +88,7 @@ function current_axis!(ax) # if the current axis is in a different figure, we switch to that as well # so that current_axis and current_figure are not out of sync current_figure!(fig) - ax + return ax end to_rectsides(n::Number) = to_rectsides((n, n, n, n)) @@ -109,7 +108,7 @@ function Figure(; kwargs...) kwargs_dict = Dict(kwargs) padding = pop!(kwargs_dict, :figure_padding, theme(:figure_padding)) - scene = Scene(; camera=campixel!, clear = true, kwargs_dict...) + scene = Scene(; camera = campixel!, clear = true, kwargs_dict...) padding = convert(Observable{Any}, padding) alignmode = lift(Outside ∘ to_rectsides, padding) @@ -131,24 +130,24 @@ function Figure(; kwargs...) # set figure as layout parent so GridPositions can refer to the figure # if connected correctly layout.parent = f - f + return f end export Figure, current_axis, current_figure, current_axis!, current_figure! function Base.getindex(fig::Figure, rows, cols, side = GridLayoutBase.Inner()) - fig.layout[rows, cols, side] + return fig.layout[rows, cols, side] end function Base.setindex!(fig::Figure, obj, rows, cols, side = GridLayoutBase.Inner()) fig.layout[rows, cols, side] = obj - obj + return obj end function Base.setindex!(fig::Figure, obj::AbstractArray, rows, cols) fig.layout[rows, cols] = obj - obj + return obj end Base.lastindex(f::Figure, i) = lastindex(f.layout, i) @@ -163,7 +162,7 @@ Base.show(io::IO, ::MIME"text/plain", fig::Figure) = print(io, "Figure()") get_figure(gsp::GridLayoutBase.GridSubposition) = get_figure(gsp.parent) function get_figure(gp::GridLayoutBase.GridPosition) top_parent = GridLayoutBase.top_parent(gp.layout) - if top_parent isa Figure + return if top_parent isa Figure top_parent else nothing @@ -190,7 +189,7 @@ function resize_to_layout!(fig::Figure) bbox = GridLayoutBase.tight_bbox(fig.layout) new_size = (widths(bbox)...,) resize!(fig.scene, widths(bbox)...) - new_size + return new_size end function Base.empty!(fig::Figure) diff --git a/src/float32-scaling.jl b/src/float32-scaling.jl index 0b769fbe9b5..60401f7fe34 100644 --- a/src/float32-scaling.jl +++ b/src/float32-scaling.jl @@ -16,16 +16,16 @@ @inline (ls::LinearScaling)(p::VecTypes{3}) = ls.scale .* p + ls.offset -@inline function f32_convert(ls::LinearScaling, p::VecTypes{N}) where N +@inline function f32_convert(ls::LinearScaling, p::VecTypes{N}) where {N} # TODO Point{N, Float32}(::Point{N, Int}) doesn't work return to_ndim(Point{N, Float32}, ls(p), 0) end -@inline function f32_convert(ls::LinearScaling, ps::AbstractArray{<: VecTypes{N}}) where N +@inline function f32_convert(ls::LinearScaling, ps::AbstractArray{<:VecTypes{N}}) where {N} return [to_ndim(Point{N, Float32}, ls(p), 0) for p in ps] end @inline f32_convert(ls::LinearScaling, x::Union{Real, VecTypes}, dim::Integer) = Float32(ls(x, dim)) -@inline function f32_convert(ls::LinearScaling, xs::AbstractArray{<: Union{Real, VecTypes}}, dim::Integer) +@inline function f32_convert(ls::LinearScaling, xs::AbstractArray{<:Union{Real, VecTypes}}, dim::Integer) return [Float32(ls(x, dim)) for x in xs] end @@ -97,16 +97,16 @@ end # TODO: How do we actually judge this well? function is_float_safe(scale, trans) - resolution = 1e4 + resolution = 1.0e4 return all(abs.(scale) .> resolution .* eps.(Float32.(trans))) end function patch_model(@nospecialize(plot), f32c::Float32Convert, model::Observable) # Observable{Any} :( - f32c_obs = Observable{LinearScaling}(f32c.scaling[], ignore_equal_values = true) + f32c_obs = Observable{LinearScaling}(f32c.scaling[], ignore_equal_values = true) model_obs = Observable{Mat4f}(Mat4f(I), ignore_equal_values = true) onany(plot, f32c.scaling, model, update = true) do f32c, model - # Neutral f32c can mean that data and model cancel each other and we + # Neutral f32c can mean that data and model cancel each other and we # still have Float32 preicsion issues in between. # works with rotation component as well, but drops signs on scale @@ -120,17 +120,17 @@ function patch_model(@nospecialize(plot), f32c::Float32Convert, model::Observabl model_obs[] = Mat4f(model) elseif is_float_safe(scale, trans) && is_rot_free - # model can be applied on GPU and we can pull f32c through the - # model matrix. This can be merged with the option below, but + # model can be applied on GPU and we can pull f32c through the + # model matrix. This can be merged with the option below, but # keeping them separate improves compatibility with transform_marker scale = Vec3d(model[1, 1], model[2, 2], model[3, 3]) # existing scale is missing signs f32c_obs[] = Makie.LinearScaling( f32c.scale, ((f32c.scale .- 1) .* trans .+ f32c.offset) ./ scale ) model_obs[] = model - + elseif is_rot_free - # Model has no rotation so we can extract scale + translation and move + # Model has no rotation so we can extract scale + translation and move # it to the f32c. scale = Vec3d(model[1, 1], model[2, 2], model[3, 3]) # existing scale is missing signs f32c_obs[] = Makie.LinearScaling( @@ -173,7 +173,7 @@ available. I.e. the conversion ensures that `(max - min) > resolution * max(eps(min), eps(max))` whenever `update_limits!` is called. Note that resolution must be smaller than `1 / eps(Float32)`. """ -function Float32Convert(resolution = 1e4) +function Float32Convert(resolution = 1.0e4) scaling = LinearScaling(Vec{3, Float64}(1.0), Vec{3, Float64}(0.0)) return Float32Convert(Observable(scaling), resolution) end @@ -201,7 +201,7 @@ function always returns false. function update_limits!(c::Float32Convert, mini::VecTypes{3, Float64}, maxi::VecTypes{3, Float64}) linscale = c.scaling[] - low = linscale(mini) + low = linscale(mini) high = linscale(maxi) @assert all(low .<= high) # TODO: Axis probably does that @@ -221,7 +221,7 @@ function update_limits!(c::Float32Convert, mini::VecTypes{3, Float64}, maxi::Vec if needs_update # Vec{N}(+1) = scale * maxi + offset # Vec{N}(-1) = scale * mini + offset - scale = 2.0 ./ (maxi - mini) + scale = 2.0 ./ (maxi - mini) offset = 1.0 .- scale * maxi c.scaling[] = LinearScaling(scale, offset) @@ -232,7 +232,7 @@ function update_limits!(c::Float32Convert, mini::VecTypes{3, Float64}, maxi::Vec end @inline f32_convert(::Nothing, x::Real) = Float32(x) -@inline f32_convert(::Nothing, x::VecTypes{N}) where N = to_ndim(Point{N, Float32}, x, 0) +@inline f32_convert(::Nothing, x::VecTypes{N}) where {N} = to_ndim(Point{N, Float32}, x, 0) @inline f32_convert(::Nothing, x::AbstractArray) = f32_convert.(nothing, x) @inline f32_convert(::Nothing, x::Real, dim::Integer) = Float32(x) @@ -247,11 +247,11 @@ end @inline inv_f32_convert(c::Nothing, args...) = inv_f32_convert(c::Nothing, args) @inline inv_f32_convert(::Nothing, x::Real) = Float64(x) -@inline inv_f32_convert(::Nothing, x::VecTypes{N}) where N = to_ndim(Point{N, Float64}, x, 0) +@inline inv_f32_convert(::Nothing, x::VecTypes{N}) where {N} = to_ndim(Point{N, Float64}, x, 0) @inline inv_f32_convert(c::Float32Convert, x::Real) = inv(c.scaling[])(Float64(x)) -@inline inv_f32_convert(c::Float32Convert, x::VecTypes{N}) where N = inv(c.scaling[])(to_ndim(Point{N, Float64}, x, 0)) +@inline inv_f32_convert(c::Float32Convert, x::VecTypes{N}) where {N} = inv(c.scaling[])(to_ndim(Point{N, Float64}, x, 0)) @inline inv_f32_convert(c::Union{Nothing, Float32Convert}, x::AbstractArray) = inv_f32_convert.((c,), x) @inline inv_f32_convert(ls::Float32Convert, r::Rect) = inv_f32_convert(ls.scaling[], r) @inline inv_f32_convert(x::SceneLike, args...) = inv_f32_convert(f32_conversion(x), args...) @@ -322,7 +322,7 @@ function apply_transform_and_f32_conversion( transform_func, model::Mat4d, data, space::Symbol ) # TODO: - # - Optimization: avoid intermediate arrays + # - Optimization: avoid intermediate arrays # - Is transform_func strictly per element? trans, scale = decompose_translation_scale_matrix(model) @@ -337,7 +337,7 @@ function apply_transform_and_f32_conversion( return f32_convert(float32convert, to_ndim.(Point3d, transformed, 0), space) else - # model contains rotation which stops us from applying f32convert + # model contains rotation which stops us from applying f32convert # before model transformed = apply_transform_and_model(model, transform_func, data, space) return f32_convert(float32convert, transformed) @@ -364,9 +364,9 @@ function apply_transform_and_f32_conversion( float32convert::Union{Nothing, Float32Convert, LinearScaling}, transform_func, model::Mat4d, data, dim::Integer, space::Symbol ) - + dim in (1, 2, 3) || error("The transform_func and float32 conversion can only be applied along dimensions 1, 2 or 3, not $dim") - + dimpoints = if dim == 1 Point2.(data, 0) elseif dim == 2 @@ -380,7 +380,7 @@ function apply_transform_and_f32_conversion( # model applied on GPU, float32convert skippable transformed = apply_transform(transform_func, dimpoints, space) return [Float32(p[dim]) for p in transformed] - + elseif is_translation_scale_matrix(model) # translation and scale of model have been moved to f32convert, so just apply that transformed = apply_transform(transform_func, dimpoints, space) diff --git a/src/interaction/events.jl b/src/interaction/events.jl index 90e3e06f640..642521cd37d 100644 --- a/src/interaction/events.jl +++ b/src/interaction/events.jl @@ -1,5 +1,3 @@ - - window_area(scene, native_window) = not_implemented_for(native_window) window_open(scene, native_window) = not_implemented_for(native_window) mouse_buttons(scene, native_window) = not_implemented_for(native_window) @@ -61,8 +59,8 @@ Picks a mouse position. Implemented by the backend. """ function pick end -function pick(::Scene, ::Screen, xy) where Screen - @warn "Picking not supported yet by $(parentmodule(Screen))" maxlog=1 +function pick(::Scene, ::Screen, xy) where {Screen} + @warn "Picking not supported yet by $(parentmodule(Screen))" maxlog = 1 return nothing, 0 end @@ -90,8 +88,8 @@ end function next_tick!(tick::Observable{Tick}, state::TickState, start_time::UInt64, last_time::UInt64) t = time_ns() - since_start = 1e-9 * (t - start_time) - delta_time = 1e-9 * (t - last_time) + since_start = 1.0e-9 * (t - start_time) + delta_time = 1.0e-9 * (t - last_time) tick[] = Tick(state, tick[].count + 1, since_start, delta_time) return t end @@ -172,23 +170,23 @@ function Base.show(io::IO, op::And) show(io, op.left) print(io, " & ") show(io, op.right) - print(io, ")") + return print(io, ")") end function Base.show(io::IO, op::Or) print(io, "(") show(io, op.left) print(io, " | ") show(io, op.right) - print(io, ")") + return print(io, ")") end function Base.show(io::IO, op::Not) print(io, "!") - show(io, op.x) + return show(io, op.x) end function Base.show(io::IO, op::Exclusively) print(io, "exclusively(") join(io, op.x, " & ") - print(io, ")") + return print(io, ")") end # Constructors @@ -203,25 +201,25 @@ function Base.:(&)( left::Union{BooleanOperator, Keyboard.Button, Mouse.Button}, right::Union{BooleanOperator, Keyboard.Button, Mouse.Button, Bool} ) - And(left, right) + return And(left, right) end function Base.:(&)( left::Bool, right::Union{BooleanOperator, Keyboard.Button, Mouse.Button} ) - And(left, right) + return And(left, right) end function Base.:(|)( left::Union{BooleanOperator, Keyboard.Button, Mouse.Button}, right::Union{BooleanOperator, Keyboard.Button, Mouse.Button, Bool} ) - Or(left, right) + return Or(left, right) end function Base.:(|)( left::Bool, right::Union{BooleanOperator, Keyboard.Button, Mouse.Button} ) - Or(left, right) + return Or(left, right) end Base.:(!)(x::Union{BooleanOperator, Keyboard.Button, Mouse.Button}) = Not(x) @@ -235,13 +233,15 @@ Exclusively(x::And) = Or(Exclusively.(unique(create_sets(x)))...) # Sets represent `And`, arrays represent `Or` function create_sets(x::And) - [union(left, right) for left in create_sets(x.left) - for right in create_sets(x.right)] + return [ + union(left, right) for left in create_sets(x.left) + for right in create_sets(x.right) + ] end create_sets(x::Or) = vcat(create_sets(x.left), create_sets(x.right)) create_sets(::Not) = Set{Union{Keyboard.Button, Mouse.Button}}() function create_sets(b::Union{Keyboard.Button, Mouse.Button}) - [Set{Union{Keyboard.Button, Mouse.Button}}((b,))] + return [Set{Union{Keyboard.Button, Mouse.Button}}((b,))] end create_sets(s::Set) = [Set{Union{Keyboard.Button, Mouse.Button}}(s)] @@ -294,7 +294,7 @@ ispressed(parent, key::Keyboard.Button, waspressed = nothing) = ispressed(events # Boolean Operator evaluation ispressed(parent, op::And, waspressed = nothing) = ispressed(parent, op.left, waspressed) && ispressed(parent, op.right, waspressed) -ispressed(parent, op::Or, waspressed = nothing) = ispressed(parent, op.left, waspressed) || ispressed(parent, op.right, waspressed) +ispressed(parent, op::Or, waspressed = nothing) = ispressed(parent, op.left, waspressed) || ispressed(parent, op.right, waspressed) ispressed(parent, op::Not, waspressed = nothing) = !ispressed(parent, op.x, waspressed) ispressed(parent, op::Exclusively, waspressed = nothing) = ispressed(events(parent), op, waspressed) ispressed(e::Events, op::Exclusively, waspressed::Union{Mouse.Button, Keyboard.Button}) = op.x == union(e.keyboardstate, e.mousebuttonstate, waspressed) @@ -303,4 +303,4 @@ ispressed(e::Events, op::Exclusively, waspressed = nothing) = op.x == union(e.ke # collections ispressed(parent, set::Set, waspressed = nothing) = all(x -> ispressed(parent, x, waspressed), set) ispressed(parent, set::Vector, waspressed = nothing) = all(x -> ispressed(parent, x, waspressed), set) -ispressed(parent, set::Tuple, waspressed = nothing) = all(x -> ispressed(parent, x, waspressed), set) \ No newline at end of file +ispressed(parent, set::Tuple, waspressed = nothing) = all(x -> ispressed(parent, x, waspressed), set) diff --git a/src/interaction/inspector.jl b/src/interaction/inspector.jl index 8f8ddadb3b4..4af2923b9f0 100644 --- a/src/interaction/inspector.jl +++ b/src/interaction/inspector.jl @@ -10,7 +10,7 @@ position2string(p::StaticVector{3}) = @sprintf("x: %0.6f\ny: %0.6f\nz: %0.6f", p function bbox2string(bbox::Rect3) p0 = origin(bbox) p1 = p0 .+ widths(bbox) - @sprintf( + return @sprintf( """ Bounding Box: x: (%0.3f, %0.3f) @@ -24,7 +24,7 @@ end function bbox2string(bbox::Rect2) p0 = origin(bbox) p1 = p0 .+ widths(bbox) - @sprintf( + return @sprintf( """ Bounding Box: x: (%0.3f, %0.3f) @@ -38,7 +38,7 @@ color2text(c::AbstractFloat) = @sprintf("%0.3f", c) color2text(c::Symbol) = string(c) color2text(c) = color2text(to_color(c)) function color2text(c::RGBAf) - if c.alpha == 1.0 + return if c.alpha == 1.0 @sprintf("RGB(%0.2f, %0.2f, %0.2f)", c.r, c.g, c.b) else @sprintf("RGBA(%0.2f, %0.2f, %0.2f, %0.2f)", c.r, c.g, c.b, c.alpha) @@ -48,7 +48,7 @@ end color2text(name, i::Integer, j::Integer, c) = "$name[$i, $j] = $(color2text(c))" function color2text(name, i, j, c) idxs = @sprintf("%0.2f, %0.2f", i, j) - "$name[$idxs] = $(color2text(c))" + return "$name[$idxs] = $(color2text(c))" end @@ -70,10 +70,10 @@ _to_rotation(x::Vector, idx) = to_rotation(x[idx]) function closest_point_on_line(A::Point2f, B::Point2f, P::Point2f) # This only works in 2D AP = P .- A; AB = B .- A - A .+ AB * dot(AP, AB) / dot(AB, AB) + return A .+ AB * dot(AP, AB) / dot(AB, AB) end -function point_in_triangle(A::Point2, B::Point2, C::Point2, P::Point2, ϵ = 1e-6) +function point_in_triangle(A::Point2, B::Point2, C::Point2, P::Point2, ϵ = 1.0e-6) # adjusted from ray_triangle_intersection AO = A .- P BO = B .- P @@ -86,7 +86,6 @@ function point_in_triangle(A::Point2, B::Point2, C::Point2, P::Point2, ϵ = 1e-6 end - ### Mapping mesh vertex indices to Vector{Polygon} index ######################################## @@ -110,7 +109,7 @@ function ncoords(poly::Polygon) for int in poly.interiors N += length(int) + 1 end - N + return N end ## Band Sections @@ -131,7 +130,7 @@ inside the quad and that none of the edges cross. """ function point_in_quad_parameter( A::Point2, B::Point2, C::Point2, D::Point2, P::Point2; - iterations = 50, epsilon = 1e-6 + iterations = 50, epsilon = 1.0e-6 ) # Our initial guess is that P is in the center of the quad (in terms of AB and DC) @@ -164,7 +163,7 @@ end @deprecate shift_project(scene, plot, pos) shift_project(scene, pos) false function shift_project(scene, pos) - project( + return project( camera(scene).projectionview[], Vec2f(size(scene)), f32_convert(scene, pos), @@ -172,13 +171,11 @@ function shift_project(scene, pos) end - ################################################################################ ### Interactive selection via DataInspector ################################################################################ - # TODO destructor? mutable struct DataInspector root::Scene @@ -201,11 +198,11 @@ function cleanup(inspector::DataInspector) empty!(inspector.obsfuncs) delete!(inspector.root, inspector.plot) clear_temporary_plots!(inspector, inspector.selection) - inspector + return inspector end function Base.delete!(::Union{Scene, Figure}, inspector::DataInspector) - cleanup(inspector) + return cleanup(inspector) end enable!(inspector::DataInspector) = inspector.attributes.enabled[] = true @@ -239,7 +236,7 @@ returning a label. See Makie documentation for more detail. - and all attributes from `Tooltip` """ function DataInspector(fig_or_block; kwargs...) - DataInspector(get_scene(fig_or_block); kwargs...) + return DataInspector(get_scene(fig_or_block); kwargs...) end function DataInspector(scene::Scene; priority = 100, kwargs...) @@ -251,9 +248,9 @@ function DataInspector(scene::Scene; priority = 100, kwargs...) # General DataInspector settings range = pop!(attrib_dict, :range, 10), enabled = pop!(attrib_dict, :enabled, true), - depth = pop!(attrib_dict, :depth, 9e3), + depth = pop!(attrib_dict, :depth, 9.0e3), enable_indicators = pop!(attrib_dict, :show_bbox_indicators, true), - offset = get(attrib_dict, :offset, 10f0), + offset = get(attrib_dict, :offset, 10.0f0), apply_tooltip_offset = pop!(attrib_dict, :apply_tooltip_offset, true), # Settings for indicators (plots that highlight the current selection) @@ -265,10 +262,10 @@ function DataInspector(scene::Scene; priority = 100, kwargs...) indicator_visible = false, # General reusable - _color = RGBAf(0,0,0,0), + _color = RGBAf(0, 0, 0, 0), ) - plot = tooltip!(parent, Observable(Point2f(0)), text = Observable(""); visible=false, attrib_dict...) + plot = tooltip!(parent, Observable(Point2f(0)), text = Observable(""); visible = false, attrib_dict...) on(z -> translate!(plot, 0, 0, z), base_attrib.depth) notify(base_attrib.depth) @@ -304,7 +301,7 @@ function DataInspector(scene::Scene; priority = 100, kwargs...) return end - inspector + return inspector end DataInspector(; kwargs...) = DataInspector(current_figure(); kwargs...) @@ -403,7 +400,7 @@ function clear_temporary_plots!(inspector::DataInspector, plot) # clear attributes which are reused for indicator plots for key in ( :indicator_color, :indicator_linestyle, - :indicator_linewidth, :indicator_visible + :indicator_linewidth, :indicator_visible, ) empty!(inspector.attributes[key].listeners) end @@ -428,13 +425,11 @@ function update_tooltip_alignment!(inspector, proj_pos) end - ################################################################################ ### show_data for primitive plots ################################################################################ - # TODO: better 3D scaling function show_data(inspector::DataInspector, plot::Scatter, idx) a = inspector.attributes @@ -472,9 +467,11 @@ function show_data(inspector::DataInspector, plot::MeshScatter, idx) rotation = to_rotation(_to_rotation(plot.rotation[], idx)) scale = inv_f32_scale(plot, _to_scale(plot.markersize[], idx)) - bbox = Rect3d(convert_attribute( - plot.marker[], Key{:marker}(), Key{Makie.plotkey(plot)}() - )) + bbox = Rect3d( + convert_attribute( + plot.marker[], Key{:marker}(), Key{Makie.plotkey(plot)}() + ) + ) ps = convert_arguments(LineSegments, bbox)[1] ps = map(ps) do p @@ -621,7 +618,7 @@ function show_data(inspector::DataInspector, plot::Surface, idx) tt.text[] = plot[:inspector_label][](plot, idx, pos) end tt.visible[] = true - tt.offset[] = 0f0 + tt.offset[] = 0.0f0 else tt.visible[] = false end @@ -631,11 +628,11 @@ function show_data(inspector::DataInspector, plot::Surface, idx) end function show_data(inspector::DataInspector, plot::Heatmap, idx) - show_imagelike(inspector, plot, "H", idx, true) + return show_imagelike(inspector, plot, "H", idx, true) end function show_data(inspector::DataInspector, plot::Image, idx) - show_imagelike(inspector, plot, "img", idx, false) + return show_imagelike(inspector, plot, "img", idx, false) end _to_array(x::AbstractArray) = x @@ -703,10 +700,10 @@ function show_imagelike(inspector, plot, name, idx, edge_based) inspectable = false, model = plot.model, # TODO switch to Rect with 2r-1 or 2r-2 markersize to have # just enough space to always detect the underlying image - marker=:rect, markersize = map(r -> 2r, a.range), + marker = :rect, markersize = map(r -> 2r, a.range), strokecolor = a.indicator_color, strokewidth = a.indicator_linewidth, - depth_shift = -1f-3 + depth_shift = -1.0f-3 ) push!(inspector.temp_plots, p) else @@ -723,7 +720,7 @@ function show_imagelike(inspector, plot, name, idx, edge_based) scene, bbox, color = a.indicator_color, model = plot.model, linewidth = a.indicator_linewidth, linestyle = a.indicator_linestyle, visible = a.indicator_visible, inspectable = false, - depth_shift = -1f-3 + depth_shift = -1.0f-3 ) push!(inspector.temp_plots, p) else @@ -747,12 +744,12 @@ function _interpolated_getindex(xs, ys, img, mpos) i = clamp((x - x0) / (x1 - x0) * size(img, 1) + 0.5, 1, size(img, 1)) j = clamp((y - y0) / (y1 - y0) * size(img, 2) + 0.5, 1, size(img, 2)) - l = clamp(floor(Int, i), 1, size(img, 1)-1); - r = clamp(l+1, 2, size(img, 1)) - b = clamp(floor(Int, j), 1, size(img, 2)-1); - t = clamp(b+1, 2, size(img, 2)) - z = ((r-i) * img[l, b] + (i-l) * img[r, b]) * (t-j) + - ((r-i) * img[l, t] + (i-l) * img[r, t]) * (j-b) + l = clamp(floor(Int, i), 1, size(img, 1) - 1) + r = clamp(l + 1, 2, size(img, 1)) + b = clamp(floor(Int, j), 1, size(img, 2) - 1) + t = clamp(b + 1, 2, size(img, 2)) + z = ((r - i) * img[l, b] + (i - l) * img[r, b]) * (t - j) + + ((r - i) * img[l, t] + (i - l) * img[r, t]) * (j - b) # float, float, value (i, j are no longer used) return i, j, z @@ -766,7 +763,7 @@ function _pixelated_getindex(xs, ys, img, mpos, edge_based) j = clamp(round(Int, (y - y0) / (y1 - y0) * size(img, 2) + 0.5), 1, size(img, 2)) # int, int, value - return i, j, img[i,j] + return i, j, img[i, j] end function _interpolated_getindex(xs::Vector, ys::Vector, img, mpos) @@ -776,16 +773,16 @@ function _interpolated_getindex(xs::Vector, ys::Vector, img, mpos) # z = ((xs[i+1] - x) / w * img[i, j] + (x - xs[i]) / w * img[i+1, j]) * (ys[j+1] - y) / h + # ((xs[i+1] - x) / w * img[i, j+1] + (x - xs[i]) / w * img[i+1, j+1]) * (y - ys[j]) / h # return i, j, z - _interpolated_getindex(minimum(xs)..maximum(xs), minimum(ys)..maximum(ys), img, mpos) + return _interpolated_getindex(minimum(xs) .. maximum(xs), minimum(ys) .. maximum(ys), img, mpos) end function _pixelated_getindex(xs::Vector, ys::Vector, img, mpos, edge_based) if edge_based x, y = mpos - i = max(1, something(findfirst(v -> v >= x, xs), length(xs))-1) - j = max(1, something(findfirst(v -> v >= y, ys), length(ys))-1) + i = max(1, something(findfirst(v -> v >= x, xs), length(xs)) - 1) + j = max(1, something(findfirst(v -> v >= y, ys), length(ys)) - 1) return i, j, img[i, j] else - _pixelated_getindex(minimum(xs)..maximum(xs), minimum(ys)..maximum(ys), img, mpos, edge_based) + _pixelated_getindex(minimum(xs) .. maximum(xs), minimum(ys) .. maximum(ys), img, mpos, edge_based) end end @@ -793,20 +790,20 @@ function _pixelated_image_bbox(xs, ys, img, i::Integer, j::Integer, edge_based) x0, x1 = extrema(xs) y0, y1 = extrema(ys) nw, nh = ((x1 - x0), (y1 - y0)) ./ size(img) - Rect2d(x0 + nw * (i-1), y0 + nh * (j-1), nw, nh) + return Rect2d(x0 + nw * (i - 1), y0 + nh * (j - 1), nw, nh) end function _pixelated_image_bbox(xs::Vector, ys::Vector, img, i::Integer, j::Integer, edge_based) - if edge_based - Rect2d(xs[i], ys[j], xs[i+1] - xs[i], ys[j+1] - ys[j]) + return if edge_based + Rect2d(xs[i], ys[j], xs[i + 1] - xs[i], ys[j + 1] - ys[j]) else _pixelated_image_bbox( - minimum(xs)..maximum(xs), minimum(ys)..maximum(ys), + minimum(xs) .. maximum(xs), minimum(ys) .. maximum(ys), img, i, j, edge_based ) end end -function show_data(inspector::DataInspector, plot, idx, source=nothing) +function show_data(inspector::DataInspector, plot, idx, source = nothing) return false end @@ -816,13 +813,12 @@ end ################################################################################ - function show_data(inspector::DataInspector, plot::BarPlot, idx, ::Lines) - return show_data(inspector, plot, div(idx-1, 6)+1) + return show_data(inspector, plot, div(idx - 1, 6) + 1) end function show_data(inspector::DataInspector, plot::BarPlot, idx, ::Mesh) - return show_data(inspector, plot, div(idx-1, 4)+1) + return show_data(inspector, plot, div(idx - 1, 4) + 1) end @@ -873,7 +869,7 @@ function show_data(inspector::DataInspector, plot::BarPlot, idx) end function show_data(inspector::DataInspector, plot::Arrows, idx, ::LineSegments) - return show_data(inspector, plot, div(idx+1, 2), nothing) + return show_data(inspector, plot, div(idx + 1, 2), nothing) end function show_data(inspector::DataInspector, plot::Arrows, idx, source) @@ -948,7 +944,7 @@ function show_poly(inspector, plot, poly, idx, source) scene, line_collection, color = a.indicator_color, transformation = Transformation(source), strokewidth = a.indicator_linewidth, linestyle = a.indicator_linestyle, - visible = a.indicator_visible, inspectable = false, depth_shift = -1f-3 + visible = a.indicator_visible, inspectable = false, depth_shift = -1.0f-3 ) push!(inspector.temp_plots, p) @@ -1012,9 +1008,9 @@ function show_data(inspector::DataInspector, plot::Band, idx::Integer, mesh::Mes ps2 = plot.converted[2][] # find first triangle containing the cursor position - idx = findfirst(1:length(ps1)-1) do i - point_in_triangle(ps1[i], ps1[i+1], ps2[i+1], pos) || - point_in_triangle(ps1[i], ps2[i+1], ps2[i], pos) + idx = findfirst(1:(length(ps1) - 1)) do i + point_in_triangle(ps1[i], ps1[i + 1], ps2[i + 1], pos) || + point_in_triangle(ps1[i], ps2[i + 1], ps2[i], pos) end if idx !== nothing @@ -1022,9 +1018,9 @@ function show_data(inspector::DataInspector, plot::Band, idx::Integer, mesh::Mes # Within the quad we can draw a line from ps1[idx] + f * (ps1[idx+1] - ps1[idx]) # to ps2[idx] + f * (ps2[idx+1] - ps2[idx]) which crosses through the # cursor position. Find the parameter f that describes this line - f = point_in_quad_parameter(ps1[idx], ps1[idx+1], ps2[idx+1], ps2[idx], pos) - P1 = ps1[idx] + f * (ps1[idx+1] - ps1[idx]) - P2 = ps2[idx] + f * (ps2[idx+1] - ps2[idx]) + f = point_in_quad_parameter(ps1[idx], ps1[idx + 1], ps2[idx + 1], ps2[idx], pos) + P1 = ps1[idx] + f * (ps1[idx + 1] - ps1[idx]) + P2 = ps2[idx] + f * (ps2[idx + 1] - ps2[idx]) # Draw the line if a.enable_indicators[] @@ -1036,7 +1032,7 @@ function show_data(inspector::DataInspector, plot::Band, idx::Integer, mesh::Mes color = a.indicator_color, strokewidth = a.indicator_linewidth, linestyle = a.indicator_linestyle, visible = a.indicator_visible, inspectable = false, - depth_shift = -1f-3 + depth_shift = -1.0f-3 ) push!(inspector.temp_plots, p) elseif !isempty(inspector.temp_plots) @@ -1088,9 +1084,11 @@ function show_data(inspector::DataInspector, spy::Spy, idx, picked_plot) else tt.text[] = scatter.inspector_label[](spy, idx2d, spy.z[][idx2d...]) end - tt.offset[] = ifelse(a.apply_tooltip_offset[], - 0.5 * maximum(sv_getindex(scatter.markersize[], idx)) + 2, - a.offset[]) + tt.offset[] = ifelse( + a.apply_tooltip_offset[], + 0.5 * maximum(sv_getindex(scatter.markersize[], idx)) + 2, + a.offset[] + ) tt.visible[] = true a.indicator_visible[] && (a.indicator_visible[] = false) diff --git a/src/interaction/interactive_api.jl b/src/interaction/interactive_api.jl index b3fdff252e4..0a1e4b5aaaa 100644 --- a/src/interaction/interactive_api.jl +++ b/src/interaction/interactive_api.jl @@ -20,11 +20,11 @@ Calls `f(plot, idx)` whenever the mouse is over any of `plots`. `idx` is an index, e.g. when over a scatter plot, it will be the index of the hovered element """ -onpick(f, x, plots::AbstractPlot...; range=1) = onpick(f, get_scene(x), plots..., range = range) -function onpick(f, scene::Scene, plots::AbstractPlot...; range=1) +onpick(f, x, plots::AbstractPlot...; range = 1) = onpick(f, get_scene(x), plots..., range = range) +function onpick(f, scene::Scene, plots::AbstractPlot...; range = 1) fplots = collect_atomic_plots(plots) args = range == 1 ? (scene,) : (scene, range) - on(events(scene).mouseposition) do mp + return on(events(scene).mouseposition) do mp p, idx = pick(args...) (p in fplots) && f(p, idx) return Consume(false) @@ -45,7 +45,7 @@ function mouse_in_scene(scene::Scene; priority = 0) output[] = Vec(mp) .- minimum(viewport(scene)[]) return Consume(false) end - output + return output end @@ -81,7 +81,7 @@ pick(obj, xy::VecTypes{2}) = pick(get_scene(obj), xy) function pick(scene::Scene, xy::VecTypes{2}) screen = getscreen(scene) screen === nothing && return (nothing, 0) - pick(scene, screen, Vec{2, Float64}(xy)) + return pick(scene, screen, Vec{2, Float64}(xy)) end pick(obj, range::Real) = pick(get_scene(obj), events(obj).mouseposition[], range) @@ -90,7 +90,7 @@ pick(obj, x::Real, y::Real, range::Real) = pick(get_scene(obj), Vec2(x, y), rang function pick(scene::Scene, xy::VecTypes{2}, range::Real) screen = getscreen(scene) screen === nothing && return (nothing, 0) - pick_closest(scene, screen, xy, range) + return pick_closest(scene, screen, xy, range) end # The backend may handle this more optimally @@ -105,9 +105,9 @@ function pick_closest(scene::SceneLike, screen, xy, range) min_dist = range^2 selected = (0, 0) - x, y = xy .+ 1 .- Vec2f(x0, y0) + x, y = xy .+ 1 .- Vec2f(x0, y0) for i in 1:dx, j in 1:dy - d = (x-i)^2 + (y-j)^2 + d = (x - i)^2 + (y - j)^2 if (d < min_dist) && (picks[i, j][1] !== nothing) min_dist = d selected = (i, j) @@ -144,10 +144,10 @@ function pick_sorted(scene::Scene, screen, xy, range) selected = filter(x -> x[1] !== nothing, unique(vec(picks))) distances = [range^2 for _ in selected] - x, y = xy .+ 1 .- Vec2f(x0, y0) + x, y = xy .+ 1 .- Vec2f(x0, y0) for i in 1:dx, j in 1:dy if picks[i, j][1] !== nothing - d = (x-i)^2 + (y-j)^2 + d = (x - i)^2 + (y - j)^2 i = findfirst(isequal(picks[i, j]), selected)::Int if distances[i] > d distances[i] = d @@ -238,7 +238,7 @@ function select_rectangle(scene; blocking = false, priority = 2, strokewidth = 3 scene, rect, visible = false, color = RGBAf(0, 0, 0, 0), strokecolor = RGBAf(0.1, 0.1, 0.8, 0.5), strokewidth = strokewidth, kwargs..., ) - on(events(scene).mousebutton, priority=priority) do event + on(events(scene).mousebutton, priority = priority) do event if event.button == key if event.action == Mouse.press && is_mouseinside(scene) mp = mouseposition(scene) @@ -264,7 +264,7 @@ function select_rectangle(scene; blocking = false, priority = 2, strokewidth = 3 return Consume(false) end - on(events(scene).mouseposition, priority=priority) do event + on(events(scene).mouseposition, priority = priority) do event if waspressed[] mp = mouseposition(scene) mini = minimum(rect[]) @@ -294,15 +294,15 @@ The `kwargs...` are propagated into `lines!` which plots the selected line. function select_line(scene; blocking = false, priority = 2, kwargs...) key = Mouse.left waspressed = Observable(false) - line = Observable([Point2f(0,0), Point2f(1,1)]) - line_ret = Observable([Point2f(0,0), Point2f(1,1)]) + line = Observable([Point2f(0, 0), Point2f(1, 1)]) + line_ret = Observable([Point2f(0, 0), Point2f(1, 1)]) # Create an initially hidden arrow plotted_line = lines!( scene, line; visible = false, color = RGBAf(0.1, 0.1, 0.8, 0.5), linewidth = 4, kwargs..., ) - on(events(scene).mousebutton, priority=priority) do event + on(events(scene).mousebutton, priority = priority) do event if event.button == key && is_mouseinside(scene) mp = mouseposition(scene) if event.action == Mouse.press @@ -326,7 +326,7 @@ function select_line(scene; blocking = false, priority = 2, kwargs...) end return Consume(false) end - on(events(scene).mouseposition, priority=priority) do event + on(events(scene).mouseposition, priority = priority) do event if waspressed[] mp = mouseposition(scene) line[][2] = mp @@ -352,18 +352,18 @@ The value of the returned point is updated **only** when the user un-clicks. The `kwargs...` are propagated into `scatter!` which plots the selected point. """ -function select_point(scene; blocking = false, priority=2, kwargs...) +function select_point(scene; blocking = false, priority = 2, kwargs...) key = Mouse.left waspressed = Observable(false) - point = Observable([Point2f(0,0)]) - point_ret = Observable(Point2f(0,0)) + point = Observable([Point2f(0, 0)]) + point_ret = Observable(Point2f(0, 0)) # Create an initially hidden arrow plotted_point = scatter!( scene, point; visible = false, marker = Circle, markersize = 20px, color = RGBAf(0.1, 0.1, 0.8, 0.5), kwargs..., ) - on(events(scene).mousebutton, priority=priority) do event + on(events(scene).mousebutton, priority = priority) do event if event.button == key && is_mouseinside(scene) mp = mouseposition(scene) if event.action == Mouse.press @@ -384,7 +384,7 @@ function select_point(scene; blocking = false, priority=2, kwargs...) end return Consume(false) end - on(events(scene).mouseposition, priority=priority) do event + on(events(scene).mouseposition, priority = priority) do event if waspressed[] mp = mouseposition(scene) point[][1] = mp diff --git a/src/interaction/iodevices.jl b/src/interaction/iodevices.jl index 4d6d2855d1d..7c0e607f669 100644 --- a/src/interaction/iodevices.jl +++ b/src/interaction/iodevices.jl @@ -11,130 +11,131 @@ module Keyboard Enumerates all keyboard buttons. See the implementation for details. """ - @enum(Button, - unknown = -1, - # printable keys, - space = 32, - apostrophe = 39, # ', - comma = 44, # ,, - minus = 45, # -, - period = 46, # ., - slash = 47, # /, - _0 = 48, - _1 = 49, - _2 = 50, - _3 = 51, - _4 = 52, - _5 = 53, - _6 = 54, - _7 = 55, - _8 = 56, - _9 = 57, - semicolon = 59, # ;, - equal = 61, # =, - a = 65, - b = 66, - c = 67, - d = 68, - e = 69, - f = 70, - g = 71, - h = 72, - i = 73, - j = 74, - k = 75, - l = 76, - m = 77, - n = 78, - o = 79, - p = 80, - q = 81, - r = 82, - s = 83, - t = 84, - u = 85, - v = 86, - w = 87, - x = 88, - y = 89, - z = 90, - left_bracket = 91, # [, - backslash = 92, # , - right_bracket = 93, # ], - grave_accent = 96, # `, - world_1 = 161, # non-us #1, - world_2 = 162, # non-us #2, - # function keys, - escape = 256, - enter = 257, - tab = 258, - backspace = 259, - insert = 260, - delete = 261, - right = 262, - left = 263, - down = 264, - up = 265, - page_up = 266, - page_down = 267, - home = 268, - _end = 269, - caps_lock = 280, - scroll_lock = 281, - num_lock = 282, - print_screen = 283, - pause = 284, - f1 = 290, - f2 = 291, - f3 = 292, - f4 = 293, - f5 = 294, - f6 = 295, - f7 = 296, - f8 = 297, - f9 = 298, - f10 = 299, - f11 = 300, - f12 = 301, - f13 = 302, - f14 = 303, - f15 = 304, - f16 = 305, - f17 = 306, - f18 = 307, - f19 = 308, - f20 = 309, - f21 = 310, - f22 = 311, - f23 = 312, - f24 = 313, - f25 = 314, - kp_0 = 320, - kp_1 = 321, - kp_2 = 322, - kp_3 = 323, - kp_4 = 324, - kp_5 = 325, - kp_6 = 326, - kp_7 = 327, - kp_8 = 328, - kp_9 = 329, - kp_decimal = 330, - kp_divide = 331, - kp_multiply = 332, - kp_subtract = 333, - kp_add = 334, - kp_enter = 335, - kp_equal = 336, - left_shift = 340, - left_control = 341, - left_alt = 342, - left_super = 343, - right_shift = 344, - right_control = 345, - right_alt = 346, - right_super = 347, - menu = 348, + @enum( + Button, + unknown = -1, + # printable keys, + space = 32, + apostrophe = 39, # ', + comma = 44, # ,, + minus = 45, # -, + period = 46, # ., + slash = 47, # /, + _0 = 48, + _1 = 49, + _2 = 50, + _3 = 51, + _4 = 52, + _5 = 53, + _6 = 54, + _7 = 55, + _8 = 56, + _9 = 57, + semicolon = 59, # ;, + equal = 61, # =, + a = 65, + b = 66, + c = 67, + d = 68, + e = 69, + f = 70, + g = 71, + h = 72, + i = 73, + j = 74, + k = 75, + l = 76, + m = 77, + n = 78, + o = 79, + p = 80, + q = 81, + r = 82, + s = 83, + t = 84, + u = 85, + v = 86, + w = 87, + x = 88, + y = 89, + z = 90, + left_bracket = 91, # [, + backslash = 92, # , + right_bracket = 93, # ], + grave_accent = 96, # `, + world_1 = 161, # non-us #1, + world_2 = 162, # non-us #2, + # function keys, + escape = 256, + enter = 257, + tab = 258, + backspace = 259, + insert = 260, + delete = 261, + right = 262, + left = 263, + down = 264, + up = 265, + page_up = 266, + page_down = 267, + home = 268, + _end = 269, + caps_lock = 280, + scroll_lock = 281, + num_lock = 282, + print_screen = 283, + pause = 284, + f1 = 290, + f2 = 291, + f3 = 292, + f4 = 293, + f5 = 294, + f6 = 295, + f7 = 296, + f8 = 297, + f9 = 298, + f10 = 299, + f11 = 300, + f12 = 301, + f13 = 302, + f14 = 303, + f15 = 304, + f16 = 305, + f17 = 306, + f18 = 307, + f19 = 308, + f20 = 309, + f21 = 310, + f22 = 311, + f23 = 312, + f24 = 313, + f25 = 314, + kp_0 = 320, + kp_1 = 321, + kp_2 = 322, + kp_3 = 323, + kp_4 = 324, + kp_5 = 325, + kp_6 = 326, + kp_7 = 327, + kp_8 = 328, + kp_9 = 329, + kp_decimal = 330, + kp_divide = 331, + kp_multiply = 332, + kp_subtract = 333, + kp_add = 334, + kp_enter = 335, + kp_equal = 336, + left_shift = 340, + left_control = 341, + left_alt = 342, + left_super = 343, + right_shift = 344, + right_control = 345, + right_alt = 346, + right_super = 347, + menu = 348, ) """ @@ -146,8 +147,8 @@ module Keyboard """ @enum Action begin release = 0 - press = 1 - repeat = 2 + press = 1 + repeat = 2 end end @@ -156,60 +157,59 @@ Backend independent enums and fields which represent mouse actions. """ module Mouse - using ..Makie: INSTANCES # import the docstring extensions +using ..Makie: INSTANCES # import the docstring extensions - """ - Mouse.Button +""" + Mouse.Button - Enumerates all mouse buttons in accordance with the GLFW spec. +Enumerates all mouse buttons in accordance with the GLFW spec. - $(INSTANCES) - """ - @enum Button begin - left = 0 - middle = 2 - right = 1 # Conform to GLFW - none = -1 # for convenience - button_4 = 3 - button_5 = 4 - button_6 = 5 - button_7 = 6 - button_8 = 7 - end +$(INSTANCES) +""" +@enum Button begin + left = 0 + middle = 2 + right = 1 # Conform to GLFW + none = -1 # for convenience + button_4 = 3 + button_5 = 4 + button_6 = 5 + button_7 = 6 + button_8 = 7 +end - """ - Mouse.Action +""" + Mouse.Action - Enumerates all mouse states/actions in accordance with the GLFW spec. +Enumerates all mouse states/actions in accordance with the GLFW spec. - $(INSTANCES) - """ - @enum Action begin - press = 1 - release = 0 - end +$(INSTANCES) +""" +@enum Action begin + press = 1 + release = 0 +end - # deprecated, remove eventually - """ - Mouse.DragEnum +# deprecated, remove eventually +""" + Mouse.DragEnum - Enumerates the drag states of the mouse. +Enumerates the drag states of the mouse. - $(INSTANCES) - """ - @enum DragEnum begin - down - up - pressed - notpressed - end +$(INSTANCES) +""" +@enum DragEnum begin + down + up + pressed + notpressed +end end # Void for no button needs to be pressed, const ButtonTypes = Union{Nothing, Mouse.Button, Keyboard.Button} - struct KeyEvent key::Keyboard.Button action::Keyboard.Action diff --git a/src/interaction/liftmacro.jl b/src/interaction/liftmacro.jl index eaf867127d2..cad42679636 100644 --- a/src/interaction/liftmacro.jl +++ b/src/interaction/liftmacro.jl @@ -18,7 +18,7 @@ find_observable_expressions(x) = Set() is_interpolated_observable(x) = false function is_interpolated_observable(e::Expr) - e.head == Symbol(:$) && length(e.args) == 1 + return e.head == Symbol(:$) && length(e.args) == 1 end """ diff --git a/src/interaction/observables.jl b/src/interaction/observables.jl index 38aefb23fa3..967e7aecb9f 100644 --- a/src/interaction/observables.jl +++ b/src/interaction/observables.jl @@ -15,20 +15,21 @@ function safe_off(o::Observables.AbstractObservable, f) return end end + return end -function on_latest(f, observable::Observable; update=false, spawn=false) - return on_latest(f, nothing, observable; update=update, spawn=spawn) +function on_latest(f, observable::Observable; update = false, spawn = false) + return on_latest(f, nothing, observable; update = update, spawn = spawn) end -function on_latest(f, to_track, observable::Observable; update=false, spawn=false) +function on_latest(f, to_track, observable::Observable; update = false, spawn = false) last_task = nothing has_changed = Threads.Atomic{Bool}(false) function run_f(new_value) try f(new_value) catch e - @warn "Error in f" exception=(e, Base.catch_backtrace()) + @warn "Error in f" exception = (e, Base.catch_backtrace()) end # Since we skip updates completely while executing the above `f` # We need to check after finishing, if the value has changed! @@ -36,7 +37,7 @@ function on_latest(f, to_track, observable::Observable; update=false, spawn=fals # But `==` would be better, considering, that one could arrive at an old value. # This should be configurable, but since async_latest is needed for working on big data as input # we assume for now that `==` is prohibitive as the default - if has_changed[] + return if has_changed[] has_changed[] = false run_f(observable[]) # needs to be recursive end @@ -64,19 +65,19 @@ function on_latest(f, to_track, observable::Observable; update=false, spawn=fals end end -function onany_latest(f, observables...; update=false, spawn=false) +function onany_latest(f, observables...; update = false, spawn = false) result = Observable{Any}(map(to_value, observables)) - onany((args...)-> (result[] = args), observables...) - on_latest((args)-> f(args...), result; update=update, spawn=spawn) + onany((args...) -> (result[] = args), observables...) + return on_latest((args) -> f(args...), result; update = update, spawn = spawn) end -function map_latest!(f, result::Observable, observables...; update=false, spawn=false) +function map_latest!(f, result::Observable, observables...; update = false, spawn = false) callback = Observables.MapCallback(f, result, observables) - return onany_latest(callback, observables...; update=update, spawn=spawn) + return onany_latest(callback, observables...; update = update, spawn = spawn) end -function map_latest(f, observables...; spawn=false, ignore_equal_values=false) - result = Observable(f(map(to_value, observables)...); ignore_equal_values=ignore_equal_values) - map_latest!(f, result, observables...; spawn=spawn) +function map_latest(f, observables...; spawn = false, ignore_equal_values = false) + result = Observable(f(map(to_value, observables)...); ignore_equal_values = ignore_equal_values) + map_latest!(f, result, observables...; spawn = spawn) return result end diff --git a/src/interaction/ray_casting.jl b/src/interaction/ray_casting.jl index 4ff0a5bf7b0..594254fa5b2 100644 --- a/src/interaction/ray_casting.jl +++ b/src/interaction/ray_casting.jl @@ -66,16 +66,16 @@ function Ray(scene::Scene, cam::Camera2D, xy::VecTypes{2}) m = Vec2f(pv[1, 1], pv[2, 2]) b = Vec2f(pv[1, 4], pv[2, 4]) origin = (2 * rel_pos .- 1 - b) ./ m - return Ray(to_ndim(Point3f, origin, 10_000f0), Vec3f(0,0,-1)) + return Ray(to_ndim(Point3f, origin, 10_000f0), Vec3f(0, 0, -1)) end function Ray(::Scene, ::PixelCamera, xy::VecTypes{2}) - return Ray(to_ndim(Point3f, xy, 10_000f0), Vec3f(0,0,-1)) + return Ray(to_ndim(Point3f, xy, 10_000f0), Vec3f(0, 0, -1)) end function Ray(scene::Scene, ::RelativeCamera, xy::VecTypes{2}) origin = xy ./ widths(scene) - return Ray(to_ndim(Point3f, origin, 10_000f0), Vec3f(0,0,-1)) + return Ray(to_ndim(Point3f, origin, 10_000f0), Vec3f(0, 0, -1)) end Ray(scene::Scene, cam, xy::VecTypes{2}) = ray_from_projectionview(scene, xy) @@ -88,16 +88,16 @@ function ray_from_projectionview(scene::Scene, xy::VecTypes{2}) # This figures out the camera view direction from the projectionview matrix # and computes a ray from a near and a far point. # Based on ComputeCameraRay from ImGuizmo - mp = 2f0 .* xy ./ widths(area) .- 1f0 + mp = 2.0f0 .* xy ./ widths(area) .- 1.0f0 v = inv_view_proj * Vec4f(0, 0, -10, 1) reversed = v[3] < v[4] - near = reversed ? 1f0 - 1e-6 : 0f0 - far = reversed ? 0f0 : 1f0 - 1e-6 + near = reversed ? 1.0f0 - 1.0e-6 : 0.0f0 + far = reversed ? 0.0f0 : 1.0f0 - 1.0e-6 - origin = inv_view_proj * Vec4f(mp[1], mp[2], near, 1f0) + origin = inv_view_proj * Vec4f(mp[1], mp[2], near, 1.0f0) origin = origin[Vec(1, 2, 3)] ./ origin[4] - p = inv_view_proj * Vec4f(mp[1], mp[2], far, 1f0) + p = inv_view_proj * Vec4f(mp[1], mp[2], far, 1.0f0) p = p[Vec(1, 2, 3)] ./ p[4] dir = normalize(p .- origin) @@ -107,9 +107,9 @@ end function transform(M::Mat4{T}, ray::Ray) where {T} - p4d = M * to_ndim(Point4{T}, ray.origin, 1f0) - dir = normalize(M[Vec(1,2,3), Vec(1,2,3)] * ray.direction) - return Ray(p4d[Vec(1,2,3)] / p4d[4], dir) + p4d = M * to_ndim(Point4{T}, ray.origin, 1.0f0) + dir = normalize(M[Vec(1, 2, 3), Vec(1, 2, 3)] * ray.direction) + return Ray(p4d[Vec(1, 2, 3)] / p4d[4], dir) end f32_convert(::Nothing, ray::Ray) = ray @@ -146,7 +146,7 @@ function closest_point_on_line(A::Point3, B::Point3, ray::Ray) return A .+ clamp(t, 0.0, AB_norm) * u_AB end -function ray_triangle_intersection(A::VecTypes, B::VecTypes, C::VecTypes, ray::Ray, ϵ = 1e-6) +function ray_triangle_intersection(A::VecTypes, B::VecTypes, C::VecTypes, ray::Ray, ϵ = 1.0e-6) return ray_triangle_intersection( to_ndim(Point3d, A, 0), to_ndim(Point3d, B, 0), to_ndim(Point3d, C, 0), ray, ϵ @@ -154,7 +154,7 @@ function ray_triangle_intersection(A::VecTypes, B::VecTypes, C::VecTypes, ray::R end function ray_triangle_intersection( - A::VecTypes{3, T1}, B::VecTypes{3, T2}, C::VecTypes{3, T3}, ray::Ray{T4}, ϵ = 1e-6 + A::VecTypes{3, T1}, B::VecTypes{3, T2}, C::VecTypes{3, T3}, ray::Ray{T4}, ϵ = 1.0e-6 ) where {T1, T2, T3, T4} T = promote_type(T1, T2, T3, T4, Float32) # See: https://www.iue.tuwien.ac.at/phd/ertl/node114.html @@ -177,7 +177,7 @@ end function ray_rect_intersection(rect::Rect2, ray::Ray) possible_hit = ray.origin - ray.origin[3] / ray.direction[3] * ray.direction min = minimum(rect); max = maximum(rect) - if all(min <= possible_hit[Vec(1,2)] <= max) + if all(min <= possible_hit[Vec(1, 2)] <= max) return possible_hit end return Point3f(NaN) @@ -207,7 +207,7 @@ function is_point_on_ray(p::Point3{T1}, ray::Ray{T2}) where {T1 <: Real, T2 <: R end -function ray_plane_intersection(plane::Plane3{T1}, ray::Ray{T2}, epsilon = 1e-6) where {T1 <: Real, T2 <: Real} +function ray_plane_intersection(plane::Plane3{T1}, ray::Ray{T2}, epsilon = 1.0e-6) where {T1 <: Real, T2 <: Real} # --- p --- plane with normal (assumed normalized) # ↓ # : distance d along plane normal direction @@ -301,7 +301,7 @@ function position_on_plot(plot::Union{Lines, LineSegments}, idx, ray::Ray; apply if idx == 1 idx = 2 end - p0, p1 = apply_transform_and_model(plot, plot[1][][(idx-1):idx]) + p0, p1 = apply_transform_and_model(plot, plot[1][][(idx - 1):idx]) pos = closest_point_on_line(f32_convert(plot, p0), f32_convert(plot, p1), ray) @@ -365,11 +365,11 @@ function position_on_plot(plot::Mesh, idx, ray::Ray; apply_transform = true) end # Handling indexing into different surface input types -surface_x(xs::ClosedInterval, i, j, N) = minimum(xs) + (maximum(xs) - minimum(xs)) * (i-1) / (N-1) +surface_x(xs::ClosedInterval, i, j, N) = minimum(xs) + (maximum(xs) - minimum(xs)) * (i - 1) / (N - 1) surface_x(xs, i, j, N) = xs[i] surface_x(xs::AbstractMatrix, i, j, N) = xs[i, j] -surface_y(ys::ClosedInterval, i, j, N) = minimum(ys) + (maximum(ys) - minimum(ys)) * (j-1) / (N-1) +surface_y(ys::ClosedInterval, i, j, N) = minimum(ys) + (maximum(ys) - minimum(ys)) * (j - 1) / (N - 1) surface_y(ys, i, j, N) = ys[j] surface_y(ys::AbstractMatrix, i, j, N) = ys[i, j] @@ -383,7 +383,7 @@ function position_on_plot(plot::Surface, idx, ray::Ray; apply_transform = true) ys = plot[2][] zs = plot[3][] w, h = size(zs) - _i = mod1(idx, w); _j = div(idx-1, w) + _i = mod1(idx, w); _j = div(idx - 1, w) ray = transform(inv(plot.model[]), inv_f32_convert(plot, ray)) tf = transform_func(plot) @@ -391,14 +391,14 @@ function position_on_plot(plot::Surface, idx, ray::Ray; apply_transform = true) # This isn't the most accurate so we include some neighboring faces pos = Point3f(NaN) - for i in _i-1:_i+1, j in _j-1:_j+1 + for i in (_i - 1):(_i + 1), j in (_j - 1):(_j + 1) (1 <= i <= w) && (1 <= j < h) || continue if i - 1 > 0 # transforms only apply to x and y coordinates of surfaces - A = surface_pos(xs, ys, zs, i, j) - B = surface_pos(xs, ys, zs, i-1, j) - C = surface_pos(xs, ys, zs, i, j+1) + A = surface_pos(xs, ys, zs, i, j) + B = surface_pos(xs, ys, zs, i - 1, j) + C = surface_pos(xs, ys, zs, i, j + 1) A, B, C = map((A, B, C)) do p xy = Makie.apply_transform(tf, Point2d(p), space) Point3d(xy[1], xy[2], p[3]) @@ -407,9 +407,9 @@ function position_on_plot(plot::Surface, idx, ray::Ray; apply_transform = true) end if i + 1 <= w && isnan(pos) - A = surface_pos(xs, ys, zs, i, j) - B = surface_pos(xs, ys, zs, i, j+1) - C = surface_pos(xs, ys, zs, i+1, j+1) + A = surface_pos(xs, ys, zs, i, j) + B = surface_pos(xs, ys, zs, i, j + 1) + C = surface_pos(xs, ys, zs, i + 1, j + 1) A, B, C = map((A, B, C)) do p xy = Makie.apply_transform(tf, Point2d(p), space) Point3d(xy[1], xy[2], p[3]) @@ -449,10 +449,12 @@ function position_on_plot(plot::Volume, idx, ray::Ray; apply_transform = true) # TODO: After GeometryBasics refactor this can just use triangle_mesh(Rect3d(min, max - min)) w = max - min ps = Point3d[min + (x, y, z) .* w for x in (0, 1) for y in (0, 1) for z in (0, 1)] - fs = decompose(GLTriangleFace, QuadFace{Int}[ - (1, 2, 4, 3), (7, 8, 6, 5), (5, 6, 2, 1), - (3, 4, 8, 7), (1, 3, 7, 5), (6, 8, 4, 2) - ]) + fs = decompose( + GLTriangleFace, QuadFace{Int}[ + (1, 2, 4, 3), (7, 8, 6, 5), (5, 6, 2, 1), + (3, 4, 8, 7), (1, 3, 7, 5), (6, 8, 4, 2), + ] + ) if apply_transform ps = apply_transform_and_model(plot, ps) diff --git a/src/interfaces.jl b/src/interfaces.jl index f7b00cc0d30..e87cced4cd1 100644 --- a/src/interfaces.jl +++ b/src/interfaces.jl @@ -1,5 +1,4 @@ - -function add_cycle_attribute!(plot::Plot, scene::Scene, cycle=get_cycle_for_plottype(plot.cycle[])) +function add_cycle_attribute!(plot::Plot, scene::Scene, cycle = get_cycle_for_plottype(plot.cycle[])) cycler = scene.cycler palette = scene.theme.palette add_cycle_attributes!(plot, cycle, cycler, palette) @@ -12,27 +11,27 @@ function color_and_colormap!(plot, colors = plot.color) add_cycle_attribute!(plot, scene) end colors = assemble_colors(colors[], colors, plot) - attributes(plot.attributes)[:calculated_colors] = colors + return attributes(plot.attributes)[:calculated_colors] = colors end -function calculated_attributes!(::Type{<: AbstractPlot}, plot) +function calculated_attributes!(::Type{<:AbstractPlot}, plot) scene = parent_scene(plot) - if !isnothing(scene) && haskey(plot, :cycle) + return if !isnothing(scene) && haskey(plot, :cycle) add_cycle_attribute!(plot, scene) end end -function calculated_attributes!(::Type{<: Mesh}, plot) +function calculated_attributes!(::Type{<:Mesh}, plot) color = hasproperty(plot.mesh[], :color) ? lift(x -> x.color, plot, plot.mesh) : plot.color color_and_colormap!(plot, color) return end -function calculated_attributes!(::Type{<: Union{Heatmap, Image}}, plot) - color_and_colormap!(plot, plot[3]) +function calculated_attributes!(::Type{<:Union{Heatmap, Image}}, plot) + return color_and_colormap!(plot, plot[3]) end -function calculated_attributes!(::Type{<: Surface}, plot) +function calculated_attributes!(::Type{<:Surface}, plot) colors = plot[3] if haskey(plot, :color) color = plot[:color][] @@ -40,10 +39,10 @@ function calculated_attributes!(::Type{<: Surface}, plot) colors = plot[:color] end end - color_and_colormap!(plot, colors) + return color_and_colormap!(plot, colors) end -function calculated_attributes!(::Type{<: MeshScatter}, plot) +function calculated_attributes!(::Type{<:MeshScatter}, plot) color_and_colormap!(plot) return end @@ -58,13 +57,13 @@ function calculated_attributes!(::Type{<:Text}, plot) return end -function calculated_attributes!(::Type{<: Scatter}, plot) +function calculated_attributes!(::Type{<:Scatter}, plot) # calculate base case color_and_colormap!(plot) - replace_automatic!(plot, :markerspace) do + return replace_automatic!(plot, :markerspace) do lift(plot, plot.markersize) do ms - if ms isa Pixel || (ms isa AbstractVector && all(x-> ms isa Pixel, ms)) + if ms isa Pixel || (ms isa AbstractVector && all(x -> ms isa Pixel, ms)) return :pixel else return :data @@ -73,7 +72,7 @@ function calculated_attributes!(::Type{<: Scatter}, plot) end end -function calculated_attributes!(::Type{T}, plot) where {T<:Union{Lines, LineSegments}} +function calculated_attributes!(::Type{T}, plot) where {T <: Union{Lines, LineSegments}} pos = plot[1][] # extend one color/linewidth per linesegment to be one (the same) color/linewidth per vertex if T <: LineSegments @@ -93,20 +92,22 @@ end const atomic_functions = ( text, meshscatter, scatter, mesh, linesegments, - lines, surface, volume, heatmap, image, voxels + lines, surface, volume, heatmap, image, voxels, ) -const Atomic{Arg} = Union{map(x-> Plot{x, Arg}, atomic_functions)...} +const Atomic{Arg} = Union{map(x -> Plot{x, Arg}, atomic_functions)...} function get_kw_values(func, names, kw) - return [Pair{Symbol,Any}(k, func(kw[k])) - for k in names if haskey(kw, k)] + return [ + Pair{Symbol, Any}(k, func(kw[k])) + for k in names if haskey(kw, k) + ] end function get_kw_obs(names, kw) isempty(names) && return Observable(Pair{Symbol, Any}[]) kw_copy = copy(kw) init = get_kw_values(to_value, names, kw_copy) - obs = Observable(init; ignore_equal_values=true) + obs = Observable(init; ignore_equal_values = true) in_obs = [kw_copy[k] for k in names if haskey(kw_copy, k)] onany(in_obs...) do args... obs[] = get_kw_values(to_value, names, kw_copy) @@ -131,17 +132,17 @@ expand_dimensions(::PointBased, y::OffsetVector{<:Real}) = function expand_dimensions(::Union{ImageLike, GridBased}, data::AbstractMatrix{<:Union{<:Real, <:Colorant}}) # Float32, because all ploteable sizes should fit into float32 - x, y = map(x-> (0f0, Float32(x)), size(data)) + x, y = map(x -> (0.0f0, Float32(x)), size(data)) return (x, y, data) end -function expand_dimensions(::Union{CellGrid, VertexGrid}, data::AbstractMatrix{<:Union{<:Real,<:Colorant}}) - x, y = map(x-> (1f0, Float32(x)), size(data)) +function expand_dimensions(::Union{CellGrid, VertexGrid}, data::AbstractMatrix{<:Union{<:Real, <:Colorant}}) + x, y = map(x -> (1.0f0, Float32(x)), size(data)) return (x, y, data) end function expand_dimensions(::VolumeLike, data::RealArray{3}) - x, y, z = map(x-> (0f0, Float32(x)), size(data)) + x, y, z = map(x -> (0.0f0, Float32(x)), size(data)) return (x, y, z, data) end @@ -156,8 +157,8 @@ function apply_expand_dimensions(trait, args, args_obs, deregister) for (obs, arg) in zip(new_obs, expanded) obs.val = arg end - # It should be enough to trigger the first observable since - # this will go into `map(convert_arguments, new_obs...)` + # It should be enough to trigger the first observable since + # this will go into `map(convert_arguments, new_obs...)` # Without this, we'll get 3 updates for `notify(data)` in `heatmap(data)` notify(new_obs[1]) return @@ -174,7 +175,7 @@ function convert_observable_args(P, args_obs, kw_obs, converted, deregister) new_args_obs = map(Observable, converted) fs = onany(kw_obs, args_obs...) do kw, args... conv = convert_arguments(P, args...; kw...) - if conv isa Union{PlotSpec,BlockSpec,GridLayoutSpec,AbstractVector{PlotSpec}} + if conv isa Union{PlotSpec, BlockSpec, GridLayoutSpec, AbstractVector{PlotSpec}} conv = (conv,) # for PlotSpec elseif !(conv isa Tuple) error("Returned type of convert_arguments needs to be a PlotSpec or Tuple, got: $(typeof(conv))") @@ -190,7 +191,7 @@ function convert_observable_args(P, args_obs, kw_obs, converted, deregister) end function got_converted(P::Type, PTrait::ConversionTrait, result) - if result isa Union{PlotSpec,BlockSpec,GridLayoutSpec,AbstractVector{PlotSpec}} + if result isa Union{PlotSpec, BlockSpec, GridLayoutSpec, AbstractVector{PlotSpec}} return SpecApi end types = MakieCore.types_for_plot_arguments(P, PTrait) @@ -209,7 +210,8 @@ Applies dim_converts, expand_dimensions (in `try_dim_convert`), convert_argument """ function conversion_pipeline( P::Type{<:Plot}, used_attrs::Tuple, args::Tuple, kw_obs, - args_obs::Tuple, user_attributes::Dict{Symbol, Any}, deregister, recursion=1) + args_obs::Tuple, user_attributes::Dict{Symbol, Any}, deregister, recursion = 1 + ) if recursion === 3 error("Recursion limit reached. This should not happen, please open an issue with Makie.jl and provide a minimal working example.") return P, args_obs @@ -230,19 +232,25 @@ function conversion_pipeline( # We haven't reached a target type, so we try to apply convert arguments again and try_dim_convert # This is the case for e.g. convert_arguments returning types that need dim_convert new_args_obs = convert_observable_args(P, dim_converted, kw_obs, converted, deregister) - return conversion_pipeline(P, used_attrs, map(to_value, new_args_obs), kw_obs, new_args_obs, - user_attributes, deregister, - recursion + 1) + return conversion_pipeline( + P, used_attrs, map(to_value, new_args_obs), kw_obs, new_args_obs, + user_attributes, deregister, + recursion + 1 + ) elseif status === false && recursion === 2 - kw_str = isempty(kw) ? "" : " and kw: $(typeof(kw))" + kw_str = isempty(kw) ? "" : " and kw: $(typeof(kw))" kw_convert = isempty(kw) ? "" : "; kw..." conv_trait = PTrait isa NoConversion ? "" : " (With conversion trait $(PTrait))" types = MakieCore.types_for_plot_arguments(P, PTrait) - throw(ArgumentError(""" - Conversion failed for $(P)$(conv_trait) with args: $(typeof(args)) $(kw_str). - $(P) requires to convert to argument types $(types), which convert_arguments didn't succeed in. - To fix this overload convert_arguments(P, args...$(kw_convert)) for $(P) or $(PTrait) and return an object of type $(types).` - """)) + throw( + ArgumentError( + """ + Conversion failed for $(P)$(conv_trait) with args: $(typeof(args)) $(kw_str). + $(P) requires to convert to argument types $(types), which convert_arguments didn't succeed in. + To fix this overload convert_arguments(P, args...$(kw_convert)) for $(P) or $(PTrait) and return an object of type $(types).` + """ + ) + ) elseif isnothing(status) # No types_for_plot_arguments defined, so we don't know what we need to convert to. # This is for backwards compatibility for recipes that don't define argument types @@ -275,9 +283,10 @@ function Plot{Func}(user_args::Tuple, user_attributes::Dict) where {Func} ArgTyp = MakieCore.argtypes(args2) FinalPlotFunc = plotfunc(plottype(P, args2...)) foreach(x -> delete!(user_attributes, x), attr) - return Plot{FinalPlotFunc,ArgTyp}( + return Plot{FinalPlotFunc, ArgTyp}( user_attributes, kw_obs, Any[args_obs...], - Observable[converted_obs...], deregister) + Observable[converted_obs...], deregister + ) end """ @@ -309,7 +318,7 @@ used_attributes(args...) = () # Chose the more specific plot type from arguments or input type # Note the plottype(Scatter, Plot{plot}) will return Scatter # And plottype(args...) falls back to Plot{plot} -plottype(P::Type{<: Plot{T}}, argvalues...) where T = plottype(P, plottype(argvalues...)) +plottype(P::Type{<:Plot{T}}, argvalues...) where {T} = plottype(P, plottype(argvalues...)) plottype(P::Type{<:Plot{T}}) where {T} = P plottype(P1::Type{<:Plot{T1}}, ::Type{<:Plot{T2}}) where {T1, T2} = P1 plottype(::Type{Plot{plot}}, ::Type{Plot{plot}}) = Plot{plot} @@ -333,8 +342,8 @@ plottype(P::Type{<:Plot{T}}, ::Type{Plot{plot}}) where {T} = P plottype(::AbstractVector, ::AbstractVector, ::AbstractVector) = Scatter plottype(::AbstractVector, ::AbstractVector) = Scatter plottype(::AbstractVector) = Scatter -plottype(::AbstractMatrix{<: Real}) = Heatmap -plottype(::Array{<: AbstractFloat, 3}) = Volume +plottype(::AbstractMatrix{<:Real}) = Heatmap +plottype(::Array{<:AbstractFloat, 3}) = Volume plottype(::AbstractString) = Text plottype(::LineString) = Lines @@ -354,7 +363,7 @@ clip_planes_obs(parent::Scene) = parent.theme[:clip_planes] const PlotFunc = Type{<:AbstractPlot} function plot!(::Plot{F, Args}) where {F, Args} - if !(F in atomic_functions) + return if !(F in atomic_functions) error("No recipe for $(F) with args: $(Args)") end end @@ -409,7 +418,7 @@ function plot!(scene::SceneLike, plot::Plot) return plot end -function apply_theme!(scene::Scene, plot::P) where {P<: Plot} +function apply_theme!(scene::Scene, plot::P) where {P <: Plot} raw_attr = attributes(plot.attributes) plot_theme = default_theme(scene, P) plot_sym = plotsym(P) diff --git a/src/jl_rasterizer/bmp.jl b/src/jl_rasterizer/bmp.jl index e18a6d27f77..f38308f50c2 100644 --- a/src/jl_rasterizer/bmp.jl +++ b/src/jl_rasterizer/bmp.jl @@ -6,7 +6,7 @@ function writebmp(io, img) # be a multiple of 4 bytes. extrabytes = 4 - ((w * 3) % 4) (extrabytes == 4) && (extrabytes = 0) - paddedsize = ((w * 3) + extrabytes) * h; + paddedsize = ((w * 3) + extrabytes) * h # file header write(io, b"BM") @@ -34,10 +34,11 @@ function writebmp(io, img) write(io, reinterpret(UInt8, green(rgb))) write(io, reinterpret(UInt8, red(rgb))) end - for i = 1:extrabytes + for i in 1:extrabytes write(io, UInt8(0)) end end + return end using Images, Colors diff --git a/src/jl_rasterizer/main.jl b/src/jl_rasterizer/main.jl index 24305d1d28c..8e204034f51 100644 --- a/src/jl_rasterizer/main.jl +++ b/src/jl_rasterizer/main.jl @@ -4,21 +4,21 @@ using ImageShow using Makie: orthographicprojection @inline function edge_function(a, b, c) - (c[1] - a[1]) * (b[2] - a[2]) - (c[2] - a[2]) * (b[1] - a[1]) + return (c[1] - a[1]) * (b[2] - a[2]) - (c[2] - a[2]) * (b[1] - a[1]) end -@inline function src_alpha(c::T) where T <: Colorant +@inline function src_alpha(c::T) where {T <: Colorant} a = alpha(c) a == 0.0 && return zero(T) - c ./ a + return c ./ a end one_minus_alpha(c::T) where {T <: Colorant} = one(T) .- src_alpha(c) blend(source, dest, src_func, dest_func) = clamp01(src_func(source) .+ dest_func(dest)) ColorTypes.alpha(x::StaticVector) = x[4] -function standard_transparency(source, dest::T) where T - (alpha(source) .* source) .+ ((one(eltype(T)) - alpha(source)) .* dest) +function standard_transparency(source, dest::T) where {T} + return (alpha(source) .* source) .+ ((one(eltype(T)) - alpha(source)) .* dest) end mutable struct FixedGeomView{GeomOut, VT} @@ -36,9 +36,9 @@ Base.size(x::TriangleStripView) = (2,) function Base.getindex(x::TriangleStripView, i) if i === 1 - return ntuple(i-> x.parent[i], 3) + return ntuple(i -> x.parent[i], 3) elseif i === 2 - return map(i-> x.parent[i], (3, 2, 4)) + return map(i -> x.parent[i], (3, 2, 4)) else error("Out of bounds") end @@ -60,7 +60,7 @@ function FixedGeomView(T, max_primitives, primitive_in, primitive_out) end function reset!(A::FixedGeomView) - A.idx = 1 + return A.idx = 1 end function Base.push!(A::FixedGeomView, element) @@ -88,7 +88,7 @@ function JLRasterizer{Vertex, Args, FragN}( geometry_view::GV, emit::EF ) where {Vertex, Args, FragN, VS, FS, GS, GV, EF} - JLRasterizer{Vertex, Args, FragN, VS, FS, GS, GV, EF}( + return JLRasterizer{Vertex, Args, FragN, VS, FS, GS, GV, EF}( vertexshader, fragmentshader, geometryshader, @@ -105,7 +105,7 @@ function geometry_return_type(vertex_array, vertexshader, geometryshader, unifor vertexshader(f, uniforms...) end geometryshader(emit_t, vertex_stage, uniforms...) # figure out typ - typ + return typ end arglength(::Type{T}) where {T <: Tuple} = length(T.parameters) @@ -148,26 +148,26 @@ function rasterizer( geometry_view, emit ) - raster, (vertexarray, uniforms) + return raster, (vertexarray, uniforms) end Base.@pure Next(::Val{N}) where {N} = Val(N - 1) function interpolate(bary, face::NTuple{N, T}, vn::Val{0}, aggregate) where {N, T} - if T <: Tuple + return if T <: Tuple aggregate else T(aggregate...) end end -function interpolate(bary, face, vn::Val{N}, aggregate = ()) where N +function interpolate(bary, face, vn::Val{N}, aggregate = ()) where {N} @inbounds begin res = ( bary[1] * getfield(face[1], N) .+ - bary[2] * getfield(face[2], N) .+ - bary[3] * getfield(face[3], N) + bary[2] * getfield(face[2], N) .+ + bary[3] * getfield(face[3], N) ) end return interpolate(bary, face, Next(vn), (res, aggregate...)) @@ -179,7 +179,7 @@ broadcastmax(a, b) = max.(a, b) function clip2pixel_space(position, resolution) clipspace = position ./ position[4] p = clipspace[Vec(1, 2)] - (((p .+ 1f0) / 2f0) .* (resolution .- 1f0)) .+ 1f0, clipspace[3] + return (((p .+ 1.0f0) / 2.0f0) .* (resolution .- 1.0f0)) .+ 1.0f0, clipspace[3] end @@ -216,11 +216,11 @@ function (r::JLRasterizer{Vert, Args, FragN})( depths = map(last, fdepth) vertex_out = map(last, geom_face) # Bounding rectangle - mini = max.(reduce(broadcastmin, f), 1f0) + mini = max.(reduce(broadcastmin, f), 1.0f0) maxi = min.(reduce(broadcastmax, f), resolution) area = edge_function(f[1], f[2], f[3]) - for y = mini[2]:maxi[2] - for x = mini[1]:maxi[1] + for y in mini[2]:maxi[2] + for x in mini[1]:maxi[1] p = Vec(x, y) w = Vec( edge_function(f[2], f[3], p), @@ -228,7 +228,7 @@ function (r::JLRasterizer{Vert, Args, FragN})( edge_function(f[1], f[2], p) ) yi, xi = round(Int, y), round(Int, x) - if all(w-> w >= 0f0, w) && checkbounds(Bool, framebuffers[1], yi, xi) + if all(w -> w >= 0.0f0, w) && checkbounds(Bool, framebuffers[1], yi, xi) bary = w / area depth = bary[1] * depths[1] + bary[2] * depths[2] + bary[3] * depths[3] @@ -237,7 +237,7 @@ function (r::JLRasterizer{Vert, Args, FragN})( depthbuffer[yi, xi] = depth fragment_in = interpolate(bary, vertex_out, FragNVal) fragment_out = fshader(fragment_in, uniforms...) - for i = eachindex(fragment_out) + for i in eachindex(fragment_out) src_color = framebuffers[i][yi, xi] dest_color = fragment_out[i] fragments_drawn += 1 @@ -264,21 +264,21 @@ smoothstep performs smooth Hermite interpolation between 0 and 1 when edge0 < x ``` Results are undefined if edge0 ≥ edge1. """ -function smoothstep(edge0, edge1, x::T) where T +function smoothstep(edge0, edge1, x::T) where {T} t = clamp.((x .- edge0) ./ (edge1 .- edge0), T(0), T(1)) return t * t * (T(3) - T(2) * t) end -function aastep(threshold1::T, value) where T - afwidth = norm(Vec2f(dFdx(value), dFdy(value))) * T(1.05); - smoothstep(threshold1 - afwidth, threshold1 + afwidth, value) +function aastep(threshold1::T, value) where {T} + afwidth = norm(Vec2f(dFdx(value), dFdy(value))) * T(1.05) + return smoothstep(threshold1 - afwidth, threshold1 + afwidth, value) end -function aastep(threshold1::T, threshold2::T, value::T) where T - afwidth = norm(Vec2f(dFdx(value), dFdy(value))) * T(1.05); +function aastep(threshold1::T, threshold2::T, value::T) where {T} + afwidth = norm(Vec2f(dFdx(value), dFdy(value))) * T(1.05) return ( smoothstep(threshold1 - afwidth, threshold1 + afwidth, value) - - smoothstep(threshold2 - afwidth, threshold2 + afwidth, value) + smoothstep(threshold2 - afwidth, threshold2 + afwidth, value) ) end @@ -318,7 +318,7 @@ function vert_particles(vertex, uniforms) p = vertex.position scale = vertex.scale return Vertex2Geom( - Vec4f(0,0,1,1), + Vec4f(0, 0, 1, 1), vertex.color, Vec4f(p[1], p[2], scale[1], scale[2]) ) @@ -355,7 +355,7 @@ function geom_particles(emit!, vertex_out, uniforms) pos_scale = arg.rect pos = pos_scale[Vec(1, 2)] scale = pos_scale[Vec(3, 4)] - quad = Vec4f(0f0, 0f0, scale[1], scale[2]) + quad = Vec4f(0.0f0, 0.0f0, scale[1], scale[2]) uv = arg.uvrect emit_vertex(emit!, quad[Vec(1, 2)], uv[Vec(1, 4)], arg, pos, uniforms) emit_vertex(emit!, quad[Vec(1, 4)], uv[Vec(1, 2)], arg, pos, uniforms) @@ -366,23 +366,23 @@ end function sdf2color(dist, bg_color, color) - inside = aastep(0f0, dist) - mix(bg_color, color, inside) + inside = aastep(0.0f0, dist) + return mix(bg_color, color, inside) end function frag_particles(geom_out, uniforms, image) uv = geom_out[1]; color = geom_out[2] dist = -image[uv][1] - bg_color = Vec4f(0f0, 0f0, 0f0, 0f0) - (sdf2color(dist, bg_color, color), ) + bg_color = Vec4f(0.0f0, 0.0f0, 0.0f0, 0.0f0) + return (sdf2color(dist, bg_color, color),) end function frag_particles(geom_out, uniforms) uv = geom_out[1]; color = geom_out[2] dist = uniforms.distance_func(uv) - bg_color = Vec4f(0f0, 0f0, 0f0, 0f0) + bg_color = Vec4f(0.0f0, 0.0f0, 0.0f0, 0.0f0) # col = Vec4f(norm(uv .- 0.5), 0, 0, 1) - (sdf2color(dist, bg_color, color), ) + return (sdf2color(dist, bg_color, color),) end resolution = (1024, 1024) @@ -400,13 +400,17 @@ uniforms = Uniforms( N = 10 -middle = Vec2f(resolution) / 2f0 -radius = (min(resolution...) / 2f0) - 50 -vertices = [(VertexCS( - Vec2f((sin(2pi * (i / N)) , cos(2pi * (i / N))) .* radius) .+ middle, - Vec4f(1, i/N, 0, 1), - Vec2f(40, 40) -),) for i = 1:N] +middle = Vec2f(resolution) / 2.0f0 +radius = (min(resolution...) / 2.0f0) - 50 +vertices = [ + ( + VertexCS( + Vec2f((sin(2pi * (i / N)), cos(2pi * (i / N))) .* radius) .+ middle, + Vec4f(1, i / N, 0, 1), + Vec2f(40, 40) + ), + ) for i in 1:N +] raster, rest = rasterizer( @@ -426,7 +430,7 @@ struct Canvas{N} end function Canvas(xdim::Integer, ydim::Integer) - color = fill(RGBA{Float32}(0,0,0,0), xdim, ydim) + color = fill(RGBA{Float32}(0, 0, 0, 0), xdim, ydim) depth = ones(Float32, xdim, ydim) return Canvas((color,), depth) end diff --git a/src/layouting/boundingbox.jl b/src/layouting/boundingbox.jl index ba7bb5a6854..08cced6484b 100644 --- a/src/layouting/boundingbox.jl +++ b/src/layouting/boundingbox.jl @@ -1,4 +1,3 @@ - ################################################################################ ### boundingbox ################################################################################ @@ -14,7 +13,7 @@ the `model` matrix. Plots with `exclude(plot) == true` are excluded. See also: [`data_limits`](@ref) """ -function boundingbox(scenelike, exclude::Function = (p)-> false, space::Symbol = :data) +function boundingbox(scenelike, exclude::Function = (p) -> false, space::Symbol = :data) bb_ref = Base.RefValue(Rect3d()) foreach_plot(scenelike) do plot if !exclude(plot) @@ -60,7 +59,7 @@ function boundingbox(plot::MeshScatter, space::Symbol = :data) bb = Rect3d(positions) marker_bb = rotation * (marker_bb * scales) if plot.transform_marker[]::Bool - model = (plot.model[][Vec(1,2,3), Vec(1,2,3)])::Mat3d + model = (plot.model[][Vec(1, 2, 3), Vec(1, 2, 3)])::Mat3d corners = [model * p for p in coordinates(marker_bb)] mini = minimum(corners); maxi = maximum(corners) return Rect3d(minimum(bb) + mini, widths(bb) + maxi - mini) @@ -79,7 +78,7 @@ end function limits_with_marker_transforms(positions, scales, rotation, model, element_bbox) isempty(positions) && return Rect3d() # translations don't apply to element_bbox, they are already included in positions - model3 = model[Vec(1,2,3), Vec(1,2,3)] + model3 = model[Vec(1, 2, 3), Vec(1, 2, 3)] vertices = decompose(Point3d, element_bbox) full_bbox = Ref(Rect3d()) @@ -107,7 +106,7 @@ function boundingbox(plot::Scatter) rotations = convert_attribute(to_value(get(plot, :rotation, 0)), key"rotation"()) marker_offsets = convert_attribute(plot.marker_offset[], key"marker_offset"(), key"scatter"()) model = plot.model[] - model33 = model[Vec(1,2,3), Vec(1,2,3)] + model33 = model[Vec(1, 2, 3), Vec(1, 2, 3)] transform_marker = to_value(get(plot, :transform_marker, false))::Bool clip_planes = plot.clip_planes[] @@ -124,9 +123,9 @@ function boundingbox(plot::Scatter) quad_rotation = sv_getindex(rotations, i) if transform_marker - marker_pos += model[Vec(1,2,3), Vec(1,2,3)] * marker_offset + marker_pos += model[Vec(1, 2, 3), Vec(1, 2, 3)] * marker_offset p4d = model * to_ndim(Point4d, quad_origin, 1) - quad_origin = quad_rotation * p4d[Vec(1,2,3)] / p4d[4] + quad_origin = quad_rotation * p4d[Vec(1, 2, 3)] / p4d[4] quad_v1 = quad_rotation * (model33 * Vec3d(quad_size[1], 0, 0)) quad_v2 = quad_rotation * (model33 * Vec3d(0, quad_size[2], 0)) else @@ -150,7 +149,6 @@ function boundingbox(plot::Scatter) end - ################################################################################ ### transformed point iterator ################################################################################ @@ -158,6 +156,6 @@ end @inline iterate_transformed(plot) = iterate_transformed(plot, point_iterator(plot)) -function iterate_transformed(plot, points::AbstractArray{<: VecTypes}) +function iterate_transformed(plot, points::AbstractArray{<:VecTypes}) return filter(p -> !is_clipped(plot.clip_planes[], p), apply_transform_and_model(plot, points)) end diff --git a/src/layouting/data_limits.jl b/src/layouting/data_limits.jl index 113907e0c78..b72c4588f35 100644 --- a/src/layouting/data_limits.jl +++ b/src/layouting/data_limits.jl @@ -22,7 +22,7 @@ a plot and thus does not include any transformations. See also: [`boundingbox`](@ref) """ -function data_limits(scenelike, exclude::Function = (p)-> false) +function data_limits(scenelike, exclude::Function = (p) -> false) bb_ref = Base.RefValue(Rect3d()) foreach_plot(scenelike) do plot if !exclude(plot) @@ -167,7 +167,7 @@ function point_iterator(plot::Union{Scatter, MeshScatter, Lines, LineSegments}) end point_iterator(plot::Text) = point_iterator(plot.plots[1]) -function point_iterator(plot::Text{<: Tuple{<: Union{GlyphCollection, AbstractVector{GlyphCollection}}}}) +function point_iterator(plot::Text{<:Tuple{<:Union{GlyphCollection, AbstractVector{GlyphCollection}}}}) return plot.position[] end @@ -187,7 +187,7 @@ point_iterator(bbox::Rect) = unique(decompose(Point3d, bbox)) isfinite_rect(x::Rect) = all(isfinite, x.origin) && all(isfinite, x.widths) -function isfinite_rect(x::Rect{N}, dim::Int) where N +function isfinite_rect(x::Rect{N}, dim::Int) where {N} if 0 < dim <= N return isfinite(origin(x)[dim]) && isfinite(widths(x)[dim]) else @@ -240,12 +240,12 @@ end # used in colorsampler.jl, datashader.jl function distinct_extrema_nan(x) lo, hi = extrema_nan(x) - lo == hi ? (lo - 0.5f0, hi + 0.5f0) : (lo, hi) + return lo == hi ? (lo - 0.5f0, hi + 0.5f0) : (lo, hi) end # TODO: Consider deprecating Ref versions (performance is the same) function update_boundingbox!(bb_ref::Base.RefValue, point) - bb_ref[] = update_boundingbox(bb_ref[], point) + return bb_ref[] = update_boundingbox(bb_ref[], point) end function update_boundingbox(bb::Rect{N, T1}, point::VecTypes{M, T2}) where {N, T1, M, T2} p = to_ndim(Vec{N, promote_type(T1, T2)}, point, 0.0) @@ -255,9 +255,9 @@ function update_boundingbox(bb::Rect{N, T1}, point::VecTypes{M, T2}) where {N, T end function update_boundingbox!(bb_ref::Base.RefValue, bb::Rect) - bb_ref[] = update_boundingbox(bb_ref[], bb) + return bb_ref[] = update_boundingbox(bb_ref[], bb) end -function update_boundingbox(a::Rect{N}, b::Rect{N}) where N +function update_boundingbox(a::Rect{N}, b::Rect{N}) where {N} mini = finite_min.(minimum(a), minimum(b)) maxi = finite_max.(maximum(a), maximum(b)) return Rect{N}(mini, maxi - mini) @@ -271,7 +271,7 @@ foreach_plot(f, s::Scene) = foreach_plot(f, s.plots) # foreach_plot(f, s::FigureAxisPlot) = foreach_plot(f, s.figure) foreach_plot(f, list::AbstractVector) = foreach(f, list) function foreach_plot(f, plot::Plot) - if isempty(plot.plots) + return if isempty(plot.plots) f(plot) else foreach_plot(f, plot.plots) diff --git a/src/layouting/text_boundingbox.jl b/src/layouting/text_boundingbox.jl index 649ecece193..a7aa660c29c 100644 --- a/src/layouting/text_boundingbox.jl +++ b/src/layouting/text_boundingbox.jl @@ -59,7 +59,7 @@ function string_boundingbox(x::Text{<:Tuple{<:AbstractArray{<:GlyphCollection}}} return string_boundingbox(x[1][], pos, to_rotation(x.rotation[])) end -function string_boundingbox(x::Union{GlyphCollection,AbstractArray{<:GlyphCollection}}, args...) +function string_boundingbox(x::Union{GlyphCollection, AbstractArray{<:GlyphCollection}}, args...) bb = unchecked_boundingbox(x, args...) isfinite_rect(bb) || error("Invalid text boundingbox $bb") return bb @@ -67,11 +67,12 @@ end # Utility function text_bb(str, font, size) - rot = Quaternionf(0,0,0,1) + rot = Quaternionf(0, 0, 0, 1) fonts = nothing # TODO: remove the arg if possible layout = layout_text( str, size, font, fonts, Vec2f(0), rot, 0.5, 1.0, - RGBAf(0, 0, 0, 0), RGBAf(0, 0, 0, 0), 0f0, 0f0) + RGBAf(0, 0, 0, 0), RGBAf(0, 0, 0, 0), 0.0f0, 0.0f0 + ) return string_boundingbox(layout, Point3d(0), rot) end @@ -122,7 +123,7 @@ end function gl_bboxes(gl::GlyphCollection) scales = gl.scales.sv isa Vec2 ? (gl.scales.sv for _ in gl.extents) : gl.scales.sv - map(gl.glyphs, gl.extents, scales) do c, ext, scale + return map(gl.glyphs, gl.extents, scales) do c, ext, scale hi_bb = height_insensitive_boundingbox_with_advance(ext) # TODO c != 0 filters out all non renderables, which is not always desired return Rect2d(origin(hi_bb) * scale, (c != 0) * widths(hi_bb) * scale) @@ -149,4 +150,4 @@ end function rotate_bbox(bb::Rect3{T}, rot) where {T <: Real} points = decompose(Point3{T}, bb) return Rect3{T}(Ref(rot) .* points) -end \ No newline at end of file +end diff --git a/src/layouting/text_layouting.jl b/src/layouting/text_layouting.jl index ce3bab23f17..1b7958f6572 100644 --- a/src/layouting/text_layouting.jl +++ b/src/layouting/text_layouting.jl @@ -31,7 +31,6 @@ function attribute_per_char(string, attribute) end - """ layout_text( string::AbstractString, fontsize::Union{AbstractVector, Number}, @@ -74,7 +73,8 @@ function glyph_collection( isempty(str) && return GlyphCollection( [], NativeFont[], Point3f[], FreeTypeAbstraction.FontExtent{Float32}[], - Vec2f[], Float32[], RGBAf[], RGBAf[], 0f0) + Vec2f[], Float32[], RGBAf[], RGBAf[], 0.0f0 + ) # collect information about every character in the string charinfos = broadcast((c for c in str), font_per_char, fontscale_px) do char, font, scale @@ -83,7 +83,7 @@ function glyph_collection( font = font, scale = scale, lineheight = Float32(font.height / font.units_per_EM * lineheight_factor * last(scale)), - extent = GlyphExtent(font, char) + extent = GlyphExtent(font, char), ) end @@ -95,8 +95,8 @@ function glyph_collection( last_space_local_idx = 0 last_space_global_idx = 0 - newline_offset = 0f0 - x = 0f0 + newline_offset = 0.0f0 + x = 0.0f0 xs = [Float32[]] # If word_wrap_width > 0: @@ -117,17 +117,19 @@ function glyph_collection( ((ci.char in (' ', '\n')) || i == length(charinfos)) newline_offset = xs[end][last_space_local_idx + 1] - push!(xs, xs[end][last_space_local_idx+1:end] .- newline_offset) - xs[end-1] = xs[end-1][1:last_space_local_idx] + push!(xs, xs[end][(last_space_local_idx + 1):end] .- newline_offset) + xs[end - 1] = xs[end - 1][1:last_space_local_idx] push!(lineinfos, view(charinfos, last_line_start:last_space_global_idx)) - last_line_start = last_space_global_idx+1 + last_line_start = last_space_global_idx + 1 x = xs[end][end] + ci.extent.hadvance * first(ci.scale) # TODO Do we need to redo the metrics for newlines? charinfos[last_space_global_idx] = let _, font, scale, lineheight, extent = charinfos[last_space_global_idx] - (char = '\n', font = font, scale = scale, - lineheight = lineheight, extent = extent) + ( + char = '\n', font = font, scale = scale, + lineheight = lineheight, extent = extent, + ) end end @@ -135,8 +137,8 @@ function glyph_collection( push!(xs, Float32[]) push!(lineinfos, view(charinfos, last_line_start:i)) last_space_local_idx = 0 - last_line_start = i+1 - x = 0f0 + last_line_start = i + 1 + x = 0.0f0 elseif i == length(charinfos) push!(lineinfos, view(charinfos, last_line_start:i)) end @@ -230,7 +232,7 @@ function glyph_collection( # compute boundingboxes without relayouting and maybe implement # interactive features that need to know where characters begin and end function scalar_or_vec(attr) - attr # attribute_per_char returns generators + return attr # attribute_per_char returns generators end return GlyphCollection( [FreeTypeAbstraction.glyph_index(x.font, x.char) for x in charinfos], @@ -246,7 +248,7 @@ function glyph_collection( end # function to concatenate vectors with a value between every pair -function padded_vcat(arrs::AbstractVector{T}, fillvalue) where T <: AbstractVector{S} where S +function padded_vcat(arrs::AbstractVector{T}, fillvalue) where {T <: AbstractVector{S}} where {S} n = sum(length.(arrs)) arr = fill(convert(S, fillvalue), n + length(arrs) - 1) @@ -258,7 +260,7 @@ function padded_vcat(arrs::AbstractVector{T}, fillvalue) where T <: AbstractVect end counter += 1 end - arr + return arr end # Backend data @@ -318,7 +320,7 @@ function text_quads(atlas::TextureAtlas, position::VecTypes, gc::GlyphCollection return pos, char_offsets, quad_offsets, uvs, scales end -function text_quads(atlas::TextureAtlas, positions::Vector, gcs::Vector{<: GlyphCollection}, offset) +function text_quads(atlas::TextureAtlas, positions::Vector, gcs::Vector{<:GlyphCollection}, offset) pos = [to_ndim(Point3f, p, 0) for (p, gc) in zip(positions, gcs) for _ in gc.origins] pad = atlas.glyph_padding / atlas.pix_per_glyph diff --git a/src/layouting/transformation.jl b/src/layouting/transformation.jl index 4848cd58506..ef409473111 100644 --- a/src/layouting/transformation.jl +++ b/src/layouting/transformation.jl @@ -13,16 +13,16 @@ function parent_transform(x) return isnothing(p) ? Mat4f(I) : p.model[] end -function Observables.connect!(parent::Transformation, child::Transformation; connect_func=true) +function Observables.connect!(parent::Transformation, child::Transformation; connect_func = true) tfuncs = [] # Observables.clear(child.parent_model) - obsfunc = on(parent.model; update=true) do m + obsfunc = on(parent.model; update = true) do m return child.parent_model[] = m end push!(tfuncs, obsfunc) if connect_func # Observables.clear(child.transform_func) - t2 = on(parent.transform_func; update=true) do f + t2 = on(parent.transform_func; update = true) do f child.transform_func[] = f return end @@ -49,13 +49,13 @@ end function translated(scene::Scene, translation...) tscene = Scene(scene, transformation = Transformation()) transform!(tscene, translation...) - tscene + return tscene end function translated(scene::Scene; kw_args...) tscene = Scene(scene, transformation = Transformation()) transform!(tscene; kw_args...) - tscene + return tscene end function transform!( @@ -66,13 +66,13 @@ function transform!( ) translate!(t, to_value(translation)) scale!(t, to_value(scale)) - rotate!(t, to_value(rotation)) + return rotate!(t, to_value(rotation)) end function transform!( t::Transformable, attributes::Union{Attributes, AbstractDict, NamedTuple} ) - transform!(t; attributes...) + return transform!(t; attributes...) end transformation(t::Scene) = t.transformation @@ -98,7 +98,7 @@ scale(t::Transformable) = transformation(t).scale function scale!(::Type{T}, t::Transformable, s::VecTypes) where {T} factor = to_ndim(Vec3d, s, 1) - if T === Accum + return if T === Accum scale(t)[] = scale(t)[] .* factor elseif T == Absolute scale(t)[] = factor @@ -121,9 +121,9 @@ scale!(::Type{T}, t::Transformable, xyz...) where {T} = scale!(T, t, xyz) rotation(t::Transformable) = transformation(t).rotation -function rotate!(::Type{T}, t::Transformable, q) where T +function rotate!(::Type{T}, t::Transformable, q) where {T} rot = convert_attribute(q, key"rotation"()) - if T === Accum + return if T === Accum rot1 = rotation(t)[] rotation(t)[] = rot1 * rot elseif T == Absolute @@ -138,7 +138,7 @@ end Apply a relative rotation to the transformable, by multiplying by the current rotation. """ -rotate!(::Type{T}, t::Transformable, axis_rot...) where T = rotate!(T, t, axis_rot) +rotate!(::Type{T}, t::Transformable, axis_rot...) where {T} = rotate!(T, t, axis_rot) """ rotate!(t::Transformable, axis_rot::Quaternion) @@ -153,9 +153,9 @@ rotate!(t::Transformable, axis_rot::Real) = rotate!(Absolute, t, axis_rot) translation(t::Transformable) = transformation(t).translation -function translate!(::Type{T}, t::Transformable, trans) where T +function translate!(::Type{T}, t::Transformable, trans) where {T} offset = to_ndim(Vec3d, trans, 0) - if T === Accum + return if T === Accum translation(t)[] = translation(t)[] .+ offset elseif T === Absolute translation(t)[] = offset @@ -177,7 +177,7 @@ translate!(t::Transformable, xyz...) = translate!(Absolute, t, xyz) Translate the given `Transformable` (a Scene or Plot), relative to its current position. """ -translate!(::Type{T}, t::Transformable, xyz...) where T = translate!(T, t, xyz) +translate!(::Type{T}, t::Transformable, xyz...) where {T} = translate!(T, t, xyz) GeometryBasics.origin(t::Transformable) = transformation(t).origin @@ -194,9 +194,9 @@ origin!(t::Transformable, xyz...) = origin!(Absolute, t, xyz) origin!(t::Transformable, xyz::VecTypes) = origin!(Absolute, t, xyz) origin!(::Type{T}, t::Transformable, xyz...) where {T} = origin!(T, t, xyz) -function origin!(::Type{T}, t::Transformable, xyz::VecTypes) where T +function origin!(::Type{T}, t::Transformable, xyz::VecTypes) where {T} offset = to_ndim(Vec3d, xyz, 0) - if T === Accum + return if T === Accum origin(t)[] = origin(t)[] + offset elseif T === Absolute origin(t)[] = offset @@ -205,23 +205,23 @@ function origin!(::Type{T}, t::Transformable, xyz::VecTypes) where T end end -function transform!(t::Transformable, x::Tuple{Symbol, <: Number}) +function transform!(t::Transformable, x::Tuple{Symbol, <:Number}) plane, dimval = string(x[1]), Float64(x[2]) - if length(plane) != 2 || (!all(x-> x in ('x', 'y', 'z'), plane)) + if length(plane) != 2 || (!all(x -> x in ('x', 'y', 'z'), plane)) error("plane needs to define a 2D plane in xyz. It should only contain 2 symbols out of (:x, :y, :z). Found: $plane") end - if all(x-> x in ('x', 'y'), plane) # xy plane + if all(x -> x in ('x', 'y'), plane) # xy plane translate!(t, 0, 0, dimval) - elseif all(x-> x in ('x', 'z'), plane) # xz plane + elseif all(x -> x in ('x', 'z'), plane) # xz plane rotate!(t, Vec3f(1, 0, 0), 0.5pi) translate!(t, 0, dimval, 0) else #yz plane r1 = qrotation(Vec3f(0, 1, 0), 0.5pi) r2 = qrotation(Vec3f(1, 0, 0), 0.5pi) - rotate!(t, r2 * r1) + rotate!(t, r2 * r1) translate!(t, dimval, 0, 0) end - t + return t end transformationmatrix(x)::Observable{Mat4d} = transformation(x).model @@ -294,7 +294,7 @@ function apply_model(model::Mat4, transformed::Rect{N, T}, space::Symbol) where end promote_geom(::Type{<:VT}, x::VT) where {VT} = x -promote_geom(::Type{<:VT}, x::AbstractArray{<: VT}) where {VT} = x +promote_geom(::Type{<:VT}, x::AbstractArray{<:VT}) where {VT} = x promote_geom(::Type{<:VecTypes{N, T}}, x::Rect{N, T}) where {N, T} = x promote_geom(output_type::Type{<:VecTypes}, x::VecTypes) = to_ndim(output_type, x, 0) @@ -311,7 +311,7 @@ of the the transformation spaces (currently only :data is transformed) """ apply_transform(f, data, space) = to_value(space) === :data ? apply_transform(f, data) : data function apply_transform(f::Observable, data::Observable, space::Observable) - return lift((f, d, s)-> apply_transform(f, d, s), f, data, space) + return lift((f, d, s) -> apply_transform(f, d, s), f, data, space) end """ @@ -343,14 +343,14 @@ struct PointTrans{N, F} if !hasmethod(f, Tuple{Point{N}}) error("PointTrans with parameter N = $N must be applicable to an argument of type Point{$N}.") end - new{N, F}(f) + return new{N, F}(f) end end # PointTrans{N}(func::F) where {N, F} = PointTrans{N, F}(func) Base.broadcastable(x::PointTrans) = (x,) -function apply_transform(f::PointTrans{N}, point::Point{N}) where N +function apply_transform(f::PointTrans{N}, point::Point{N}) where {N} return f.f(point) end @@ -358,7 +358,7 @@ function apply_transform(f::PointTrans{N1}, point::Point{N2, T}) where {N1, N2, p_dim = to_ndim(Point{N1, T}, point, 0.0) p_trans = f.f(p_dim) if N1 < N2 - p_large = ntuple(i-> i <= N1 ? p_trans[i] : point[i], N2) + p_large = ntuple(i -> i <= N1 ? p_trans[i] : point[i], N2) return Point{N2, T}(p_large) else return to_ndim(Point{N2, T}, p_trans, 0.0) @@ -366,11 +366,11 @@ function apply_transform(f::PointTrans{N1}, point::Point{N2, T}) where {N1, N2, end function apply_transform(f, data::AbstractArray) - map(point -> apply_transform(f, point), data) + return map(point -> apply_transform(f, point), data) end -function apply_transform(f::Tuple{Any, Any}, point::VecTypes{2, T}) where T - Point2{T}( +function apply_transform(f::Tuple{Any, Any}, point::VecTypes{2, T}) where {T} + return Point2{T}( f[1](point[1]), f[2](point[2]), ) @@ -380,13 +380,13 @@ apply_transform(f::NTuple{2, typeof(identity)}, point::VecTypes{2}) = point function apply_transform(f::Tuple{Any, Any}, point::VecTypes{3}) - apply_transform((f..., identity), point) + return apply_transform((f..., identity), point) end # ambiguity fix apply_transform(f::NTuple{2, typeof(identity)}, point::VecTypes{3}) = point -function apply_transform(f::Tuple{Any, Any, Any}, point::VecTypes{3, T}) where T - Point3{T}( +function apply_transform(f::Tuple{Any, Any, Any}, point::VecTypes{3, T}) where {T} + return Point3{T}( f[1](point[1]), f[2](point[2]), f[3](point[3]), @@ -399,7 +399,7 @@ apply_transform(f::NTuple{3, typeof(identity)}, point::VecTypes{3}) = point apply_transform(f, number::Number) = f(number) function apply_transform(f::Observable, data::Observable) - return lift((f, d)-> apply_transform(f, d), f, data) + return lift((f, d) -> apply_transform(f, d), f, data) end apply_transform(f, itr::Pair) = apply_transform(f, itr[1]) => apply_transform(f, itr[2]) @@ -413,14 +413,14 @@ function apply_transform(f, r::Rect) ma = maximum(r) mi_t = apply_transform(f, mi) ma_t = apply_transform(f, ma) - Rect(Vec(mi_t), Vec(ma_t .- mi_t)) + return Rect(Vec(mi_t), Vec(ma_t .- mi_t)) end function apply_transform(f::PointTrans, r::Rect) mi = minimum(r) ma = maximum(r) mi_t = apply_transform(f, Point(mi)) ma_t = apply_transform(f, Point(ma)) - Rect(Vec(mi_t), Vec(ma_t .- mi_t)) + return Rect(Vec(mi_t), Vec(ma_t .- mi_t)) end # ambiguity fix @@ -431,8 +431,8 @@ apply_transform(f::NTuple{3, typeof(identity)}, r::Rect) = r const pseudolog10 = ReversibleScale( x -> sign(x) * log10(abs(x) + 1), x -> sign(x) * (exp10(abs(x)) - 1); - limits=(0f0, 3f0), - name=:pseudolog10 + limits = (0.0f0, 3.0f0), + name = :pseudolog10 ) Symlog10(hi) = Symlog10(-hi, hi) @@ -453,7 +453,7 @@ function Symlog10(lo, hi) else x end - return ReversibleScale(forward, inverse; limits=(0.0f0, 3.0f0), name=:Symlog10) + return ReversibleScale(forward, inverse; limits = (0.0f0, 3.0f0), name = :Symlog10) end function inverse_transform(f) @@ -464,7 +464,7 @@ inverse_transform(F::Tuple) = map(inverse_transform, F) inverse_transform(s::ReversibleScale) = s.inverse function is_identity_transform(t) - return t === identity || t isa Tuple && all(x-> x === identity, t) + return t === identity || t isa Tuple && all(x -> x === identity, t) end @@ -508,7 +508,7 @@ end Base.broadcastable(x::Polar) = (x,) -function apply_transform(trans::Polar, point::VecTypes{2, T}) where T <: Real +function apply_transform(trans::Polar, point::VecTypes{2, T}) where {T <: Real} if trans.theta_as_x θ, r = point else @@ -528,7 +528,7 @@ function apply_transform(f::Polar, point::VecTypes{N2, T}) where {N2, T} p_dim = to_ndim(Point2{T}, point, 0.0) p_trans = apply_transform(f, p_dim) if 2 < N2 - p_large = ntuple(i-> i <= 2 ? p_trans[i] : point[i], N2) + p_large = ntuple(i -> i <= 2 ? p_trans[i] : point[i], N2) return Point{N2, T}(p_large) else return to_ndim(Point{N2, T}, p_trans, 0.0) @@ -553,7 +553,7 @@ function inverse_transform(trans::Polar) if trans.theta_as_x return Makie.PointTrans{2}() do point typeof(point)( - mod(trans.direction * atan(point[2], point[1]) - trans.theta_0, 0..2pi), + mod(trans.direction * atan(point[2], point[1]) - trans.theta_0, 0 .. 2pi), hypot(point[1], point[2]) + trans.r0 ) end @@ -561,7 +561,7 @@ function inverse_transform(trans::Polar) return Makie.PointTrans{2}() do point typeof(point)( hypot(point[1], point[2]) + trans.r0, - mod(trans.direction * atan(point[2], point[1]) - trans.theta_0, 0..2pi) + mod(trans.direction * atan(point[2], point[1]) - trans.theta_0, 0 .. 2pi) ) end end @@ -575,4 +575,4 @@ end # by heatmaps or images # zvalue2d(x)::Float32 = Float32(Makie.translation(x)[][3] + zvalue2d(x.parent)) @inline zvalue2d(x)::Float32 = Float32(transformationmatrix(x)[][3, 4]) -@inline zvalue2d(::Nothing)::Float32 = 0f0 +@inline zvalue2d(::Nothing)::Float32 = 0.0f0 diff --git a/src/lighting.jl b/src/lighting.jl index ca2b21e1ca1..e351dc27c5e 100644 --- a/src/lighting.jl +++ b/src/lighting.jl @@ -4,12 +4,12 @@ abstract type AbstractLight end # These need to match up with light shaders to differentiate light types module LightType - const UNDEFINED = 0 - const Ambient = 1 - const PointLight = 2 + const UNDEFINED = 0 + const Ambient = 1 + const PointLight = 2 const DirectionalLight = 3 - const SpotLight = 4 - const RectLight = 5 + const SpotLight = 4 + const RectLight = 5 end # Each light should implement @@ -59,15 +59,15 @@ struct PointLight <: AbstractLight end # no attenuation -function PointLight(color::Union{Colorant, Observable{<: Colorant}}, position::Union{VecTypes{3}, Observable{<: VecTypes{3}}}) +function PointLight(color::Union{Colorant, Observable{<:Colorant}}, position::Union{VecTypes{3}, Observable{<:VecTypes{3}}}) return PointLight(color, position, Vec2f(0)) end # automatic attenuation -function PointLight(color::Union{Colorant, Observable{<: Colorant}}, position::Union{VecTypes{3}, Observable{<: VecTypes{3}}}, range::Real) +function PointLight(color::Union{Colorant, Observable{<:Colorant}}, position::Union{VecTypes{3}, Observable{<:VecTypes{3}}}, range::Real) return PointLight(color, position, default_attenuation(range)) end -@deprecate PointLight(position::Union{VecTypes{3}, Observable{<: VecTypes{3}}}, color::Union{Colorant, Observable{<: Colorant}}) PointLight(color, position) +@deprecate PointLight(position::Union{VecTypes{3}, Observable{<:VecTypes{3}}}, color::Union{Colorant, Observable{<:Colorant}}) PointLight(color, position) light_type(::PointLight) = LightType.PointLight light_color(l::PointLight) = l.color[] @@ -75,8 +75,8 @@ light_color(l::PointLight) = l.color[] # fit of values used on learnopengl/ogre3d function default_attenuation(range::Real) return Vec2f( - 4.690507869767646 * range ^ -1.009712247799057, - 82.4447791934059 * range ^ -2.0192061630628966 + 4.690507869767646 * range^-1.009712247799057, + 82.4447791934059 * range^-2.0192061630628966 ) end @@ -173,15 +173,15 @@ function RectLight(color, r::Rect2) position = Observable(to_ndim(Point3f, mini + 0.5 * ws, 0)) u1 = Observable(Vec3f(ws[1], 0, 0)) u2 = Observable(Vec3f(0, ws[2], 0)) - return RectLight(color, position, u1, u2, normalize(Vec3f(0,0,-1))) + return RectLight(color, position, u1, u2, normalize(Vec3f(0, 0, -1))) end # Implement Transformable interface (more or less) to simplify working with # RectLights -function translate!(::Type{T}, l::RectLight, v) where T +function translate!(::Type{T}, l::RectLight, v) where {T} offset = to_ndim(Vec3f, Float32.(v), 0) - if T === Accum + return if T === Accum l.position[] = l.position[] + offset elseif T === Absolute l.position[] = offset @@ -195,12 +195,12 @@ function rotate!(l::RectLight, q...) rot = convert_attribute(q, key"rotation"()) l.u1[] = rot * l.u1[] l.u2[] = rot * l.u2[] - l.direction[] = rot * l.direction[] + return l.direction[] = rot * l.direction[] end -function scale!(::Type{T}, l::RectLight, s) where T +function scale!(::Type{T}, l::RectLight, s) where {T} scale = to_ndim(Vec2f, Float32.(s), 0) - if T === Accum + return if T === Accum l.u1[] = scale[1] * l.u1[] l.u2[] = scale[2] * l.u2[] elseif T === Absolute @@ -222,12 +222,12 @@ light_color(l::RectLight) = l.color[] function get_one_light(lights, Typ) - indices = findall(x-> x isa Typ, lights) + indices = findall(x -> x isa Typ, lights) isempty(indices) && return nothing return lights[indices[1]] end -function default_shading!(plot, lights::Vector{<: AbstractLight}) +function default_shading!(plot, lights::Vector{<:AbstractLight}) # if the plot does not have :shading we assume the plot doesn't support it haskey(plot.attributes, :shading) || return @@ -275,4 +275,4 @@ function default_shading!(plot, lights::Vector{<: AbstractLight}) plot.attributes[:shading] = shading return -end \ No newline at end of file +end diff --git a/src/makielayout/blocks.jl b/src/makielayout/blocks.jl index b37780777e8..dd7b5b6cb7c 100644 --- a/src/makielayout/blocks.jl +++ b/src/makielayout/blocks.jl @@ -1,5 +1,3 @@ - - function is_attribute end function default_attribute_values end function attribute_default_expressions end @@ -51,7 +49,7 @@ macro Block(_name::Union{Expr, Symbol}, body::Expr = Expr(:block)) constructor = quote function $name($(basefields...)) - new($(basefields...)) + return new($(basefields...)) end end @@ -83,7 +81,7 @@ macro Block(_name::Union{Expr, Symbol}, body::Expr = Expr(:block)) export $name $(Makie).symbol_to_block(::Val{$(QuoteNode(name))}) = $name function $(Makie).is_attribute(::Type{$(name)}, sym::Symbol) - sym in ($((attrs !== nothing ? [QuoteNode(a.symbol) for a in attrs] : [])...),) + return sym in ($((attrs !== nothing ? [QuoteNode(a.symbol) for a in attrs] : [])...),) end function $(Makie).default_attribute_values(::Type{$(name)}, scene::Union{Scene, Nothing}) @@ -103,11 +101,13 @@ macro Block(_name::Union{Expr, Symbol}, body::Expr = Expr(:block)) end function $(Makie)._attribute_docs(::Type{$(name)}) - Dict( + return Dict( $( - (attrs !== nothing ? - [Expr(:call, :(=>), QuoteNode(a.symbol), a.docs) for a in attrs] : - [])... + ( + attrs !== nothing ? + [Expr(:call, :(=>), QuoteNode(a.symbol), a.docs) for a in attrs] : + [] + )... ) ) end @@ -118,18 +118,18 @@ macro Block(_name::Union{Expr, Symbol}, body::Expr = Expr(:block)) @doc docstring_modified $name end - esc(q) + return esc(q) end _defaultstring(x) = string(MacroTools.striplines(x)) _defaultstring(x::String) = repr(x) function make_attr_dict_expr(::Nothing, sceneattrsym, curthemesym) - :(Dict()) + return :(Dict()) end function make_block_docstring(T::Type{<:Block}, docstring) - """ + return """ **`$T <: Block`** $docstring @@ -144,7 +144,7 @@ end function _attribute_list(T) ks = sort(collect(keys(_attribute_docs(T)))) - join(("`$k`" for k in ks), ", ") + return join(("`$k`" for k in ks), ", ") end function make_attr_dict_expr(attrs, sceneattrsym, curthemesym) @@ -177,8 +177,8 @@ function make_attr_dict_expr(attrs, sceneattrsym, curthemesym) :(d[$(QuoteNode(a.symbol))] = $d) end - quote - d = Dict{Symbol,Any}() + return quote + d = Dict{Symbol, Any}() $(exprs...) d end @@ -187,8 +187,10 @@ end function extract_attributes!(body) i = findfirst( - (x -> x isa Expr && x.head === :macrocall && x.args[1] == Symbol("@attributes") && - x.args[3] isa Expr && x.args[3].head === :block), + ( + x -> x isa Expr && x.head === :macrocall && x.args[1] == Symbol("@attributes") && + x.args[3] isa Expr && x.args[3].head === :block + ), body.args ) if i === nothing @@ -232,12 +234,12 @@ function extract_attributes!(body) end end - attrs + return attrs end # intercept all block constructors and divert to _block(T, ...) -function (::Type{T})(args...; kwargs...) where {T<:Block} - _block(T, args...; kwargs...) +function (::Type{T})(args...; kwargs...) where {T <: Block} + return _block(T, args...; kwargs...) end can_be_current_axis(x) = false @@ -246,20 +248,22 @@ get_top_parent(gp::GridLayout) = GridLayoutBase.top_parent(gp) get_top_parent(gp::GridPosition) = GridLayoutBase.top_parent(gp.layout) get_top_parent(gp::GridSubposition) = get_top_parent(gp.parent) -function _block(T::Type{<:Block}, - gp::Union{GridPosition, GridSubposition}, args...; kwargs...) +function _block( + T::Type{<:Block}, + gp::Union{GridPosition, GridSubposition}, args...; kwargs... + ) top_parent = get_top_parent(gp) if top_parent === nothing error("Found nothing as the top parent of this GridPosition. A GridPosition or GridSubposition needs to be connected to the top layout of a Figure, Scene or comparable object, either directly or through nested GridLayouts in order to plot into it.") end b = gp[] = _block(T, top_parent, args...; kwargs...) - b + return b end function _block(T::Type{<:Block}, fig_or_scene::Union{Figure, Scene}, args...; bbox = nothing, kwargs...) - return _block(T, fig_or_scene, Any[args...], Dict{Symbol,Any}(kwargs), bbox) + return _block(T, fig_or_scene, Any[args...], Dict{Symbol, Any}(kwargs), bbox) end function block_defaults(blockname::Symbol, attribute_kwargs::Dict, scene::Union{Nothing, Scene}) @@ -269,8 +273,8 @@ function block_defaults(::Type{B}, attribute_kwargs::Dict, scene::Union{Nothing, default_attrs = default_attribute_values(B, scene) blockname = nameof(B) typekey_scene_attrs = get(theme(scene), blockname, Attributes()) - typekey_attrs = theme(blockname; default=Attributes())::Attributes - attributes = Dict{Symbol,Any}() + typekey_attrs = theme(blockname; default = Attributes())::Attributes + attributes = Dict{Symbol, Any}() # make a final attribute dictionary using different priorities # for the different themes for (key, val) in default_attrs @@ -314,7 +318,7 @@ function _check_remaining_kwargs(T::Type{<:Block}, kwdict::Dict) return end -function _block(T::Type{<:Block}, fig_or_scene::Union{Figure,Scene}, args, kwdict::Dict, bbox; kwdict_complete=false) +function _block(T::Type{<:Block}, fig_or_scene::Union{Figure, Scene}, args, kwdict::Dict, bbox; kwdict_complete = false) # first sort out all user kwargs that correspond to block attributes check_textsize_deprecation(kwdict) @@ -359,7 +363,7 @@ function _block(T::Type{<:Block}, fig_or_scene::Union{Figure,Scene}, args, kwdic suggestedbbox = bbox ) - blockscene = Scene(topscene, clear=false, camera = campixel!) + blockscene = Scene(topscene, clear = false, camera = campixel!) # create base block with otherwise undefined fields b = T(fig_or_scene, lobservables, blockscene) @@ -413,8 +417,10 @@ function _block(T::Type{<:Block}, fig_or_scene::Union{Figure,Scene}, args, kwdic end # forward all layout attributes to the block's layoutobservables - connect_block_layoutobservables!(b, layout_width, layout_height, layout_tellwidth, - layout_tellheight, layout_halign, layout_valign, layout_alignmode) + connect_block_layoutobservables!( + b, layout_width, layout_height, layout_tellwidth, + layout_tellheight, layout_halign, layout_valign, layout_alignmode + ) if fig_or_scene isa Figure register_in_figure!(fig_or_scene, b) @@ -422,7 +428,7 @@ function _block(T::Type{<:Block}, fig_or_scene::Union{Figure,Scene}, args, kwdic Makie.current_axis!(fig_or_scene, b) end end - b + return b end """ @@ -434,7 +440,7 @@ function get_topscene(s::Scene) if !(Makie.cameracontrols(s) isa Makie.PixelCamera) error("Can only use scenes with PixelCamera as topscene") end - s + return s end function register_in_figure!(fig::Figure, @nospecialize block::Block) @@ -444,7 +450,7 @@ function register_in_figure!(fig::Figure, @nospecialize block::Block) if !(block in fig.content) push!(fig.content, block) end - nothing + return nothing end zshift!(b::Block, z) = translate!(b.blockscene, 0, 0, z) @@ -460,8 +466,8 @@ function connect_block_layoutobservables!(@nospecialize(block), layout_width, la return end -@inline function Base.setproperty!(x::T, key::Symbol, value) where T <: Block - if hasfield(T, key) +@inline function Base.setproperty!(x::T, key::Symbol, value) where {T <: Block} + return if hasfield(T, key) if fieldtype(T, key) <: Observable if value isa Observable error("It is disallowed to set `$key`, an Observable field of the $T struct, to an Observable with dot notation (`setproperty!`), because this would replace the existing Observable. If you really want to do this, use `setfield!` instead.") @@ -469,7 +475,7 @@ end obs = fieldtype(T, key) getfield(x, key)[] = convert_for_attribute(observable_type(obs), value) else - setfield!(x, key, value) + setfield!(x, key, value) end else # this will throw correctly @@ -480,8 +486,8 @@ end # treat all blocks as scalars when broadcasting Base.Broadcast.broadcastable(l::Block) = Ref(l) -function Base.show(io::IO, ::T) where T <: Block - print(io, "$T()") +function Base.show(io::IO, ::T) where {T <: Block} + return print(io, "$T()") end # fallback if block doesn't need specific clean up @@ -502,7 +508,7 @@ function unhide!(block::Block) if !block.blockscene.visible[] block.blockscene.visible[] = true end - if hasproperty(block, :scene) && !block.scene.visible[] + return if hasproperty(block, :scene) && !block.scene.visible[] block.scene.visible[] = true end end @@ -511,7 +517,7 @@ function hide!(block::Block) if block.blockscene.visible[] block.blockscene.visible[] = false end - if hasproperty(block, :scene) && block.scene.visible[] + return if hasproperty(block, :scene) && block.scene.visible[] block.scene.visible[] = false end end @@ -539,19 +545,19 @@ function delete_from_parent!(figure::Figure, block::Block) if current_axis(figure) === block current_axis!(figure, nothing) end - nothing + return nothing end function remove_element(x) - delete!(x) + return delete!(x) end function remove_element(x::AbstractPlot) - delete!(x.parent, x) + return delete!(x.parent, x) end function remove_element(xs::AbstractArray) - foreach(remove_element, xs) + return foreach(remove_element, xs) end function remove_element(::Nothing) @@ -577,7 +583,7 @@ function init_observable!(@nospecialize(block), key::Symbol, @nospecialize(OT), return block end -observable_type(x::Type{Observable{T}}) where T = T +observable_type(x::Type{Observable{T}}) where {T} = T convert_for_attribute(t::Any, x) = x convert_for_attribute(t::Type{Float64}, x) = convert(Float64, x) @@ -589,10 +595,10 @@ Base.@kwdef struct Example backend_using::Symbol = backend # the backend that is shown for `using` (for CairoMakie-rendered plots of interactive stuff that should show `using GLMakie`) svg::Bool = true # only for CairoMakie code::String - caption::Union{Nothing,String} = nothing + caption::Union{Nothing, String} = nothing end -function repl_docstring(type::Symbol, attr::Symbol, docs::Union{Nothing,String}, examples::Vector{Example}, default_str) +function repl_docstring(type::Symbol, attr::Symbol, docs::Union{Nothing, String}, examples::Vector{Example}, default_str) io = IOBuffer() println(io, "Default value: `$default_str`") @@ -616,7 +622,7 @@ function repl_docstring(type::Symbol, attr::Symbol, docs::Union{Nothing,String}, println(io) end - Markdown.parse(String(take!(io))) + return Markdown.parse(String(take!(io))) end # function example(type::Type{<:Block}, attr::Symbol, i::Int) @@ -628,8 +634,8 @@ end # return # end -function attribute_examples(b::Union{Type{<:Block},Type{<:Plot}}) - Dict{Symbol,Vector{Example}}() +function attribute_examples(b::Union{Type{<:Block}, Type{<:Plot}}) + return Dict{Symbol, Vector{Example}}() end # overrides `?Axis.xticks` and similar lookups in the REPL diff --git a/src/makielayout/blocks/axis.jl b/src/makielayout/blocks/axis.jl index d421d4b86ef..8e078d6c2a4 100644 --- a/src/makielayout/blocks/axis.jl +++ b/src/makielayout/blocks/axis.jl @@ -63,7 +63,7 @@ end function update_axis_camera(scene::Scene, t, lims, xrev::Bool, yrev::Bool) nearclip = -10_000f0 - farclip = 10_000f0 + farclip = 10_000f0 # we are computing transformed camera position, so this isn't space dependent tlims = Makie.apply_transform(t, lims) @@ -72,14 +72,15 @@ function update_axis_camera(scene::Scene, t, lims, xrev::Bool, yrev::Bool) update_limits!(scene.float32convert, tlims) # update float32 scaling lims32 = f32_convert(scene.float32convert, tlims) # get scaled limits left, bottom = minimum(lims32) - right, top = maximum(lims32) + right, top = maximum(lims32) leftright = xrev ? (right, left) : (left, right) bottomtop = yrev ? (top, bottom) : (bottom, top) projection = Makie.orthographicprojection( Float32, leftright..., - bottomtop..., nearclip, farclip) + bottomtop..., nearclip, farclip + ) Makie.set_proj_view!(camera, projection, Makie.Mat4f(Makie.I)) return @@ -100,22 +101,24 @@ function calculate_title_position(area, titlegap, subtitlegap, align, xaxisposit local subtitlespace::Float32 = if ax.subtitlevisible[] && !iswhitespace(ax.subtitle[]) boundingbox(subtitlet, :data).widths[2] + subtitlegap else - 0f0 + 0.0f0 end - local yoffset::Float32 = top(area) + titlegap + (xaxisposition === :top ? xaxisprotrusion : 0f0) + + local yoffset::Float32 = top(area) + titlegap + (xaxisposition === :top ? xaxisprotrusion : 0.0f0) + subtitlespace return Point2f(x, yoffset) end -function compute_protrusions(title, titlesize, titlegap, titlevisible, spinewidth, +function compute_protrusions( + title, titlesize, titlegap, titlevisible, spinewidth, topspinevisible, bottomspinevisible, leftspinevisible, rightspinevisible, xaxisprotrusion, yaxisprotrusion, xaxisposition, yaxisposition, subtitle, subtitlevisible, subtitlesize, subtitlegap, titlelineheight, subtitlelineheight, - subtitlet, titlet) + subtitlet, titlet + ) - local left::Float32, right::Float32, bottom::Float32, top::Float32 = 0f0, 0f0, 0f0, 0f0 + local left::Float32, right::Float32, bottom::Float32, top::Float32 = 0.0f0, 0.0f0, 0.0f0, 0.0f0 if xaxisposition === :bottom bottom = xaxisprotrusion @@ -127,12 +130,12 @@ function compute_protrusions(title, titlesize, titlegap, titlevisible, spinewidt subtitleheight = boundingbox(subtitlet, :data).widths[2] + subtitlegap titlespace = if !titlevisible || iswhitespace(title) - 0f0 + 0.0f0 else titleheight end subtitlespace = if !subtitlevisible || iswhitespace(subtitle) - 0f0 + 0.0f0 else subtitleheight end @@ -157,7 +160,7 @@ function initialize_block!(ax::Axis; palette = nothing) # initialize either with user limits, or pick defaults based on scales # so that we don't immediately error targetlimits = Observable{Rect2d}(defaultlimits(ax.limits[], ax.xscale[], ax.yscale[])) - finallimits = Observable{Rect2d}(targetlimits[]; ignore_equal_values=true) + finallimits = Observable{Rect2d}(targetlimits[]; ignore_equal_values = true) setfield!(ax, :targetlimits, targetlimits) setfield!(ax, :finallimits, finallimits) @@ -173,7 +176,7 @@ function initialize_block!(ax::Axis; palette = nothing) scenearea = sceneareanode!(ax.layoutobservables.computedbbox, finallimits, ax.aspect) - scene = Scene(blockscene, viewport=scenearea) + scene = Scene(blockscene, viewport = scenearea) ax.scene = scene # transfer conversions from axis to scene if there are any # or the other way around @@ -189,7 +192,7 @@ function initialize_block!(ax::Axis; palette = nothing) # TODO: replace with mesh, however, CairoMakie needs a poly path for this signature # so it doesn't rasterize the scene - background = poly!(blockscene, scenearea; color=ax.backgroundcolor, inspectable=false, shading=NoShading, strokecolor=:transparent) + background = poly!(blockscene, scenearea; color = ax.backgroundcolor, inspectable = false, shading = NoShading, strokecolor = :transparent) translate!(background, 0, 0, -100) elements[:background] = background @@ -199,7 +202,7 @@ function initialize_block!(ax::Axis; palette = nothing) ax.xaxislinks = Axis[] ax.yaxislinks = Axis[] - xgridnode = Observable(Point2f[]; ignore_equal_values=true) + xgridnode = Observable(Point2f[]; ignore_equal_values = true) xgridlines = linesegments!( blockscene, xgridnode, linewidth = ax.xgridwidth, visible = ax.xgridvisible, color = ax.xgridcolor, linestyle = ax.xgridstyle, inspectable = false @@ -208,7 +211,7 @@ function initialize_block!(ax::Axis; palette = nothing) translate!(xgridlines, 0, 0, -10) elements[:xgridlines] = xgridlines - xminorgridnode = Observable(Point2f[]; ignore_equal_values=true) + xminorgridnode = Observable(Point2f[]; ignore_equal_values = true) xminorgridlines = linesegments!( blockscene, xminorgridnode, linewidth = ax.xminorgridwidth, visible = ax.xminorgridvisible, color = ax.xminorgridcolor, linestyle = ax.xminorgridstyle, inspectable = false @@ -217,7 +220,7 @@ function initialize_block!(ax::Axis; palette = nothing) translate!(xminorgridlines, 0, 0, -10) elements[:xminorgridlines] = xminorgridlines - ygridnode = Observable(Point2f[]; ignore_equal_values=true) + ygridnode = Observable(Point2f[]; ignore_equal_values = true) ygridlines = linesegments!( blockscene, ygridnode, linewidth = ax.ygridwidth, visible = ax.ygridvisible, color = ax.ygridcolor, linestyle = ax.ygridstyle, inspectable = false @@ -226,7 +229,7 @@ function initialize_block!(ax::Axis; palette = nothing) translate!(ygridlines, 0, 0, -10) elements[:ygridlines] = ygridlines - yminorgridnode = Observable(Point2f[]; ignore_equal_values=true) + yminorgridnode = Observable(Point2f[]; ignore_equal_values = true) yminorgridlines = linesegments!( blockscene, yminorgridnode, linewidth = ax.yminorgridwidth, visible = ax.yminorgridvisible, color = ax.yminorgridcolor, linestyle = ax.yminorgridstyle, inspectable = false @@ -251,13 +254,17 @@ function initialize_block!(ax::Axis; palette = nothing) notify(ax.xscale) # 3. Update the view onto the plot (camera matrices) - onany(blockscene, scene.transformation.transform_func, finallimits, - ax.xreversed, ax.yreversed; priority=-2) do args... + onany( + blockscene, scene.transformation.transform_func, finallimits, + ax.xreversed, ax.yreversed; priority = -2 + ) do args... update_axis_camera(scene, args...) end - xaxis_endpoints = lift(blockscene, ax.xaxisposition, scene.viewport; - ignore_equal_values=true) do xaxisposition, area + xaxis_endpoints = lift( + blockscene, ax.xaxisposition, scene.viewport; + ignore_equal_values = true + ) do xaxisposition, area if xaxisposition === :bottom return bottomline(Rect2f(area)) elseif xaxisposition === :top @@ -267,8 +274,10 @@ function initialize_block!(ax::Axis; palette = nothing) end end - yaxis_endpoints = lift(blockscene, ax.yaxisposition, scene.viewport; - ignore_equal_values=true) do yaxisposition, area + yaxis_endpoints = lift( + blockscene, ax.yaxisposition, scene.viewport; + ignore_equal_values = true + ) do yaxisposition, area if yaxisposition === :left return leftline(Rect2f(area)) elseif yaxisposition === :right @@ -278,46 +287,63 @@ function initialize_block!(ax::Axis; palette = nothing) end end - xaxis_flipped = lift(x -> x === :top, blockscene, ax.xaxisposition; ignore_equal_values=true) - yaxis_flipped = lift(x -> x === :right, blockscene, ax.yaxisposition; ignore_equal_values=true) + xaxis_flipped = lift(x -> x === :top, blockscene, ax.xaxisposition; ignore_equal_values = true) + yaxis_flipped = lift(x -> x === :right, blockscene, ax.yaxisposition; ignore_equal_values = true) - xspinevisible = lift(blockscene, xaxis_flipped, ax.bottomspinevisible, ax.topspinevisible; - ignore_equal_values=true) do xflip, bv, tv + xspinevisible = lift( + blockscene, xaxis_flipped, ax.bottomspinevisible, ax.topspinevisible; + ignore_equal_values = true + ) do xflip, bv, tv xflip ? tv : bv end - xoppositespinevisible = lift(blockscene, xaxis_flipped, ax.bottomspinevisible, ax.topspinevisible; - ignore_equal_values=true) do xflip, bv, tv + xoppositespinevisible = lift( + blockscene, xaxis_flipped, ax.bottomspinevisible, ax.topspinevisible; + ignore_equal_values = true + ) do xflip, bv, tv xflip ? bv : tv end - yspinevisible = lift(blockscene, yaxis_flipped, ax.leftspinevisible, ax.rightspinevisible; - ignore_equal_values=true) do yflip, lv, rv + yspinevisible = lift( + blockscene, yaxis_flipped, ax.leftspinevisible, ax.rightspinevisible; + ignore_equal_values = true + ) do yflip, lv, rv yflip ? rv : lv end - yoppositespinevisible = lift(blockscene, yaxis_flipped, ax.leftspinevisible, ax.rightspinevisible; - ignore_equal_values=true) do yflip, lv, rv + yoppositespinevisible = lift( + blockscene, yaxis_flipped, ax.leftspinevisible, ax.rightspinevisible; + ignore_equal_values = true + ) do yflip, lv, rv yflip ? lv : rv end - xspinecolor = lift(blockscene, xaxis_flipped, ax.bottomspinecolor, ax.topspinecolor; - ignore_equal_values=true) do xflip, bc, tc + xspinecolor = lift( + blockscene, xaxis_flipped, ax.bottomspinecolor, ax.topspinecolor; + ignore_equal_values = true + ) do xflip, bc, tc xflip ? tc : bc end - xoppositespinecolor = lift(blockscene, xaxis_flipped, ax.bottomspinecolor, ax.topspinecolor; - ignore_equal_values=true) do xflip, bc, tc + xoppositespinecolor = lift( + blockscene, xaxis_flipped, ax.bottomspinecolor, ax.topspinecolor; + ignore_equal_values = true + ) do xflip, bc, tc xflip ? bc : tc end - yspinecolor = lift(blockscene, yaxis_flipped, ax.leftspinecolor, ax.rightspinecolor; - ignore_equal_values=true) do yflip, lc, rc + yspinecolor = lift( + blockscene, yaxis_flipped, ax.leftspinecolor, ax.rightspinecolor; + ignore_equal_values = true + ) do yflip, lc, rc yflip ? rc : lc end - yoppositespinecolor = lift(blockscene, yaxis_flipped, ax.leftspinecolor, ax.rightspinecolor; - ignore_equal_values=true) do yflip, lc, rc + yoppositespinecolor = lift( + blockscene, yaxis_flipped, ax.leftspinecolor, ax.rightspinecolor; + ignore_equal_values = true + ) do yflip, lc, rc yflip ? lc : rc end - xlims = lift(xlimits, blockscene, finallimits; ignore_equal_values=true) - ylims = lift(ylimits, blockscene, finallimits; ignore_equal_values=true) + xlims = lift(xlimits, blockscene, finallimits; ignore_equal_values = true) + ylims = lift(ylimits, blockscene, finallimits; ignore_equal_values = true) - xaxis = LineAxis(blockscene, endpoints = xaxis_endpoints, limits = xlims, + xaxis = LineAxis( + blockscene, endpoints = xaxis_endpoints, limits = xlims, flipped = xaxis_flipped, ticklabelrotation = ax.xticklabelrotation, ticklabelalign = ax.xticklabelalign, labelsize = ax.xlabelsize, labelpadding = ax.xlabelpadding, ticklabelpad = ax.xticklabelpad, labelvisible = ax.xlabelvisible, @@ -327,11 +353,12 @@ function initialize_block!(ax::Axis; palette = nothing) ticklabelsize = ax.xticklabelsize, trimspine = ax.xtrimspine, ticksize = ax.xticksize, reversed = ax.xreversed, tickwidth = ax.xtickwidth, tickcolor = ax.xtickcolor, minorticksvisible = ax.xminorticksvisible, minortickalign = ax.xminortickalign, minorticksize = ax.xminorticksize, minortickwidth = ax.xminortickwidth, minortickcolor = ax.xminortickcolor, minorticks = ax.xminorticks, scale = ax.xscale, - ) + ) ax.xaxis = xaxis - yaxis = LineAxis(blockscene, endpoints = yaxis_endpoints, limits = ylims, + yaxis = LineAxis( + blockscene, endpoints = yaxis_endpoints, limits = ylims, flipped = yaxis_flipped, ticklabelrotation = ax.yticklabelrotation, ticklabelalign = ax.yticklabelalign, labelsize = ax.ylabelsize, labelpadding = ax.ylabelpadding, ticklabelpad = ax.yticklabelpad, labelvisible = ax.ylabelvisible, @@ -339,14 +366,16 @@ function initialize_block!(ax::Axis; palette = nothing) ticklabelspace = ax.yticklabelspace, dim_convert = ax.dim2_conversion, ticks = ax.yticks, tickformat = ax.ytickformat, ticklabelsvisible = ax.yticklabelsvisible, ticksvisible = ax.yticksvisible, spinevisible = yspinevisible, spinecolor = yspinecolor, spinewidth = ax.spinewidth, trimspine = ax.ytrimspine, ticklabelsize = ax.yticklabelsize, ticksize = ax.yticksize, flip_vertical_label = ax.flip_ylabel, reversed = ax.yreversed, tickwidth = ax.ytickwidth, - tickcolor = ax.ytickcolor, + tickcolor = ax.ytickcolor, minorticksvisible = ax.yminorticksvisible, minortickalign = ax.yminortickalign, minorticksize = ax.yminorticksize, minortickwidth = ax.yminortickwidth, minortickcolor = ax.yminortickcolor, minorticks = ax.yminorticks, scale = ax.yscale, - ) + ) ax.yaxis = yaxis - xoppositelinepoints = lift(blockscene, scene.viewport, ax.spinewidth, ax.xaxisposition; - ignore_equal_values=true) do r, sw, xaxpos + xoppositelinepoints = lift( + blockscene, scene.viewport, ax.spinewidth, ax.xaxisposition; + ignore_equal_values = true + ) do r, sw, xaxpos if xaxpos === :top y = bottom(r) p1 = Point2f(left(r) - 0.5sw, y) @@ -360,8 +389,10 @@ function initialize_block!(ax::Axis; palette = nothing) end end - yoppositelinepoints = lift(blockscene, scene.viewport, ax.spinewidth, ax.yaxisposition; - ignore_equal_values=true) do r, sw, yaxpos + yoppositelinepoints = lift( + blockscene, scene.viewport, ax.spinewidth, ax.yaxisposition; + ignore_equal_values = true + ) do r, sw, yaxpos if yaxpos === :right x = left(r) p1 = Point2f(x, bottom(r) - 0.5sw) @@ -375,36 +406,56 @@ function initialize_block!(ax::Axis; palette = nothing) end end - xticksmirrored = lift(mirror_ticks, blockscene, xaxis.tickpositions, ax.xticksize, ax.xtickalign, - scene.viewport, :x, ax.xaxisposition[], ax.spinewidth) - xticksmirrored_lines = linesegments!(blockscene, xticksmirrored, visible = @lift($(ax.xticksmirrored) && $(ax.xticksvisible)), - linewidth = ax.xtickwidth, color = ax.xtickcolor) + xticksmirrored = lift( + mirror_ticks, blockscene, xaxis.tickpositions, ax.xticksize, ax.xtickalign, + scene.viewport, :x, ax.xaxisposition[], ax.spinewidth + ) + xticksmirrored_lines = linesegments!( + blockscene, xticksmirrored, visible = @lift($(ax.xticksmirrored) && $(ax.xticksvisible)), + linewidth = ax.xtickwidth, color = ax.xtickcolor + ) translate!(xticksmirrored_lines, 0, 0, 10) - yticksmirrored = lift(mirror_ticks, blockscene, yaxis.tickpositions, ax.yticksize, ax.ytickalign, - scene.viewport, :y, ax.yaxisposition[], ax.spinewidth) - yticksmirrored_lines = linesegments!(blockscene, yticksmirrored, visible = @lift($(ax.yticksmirrored) && $(ax.yticksvisible)), - linewidth = ax.ytickwidth, color = ax.ytickcolor) + yticksmirrored = lift( + mirror_ticks, blockscene, yaxis.tickpositions, ax.yticksize, ax.ytickalign, + scene.viewport, :y, ax.yaxisposition[], ax.spinewidth + ) + yticksmirrored_lines = linesegments!( + blockscene, yticksmirrored, visible = @lift($(ax.yticksmirrored) && $(ax.yticksvisible)), + linewidth = ax.ytickwidth, color = ax.ytickcolor + ) translate!(yticksmirrored_lines, 0, 0, 10) - xminorticksmirrored = lift(mirror_ticks, blockscene, xaxis.minortickpositions, ax.xminorticksize, - ax.xminortickalign, scene.viewport, :x, ax.xaxisposition[], ax.spinewidth) - xminorticksmirrored_lines = linesegments!(blockscene, xminorticksmirrored, visible = @lift($(ax.xticksmirrored) && $(ax.xminorticksvisible)), - linewidth = ax.xminortickwidth, color = ax.xminortickcolor) + xminorticksmirrored = lift( + mirror_ticks, blockscene, xaxis.minortickpositions, ax.xminorticksize, + ax.xminortickalign, scene.viewport, :x, ax.xaxisposition[], ax.spinewidth + ) + xminorticksmirrored_lines = linesegments!( + blockscene, xminorticksmirrored, visible = @lift($(ax.xticksmirrored) && $(ax.xminorticksvisible)), + linewidth = ax.xminortickwidth, color = ax.xminortickcolor + ) translate!(xminorticksmirrored_lines, 0, 0, 10) - yminorticksmirrored = lift(mirror_ticks, blockscene, yaxis.minortickpositions, ax.yminorticksize, - ax.yminortickalign, scene.viewport, :y, ax.yaxisposition[], ax.spinewidth) - yminorticksmirrored_lines = linesegments!(blockscene, yminorticksmirrored, visible = @lift($(ax.yticksmirrored) && $(ax.yminorticksvisible)), - linewidth = ax.yminortickwidth, color = ax.yminortickcolor) + yminorticksmirrored = lift( + mirror_ticks, blockscene, yaxis.minortickpositions, ax.yminorticksize, + ax.yminortickalign, scene.viewport, :y, ax.yaxisposition[], ax.spinewidth + ) + yminorticksmirrored_lines = linesegments!( + blockscene, yminorticksmirrored, visible = @lift($(ax.yticksmirrored) && $(ax.yminorticksvisible)), + linewidth = ax.yminortickwidth, color = ax.yminortickcolor + ) translate!(yminorticksmirrored_lines, 0, 0, 10) - xoppositeline = linesegments!(blockscene, xoppositelinepoints, linewidth = ax.spinewidth, + xoppositeline = linesegments!( + blockscene, xoppositelinepoints, linewidth = ax.spinewidth, visible = xoppositespinevisible, color = xoppositespinecolor, inspectable = false, - linestyle = nothing) + linestyle = nothing + ) elements[:xoppositeline] = xoppositeline translate!(xoppositeline, 0, 0, 20) - yoppositeline = linesegments!(blockscene, yoppositelinepoints, linewidth = ax.spinewidth, + yoppositeline = linesegments!( + blockscene, yoppositelinepoints, linewidth = ax.spinewidth, visible = yoppositespinevisible, color = yoppositespinecolor, inspectable = false, - linestyle = nothing) + linestyle = nothing + ) elements[:yoppositeline] = yoppositeline translate!(yoppositeline, 0, 0, 20) @@ -432,20 +483,22 @@ function initialize_block!(ax::Axis; palette = nothing) update_gridlines!(yminorgridnode, Point2f(offset, 0), tickpos) end - subtitlepos = lift(blockscene, scene.viewport, ax.titlegap, ax.titlealign, ax.xaxisposition, - xaxis.protrusion; - ignore_equal_values=true) do a, - titlegap, align, xaxisposition, xaxisprotrusion + subtitlepos = lift( + blockscene, scene.viewport, ax.titlegap, ax.titlealign, ax.xaxisposition, + xaxis.protrusion; + ignore_equal_values = true + ) do a, + titlegap, align, xaxisposition, xaxisprotrusion align_factor = halign2num(align, "Horizontal title align $align not supported.") x = a.origin[1] + align_factor * a.widths[1] - yoffset = top(a) + titlegap + (xaxisposition === :top ? xaxisprotrusion : 0f0) + yoffset = top(a) + titlegap + (xaxisposition === :top ? xaxisprotrusion : 0.0f0) return Point2f(x, yoffset) end - titlealignnode = lift(blockscene, ax.titlealign; ignore_equal_values=true) do align + titlealignnode = lift(blockscene, ax.titlealign; ignore_equal_values = true) do align (align, :bottom) end @@ -459,10 +512,13 @@ function initialize_block!(ax::Axis; palette = nothing) color = ax.subtitlecolor, lineheight = ax.subtitlelineheight, markerspace = :data, - inspectable = false) + inspectable = false + ) - titlepos = lift(calculate_title_position, blockscene, scene.viewport, ax.titlegap, ax.subtitlegap, - ax.titlealign, ax.xaxisposition, xaxis.protrusion, ax.subtitlelineheight, ax, subtitlet; ignore_equal_values=true) + titlepos = lift( + calculate_title_position, blockscene, scene.viewport, ax.titlegap, ax.subtitlegap, + ax.titlealign, ax.xaxisposition, xaxis.protrusion, ax.subtitlelineheight, ax, subtitlet; ignore_equal_values = true + ) titlet = text!( blockscene, titlepos, @@ -474,15 +530,18 @@ function initialize_block!(ax::Axis; palette = nothing) color = ax.titlecolor, lineheight = ax.titlelineheight, markerspace = :data, - inspectable = false) + inspectable = false + ) elements[:title] = titlet - map!(compute_protrusions, blockscene, ax.layoutobservables.protrusions, ax.title, ax.titlesize, - ax.titlegap, ax.titlevisible, ax.spinewidth, - ax.topspinevisible, ax.bottomspinevisible, ax.leftspinevisible, ax.rightspinevisible, - xaxis.protrusion, yaxis.protrusion, ax.xaxisposition, ax.yaxisposition, - ax.subtitle, ax.subtitlevisible, ax.subtitlesize, ax.subtitlegap, - ax.titlelineheight, ax.subtitlelineheight, subtitlet, titlet) + map!( + compute_protrusions, blockscene, ax.layoutobservables.protrusions, ax.title, ax.titlesize, + ax.titlegap, ax.titlevisible, ax.spinewidth, + ax.topspinevisible, ax.bottomspinevisible, ax.leftspinevisible, ax.rightspinevisible, + xaxis.protrusion, yaxis.protrusion, ax.xaxisposition, ax.yaxisposition, + ax.subtitle, ax.subtitlevisible, ax.subtitlesize, ax.subtitlegap, + ax.titlelineheight, ax.subtitlelineheight, subtitlet, titlet + ) # trigger first protrusions with one of the observables notify(ax.title) @@ -524,22 +583,22 @@ function mirror_ticks(tickpositions, ticksize, tickalign, viewport, side, axispo a = viewport if side === :x opp = axisposition === :bottom ? top(a) : bottom(a) - sign = axisposition === :bottom ? 1 : -1 + sign = axisposition === :bottom ? 1 : -1 else opp = axisposition === :left ? right(a) : left(a) sign = axisposition === :left ? 1 : -1 end d = ticksize * sign - points = Vector{Point2f}(undef, 2*length(tickpositions)) + points = Vector{Point2f}(undef, 2 * length(tickpositions)) spineoffset = sign * (0.5 * spinewidth) if side === :x for (i, (x, _)) in enumerate(tickpositions) - points[2i-1] = Point2f(x, opp - d * tickalign + spineoffset) + points[2i - 1] = Point2f(x, opp - d * tickalign + spineoffset) points[2i] = Point2f(x, opp + d - d * tickalign + spineoffset) end else for (i, (_, y)) in enumerate(tickpositions) - points[2i-1] = Point2f(opp - d * tickalign + spineoffset, y) + points[2i - 1] = Point2f(opp - d * tickalign + spineoffset, y) points[2i] = Point2f(opp + d - d * tickalign + spineoffset, y) end end @@ -639,18 +698,18 @@ function reset_limits!(ax; xauto = true, yauto = true, zauto = true) ) end ax.targetlimits[] = tlims - nothing + return nothing end # this is so users can do limits = (left, right, bottom, top) function convert_limit_attribute(lims::Tuple{Any, Any, Any, Any}) - (lims[1:2], lims[3:4]) + return (lims[1:2], lims[3:4]) end function convert_limit_attribute(lims::Tuple{Any, Any}) _convert_single_limit(x) = x _convert_single_limit(x::Interval) = endpoints(x) - map(_convert_single_limit, lims) + return map(_convert_single_limit, lims) end function validate_limits_for_scales(lims::Rect, xsc, ysc) @@ -665,7 +724,7 @@ function validate_limits_for_scales(lims::Rect, xsc, ysc) if !validate_limits_for_scale(ylims, ysc) error("Invalid y-limits $ylims for scale $ysc which is defined on the interval $(defined_interval(ysc))") end - nothing + return nothing end validate_limits_for_scale(lims, scale) = all(x -> x in defined_interval(scale), lims) @@ -718,7 +777,7 @@ function add_cycle_attributes!(@nospecialize(plot), cycle::Cycle, cycler::Cycler # cycling but only look up exactly the passed attributes cycle_attrsyms = attrsyms(cycle) - if !isempty(manually_cycled_attributes) + return if !isempty(manually_cycled_attributes) # an attribute given as Cycled needs to be present in the cycler, # otherwise there's no cycle in which to look up a value for k in manually_cycled_attributes @@ -770,7 +829,6 @@ is_open_or_any_parent(s::Scene) = isopen(s) || is_open_or_any_parent(s.parent) is_open_or_any_parent(::Nothing) = false - needs_tight_limits(@nospecialize any) = false needs_tight_limits(::Union{Heatmap, Image}) = true function needs_tight_limits(c::Contourf) @@ -787,7 +845,7 @@ function needs_tight_limits(p::Voronoiplot) end function expandbboxwithfractionalmargins(bb, margins) - newwidths = bb.widths .* (1f0 .+ margins) + newwidths = bb.widths .* (1.0f0 .+ margins) diffs = newwidths .- bb.widths neworigin = bb.origin .- (0.5f0 .* diffs) return Rect2f(neworigin, newwidths) @@ -822,7 +880,7 @@ function expandlimits(lims, margin_low, margin_high, scale) lims = inverse.(scale.(lims) .+ (-zerodist, zerodist)) end end - lims + return lims end function getlimits(la::Axis, dim) @@ -879,7 +937,7 @@ function update_linked_limits!(block_limit_linking, xaxislinks, yaxislinks, tlim # only change linked axis if not prohibited from doing so because # we're currently being updated by another axis' link - if !block_limit_linking[] + return if !block_limit_linking[] bothlinks = intersect(xaxislinks, yaxislinks) xlinks = setdiff(xaxislinks, yaxislinks) @@ -932,7 +990,7 @@ end function autolimits!() curr_ax = current_axis() isnothing(curr_ax) && throw(ArgumentError("Attempted to call `autolimits!` on `current_axis()`, but `current_axis()` returned nothing.")) - autolimits!(curr_ax) + return autolimits!(curr_ax) end function autolimits(ax::Axis, dim::Integer) @@ -978,11 +1036,11 @@ Link both x and y axes of all given `Axis` so that they stay synchronized. """ function linkaxes!(axes::Vector{<:Axis}) linkxaxes!(axes) - linkyaxes!(axes) + return linkyaxes!(axes) end function linkaxes!(a::Axis, others...) - linkaxes!([a, others...]) + return linkaxes!([a, others...]) end function adjustlimits!(la) @@ -1080,8 +1138,10 @@ value. If that value is Makie.automatic, the reset will trigger new protrusions for the axis and the layout will adjust. This is so the layout doesn't immediately readjust during interaction, which would let the whole layout jitter around. """ -function timed_ticklabelspace_reset(ax::Axis, reset_timer::Ref, - prev_xticklabelspace::Ref, prev_yticklabelspace::Ref, threshold_sec::Real) +function timed_ticklabelspace_reset( + ax::Axis, reset_timer::Ref, + prev_xticklabelspace::Ref, prev_yticklabelspace::Ref, threshold_sec::Real + ) if !isnothing(reset_timer[]) close(reset_timer[]) @@ -1093,7 +1153,7 @@ function timed_ticklabelspace_reset(ax::Axis, reset_timer::Ref, ax.yticklabelspace = Float64(ax.yaxis.attributes.actual_ticklabelspace[]) end - reset_timer[] = Timer(threshold_sec) do t + return reset_timer[] = Timer(threshold_sec) do t reset_timer[] = nothing ax.xticklabelspace = prev_xticklabelspace[] @@ -1110,8 +1170,10 @@ end Hide decorations of the x-axis: label, ticklabels, ticks and grid. Keyword arguments can be used to disable hiding of certain types of decorations. """ -function hidexdecorations!(la::Axis; label = true, ticklabels = true, ticks = true, grid = true, - minorgrid = true, minorticks = true) +function hidexdecorations!( + la::Axis; label = true, ticklabels = true, ticks = true, grid = true, + minorgrid = true, minorticks = true + ) if label la.xlabelvisible = false end @@ -1127,7 +1189,7 @@ function hidexdecorations!(la::Axis; label = true, ticklabels = true, ticks = tr if minorgrid la.xminorgridvisible = false end - if minorticks + return if minorticks la.xminorticksvisible = false end end @@ -1139,8 +1201,10 @@ end Hide decorations of the y-axis: label, ticklabels, ticks and grid. Keyword arguments can be used to disable hiding of certain types of decorations. """ -function hideydecorations!(la::Axis; label = true, ticklabels = true, ticks = true, grid = true, - minorgrid = true, minorticks = true) +function hideydecorations!( + la::Axis; label = true, ticklabels = true, ticks = true, grid = true, + minorgrid = true, minorticks = true + ) if label la.ylabelvisible = false end @@ -1156,7 +1220,7 @@ function hideydecorations!(la::Axis; label = true, ticklabels = true, ticks = tr if minorgrid la.yminorgridvisible = false end - if minorticks + return if minorticks la.yminorticksvisible = false end end @@ -1170,12 +1234,18 @@ Keyword arguments can be used to disable hiding of certain types of decorations. See also [`hidexdecorations!`], [`hideydecorations!`], [`hidezdecorations!`] """ -function hidedecorations!(la::Axis; label = true, ticklabels = true, ticks = true, grid = true, - minorgrid = true, minorticks = true) - hidexdecorations!(la; label = label, ticklabels = ticklabels, ticks = ticks, grid = grid, - minorgrid = minorgrid, minorticks = minorticks) - hideydecorations!(la; label = label, ticklabels = ticklabels, ticks = ticks, grid = grid, - minorgrid = minorgrid, minorticks = minorticks) +function hidedecorations!( + la::Axis; label = true, ticklabels = true, ticks = true, grid = true, + minorgrid = true, minorticks = true + ) + hidexdecorations!( + la; label = label, ticklabels = ticklabels, ticks = ticks, grid = grid, + minorgrid = minorgrid, minorticks = minorticks + ) + return hideydecorations!( + la; label = label, ticklabels = ticklabels, ticks = ticks, grid = grid, + minorgrid = minorgrid, minorticks = minorticks + ) end """ @@ -1199,6 +1269,7 @@ function hidespines!(la::Axis, spines::Symbol... = (:l, :r, :b, :t)...) error("Invalid spine identifier $s. Valid options are :l, :r, :b and :t.") end end + return end """ @@ -1239,11 +1310,12 @@ function Base.show(io::IO, ::MIME"text/plain", ax::Axis) for (i, p) in enumerate(ax.scene.plots) println(io, (i == nplots ? " ┗━ " : " ┣━ ") * string(typeof(p))) end + return end function Base.show(io::IO, ax::Axis) nplots = length(ax.scene.plots) - print(io, "Axis ($nplots plots)") + return print(io, "Axis ($nplots plots)") end Makie.xlims!(ax::Axis, xlims::Interval) = Makie.xlims!(ax, endpoints(xlims)) @@ -1265,7 +1337,7 @@ function Makie.xlims!(ax::Axis, xlims) mlims = convert_limit_attribute(ax.limits[]) ax.limits.val = (xlims, mlims[2]) reset_limits!(ax, yauto = false) - nothing + return nothing end function Makie.ylims!(ax::Axis, ylims) @@ -1283,7 +1355,7 @@ function Makie.ylims!(ax::Axis, ylims) mlims = convert_limit_attribute(ax.limits[]) ax.limits.val = (mlims[1], ylims) reset_limits!(ax, xauto = false) - nothing + return nothing end """ @@ -1381,7 +1453,7 @@ If limits are ordered high-low, this reverses the axis orientation. """ function limits!(ax::Axis, xlims, ylims) Makie.xlims!(ax, xlims) - Makie.ylims!(ax, ylims) + return Makie.ylims!(ax, ylims) end """ @@ -1392,7 +1464,7 @@ If limits are ordered high-low, this reverses the axis orientation. """ function limits!(ax::Axis, x1, x2, y1, y2) Makie.xlims!(ax, x1, x2) - Makie.ylims!(ax, y1, y2) + return Makie.ylims!(ax, y1, y2) end """ @@ -1405,13 +1477,13 @@ function limits!(ax::Axis, rect::Rect2) xmin, ymin = minimum(rect) xmax, ymax = maximum(rect) Makie.xlims!(ax, xmin, xmax) - Makie.ylims!(ax, ymin, ymax) + return Makie.ylims!(ax, ymin, ymax) end function limits!(args::Union{Nothing, Real, HyperRectangle}...) axis = current_axis() axis isa Nothing && error("There is no currently active axis!") - limits!(axis, args...) + return limits!(axis, args...) end Makie.transform_func(ax::Axis) = Makie.transform_func(ax.scene) @@ -1419,7 +1491,7 @@ Makie.transform_func(ax::Axis) = Makie.transform_func(ax.scene) # these functions pick limits for different x and y scales, so that # we don't pick values that are invalid, such as 0 for log etc. function defaultlimits(userlimits::Tuple{Real, Real, Real, Real}, xscale, yscale) - BBox(Float64.(userlimits)...) + return BBox(Float64.(userlimits)...) end defaultlimits(l::Tuple{Any, Any, Any, Any}, xscale, yscale) = defaultlimits(((l[1], l[2]), (l[3], l[4])), xscale, yscale) @@ -1448,397 +1520,397 @@ defaultlimits(::typeof(Makie.logit)) = (0.01, 0.99) defined_interval(scale::ReversibleScale) = scale.interval defined_interval(::typeof(identity)) = OpenInterval(-Inf, Inf) defined_interval(::LogFunctions) = OpenInterval(0.0, Inf) -defined_interval(::typeof(sqrt)) = Interval{:closed,:open}(0, Inf) +defined_interval(::typeof(sqrt)) = Interval{:closed, :open}(0, Inf) defined_interval(::typeof(Makie.logit)) = OpenInterval(0.0, 1.0) function attribute_examples(::Type{Axis}) - Dict( + return Dict( :xticks => [ Example( code = """ - fig = Figure() - Axis(fig[1, 1], xticks = 1:10) - Axis(fig[2, 1], xticks = (1:2:9, ["A", "B", "C", "D", "E"])) - Axis(fig[3, 1], xticks = WilkinsonTicks(5)) - fig - """ - ) + fig = Figure() + Axis(fig[1, 1], xticks = 1:10) + Axis(fig[2, 1], xticks = (1:2:9, ["A", "B", "C", "D", "E"])) + Axis(fig[3, 1], xticks = WilkinsonTicks(5)) + fig + """ + ), ], :yticks => [ Example( code = """ - fig = Figure() - Axis(fig[1, 1], yticks = 1:10) - Axis(fig[1, 2], yticks = (1:2:9, ["A", "B", "C", "D", "E"])) - Axis(fig[1, 3], yticks = WilkinsonTicks(5)) - fig - """ - ) + fig = Figure() + Axis(fig[1, 1], yticks = 1:10) + Axis(fig[1, 2], yticks = (1:2:9, ["A", "B", "C", "D", "E"])) + Axis(fig[1, 3], yticks = WilkinsonTicks(5)) + fig + """ + ), ], :aspect => [ Example( code = """ - using FileIO + using FileIO - f = Figure() + f = Figure() - ax1 = Axis(f[1, 1], aspect = nothing, title = "nothing") - ax2 = Axis(f[1, 2], aspect = DataAspect(), title = "DataAspect()") - ax3 = Axis(f[2, 1], aspect = AxisAspect(1), title = "AxisAspect(1)") - ax4 = Axis(f[2, 2], aspect = AxisAspect(2), title = "AxisAspect(2)") + ax1 = Axis(f[1, 1], aspect = nothing, title = "nothing") + ax2 = Axis(f[1, 2], aspect = DataAspect(), title = "DataAspect()") + ax3 = Axis(f[2, 1], aspect = AxisAspect(1), title = "AxisAspect(1)") + ax4 = Axis(f[2, 2], aspect = AxisAspect(2), title = "AxisAspect(2)") - img = rotr90(load(assetpath("cow.png"))) - for ax in [ax1, ax2, ax3, ax4] - image!(ax, img) - end + img = rotr90(load(assetpath("cow.png"))) + for ax in [ax1, ax2, ax3, ax4] + image!(ax, img) + end - f - """ - ) + f + """ + ), ], :autolimitaspect => [ Example( code = """ - f = Figure() + f = Figure() - ax1 = Axis(f[1, 1], autolimitaspect = nothing) - ax2 = Axis(f[1, 2], autolimitaspect = 1) + ax1 = Axis(f[1, 1], autolimitaspect = nothing) + ax2 = Axis(f[1, 2], autolimitaspect = 1) - for ax in [ax1, ax2] - lines!(ax, 0..10, sin) - end + for ax in [ax1, ax2] + lines!(ax, 0..10, sin) + end - f - """ - ) + f + """ + ), ], :title => [ Example( code = """ - f = Figure() - - Axis(f[1, 1], title = "Title") - Axis(f[2, 1], title = L"\\sum_i{x_i \\times y_i}") - Axis(f[3, 1], title = rich( - "Rich text title", - subscript(" with subscript", color = :slategray) - )) - - f - """ - ) + f = Figure() + + Axis(f[1, 1], title = "Title") + Axis(f[2, 1], title = L"\\sum_i{x_i \\times y_i}") + Axis(f[3, 1], title = rich( + "Rich text title", + subscript(" with subscript", color = :slategray) + )) + + f + """ + ), ], :titlealign => [ Example( code = """ - f = Figure() + f = Figure() - Axis(f[1, 1], titlealign = :left, title = "Left aligned title") - Axis(f[2, 1], titlealign = :center, title = "Center aligned title") - Axis(f[3, 1], titlealign = :right, title = "Right aligned title") + Axis(f[1, 1], titlealign = :left, title = "Left aligned title") + Axis(f[2, 1], titlealign = :center, title = "Center aligned title") + Axis(f[3, 1], titlealign = :right, title = "Right aligned title") - f - """ - ) + f + """ + ), ], :subtitle => [ Example( code = """ - f = Figure() - - Axis(f[1, 1], title = "Title", subtitle = "Subtitle") - Axis(f[2, 1], title = "Title", subtitle = L"\\sum_i{x_i \\times y_i}") - Axis(f[3, 1], title = "Title", subtitle = rich( - "Rich text subtitle", - subscript(" with subscript", color = :slategray) - )) - - f - """ - ) + f = Figure() + + Axis(f[1, 1], title = "Title", subtitle = "Subtitle") + Axis(f[2, 1], title = "Title", subtitle = L"\\sum_i{x_i \\times y_i}") + Axis(f[3, 1], title = "Title", subtitle = rich( + "Rich text subtitle", + subscript(" with subscript", color = :slategray) + )) + + f + """ + ), ], :xlabel => [ Example( code = """ - f = Figure() - - Axis(f[1, 1], xlabel = "X Label") - Axis(f[2, 1], xlabel = L"\\sum_i{x_i \\times y_i}") - Axis(f[3, 1], xlabel = rich( - "X Label", - subscript(" with subscript", color = :slategray) - )) - - f - """ - ) + f = Figure() + + Axis(f[1, 1], xlabel = "X Label") + Axis(f[2, 1], xlabel = L"\\sum_i{x_i \\times y_i}") + Axis(f[3, 1], xlabel = rich( + "X Label", + subscript(" with subscript", color = :slategray) + )) + + f + """ + ), ], :ylabel => [ Example( code = """ - f = Figure() - - Axis(f[1, 1], ylabel = "Y Label") - Axis(f[2, 1], ylabel = L"\\sum_i{x_i \\times y_i}") - Axis(f[3, 1], ylabel = rich( - "Y Label", - subscript(" with subscript", color = :slategray) - )) - - f - """ - ) + f = Figure() + + Axis(f[1, 1], ylabel = "Y Label") + Axis(f[2, 1], ylabel = L"\\sum_i{x_i \\times y_i}") + Axis(f[3, 1], ylabel = rich( + "Y Label", + subscript(" with subscript", color = :slategray) + )) + + f + """ + ), ], :xtrimspine => [ Example( code = """ - f = Figure() - - ax1 = Axis(f[1, 1], xtrimspine = false) - ax2 = Axis(f[2, 1], xtrimspine = true) - ax3 = Axis(f[3, 1], xtrimspine = (true, false)) - ax4 = Axis(f[4, 1], xtrimspine = (false, true)) - - for ax in [ax1, ax2, ax3, ax4] - ax.xgridvisible = false - ax.ygridvisible = false - ax.rightspinevisible = false - ax.topspinevisible = false - xlims!(ax, 0.5, 5.5) - end - - f - """ - ) + f = Figure() + + ax1 = Axis(f[1, 1], xtrimspine = false) + ax2 = Axis(f[2, 1], xtrimspine = true) + ax3 = Axis(f[3, 1], xtrimspine = (true, false)) + ax4 = Axis(f[4, 1], xtrimspine = (false, true)) + + for ax in [ax1, ax2, ax3, ax4] + ax.xgridvisible = false + ax.ygridvisible = false + ax.rightspinevisible = false + ax.topspinevisible = false + xlims!(ax, 0.5, 5.5) + end + + f + """ + ), ], :ytrimspine => [ Example( code = """ - f = Figure() - - ax1 = Axis(f[1, 1], ytrimspine = false) - ax2 = Axis(f[1, 2], ytrimspine = true) - ax3 = Axis(f[1, 3], ytrimspine = (true, false)) - ax4 = Axis(f[1, 4], ytrimspine = (false, true)) - - for ax in [ax1, ax2, ax3, ax4] - ax.xgridvisible = false - ax.ygridvisible = false - ax.rightspinevisible = false - ax.topspinevisible = false - ylims!(ax, 0.5, 5.5) - end - - f - """ - ) + f = Figure() + + ax1 = Axis(f[1, 1], ytrimspine = false) + ax2 = Axis(f[1, 2], ytrimspine = true) + ax3 = Axis(f[1, 3], ytrimspine = (true, false)) + ax4 = Axis(f[1, 4], ytrimspine = (false, true)) + + for ax in [ax1, ax2, ax3, ax4] + ax.xgridvisible = false + ax.ygridvisible = false + ax.rightspinevisible = false + ax.topspinevisible = false + ylims!(ax, 0.5, 5.5) + end + + f + """ + ), ], :xaxisposition => [ Example( code = """ - f = Figure() + f = Figure() - Axis(f[1, 1], xaxisposition = :bottom) - Axis(f[1, 2], xaxisposition = :top) + Axis(f[1, 1], xaxisposition = :bottom) + Axis(f[1, 2], xaxisposition = :top) - f - """ - ) + f + """ + ), ], :yaxisposition => [ Example( code = """ - f = Figure() + f = Figure() - Axis(f[1, 1], yaxisposition = :left) - Axis(f[2, 1], yaxisposition = :right) + Axis(f[1, 1], yaxisposition = :left) + Axis(f[2, 1], yaxisposition = :right) - f - """ - ) + f + """ + ), ], :limits => [ Example( code = """ - f = Figure() + f = Figure() - ax1 = Axis(f[1, 1], limits = (nothing, nothing), title = "(nothing, nothing)") - ax2 = Axis(f[1, 2], limits = (0, 4pi, -1, 1), title = "(0, 4pi, -1, 1)") - ax3 = Axis(f[2, 1], limits = ((0, 4pi), nothing), title = "((0, 4pi), nothing)") - ax4 = Axis(f[2, 2], limits = (nothing, 4pi, nothing, 1), title = "(nothing, 4pi, nothing, 1)") + ax1 = Axis(f[1, 1], limits = (nothing, nothing), title = "(nothing, nothing)") + ax2 = Axis(f[1, 2], limits = (0, 4pi, -1, 1), title = "(0, 4pi, -1, 1)") + ax3 = Axis(f[2, 1], limits = ((0, 4pi), nothing), title = "((0, 4pi), nothing)") + ax4 = Axis(f[2, 2], limits = (nothing, 4pi, nothing, 1), title = "(nothing, 4pi, nothing, 1)") - for ax in [ax1, ax2, ax3, ax4] - lines!(ax, 0..4pi, sin) - end + for ax in [ax1, ax2, ax3, ax4] + lines!(ax, 0..4pi, sin) + end - f - """ - ) + f + """ + ), ], :yscale => [ Example( code = """ - f = Figure() + f = Figure() - for (i, scale) in enumerate([identity, log10, log2, log, sqrt, Makie.logit]) - row, col = fldmod1(i, 3) - Axis(f[row, col], yscale = scale, title = string(scale), - yminorticksvisible = true, yminorgridvisible = true, - yminorticks = IntervalsBetween(5)) + for (i, scale) in enumerate([identity, log10, log2, log, sqrt, Makie.logit]) + row, col = fldmod1(i, 3) + Axis(f[row, col], yscale = scale, title = string(scale), + yminorticksvisible = true, yminorgridvisible = true, + yminorticks = IntervalsBetween(5)) - lines!(range(0.01, 0.99, length = 200)) - end + lines!(range(0.01, 0.99, length = 200)) + end - f - """ + f + """ ), Example( code = """ - f = Figure() - - ax1 = Axis(f[1, 1], - yscale = Makie.pseudolog10, - title = "Pseudolog scale", - yticks = [-100, -10, -1, 0, 1, 10, 100] - ) - - ax2 = Axis(f[2, 1], - yscale = Makie.Symlog10(10.0), - title = "Symlog10 with linear scaling between -10 and 10", - yticks = [-100, -10, 0, 10, 100] - ) - - for ax in [ax1, ax2] - lines!(ax, -100:0.1:100) - end - - f - """ + f = Figure() + + ax1 = Axis(f[1, 1], + yscale = Makie.pseudolog10, + title = "Pseudolog scale", + yticks = [-100, -10, -1, 0, 1, 10, 100] + ) + + ax2 = Axis(f[2, 1], + yscale = Makie.Symlog10(10.0), + title = "Symlog10 with linear scaling between -10 and 10", + yticks = [-100, -10, 0, 10, 100] + ) + + for ax in [ax1, ax2] + lines!(ax, -100:0.1:100) + end + + f + """ ), ], :xscale => [ Example( code = """ - f = Figure() + f = Figure() - for (i, scale) in enumerate([identity, log10, log2, log, sqrt, Makie.logit]) - row, col = fldmod1(i, 2) - Axis(f[row, col], xscale = scale, title = string(scale), - xminorticksvisible = true, xminorgridvisible = true, - xminorticks = IntervalsBetween(5)) + for (i, scale) in enumerate([identity, log10, log2, log, sqrt, Makie.logit]) + row, col = fldmod1(i, 2) + Axis(f[row, col], xscale = scale, title = string(scale), + xminorticksvisible = true, xminorgridvisible = true, + xminorticks = IntervalsBetween(5)) - lines!(range(0.01, 0.99, length = 200), 1:200) - end + lines!(range(0.01, 0.99, length = 200), 1:200) + end - f - """ + f + """ ), Example( code = """ - f = Figure() - - ax1 = Axis(f[1, 1], - xscale = Makie.pseudolog10, - title = "Pseudolog scale", - xticks = [-100, -10, -1, 0, 1, 10, 100] - ) - - ax2 = Axis(f[1, 2], - xscale = Makie.Symlog10(10.0), - title = "Symlog10 with linear scaling\nbetween -10 and 10", - xticks = [-100, -10, 0, 10, 100] - ) - - for ax in [ax1, ax2] - lines!(ax, -100:0.1:100, -100:0.1:100) - end - - f - """ + f = Figure() + + ax1 = Axis(f[1, 1], + xscale = Makie.pseudolog10, + title = "Pseudolog scale", + xticks = [-100, -10, -1, 0, 1, 10, 100] + ) + + ax2 = Axis(f[1, 2], + xscale = Makie.Symlog10(10.0), + title = "Symlog10 with linear scaling\nbetween -10 and 10", + xticks = [-100, -10, 0, 10, 100] + ) + + for ax in [ax1, ax2] + lines!(ax, -100:0.1:100, -100:0.1:100) + end + + f + """ ), ], :xtickformat => [ Example( code = """ - f = Figure(figure_padding = 50) + f = Figure(figure_padding = 50) - Axis(f[1, 1], xtickformat = values -> ["\$(value)kg" for value in values]) - Axis(f[2, 1], xtickformat = "{:.2f}ms") - Axis(f[3, 1], xtickformat = values -> [L"\\sqrt{%\$(value^2)}" for value in values]) - Axis(f[4, 1], xtickformat = values -> [rich("\$value", superscript("XY", color = :red)) - for value in values]) + Axis(f[1, 1], xtickformat = values -> ["\$(value)kg" for value in values]) + Axis(f[2, 1], xtickformat = "{:.2f}ms") + Axis(f[3, 1], xtickformat = values -> [L"\\sqrt{%\$(value^2)}" for value in values]) + Axis(f[4, 1], xtickformat = values -> [rich("\$value", superscript("XY", color = :red)) + for value in values]) - f - """ - ) + f + """ + ), ], :ytickformat => [ Example( code = """ - f = Figure() + f = Figure() - Axis(f[1, 1], ytickformat = values -> ["\$(value)kg" for value in values]) - Axis(f[1, 2], ytickformat = "{:.2f}ms") - Axis(f[1, 3], ytickformat = values -> [L"\\sqrt{%\$(value^2)}" for value in values]) - Axis(f[1, 4], ytickformat = values -> [rich("\$value", superscript("XY", color = :red)) - for value in values]) + Axis(f[1, 1], ytickformat = values -> ["\$(value)kg" for value in values]) + Axis(f[1, 2], ytickformat = "{:.2f}ms") + Axis(f[1, 3], ytickformat = values -> [L"\\sqrt{%\$(value^2)}" for value in values]) + Axis(f[1, 4], ytickformat = values -> [rich("\$value", superscript("XY", color = :red)) + for value in values]) - f - """ - ) + f + """ + ), ], :xticksmirrored => [ Example( code = """ - f = Figure() + f = Figure() - Axis(f[1, 1], xticksmirrored = false, xminorticksvisible = true) - Axis(f[1, 2], xticksmirrored = true, xminorticksvisible = true) + Axis(f[1, 1], xticksmirrored = false, xminorticksvisible = true) + Axis(f[1, 2], xticksmirrored = true, xminorticksvisible = true) - f - """ - ) + f + """ + ), ], :yticksmirrored => [ Example( code = """ - f = Figure() + f = Figure() - Axis(f[1, 1], yticksmirrored = false, yminorticksvisible = true) - Axis(f[2, 1], yticksmirrored = true, yminorticksvisible = true) + Axis(f[1, 1], yticksmirrored = false, yminorticksvisible = true) + Axis(f[2, 1], yticksmirrored = true, yminorticksvisible = true) - f - """ - ) + f + """ + ), ], :xminorticks => [ Example( code = """ - f = Figure() + f = Figure() - kwargs = (; xminorticksvisible = true, xminorgridvisible = true) - Axis(f[1, 1]; xminorticks = IntervalsBetween(2), kwargs...) - Axis(f[2, 1]; xminorticks = IntervalsBetween(5), kwargs...) - Axis(f[3, 1]; xminorticks = [1, 2, 3, 4], kwargs...) + kwargs = (; xminorticksvisible = true, xminorgridvisible = true) + Axis(f[1, 1]; xminorticks = IntervalsBetween(2), kwargs...) + Axis(f[2, 1]; xminorticks = IntervalsBetween(5), kwargs...) + Axis(f[3, 1]; xminorticks = [1, 2, 3, 4], kwargs...) - f - """ - ) + f + """ + ), ], :yminorticks => [ Example( code = """ - f = Figure() + f = Figure() - kwargs = (; yminorticksvisible = true, yminorgridvisible = true) - Axis(f[1, 1]; yminorticks = IntervalsBetween(2), kwargs...) - Axis(f[1, 2]; yminorticks = IntervalsBetween(5), kwargs...) - Axis(f[1, 3]; yminorticks = [1, 2, 3, 4], kwargs...) + kwargs = (; yminorticksvisible = true, yminorgridvisible = true) + Axis(f[1, 1]; yminorticks = IntervalsBetween(2), kwargs...) + Axis(f[1, 2]; yminorticks = IntervalsBetween(5), kwargs...) + Axis(f[1, 3]; yminorticks = [1, 2, 3, 4], kwargs...) - f - """ - ) + f + """ + ), ], ) end @@ -1855,12 +1927,12 @@ end Gets the colorbuffer of the `Axis` in `JuliaNative` image format. If `include_decorations=false`, only the inside of the axis is fetched. """ -function colorbuffer(ax::Axis; include_decorations=true, update=true, colorbuffer_kws...) +function colorbuffer(ax::Axis; include_decorations = true, update = true, colorbuffer_kws...) if update update_state_before_display!(ax) end root_scene = root(ax.scene) - img = colorbuffer(root_scene; update=false, colorbuffer_kws...) + img = colorbuffer(root_scene; update = false, colorbuffer_kws...) scale_factor = first(size(img) ./ reverse(size(root_scene))) bb = if include_decorations bb = axis_bounds_with_decoration(ax) diff --git a/src/makielayout/blocks/axis3d.jl b/src/makielayout/blocks/axis3d.jl index 77f399973aa..5b50b6cd801 100644 --- a/src/makielayout/blocks/axis3d.jl +++ b/src/makielayout/blocks/axis3d.jl @@ -35,12 +35,12 @@ function initialize_block!(ax::Axis3) return apply_transform.(Ref(model), _planes) end - mi1 = Observable(!(pi/2 <= mod1(ax.azimuth[], 2pi) < 3pi/2)) + mi1 = Observable(!(pi / 2 <= mod1(ax.azimuth[], 2pi) < 3pi / 2)) mi2 = Observable(0 <= mod1(ax.azimuth[], 2pi) < pi) mi3 = Observable(ax.elevation[] > 0) on(scene, ax.azimuth) do x - b = !(pi/2 <= mod1(x, 2pi) < 3pi/2) + b = !(pi / 2 <= mod1(x, 2pi) < 3pi / 2) mi1.val == b || (mi1[] = b) return end @@ -57,10 +57,12 @@ function initialize_block!(ax::Axis3) setfield!(ax, :axis_offset, Observable(Vec2d(0))) setfield!(ax, :zoom_mult, Observable(1.0)) - matrices = lift(calculate_matrices, scene, finallimits, scene.viewport, ax.protrusions, - ax.elevation, ax.azimuth, ax.perspectiveness, ax.aspect, ax.viewmode, - ax.xreversed, ax.yreversed, ax.zreversed, - ax.zoom_mult, ax.axis_offset, ax.near) + matrices = lift( + calculate_matrices, scene, finallimits, scene.viewport, ax.protrusions, + ax.elevation, ax.azimuth, ax.perspectiveness, ax.aspect, ax.viewmode, + ax.xreversed, ax.yreversed, ax.zreversed, + ax.zoom_mult, ax.axis_offset, ax.near + ) on(scene, matrices) do (model, view, proj, lookat, eyepos) cam = camera(scene) @@ -98,17 +100,21 @@ function initialize_block!(ax::Axis3) # This exists as a bandaid for WGLMakie. See add_gridlines_and_frames!() overlay = Scene( blockscene, scenearea, clear = false, backgroundcolor = :transparent, - camera = scene.camera, transformation = scene.transformation) + camera = scene.camera, transformation = scene.transformation + ) xgridline1, xgridline2, xframelines = add_gridlines_and_frames!( blockscene, scene, overlay, ax, 1, finallimits, ticknode_1, mi1, mi2, mi3, - ax.xreversed, ax.yreversed, ax.zreversed) + ax.xreversed, ax.yreversed, ax.zreversed + ) ygridline1, ygridline2, yframelines = add_gridlines_and_frames!( blockscene, scene, overlay, ax, 2, finallimits, ticknode_2, mi2, mi1, mi3, - ax.xreversed, ax.yreversed, ax.zreversed) + ax.xreversed, ax.yreversed, ax.zreversed + ) zgridline1, zgridline2, zframelines = add_gridlines_and_frames!( blockscene, scene, overlay, ax, 3, finallimits, ticknode_3, mi3, mi1, mi2, - ax.xreversed, ax.yreversed, ax.zreversed) + ax.xreversed, ax.yreversed, ax.zreversed + ) xticks, xticklabels, xlabel = add_ticks_and_ticklabels!(blockscene, scene, ax, 1, finallimits, ticknode_1, mi1, mi2, mi3, ax.azimuth, ax.xreversed, ax.yreversed, ax.zreversed) @@ -140,7 +146,8 @@ function initialize_block!(ax::Axis3) font = ax.titlefont, color = ax.titlecolor, markerspace = :data, - inspectable = false) + inspectable = false + ) ax.mouseeventhandle = addmouseevents!(scene) scrollevents = Observable(ScrollEvent(0, 0)) @@ -201,8 +208,10 @@ function initialize_block!(ax::Axis3) return end -function calculate_matrices(limits, viewport, protrusions, elev, azim, perspectiveness, aspect, - viewmode, xreversed, yreversed, zreversed, zoom_mult, scene_offset, near) +function calculate_matrices( + limits, viewport, protrusions, elev, azim, perspectiveness, aspect, + viewmode, xreversed, yreversed, zreversed, zoom_mult, scene_offset, near + ) ori = limits.origin ws = widths(limits) @@ -263,29 +272,30 @@ function calculate_matrices(limits, viewport, protrusions, elev, azim, perspecti lookat = Vec3d(0) end - lookat_matrix = Makie.lookat(eyepos, lookat, Vec3d(0,0,1)) + lookat_matrix = Makie.lookat(eyepos, lookat, Vec3d(0, 0, 1)) w = width(viewport) h = height(viewport) projection_matrix = projectionmatrix( lookat_matrix * model, limits, radius, fov, - w, h, to_protrusions(protrusions), viewmode, near) + w, h, to_protrusions(protrusions), viewmode, near + ) return model, lookat_matrix, projection_matrix, lookat, eyepos end -function projectionmatrix(viewmatrix, limits, radius, fov, width, height, protrusions, viewmode, near_limit) +function projectionmatrix(viewmatrix, limits, radius, fov, width, height, protrusions, viewmode, near_limit) # model normalizes the the longest axis of the axis bbox to -1..1, so its # bounding sphere has a radius of sqrt(3) # The distance of the camera to the center of the bounding sphere is "radius" near_limit > 0.0 || error("near value must be > 0, but is $near_limit.") - near = max(near_limit, radius - sqrt(3)) - far = max((1 + 1e-3) * near, radius + sqrt(3)) + near = max(near_limit, radius - sqrt(3)) + far = max((1 + 1.0e-3) * near, radius + sqrt(3)) aspect_ratio = width / height - projection_matrix = if viewmode in (:free, :fit, :fitzoom, :stretch) + return projection_matrix = if viewmode in (:free, :fit, :fitzoom, :stretch) if height > width fov = fov / aspect_ratio end @@ -307,7 +317,7 @@ function projectionmatrix(viewmatrix, limits, radius, fov, width, height, protr projpoints = Ref(pm * viewmatrix) .* to_ndim.(Point4d, points, 1) # convert to effective viewport - w = w/width; h = h/height + w = w / width; h = h / height maxx = maximum(x -> abs(x[1] / (w * x[4])), projpoints) maxy = maximum(x -> abs(x[2] / (h * x[4])), projpoints) @@ -351,10 +361,10 @@ function getlimits(ax::Axis3, dim) filtered_plots = filter(ax.scene.plots) do p attr = p.attributes to_value(get(attr, :visible, true)) && - is_data_space(to_value(get(attr, :space, :data))) && - ifelse(dim == 1, to_value(get(attr, :xautolimits, true)), true) && - ifelse(dim == 2, to_value(get(attr, :yautolimits, true)), true) && - ifelse(dim == 3, to_value(get(attr, :zautolimits, true)), true) + is_data_space(to_value(get(attr, :space, :data))) && + ifelse(dim == 1, to_value(get(attr, :xautolimits, true)), true) && + ifelse(dim == 2, to_value(get(attr, :yautolimits, true)), true) && + ifelse(dim == 3, to_value(get(attr, :zautolimits, true)), true) end bboxes = Makie.data_limits.(filtered_plots) @@ -368,11 +378,11 @@ function getlimits(ax::Axis3, dim) templim = limitunion(templim, (bb.origin[dim], bb.origin[dim] + bb.widths[dim])) end - templim + return templim end function dimpoint(dim, v, v1, v2) - if dim == 1 + return if dim == 1 Point(v, v1, v2) elseif dim == 2 Point(v1, v, v2) @@ -382,7 +392,7 @@ function dimpoint(dim, v, v1, v2) end function dim1(dim) - if dim == 1 + return if dim == 1 2 elseif dim == 2 1 @@ -392,7 +402,7 @@ function dim1(dim) end function dim2(dim) - if dim == 1 + return if dim == 1 3 elseif dim == 2 3 @@ -425,10 +435,12 @@ function add_gridlines_and_frames!(topscene, scene, overlay, ax, dim::Int, limit dpoint(t, f1, mi[d2]), dpoint(t, f1, ma[d2]) end end - gridline1 = linesegments!(scene, endpoints, color = attr(:gridcolor), + gridline1 = linesegments!( + scene, endpoints, color = attr(:gridcolor), linewidth = attr(:gridwidth), clip_planes = Plane3f[], xautolimits = false, yautolimits = false, zautolimits = false, transparency = true, - visible = attr(:gridvisible), inspectable = false) + visible = attr(:gridvisible), inspectable = false + ) endpoints2 = lift(limits, tickvalues, min1, min2, xreversed, yreversed, zreversed) do lims, ticks, min1, min2, xrev, yrev, zrev rev1 = (xrev, yrev, zrev)[d1] @@ -442,14 +454,17 @@ function add_gridlines_and_frames!(topscene, scene, overlay, ax, dim::Int, limit dpoint(t, mi[d1], f2), dpoint(t, ma[d1], f2) end end - gridline2 = linesegments!(scene, endpoints2, color = attr(:gridcolor), + gridline2 = linesegments!( + scene, endpoints2, color = attr(:gridcolor), linewidth = attr(:gridwidth), clip_planes = Plane3f[], xautolimits = false, yautolimits = false, zautolimits = false, transparency = true, - visible = attr(:gridvisible), inspectable = false) + visible = attr(:gridvisible), inspectable = false + ) - framepoints = lift(limits, min1, min2, xreversed, yreversed, zreversed - ) do lims, mi1, mi2, xrev, yrev, zrev + framepoints = lift( + limits, min1, min2, xreversed, yreversed, zreversed + ) do lims, mi1, mi2, xrev, yrev, zrev rev1 = (xrev, yrev, zrev)[d1] rev2 = (xrev, yrev, zrev)[d2] @@ -467,8 +482,9 @@ function add_gridlines_and_frames!(topscene, scene, overlay, ax, dim::Int, limit return [p1, p2, p3, p4, p5, p6] end - framepoints_front_spines = lift(limits, min1, min2, xreversed, yreversed, zreversed - ) do lims, mi1, mi2, xrev, yrev, zrev + framepoints_front_spines = lift( + limits, min1, min2, xreversed, yreversed, zreversed + ) do lims, mi1, mi2, xrev, yrev, zrev rev1 = (xrev, yrev, zrev)[d1] rev2 = (xrev, yrev, zrev)[d2] @@ -486,14 +502,18 @@ function add_gridlines_and_frames!(topscene, scene, overlay, ax, dim::Int, limit colors = Observable{Any}() map!(vcat, colors, attr(:spinecolor_1), attr(:spinecolor_2), attr(:spinecolor_3)) - framelines = linesegments!(scene, framepoints, color = colors, linewidth = attr(:spinewidth), + framelines = linesegments!( + scene, framepoints, color = colors, linewidth = attr(:spinewidth), transparency = true, visible = attr(:spinesvisible), inspectable = false, - xautolimits = false, yautolimits = false, zautolimits = false, clip_planes = Plane3f[]) + xautolimits = false, yautolimits = false, zautolimits = false, clip_planes = Plane3f[] + ) - front_framelines = linesegments!(overlay, framepoints_front_spines, color = attr(:spinecolor_4), - linewidth = attr(:spinewidth), visible = map((a,b) -> a && b, ax.front_spines, attr(:spinesvisible)), + front_framelines = linesegments!( + overlay, framepoints_front_spines, color = attr(:spinecolor_4), + linewidth = attr(:spinewidth), visible = map((a, b) -> a && b, ax.front_spines, attr(:spinesvisible)), transparency = true, inspectable = false, - xautolimits = false, yautolimits = false, zautolimits = false, clip_planes = Plane3f[]) + xautolimits = false, yautolimits = false, zautolimits = false, clip_planes = Plane3f[] + ) #= On transparency and render order We have transparency = true here mostly for render order and depth testing @@ -539,9 +559,11 @@ function add_ticks_and_ticklabels!(topscene, scene, ax, dim::Int, limits, tickno end ticksize = attr(:ticksize) - tick_segments = lift(topscene, limits, tickvalues, miv, min1, min2, - scene.camera.projectionview, scene.viewport, ticksize, xreversed, yreversed, zreversed) do lims, ticks, miv, min1, min2, - pview, pxa, tsize, xrev, yrev, zrev + tick_segments = lift( + topscene, limits, tickvalues, miv, min1, min2, + scene.camera.projectionview, scene.viewport, ticksize, xreversed, yreversed, zreversed + ) do lims, ticks, miv, min1, min2, + pview, pxa, tsize, xrev, yrev, zrev rev1 = (xrev, yrev, zrev)[d1] rev2 = (xrev, yrev, zrev)[d2] @@ -575,18 +597,22 @@ function add_ticks_and_ticklabels!(topscene, scene, ax, dim::Int, limits, tickno diff_pp = Makie.GeometryBasics.normalize(Point2f(pp2 - pp1)) return (pp1, pp1 .+ Float32(tsize) .* diff_pp) - end + end end - ticks = linesegments!(topscene, tick_segments, + ticks = linesegments!( + topscene, tick_segments, transparency = true, inspectable = false, - color = attr(:tickcolor), linewidth = attr(:tickwidth), visible = attr(:ticksvisible)) + color = attr(:tickcolor), linewidth = attr(:tickwidth), visible = attr(:ticksvisible) + ) # move ticks behind plots, -10000 is the far value in campixel translate!(ticks, 0, 0, -10000) labels_positions = Observable{Any}() - map!(topscene, labels_positions, scene.viewport, scene.camera.projectionview, - tick_segments, ticklabels, attr(:ticklabelpad)) do pxa, pv, ticksegs, ticklabs, pad + map!( + topscene, labels_positions, scene.viewport, scene.camera.projectionview, + tick_segments, ticklabels, attr(:ticklabelpad) + ) do pxa, pv, ticksegs, ticklabs, pad o = (origin(pxa) - origin(topscene.viewport[])) @@ -596,7 +622,7 @@ function add_ticks_and_ticklabels!(topscene, scene, ax, dim::Int, limits, tickno end N = min(length(ticklabs), length(points)) - Tuple{Any,Point2f}[(ticklabs[i], points[i]) for i in 1:N] + Tuple{Any, Point2f}[(ticklabs[i], points[i]) for i in 1:N] end align = lift(topscene, miv, min1, min2) do mv, m1, m2 @@ -609,7 +635,8 @@ function add_ticks_and_ticklabels!(topscene, scene, ax, dim::Int, limits, tickno end end - ticklabels_text = text!(topscene, labels_positions, align = align, + ticklabels_text = text!( + topscene, labels_positions, align = align, color = attr(:ticklabelcolor), fontsize = attr(:ticklabelsize), font = attr(:ticklabelfont), visible = attr(:ticklabelsvisible), inspectable = false ) @@ -617,13 +644,14 @@ function add_ticks_and_ticklabels!(topscene, scene, ax, dim::Int, limits, tickno translate!(ticklabels_text, 0, 0, 1000) label_position = Observable(Point2f(0)) - label_rotation = Observable(0f0) + label_rotation = Observable(0.0f0) label_align = Observable((:center, :top)) - onany(topscene, - scene.viewport, scene.camera.projectionview, limits, miv, min1, min2, - attr(:labeloffset), attr(:labelrotation), attr(:labelalign), xreversed, yreversed, zreversed - ) do pxa, pv, lims, miv, min1, min2, labeloffset, lrotation, lalign, xrev, yrev, zrev + onany( + topscene, + scene.viewport, scene.camera.projectionview, limits, miv, min1, min2, + attr(:labeloffset), attr(:labelrotation), attr(:labelalign), xreversed, yreversed, zreversed + ) do pxa, pv, lims, miv, min1, min2, labeloffset, lrotation, lalign, xrev, yrev, zrev o = (origin(pxa) - origin(topscene.viewport[])) @@ -657,18 +685,20 @@ function add_ticks_and_ticklabels!(topscene, scene, ax, dim::Int, limits, tickno (min1 ⊻ min2 ⊻ revdim) ? 1 : -1 end - a = pi/2 + a = pi / 2 # get the vector pointing from the axis in the direction of the label anchor - offset_vec = (Makie.Mat2f(cos(a), sin(a), -sin(a), cos(a)) * - Makie.GeometryBasics.normalize(diffsign * diff)) + offset_vec = ( + Makie.Mat2f(cos(a), sin(a), -sin(a), cos(a)) * + Makie.GeometryBasics.normalize(diffsign * diff) + ) # calculate the label offset from the axis midpoint plus_offset = midpoint + labeloffset * offset_vec offset_ang = atan(offset_vec[2], offset_vec[1]) - offset_ang_90deg = offset_ang + pi/2 - offset_ang_90deg_alwaysup = ((offset_ang + pi/2 + pi/2) % pi) - pi/2 + offset_ang_90deg = offset_ang + pi / 2 + offset_ang_90deg_alwaysup = ((offset_ang + pi / 2 + pi / 2) % pi) - pi / 2 # # prefer rotated left 90deg to rotated right 90deg slight_flip = offset_ang_90deg_alwaysup < -deg2rad(88) @@ -697,7 +727,8 @@ function add_ticks_and_ticklabels!(topscene, scene, ax, dim::Int, limits, tickno end notify(attr(:labelalign)) - label = text!(topscene, label_position, + label = text!( + topscene, label_position, text = attr(:label), color = attr(:labelcolor), fontsize = attr(:labelsize), @@ -712,7 +743,7 @@ function add_ticks_and_ticklabels!(topscene, scene, ax, dim::Int, limits, tickno end function dim3point(dim1, dim2, dim3, v1, v2, v3) - if (dim1, dim2, dim3) == (1, 2, 3) + return if (dim1, dim2, dim3) == (1, 2, 3) Point(v1, v2, v3) elseif (dim1, dim2, dim3) == (2, 3, 1) Point(v3, v1, v2) @@ -725,19 +756,23 @@ end function add_panel!(scene, ax, dim1, dim2, dim3, limits, min3) - dimsym(sym) = Symbol(string((:x, :y, :z)[dim1]) * - string((:x, :y, :z)[dim2]) * string(sym)) + dimsym(sym) = Symbol( + string((:x, :y, :z)[dim1]) * + string((:x, :y, :z)[dim2]) * string(sym) + ) attr(sym) = getproperty(ax, dimsym(sym)) rect = lift(limits) do lims mi = minimum(lims) ma = maximum(lims) - Polygon([ - Point2(mi[dim1], mi[dim2]), - Point2(ma[dim1], mi[dim2]), - Point2(ma[dim1], ma[dim2]), - Point2(mi[dim1], ma[dim2]) - ]) + Polygon( + [ + Point2(mi[dim1], mi[dim2]), + Point2(ma[dim1], mi[dim2]), + Point2(ma[dim1], ma[dim2]), + Point2(mi[dim1], ma[dim2]), + ] + ) end plane_offset = lift(limits, min3) do lims, mi3 @@ -749,7 +784,8 @@ function add_panel!(scene, ax, dim1, dim2, dim3, limits, min3) plane = Symbol((:x, :y, :z)[dim1], (:x, :y, :z)[dim2]) - panel = poly!(scene, rect, inspectable = false, + panel = poly!( + scene, rect, inspectable = false, xautolimits = false, yautolimits = false, zautolimits = false, color = attr(:panelcolor), visible = attr(:panelvisible), strokecolor = :transparent, strokewidth = 0, @@ -768,8 +804,10 @@ function add_panel!(scene, ax, dim1, dim2, dim3, limits, min3) return panel end -function hidexdecorations!(ax::Axis3; - label = true, ticklabels = true, ticks = true, grid = true) +function hidexdecorations!( + ax::Axis3; + label = true, ticklabels = true, ticks = true, grid = true + ) if label ax.xlabelvisible = false @@ -790,11 +828,13 @@ function hidexdecorations!(ax::Axis3; # ax.xminorticksvisible = false # end - ax + return ax end -function hideydecorations!(ax::Axis3; - label = true, ticklabels = true, ticks = true, grid = true) +function hideydecorations!( + ax::Axis3; + label = true, ticklabels = true, ticks = true, grid = true + ) if label ax.ylabelvisible = false @@ -815,7 +855,7 @@ function hideydecorations!(ax::Axis3; # ax.yminorticksvisible = false # end - ax + return ax end """ @@ -824,8 +864,10 @@ end Hide decorations of the z-axis: label, ticklabels, ticks and grid. Keyword arguments can be used to disable hiding of certain types of decorations. """ -function hidezdecorations!(ax::Axis3; - label = true, ticklabels = true, ticks = true, grid = true) +function hidezdecorations!( + ax::Axis3; + label = true, ticklabels = true, ticks = true, grid = true + ) if label ax.zlabelvisible = false @@ -846,40 +888,47 @@ function hidezdecorations!(ax::Axis3; # ax.zminorticksvisible = false # end - ax + return ax end -function hidedecorations!(ax::Axis3; - label = true, ticklabels = true, ticks = true, grid = true) +function hidedecorations!( + ax::Axis3; + label = true, ticklabels = true, ticks = true, grid = true + ) - hidexdecorations!(ax; label = label, ticklabels = ticklabels, - ticks = ticks, grid = grid) - hideydecorations!(ax; label = label, ticklabels = ticklabels, - ticks = ticks, grid = grid) - hidezdecorations!(ax; label = label, ticklabels = ticklabels, - ticks = ticks, grid = grid) + hidexdecorations!( + ax; label = label, ticklabels = ticklabels, + ticks = ticks, grid = grid + ) + hideydecorations!( + ax; label = label, ticklabels = ticklabels, + ticks = ticks, grid = grid + ) + hidezdecorations!( + ax; label = label, ticklabels = ticklabels, + ticks = ticks, grid = grid + ) - ax + return ax end function hidespines!(ax::Axis3) ax.xspinesvisible = false ax.yspinesvisible = false ax.zspinesvisible = false - ax + return ax end - # this is so users can do limits = (x1, x2, y1, y2, z1, z2) function convert_limit_attribute(lims::Tuple{Any, Any, Any, Any, Any, Any}) - (lims[1:2], lims[3:4], lims[5:6]) + return (lims[1:2], lims[3:4], lims[5:6]) end function convert_limit_attribute(lims::Tuple{Any, Any, Any}) _convert_single_limit(x) = x _convert_single_limit(x::Interval) = endpoints(x) - map(_convert_single_limit, lims) + return map(_convert_single_limit, lims) end @@ -889,12 +938,14 @@ function xautolimits(ax::Axis3) if isnothing(xlims) xlims = (ax.targetlimits[].origin[1], ax.targetlimits[].origin[1] + ax.targetlimits[].widths[1]) else - xlims = expandlimits(xlims, + xlims = expandlimits( + xlims, ax.xautolimitmargin[][1], ax.xautolimitmargin[][2], - identity) + identity + ) end - xlims + return xlims end function yautolimits(ax::Axis3) @@ -903,12 +954,14 @@ function yautolimits(ax::Axis3) if isnothing(ylims) ylims = (ax.targetlimits[].origin[2], ax.targetlimits[].origin[2] + ax.targetlimits[].widths[2]) else - ylims = expandlimits(ylims, + ylims = expandlimits( + ylims, ax.yautolimitmargin[][1], ax.yautolimitmargin[][2], - identity) + identity + ) end - ylims + return ylims end function zautolimits(ax::Axis3) @@ -917,12 +970,14 @@ function zautolimits(ax::Axis3) if isnothing(zlims) zlims = (ax.targetlimits[].origin[3], ax.targetlimits[].origin[3] + ax.targetlimits[].widths[3]) else - zlims = expandlimits(zlims, + zlims = expandlimits( + zlims, ax.zautolimitmargin[][1], ax.zautolimitmargin[][2], - identity) + identity + ) end - zlims + return zlims end Makie.xlims!(ax::Axis3, xlims::Interval) = Makie.xlims!(ax, endpoints(xlims)) @@ -944,7 +999,7 @@ function Makie.xlims!(ax::Axis3, xlims::Tuple{Union{Real, Nothing}, Union{Real, ax.limits.val = (xlims, mlims[2], mlims[3]) reset_limits!(ax, yauto = false, zauto = false) - nothing + return nothing end function Makie.ylims!(ax::Axis3, ylims::Tuple{Union{Real, Nothing}, Union{Real, Nothing}}) @@ -962,7 +1017,7 @@ function Makie.ylims!(ax::Axis3, ylims::Tuple{Union{Real, Nothing}, Union{Real, ax.limits.val = (mlims[1], ylims, mlims[3]) reset_limits!(ax, xauto = false, zauto = false) - nothing + return nothing end function Makie.zlims!(ax::Axis3, zlims) @@ -980,7 +1035,7 @@ function Makie.zlims!(ax::Axis3, zlims) ax.limits.val = (mlims[1], mlims[2], zlims) reset_limits!(ax, xauto = false, yauto = false) - nothing + return nothing end @@ -993,7 +1048,7 @@ If limits are ordered high-low, this reverses the axis orientation. function limits!(ax::Axis3, xlims, ylims, zlims) Makie.xlims!(ax, xlims) Makie.ylims!(ax, ylims) - Makie.zlims!(ax, zlims) + return Makie.zlims!(ax, zlims) end """ @@ -1006,7 +1061,7 @@ If limits are ordered high-low, this reverses the axis orientation. function limits!(ax::Axis3, x1, x2, y1, y2, z1, z2) Makie.xlims!(ax, x1, x2) Makie.ylims!(ax, y1, y2) - Makie.zlims!(ax, z1, z2) + return Makie.zlims!(ax, z1, z2) end """ @@ -1020,107 +1075,107 @@ function limits!(ax::Axis3, rect::Rect3) xmax, ymax, zmax = maximum(rect) Makie.xlims!(ax, xmin, xmax) Makie.ylims!(ax, ymin, ymax) - Makie.zlims!(ax, zmin, zmax) + return Makie.zlims!(ax, zmin, zmax) end function attribute_examples(::Type{Axis3}) - Dict( + return Dict( :aspect => [ Example( code = """ - fig = Figure() + fig = Figure() - Axis3(fig[1, 1], aspect = (1, 1, 1), title = "aspect = (1, 1, 1)") - Axis3(fig[1, 2], aspect = (2, 1, 1), title = "aspect = (2, 1, 1)") - Axis3(fig[2, 1], aspect = (1, 2, 1), title = "aspect = (1, 2, 1)") - Axis3(fig[2, 2], aspect = (1, 1, 2), title = "aspect = (1, 1, 2)") + Axis3(fig[1, 1], aspect = (1, 1, 1), title = "aspect = (1, 1, 1)") + Axis3(fig[1, 2], aspect = (2, 1, 1), title = "aspect = (2, 1, 1)") + Axis3(fig[2, 1], aspect = (1, 2, 1), title = "aspect = (1, 2, 1)") + Axis3(fig[2, 2], aspect = (1, 1, 2), title = "aspect = (1, 1, 2)") - fig - """ + fig + """ ), Example( code = """ - using FileIO + using FileIO - fig = Figure() + fig = Figure() - brain = load(assetpath("brain.stl")) + brain = load(assetpath("brain.stl")) - ax1 = Axis3(fig[1, 1], aspect = :equal, title = "aspect = :equal") - ax2 = Axis3(fig[1, 2], aspect = :data, title = "aspect = :data") + ax1 = Axis3(fig[1, 1], aspect = :equal, title = "aspect = :equal") + ax2 = Axis3(fig[1, 2], aspect = :data, title = "aspect = :data") - for ax in [ax1, ax2] - mesh!(ax, brain, color = :gray80) - end + for ax in [ax1, ax2] + mesh!(ax, brain, color = :gray80) + end - fig - """ + fig + """ ), ], :viewmode => [ Example( code = """ - fig = Figure() + fig = Figure() - for (i, viewmode) in enumerate([:fit, :fitzoom, :stretch]) - for (j, elevation) in enumerate([0.1, 0.2, 0.3] .* pi) + for (i, viewmode) in enumerate([:fit, :fitzoom, :stretch]) + for (j, elevation) in enumerate([0.1, 0.2, 0.3] .* pi) - Label(fig[i, 1:3, Top()], "viewmode = \$(repr(viewmode))", font = :bold) + Label(fig[i, 1:3, Top()], "viewmode = \$(repr(viewmode))", font = :bold) - # show the extent of each cell using a box - Box(fig[i, j], strokewidth = 0, color = :gray95) + # show the extent of each cell using a box + Box(fig[i, j], strokewidth = 0, color = :gray95) - ax = Axis3(fig[i, j]; viewmode, elevation, protrusions = 0, aspect = :equal) - hidedecorations!(ax) + ax = Axis3(fig[i, j]; viewmode, elevation, protrusions = 0, aspect = :equal) + hidedecorations!(ax) - end end + end - fig - """ + fig + """ ), ], :perspectiveness => [ Example( code = """ - fig = Figure() + fig = Figure() - for (i, perspectiveness) in enumerate(range(0, 1, length = 6)) - ax = Axis3(fig[fldmod1(i, 3)...]; perspectiveness, protrusions = (0, 0, 0, 15), - title = ":perspectiveness = \$(perspectiveness)") - hidedecorations!(ax) - end + for (i, perspectiveness) in enumerate(range(0, 1, length = 6)) + ax = Axis3(fig[fldmod1(i, 3)...]; perspectiveness, protrusions = (0, 0, 0, 15), + title = ":perspectiveness = \$(perspectiveness)") + hidedecorations!(ax) + end - fig - """ + fig + """ ), ], :azimuth => [ Example( code = """ - fig = Figure() + fig = Figure() - for (i, azimuth) in enumerate([0, 0.1, 0.2, 0.3, 0.4, 0.5]) - Axis3(fig[fldmod1(i, 3)...], azimuth = azimuth * pi, - title = "azimuth = \$(azimuth)π", viewmode = :fit) - end + for (i, azimuth) in enumerate([0, 0.1, 0.2, 0.3, 0.4, 0.5]) + Axis3(fig[fldmod1(i, 3)...], azimuth = azimuth * pi, + title = "azimuth = \$(azimuth)π", viewmode = :fit) + end - fig - """ + fig + """ ), ], :elevation => [ Example( code = """ - fig = Figure() + fig = Figure() - for (i, elevation) in enumerate([0, 0.05, 0.1, 0.15, 0.2, 0.25]) - Axis3(fig[fldmod1(i, 3)...], elevation = elevation * pi, - title = "elevation = \$(elevation)π", viewmode = :fit) - end + for (i, elevation) in enumerate([0, 0.05, 0.1, 0.15, 0.2, 0.25]) + Axis3(fig[fldmod1(i, 3)...], elevation = elevation * pi, + title = "elevation = \$(elevation)π", viewmode = :fit) + end - fig - """ + fig + """ ), ], :xreversed => [ @@ -1145,39 +1200,39 @@ function attribute_examples(::Type{Axis3}) :yreversed => [ Example( code = """ - using FileIO + using FileIO - fig = Figure() + fig = Figure() - brain = load(assetpath("brain.stl")) + brain = load(assetpath("brain.stl")) - ax1 = Axis3(fig[1, 1], title = "yreversed = false") - ax2 = Axis3(fig[2, 1], title = "yreversed = true", yreversed = true) - for ax in [ax1, ax2] - mesh!(ax, brain, color = getindex.(brain.position, 2)) - end + ax1 = Axis3(fig[1, 1], title = "yreversed = false") + ax2 = Axis3(fig[2, 1], title = "yreversed = true", yreversed = true) + for ax in [ax1, ax2] + mesh!(ax, brain, color = getindex.(brain.position, 2)) + end - fig - """ + fig + """ ), ], :zreversed => [ Example( code = """ - using FileIO + using FileIO - fig = Figure() + fig = Figure() - brain = load(assetpath("brain.stl")) + brain = load(assetpath("brain.stl")) - ax1 = Axis3(fig[1, 1], title = "zreversed = false") - ax2 = Axis3(fig[2, 1], title = "zreversed = true", zreversed = true) - for ax in [ax1, ax2] - mesh!(ax, brain, color = getindex.(brain.position, 3)) - end + ax1 = Axis3(fig[1, 1], title = "zreversed = false") + ax2 = Axis3(fig[2, 1], title = "zreversed = true", zreversed = true) + for ax in [ax1, ax2] + mesh!(ax, brain, color = getindex.(brain.position, 3)) + end - fig - """ + fig + """ ), ], :protrusions => [ diff --git a/src/makielayout/blocks/box.jl b/src/makielayout/blocks/box.jl index 0be8b3e8699..f4d48454b9b 100644 --- a/src/makielayout/blocks/box.jl +++ b/src/makielayout/blocks/box.jl @@ -7,35 +7,40 @@ function initialize_block!(box::Box) path = lift(blockscene, box.layoutobservables.computedbbox, box.cornerradius) do bbox, r if r == 0 - BezierPath([ - MoveTo(topright(bbox)), - LineTo(topleft(bbox)), - LineTo(bottomleft(bbox)), - LineTo(bottomright(bbox)), - ClosePath() - ]) + BezierPath( + [ + MoveTo(topright(bbox)), + LineTo(topleft(bbox)), + LineTo(bottomleft(bbox)), + LineTo(bottomright(bbox)), + ClosePath(), + ] + ) else w, h = widths(bbox) - _max = min(w/2, h/2) + _max = min(w / 2, h / 2) r1, r2, r3, r4 = r isa NTuple{4, Real} ? r : r isa Real ? (r, r, r, r) : throw(ArgumentError("Invalid cornerradius value $r. Must be a `Real` or a tuple with 4 `Real`s.")) r1, r2, r3, r4 = min.(_max, (r1, r2, r3, r4)) - BezierPath([ - MoveTo(bbox.origin + Point(w, h/2)), - EllipticalArc(topright(bbox) - Point2f(r1, r1), r1, r1, 0.0, 0, pi/2), - EllipticalArc(topleft(bbox) + Point2f(r4, -r4), r4, r4, 0.0, pi/2, pi), - EllipticalArc(bottomleft(bbox) + Point2f(r3, r3), r3, r3, 0.0, pi, 3/2 * pi), - EllipticalArc(bottomright(bbox) + Point2f(-r2, r2), r2, r2, 0.0, 3/2 * pi, 2pi), - ClosePath(), - ]) + BezierPath( + [ + MoveTo(bbox.origin + Point(w, h / 2)), + EllipticalArc(topright(bbox) - Point2f(r1, r1), r1, r1, 0.0, 0, pi / 2), + EllipticalArc(topleft(bbox) + Point2f(r4, -r4), r4, r4, 0.0, pi / 2, pi), + EllipticalArc(bottomleft(bbox) + Point2f(r3, r3), r3, r3, 0.0, pi, 3 / 2 * pi), + EllipticalArc(bottomright(bbox) + Point2f(-r2, r2), r2, r2, 0.0, 3 / 2 * pi, 2pi), + ClosePath(), + ] + ) end end - - poly!(blockscene, path, color = box.color, visible = box.visible, + poly!( + blockscene, path, color = box.color, visible = box.visible, strokecolor = strokecolor_with_visibility, strokewidth = box.strokewidth, - inspectable = false, linestyle = box.linestyle) + inspectable = false, linestyle = box.linestyle + ) # trigger bbox box.layoutobservables.suggestedbbox[] = box.layoutobservables.suggestedbbox[] @@ -45,63 +50,63 @@ end function attribute_examples(::Type{Box}) - Dict( + return Dict( :color => [ Example( code = """ - fig = Figure() - Box(fig[1, 1], color = :red) - Box(fig[1, 2], color = (:red, 0.5)) - Box(fig[2, 1], color = RGBf(0.2, 0.5, 0.7)) - Box(fig[2, 2], color = RGBAf(0.2, 0.5, 0.7, 0.5)) - fig - """ - ) + fig = Figure() + Box(fig[1, 1], color = :red) + Box(fig[1, 2], color = (:red, 0.5)) + Box(fig[2, 1], color = RGBf(0.2, 0.5, 0.7)) + Box(fig[2, 2], color = RGBAf(0.2, 0.5, 0.7, 0.5)) + fig + """ + ), ], :strokecolor => [ Example( code = """ - fig = Figure() - Box(fig[1, 1], strokecolor = :red) - Box(fig[1, 2], strokecolor = (:red, 0.5)) - Box(fig[2, 1], strokecolor = RGBf(0.2, 0.5, 0.7)) - Box(fig[2, 2], strokecolor = RGBAf(0.2, 0.5, 0.7, 0.5)) - fig - """ - ) + fig = Figure() + Box(fig[1, 1], strokecolor = :red) + Box(fig[1, 2], strokecolor = (:red, 0.5)) + Box(fig[2, 1], strokecolor = RGBf(0.2, 0.5, 0.7)) + Box(fig[2, 2], strokecolor = RGBAf(0.2, 0.5, 0.7, 0.5)) + fig + """ + ), ], :strokewidth => [ Example( code = """ - fig = Figure() - Box(fig[1, 1], strokewidth = 1) - Box(fig[1, 2], strokewidth = 10) - Box(fig[1, 3], strokewidth = 0) - fig - """ - ) + fig = Figure() + Box(fig[1, 1], strokewidth = 1) + Box(fig[1, 2], strokewidth = 10) + Box(fig[1, 3], strokewidth = 0) + fig + """ + ), ], :linestyle => [ Example( code = """ - fig = Figure() - Box(fig[1, 1], linestyle = :solid) - Box(fig[1, 2], linestyle = :dot) - Box(fig[1, 3], linestyle = :dash) - fig - """ - ) + fig = Figure() + Box(fig[1, 1], linestyle = :solid) + Box(fig[1, 2], linestyle = :dot) + Box(fig[1, 3], linestyle = :dash) + fig + """ + ), ], :cornerradius => [ Example( code = """ - fig = Figure() - Box(fig[1, 1], cornerradius = 0) - Box(fig[1, 2], cornerradius = 20) - Box(fig[1, 3], cornerradius = (0, 10, 20, 30)) - fig - """ - ) + fig = Figure() + Box(fig[1, 1], cornerradius = 0) + Box(fig[1, 2], cornerradius = 20) + Box(fig[1, 3], cornerradius = (0, 10, 20, 30)) + fig + """ + ), ], ) -end \ No newline at end of file +end diff --git a/src/makielayout/blocks/button.jl b/src/makielayout/blocks/button.jl index 68a3d42b9f5..fd15fd40e7a 100644 --- a/src/makielayout/blocks/button.jl +++ b/src/makielayout/blocks/button.jl @@ -7,7 +7,7 @@ function initialize_block!(b::Button) subarea = lift(scene, b.layoutobservables.computedbbox) do bbox round_to_IRect2D(bbox) end - subscene = Scene(scene, subarea, camera=campixel!) + subscene = Scene(scene, subarea, camera = campixel!) # buttonrect is without the left bottom offset of the bbox buttonrect = lift(scene, b.layoutobservables.computedbbox) do bbox @@ -26,15 +26,19 @@ function initialize_block!(b::Button) bcolor = Observable{RGBColors}() map!((s, _...) -> to_color(bcolors[s][]), scene, bcolor, mousestate, values(bcolors)...) - button = poly!(subscene, roundedrectpoints, strokewidth = b.strokewidth, strokecolor = b.strokecolor, - color = bcolor, inspectable = false) + button = poly!( + subscene, roundedrectpoints, strokewidth = b.strokewidth, strokecolor = b.strokecolor, + color = bcolor, inspectable = false + ) lcolors = (; out = b.labelcolor, active = b.labelcolor_active, hover = b.labelcolor_hover) lcolor = Observable{RGBColors}() map!((s, _...) -> to_color(lcolors[s][]), scene, lcolor, mousestate, values(lcolors)...) - labeltext = text!(subscene, textpos, text = b.label, fontsize = b.fontsize, font = b.font, - color = lcolor, align = (:center, :center), markerspace = :data, inspectable = false) + labeltext = text!( + subscene, textpos, text = b.label, fontsize = b.fontsize, font = b.font, + color = lcolor, align = (:center, :center), markerspace = :data, inspectable = false + ) # move text in front of background to be sure it's not occluded translate!(labeltext, 0, 0, 1) diff --git a/src/makielayout/blocks/checkbox.jl b/src/makielayout/blocks/checkbox.jl index 15167bb5ae5..70c061cbb3c 100644 --- a/src/makielayout/blocks/checkbox.jl +++ b/src/makielayout/blocks/checkbox.jl @@ -13,7 +13,7 @@ function initialize_block!(c::Checkbox) end shape = lift(c.size, c.roundness) do size, roundness - r = Float64(roundness * size/2) + r = Float64(roundness * size / 2) roundedrectpath(Float64.((size, size)), (r, r, r, r)) end @@ -72,23 +72,25 @@ function initialize_block!(c::Checkbox) on(scene, c.size; update = true) do sz c.layoutobservables.autosize[] = Float64.((sz, sz)) end - + return end function roundedrectpath(size, radii) # radii go top right, bottom right, bottom left, top left rw, rh = size ./ 2 - BezierPath([ - MoveTo(rw, rh-radii[1]), - LineTo(rw, -rh+radii[2]), - EllipticalArc(Point(rw-radii[2], -rh+radii[2]), radii[2], radii[2], 0, 0, -pi/2), - LineTo(-rw+radii[3], -rh), - EllipticalArc(Point(-rw+radii[3], -rh+radii[3]), radii[3], radii[3], 0, -pi/2, -pi), - LineTo(-rw, rh-radii[4]), - EllipticalArc(Point(-rw+radii[4], rh-radii[4]), radii[4], radii[4], 0, -pi, -3pi/2), - LineTo(rw-radii[1], rh), - EllipticalArc(Point(rw-radii[1], rh-radii[1]), radii[1], radii[1], 0, -3pi/2, -2pi), - ClosePath(), - ]) + return BezierPath( + [ + MoveTo(rw, rh - radii[1]), + LineTo(rw, -rh + radii[2]), + EllipticalArc(Point(rw - radii[2], -rh + radii[2]), radii[2], radii[2], 0, 0, -pi / 2), + LineTo(-rw + radii[3], -rh), + EllipticalArc(Point(-rw + radii[3], -rh + radii[3]), radii[3], radii[3], 0, -pi / 2, -pi), + LineTo(-rw, rh - radii[4]), + EllipticalArc(Point(-rw + radii[4], rh - radii[4]), radii[4], radii[4], 0, -pi, -3pi / 2), + LineTo(rw - radii[1], rh), + EllipticalArc(Point(rw - radii[1], rh - radii[1]), radii[1], radii[1], 0, -3pi / 2, -2pi), + ClosePath(), + ] + ) end diff --git a/src/makielayout/blocks/colorbar.jl b/src/makielayout/blocks/colorbar.jl index b458e3c1d01..e1c2e2d1826 100644 --- a/src/makielayout/blocks/colorbar.jl +++ b/src/makielayout/blocks/colorbar.jl @@ -4,6 +4,7 @@ function colorbar_check(keys, kwargs_keys) error("You should not pass the `$key` attribute to the colorbar when constructing it using an existing plot object. This attribute is copied from the plot object, and setting it from the colorbar will make the plot object and the colorbar go out of sync.") end end + return end function extract_colorrange(@nospecialize(plot::AbstractPlot))::Vec2{Float64} @@ -27,7 +28,7 @@ function extract_colormap(@nospecialize(plot::AbstractPlot)) get(plot, :alpha, Observable(1.0)), get(plot, :highclip, Observable(automatic)), get(plot, :lowclip, Observable(automatic)), - get(plot, :nan_color, Observable(RGBAf(0,0,0,0))), + get(plot, :nan_color, Observable(RGBAf(0, 0, 0, 0))), ) else return nothing @@ -42,7 +43,7 @@ function extract_colormap(plot::Plot{volumeslices}) return extract_colormap(plot.plots[1]) end -function extract_colormap(plot::Union{Contourf,Tricontourf}) +function extract_colormap(plot::Union{Contourf, Tricontourf}) levels = plot._computed_levels limits = lift(l -> (l[1], l[end]), levels) function extend_color(color, computed) @@ -52,8 +53,10 @@ function extract_colormap(plot::Union{Contourf,Tricontourf}) end elow = lift(extend_color, plot.extendlow, plot._computed_extendlow) ehigh = lift(extend_color, plot.extendhigh, plot._computed_extendhigh) - return ColorMapping(levels[], levels, plot._computed_colormap, limits, plot.colorscale, Observable(1.0), - elow, ehigh, plot.nan_color) + return ColorMapping( + levels[], levels, plot._computed_colormap, limits, plot.colorscale, Observable(1.0), + elow, ehigh, plot.nan_color + ) end function extract_colormap(plot::Voxels) @@ -80,7 +83,7 @@ function extract_colormap_recursive(@nospecialize(plot::T)) where {T <: Abstract return nothing else # Prefer ColorMapping if in doubt! - cmaps = filter(x-> x isa ColorMapping, colormaps) + cmaps = filter(x -> x isa ColorMapping, colormaps) length(cmaps) == 1 && return cmaps[1] error("Multiple colormaps found for plot $(plot), please specify which one to use manually. Please overload `Makie.extract_colormap(::$(T))` to allow for the automatic creation of a Colorbar.") end @@ -99,15 +102,17 @@ function Colorbar(fig_or_scene, plot::AbstractPlot; kwargs...) error("extract_colormap(::$(Plot{func})) returned an invalid value: $cmap. Needs to return either a `Makie.ColorMapping`.") end - if to_value(cmap.color) isa Union{AbstractVector{<: Colorant}, Colorant} - error("""Plot $(func)'s color attribute uses colors directly, so it can't be used to create a Colorbar, since no numbers are mapped to a color via the colormap. - Please create the colorbar manually e.g. via `Colorbar(f[1, 2], colorrange=the_range, colormap=the_colormap)`.. - """) + if to_value(cmap.color) isa Union{AbstractVector{<:Colorant}, Colorant} + error( + """Plot $(func)'s color attribute uses colors directly, so it can't be used to create a Colorbar, since no numbers are mapped to a color via the colormap. + Please create the colorbar manually e.g. via `Colorbar(f[1, 2], colorrange=the_range, colormap=the_colormap)`.. + """ + ) end return Colorbar( fig_or_scene; - colormap=cmap, + colormap = cmap, kwargs... ) end @@ -140,7 +145,8 @@ function initialize_block!(cb::Colorbar) nan_color = Observable(RGBAf(0, 0, 0, 0)) cmap = ColorMapping( Float64[], Observable(Float64[]), cb.colormap, limits, - cb.scale, alpha, cb.lowclip, cb.highclip, nan_color) + cb.scale, alpha, cb.lowclip, cb.highclip, nan_color + ) end colormap = lift(cmap.raw_colormap, cmap.colormap, cmap.mapping) do rcm, cm, mapping @@ -153,8 +159,10 @@ function initialize_block!(cb::Colorbar) end end limits = cmap.colorrange - colors = lift(blockscene, cmap.mapping, cmap.color_mapping_type, cmap.color, cb.nsteps, limits; - ignore_equal_values=true) do mapping, mapping_type, values, n, limits + colors = lift( + blockscene, cmap.mapping, cmap.color_mapping_type, cmap.color, cb.nsteps, limits; + ignore_equal_values = true + ) do mapping, mapping_type, values, n, limits if mapping === nothing if mapping_type === Makie.banded error("Banded without a mapping is invalid. Please use colormap=cgrad(...; categorical=true)") @@ -179,9 +187,9 @@ function initialize_block!(cb::Colorbar) end end - lowclip_tri_visible = lift(x -> !(x isa Automatic), blockscene, cmap.lowclip; ignore_equal_values=true) - highclip_tri_visible = lift(x -> !(x isa Automatic), blockscene, cmap.highclip; ignore_equal_values=true) - tri_heights = lift(blockscene, highclip_tri_visible, lowclip_tri_visible, framebox; ignore_equal_values=true) do hv, lv, box + lowclip_tri_visible = lift(x -> !(x isa Automatic), blockscene, cmap.lowclip; ignore_equal_values = true) + highclip_tri_visible = lift(x -> !(x isa Automatic), blockscene, cmap.highclip; ignore_equal_values = true) + tri_heights = lift(blockscene, highclip_tri_visible, lowclip_tri_visible, framebox; ignore_equal_values = true) do hv, lv, box if cb.vertical[] return (lv * width(box), hv * width(box)) else @@ -189,7 +197,7 @@ function initialize_block!(cb::Colorbar) end .* sin(pi / 3) end - barbox = lift(blockscene, framebox; ignore_equal_values=true) do fbox + barbox = lift(blockscene, framebox; ignore_equal_values = true) do fbox if cb.vertical[] return BBox(left(fbox), right(fbox), bottom(fbox) + tri_heights[][1], top(fbox) - tri_heights[][2]) else @@ -197,8 +205,8 @@ function initialize_block!(cb::Colorbar) end end - xrange = Observable(Float32[]; ignore_equal_values=true) - yrange = Observable(Float32[]; ignore_equal_values=true) + xrange = Observable(Float32[]; ignore_equal_values = true) + yrange = Observable(Float32[]; ignore_equal_values = true) function update_xyrange(bb, v, colors, scale, mapping_type) xmin, ymin = minimum(bb) @@ -224,19 +232,21 @@ function initialize_block!(cb::Colorbar) # for continuous colormaps we sample a 1d image # to avoid white lines when rendering vector graphics - continuous_pixels = lift(blockscene, cb.vertical, colors, - cmap.color_mapping_type) do v, colors, mapping_type + continuous_pixels = lift( + blockscene, cb.vertical, colors, + cmap.color_mapping_type + ) do v, colors, mapping_type if mapping_type !== Makie.categorical - colors = (colors[1:end-1] .+ colors[2:end]) ./2 + colors = (colors[1:(end - 1)] .+ colors[2:end]) ./ 2 end n = length(colors) return v ? reshape((colors), 1, n) : reshape((colors), n, 1) end # TODO, implement interpolate = true for irregular grics in CairoMakie # Then, we can just use heatmap! and don't need the image plot! - show_cats = Observable(false; ignore_equal_values=true) - show_continuous = Observable(false; ignore_equal_values=true) - on(blockscene, cmap.color_mapping_type; update=true) do type + show_cats = Observable(false; ignore_equal_values = true) + show_continuous = Observable(false; ignore_equal_values = true) + on(blockscene, cmap.color_mapping_type; update = true) do type if type === continuous show_continuous[] = true show_cats[] = false @@ -245,14 +255,16 @@ function initialize_block!(cb::Colorbar) show_cats[] = true end end - heatmap!(blockscene, + heatmap!( + blockscene, xrange, yrange, continuous_pixels; colormap = colormap, colorrange = limits, visible = show_cats, inspectable = false ) - image!(blockscene, + image!( + blockscene, lift(extrema, xrange), lift(extrema, yrange), continuous_pixels; colormap = colormap, colorrange = limits, @@ -265,11 +277,11 @@ function initialize_block!(cb::Colorbar) lb, rb = topline(box) l = lb r = rb - t = ((l .+ r) ./ 2) .+ Point2f(0, sqrt(sum((r .- l) .^ 2)) * sin(pi/3)) + t = ((l .+ r) ./ 2) .+ Point2f(0, sqrt(sum((r .- l) .^ 2)) * sin(pi / 3)) [l, r, t] else b, t = rightline(box) - r = ((b .+ t) ./ 2) .+ Point2f(sqrt(sum((t .- b) .^ 2)) * sin(pi/3), 0) + r = ((b .+ t) ./ 2) .+ Point2f(sqrt(sum((t .- b) .^ 2)) * sin(pi / 3), 0) [t, b, r] end end @@ -278,20 +290,22 @@ function initialize_block!(cb::Colorbar) to_color(hc isa Automatic || isnothing(hc) ? :transparent : hc) end - poly!(blockscene, highclip_tri, color = highclip_tri_color, + poly!( + blockscene, highclip_tri, color = highclip_tri_color, strokecolor = :transparent, - visible = highclip_tri_visible, inspectable = false) + visible = highclip_tri_visible, inspectable = false + ) lowclip_tri = lift(blockscene, barbox, cb.spinewidth) do box, spinewidth if cb.vertical[] lb, rb = bottomline(box) l = lb r = rb - t = ((l .+ r) ./ 2) .- Point2f(0, sqrt(sum((r .- l) .^ 2)) * sin(pi/3)) + t = ((l .+ r) ./ 2) .- Point2f(0, sqrt(sum((r .- l) .^ 2)) * sin(pi / 3)) [l, r, t] else b, t = leftline(box) - l = ((b .+ t) ./ 2) .- Point2f(sqrt(sum((t .- b) .^ 2)) * sin(pi/3), 0) + l = ((b .+ t) ./ 2) .- Point2f(sqrt(sum((t .- b) .^ 2)) * sin(pi / 3), 0) [b, t, l] end end @@ -300,9 +314,11 @@ function initialize_block!(cb::Colorbar) to_color(lc isa Automatic || isnothing(lc) ? :transparent : lc) end - poly!(blockscene, lowclip_tri, color = lowclip_tri_color, + poly!( + blockscene, lowclip_tri, color = lowclip_tri_color, strokecolor = :transparent, - visible = lowclip_tri_visible, inspectable = false) + visible = lowclip_tri_visible, inspectable = false + ) borderpoints = lift(blockscene, barbox, highclip_tri_visible, lowclip_tri_visible) do bb, hcv, lcv if cb.vertical[] @@ -361,13 +377,14 @@ function initialize_block!(cb::Colorbar) return type === Makie.categorical ? (0.5, length(cs) + 0.5) : limits end - axis = LineAxis(blockscene, endpoints = axispoints, flipped = cb.flipaxis, - limits=lims, ticklabelalign=cb.ticklabelalign, label=cb.label, + axis = LineAxis( + blockscene, endpoints = axispoints, flipped = cb.flipaxis, + limits = lims, ticklabelalign = cb.ticklabelalign, label = cb.label, labelpadding = cb.labelpadding, labelvisible = cb.labelvisible, labelsize = cb.labelsize, labelcolor = cb.labelcolor, labelrotation = cb.labelrotation, - labelfont=cb.labelfont, ticklabelfont=cb.ticklabelfont, - dim_convert=nothing, # TODO, we should also have a dim convert for Colorbar - ticks=ticks, tickformat=cb.tickformat, + labelfont = cb.labelfont, ticklabelfont = cb.ticklabelfont, + dim_convert = nothing, # TODO, we should also have a dim convert for Colorbar + ticks = ticks, tickformat = cb.tickformat, ticklabelsize = cb.ticklabelsize, ticklabelsvisible = cb.ticklabelsvisible, ticksize = cb.ticksize, ticksvisible = cb.ticksvisible, ticklabelpad = cb.ticklabelpad, tickalign = cb.tickalign, ticklabelrotation = cb.ticklabelrotation, @@ -376,14 +393,15 @@ function initialize_block!(cb::Colorbar) spinecolor = :transparent, spinevisible = :false, flip_vertical_label = cb.flip_vertical_label, minorticksvisible = cb.minorticksvisible, minortickalign = cb.minortickalign, minorticksize = cb.minorticksize, minortickwidth = cb.minortickwidth, - minortickcolor = cb.minortickcolor, minorticks = cb.minorticks, scale = cmap.scale) + minortickcolor = cb.minortickcolor, minorticks = cb.minorticks, scale = cmap.scale + ) cb.axis = axis onany(blockscene, axis.protrusion, cb.vertical, cb.flipaxis) do axprotrusion, vertical, flipaxis - left, right, top, bottom = 0f0, 0f0, 0f0, 0f0 + left, right, top, bottom = 0.0f0, 0.0f0, 0.0f0, 0.0f0 if vertical if flipaxis @@ -430,7 +448,7 @@ function scaled_steps(steps, scale, lims) # scale with scaling function steps_scaled = scale.(steps) # normalize to lims range - steps_lim_scaled = @. steps_scaled * (scale(lims[2]) - scale(lims[1])) + scale(lims[1]) + steps_lim_scaled = @. steps_scaled * (scale(lims[2]) - scale(lims[1])) + scale(lims[1]) # then rescale to 0 to 1 return @. (steps_lim_scaled - steps_lim_scaled[begin]) / (steps_lim_scaled[end] - steps_lim_scaled[begin]) end diff --git a/src/makielayout/blocks/intervalslider.jl b/src/makielayout/blocks/intervalslider.jl index 01c456ca210..d78aa694360 100644 --- a/src/makielayout/blocks/intervalslider.jl +++ b/src/makielayout/blocks/intervalslider.jl @@ -19,12 +19,16 @@ function initialize_block!(isl::IntervalSlider) if horizontal y = bottom(bb) + h / 2 - [Point2f(left(bb) + h/2, y), - Point2f(right(bb) - h/2, y)] + [ + Point2f(left(bb) + h / 2, y), + Point2f(right(bb) - h / 2, y), + ] else x = left(bb) + w / 2 - [Point2f(x, bottom(bb) + w/2), - Point2f(x, top(bb) - w/2)] + [ + Point2f(x, bottom(bb) + w / 2), + Point2f(x, top(bb) - w / 2), + ] end end @@ -87,11 +91,15 @@ function initialize_block!(isl::IntervalSlider) [ci, ci] end - endbuttons = scatter!(blockscene, endpoints, color = endbuttoncolors, - markersize = isl.linewidth, strokewidth = 0, inspectable = false, marker = Circle) + endbuttons = scatter!( + blockscene, endpoints, color = endbuttoncolors, + markersize = isl.linewidth, strokewidth = 0, inspectable = false, marker = Circle + ) - linesegs = linesegments!(blockscene, linepoints, color = linecolors, - linewidth = isl.linewidth, inspectable = false) + linesegs = linesegments!( + blockscene, linepoints, color = linecolors, + linewidth = isl.linewidth, inspectable = false + ) state = Observable(:none) button_magnifications = lift(state) do state @@ -106,8 +114,10 @@ function initialize_block!(isl::IntervalSlider) end end buttonsizes = @lift($(isl.linewidth) .* $button_magnifications) - buttons = scatter!(blockscene, middlepoints, color = isl.color_active, strokewidth = 0, - markersize = buttonsizes, inspectable = false, marker = Circle) + buttons = scatter!( + blockscene, middlepoints, color = isl.color_active, strokewidth = 0, + markersize = buttonsizes, inspectable = false, marker = Circle + ) mouseevents = addmouseevents!(blockscene, isl.layoutobservables.computedbbox) @@ -268,5 +278,5 @@ function set_close_to!(intervalslider::IntervalSlider, v1, v2) mima = minmax(v1, v2) indices = closest_index.(Ref(intervalslider.range[]), mima) intervalslider.selected_indices[] = indices - getindex.(Ref(intervalslider.range[]), indices) + return getindex.(Ref(intervalslider.range[]), indices) end diff --git a/src/makielayout/blocks/label.jl b/src/makielayout/blocks/label.jl index da5853b998f..558167e24c8 100644 --- a/src/makielayout/blocks/label.jl +++ b/src/makielayout/blocks/label.jl @@ -6,18 +6,21 @@ function initialize_block!(l::Label) layoutobservables = l.layoutobservables textpos = Observable(Point3f(0, 0, 0)) - word_wrap_width = Observable(-1f0) + word_wrap_width = Observable(-1.0f0) t = text!( topscene, textpos, text = l.text, fontsize = l.fontsize, font = l.font, color = l.color, visible = l.visible, align = (:center, :center), rotation = l.rotation, markerspace = :data, justification = l.justification, lineheight = l.lineheight, word_wrap_width = word_wrap_width, - inspectable = false) + inspectable = false + ) textbb = Ref(BBox(0, 1, 0, 1)) - onany(topscene, l.text, l.fontsize, l.font, l.rotation, word_wrap_width, - l.padding) do _, _, _, _, _, pad + onany( + topscene, l.text, l.fontsize, l.font, l.rotation, word_wrap_width, + l.padding + ) do _, _, _, _, _, pad padding = to_lrbt_padding(pad) textbb[] = Rect2f(boundingbox(t, :data)) autowidth = width(textbb[]) + padding[1] + padding[2] @@ -60,5 +63,5 @@ function initialize_block!(l::Label) # trigger bbox layoutobservables.suggestedbbox[] = layoutobservables.suggestedbbox[] - l + return l end diff --git a/src/makielayout/blocks/legend.jl b/src/makielayout/blocks/legend.jl index 90a3168dc39..48531ee3f26 100644 --- a/src/makielayout/blocks/legend.jl +++ b/src/makielayout/blocks/legend.jl @@ -1,5 +1,5 @@ function initialize_block!(leg::Legend; entrygroups) - entry_groups = convert(Observable{Vector{Tuple{Any,Vector{LegendEntry}}}}, entrygroups) + entry_groups = convert(Observable{Vector{Tuple{Any, Vector{LegendEntry}}}}, entrygroups) blockscene = leg.blockscene # by default, `tellwidth = true` and `tellheight = false` for vertical legends @@ -25,10 +25,12 @@ function initialize_block!(leg::Legend; entrygroups) leg.backgroundcolor end - bg = poly!(scene, + bg = poly!( + scene, legendrect, color = backgroundcolor, strokewidth = leg.framewidth, visible = leg.framevisible, - strokecolor = leg.framecolor, inspectable = false) + strokecolor = leg.framecolor, inspectable = false + ) translate!(bg, 0, 0, -7) # bg behind patches but before content at 0 (legend is at +10) # the grid containing all content @@ -89,7 +91,7 @@ function initialize_block!(leg::Legend; entrygroups) end elseif leg.orientation[] === :horizontal if leg.titleposition[] === :left - isnothing(title) || (grid[1, 2g-1] = title) + isnothing(title) || (grid[1, 2g - 1] = title) grid[1, 2g] = GridLayout(halign = leg.gridshalign[], valign = leg.gridsvalign[]) elseif leg.titleposition[] === :top isnothing(title) || (grid[1, g] = title) @@ -99,17 +101,17 @@ function initialize_block!(leg::Legend; entrygroups) for (n, (et, er)) in enumerate(zip(etexts, erects)) i, j = leg.orientation[] === :vertical ? rowcol(n) : reverse(rowcol(n)) - subgl[i, 2j-1] = er + subgl[i, 2j - 1] = er subgl[i, 2j] = et end rowgap!(subgl, leg.rowgap[]) - for c in 1:ncols(subgl)-1 + for c in 1:(ncols(subgl) - 1) colgap!(subgl, c, c % 2 == 1 ? leg.patchlabelgap[] : leg.colgap[]) end end - for r in 1:nrows(grid)-1 + for r in 1:(nrows(grid) - 1) if leg.orientation[] === :horizontal if leg.titleposition[] === :left # nothing @@ -124,7 +126,7 @@ function initialize_block!(leg::Legend; entrygroups) end end end - for c in 1:ncols(grid)-1 + for c in 1:(ncols(grid) - 1) if leg.orientation[] === :horizontal if leg.titleposition[] === :left colgap!(grid, c, c % 2 == 1 ? leg.titlegap[] : leg.groupgap[]) @@ -155,9 +157,11 @@ function initialize_block!(leg::Legend; entrygroups) return end - onany(blockscene, leg.nbanks, leg.titleposition, leg.rowgap, leg.colgap, leg.patchlabelgap, leg.groupgap, - leg.titlegap, - leg.titlevisible, leg.orientation, leg.gridshalign, leg.gridsvalign) do args... + onany( + blockscene, leg.nbanks, leg.titleposition, leg.rowgap, leg.colgap, leg.patchlabelgap, leg.groupgap, + leg.titlegap, + leg.titlevisible, leg.orientation, leg.gridshalign, leg.gridsvalign + ) do args... relayout() return end @@ -196,8 +200,12 @@ function initialize_block!(leg::Legend; entrygroups) # in case a group has no title push!(titletexts, nothing) else - push!(titletexts, Label(scene, text = title, font = leg.titlefont, color = leg.titlecolor, - fontsize = leg.titlesize, halign = leg.titlehalign, valign = leg.titlevalign)) + push!( + titletexts, Label( + scene, text = title, font = leg.titlefont, color = leg.titlecolor, + fontsize = leg.titlesize, halign = leg.titlehalign, valign = leg.titlevalign + ) + ) end etexts = [] @@ -213,21 +221,29 @@ function initialize_block!(leg::Legend; entrygroups) justification = map(leg.labeljustification, e.labelhalign) do lj, lha return lj isa Automatic ? lha : lj end - push!(etexts, - Label(scene; text=e.label, fontsize=e.labelsize, font=e.labelfont, justification=justification, - color=e.labelcolor, halign=e.labelhalign, valign=e.labelvalign)) + push!( + etexts, + Label( + scene; text = e.label, fontsize = e.labelsize, font = e.labelfont, justification = justification, + color = e.labelcolor, halign = e.labelhalign, valign = e.labelvalign + ) + ) # create the patch rectangle - rect = Box(scene; color=e.patchcolor, strokecolor=e.patchstrokecolor, strokewidth=e.patchstrokewidth, - width=lift(x -> x[1], blockscene, e.patchsize), height=lift(x -> x[2], blockscene, e.patchsize)) + rect = Box( + scene; color = e.patchcolor, strokecolor = e.patchstrokecolor, strokewidth = e.patchstrokewidth, + width = lift(x -> x[1], blockscene, e.patchsize), height = lift(x -> x[2], blockscene, e.patchsize) + ) push!(erects, rect) translate!(rect.blockscene, 0, 0, -5) # patches before background but behind legend elements (legend is at +10) # plot the symbols belonging to this entry symbolplots = AbstractPlot[] for element in e.elements - append!(symbolplots, - legendelement_plots!(scene, element, rect.layoutobservables.computedbbox, e.attributes)) + append!( + symbolplots, + legendelement_plots!(scene, element, rect.layoutobservables.computedbbox, e.attributes) + ) end push!(eplots, symbolplots) @@ -272,13 +288,13 @@ function connect_block_layoutobservables!(leg::Legend, layout_width, layout_heig end - function legendelement_plots!(scene, element::MarkerElement, bbox::Observable{Rect2f}, defaultattrs::Attributes) merge!(element.attributes, defaultattrs) attrs = element.attributes fracpoints = attrs.markerpoints points = lift((bb, fp) -> fractionpoint.(Ref(bb), fp), scene, bbox, fracpoints) - scat = scatter!(scene, points, color = attrs.markercolor, marker = attrs.marker, + scat = scatter!( + scene, points, color = attrs.markercolor, marker = attrs.marker, markersize = attrs.markersize, strokewidth = attrs.markerstrokewidth, strokecolor = attrs.markerstrokecolor, inspectable = false, @@ -295,9 +311,11 @@ function legendelement_plots!(scene, element::LineElement, bbox::Observable{Rect fracpoints = attrs.linepoints points = lift((bb, fp) -> fractionpoint.(Ref(bb), fp), scene, bbox, fracpoints) - lin = lines!(scene, points, linewidth = attrs.linewidth, color = attrs.linecolor, + lin = lines!( + scene, points, linewidth = attrs.linewidth, color = attrs.linecolor, colormap = attrs.linecolormap, colorrange = attrs.linecolorrange, - linestyle = attrs.linestyle, inspectable = false) + linestyle = attrs.linestyle, inspectable = false + ) return [lin] end @@ -307,16 +325,18 @@ function legendelement_plots!(scene, element::PolyElement, bbox::Observable{Rect attrs = element.attributes fracpoints = attrs.polypoints points = lift((bb, fp) -> fractionpoint.(Ref(bb), fp), scene, bbox, fracpoints) - pol = poly!(scene, points, strokewidth = attrs.polystrokewidth, color = attrs.polycolor, + pol = poly!( + scene, points, strokewidth = attrs.polystrokewidth, color = attrs.polycolor, strokecolor = attrs.polystrokecolor, inspectable = false, colormap = attrs.polycolormap, colorrange = attrs.polycolorrange, - linestyle = attrs.linestyle) + linestyle = attrs.linestyle + ) return [pol] end function Base.getproperty(lentry::LegendEntry, s::Symbol) - if s in fieldnames(LegendEntry) + return if s in fieldnames(LegendEntry) getfield(lentry, s) else lentry.attributes[s] @@ -324,7 +344,7 @@ function Base.getproperty(lentry::LegendEntry, s::Symbol) end function Base.setproperty!(lentry::LegendEntry, s::Symbol, value) - if s in fieldnames(LegendEntry) + return if s in fieldnames(LegendEntry) setfield!(lentry, s, value) else lentry.attributes[s][] = value @@ -355,6 +375,7 @@ function apply_legend_override!(le::MarkerElement, override::LegendOverride) le.attributes[sym] = renamed_attrs[sym] end end + return end function apply_legend_override!(le::LineElement, override::LegendOverride) @@ -364,6 +385,7 @@ function apply_legend_override!(le::LineElement, override::LegendOverride) le.attributes[sym] = renamed_attrs[sym] end end + return end function apply_legend_override!(le::PolyElement, override::LegendOverride) @@ -373,6 +395,7 @@ function apply_legend_override!(le::PolyElement, override::LegendOverride) le.attributes[sym] = renamed_attrs[sym] end end + return end function LegendEntry(label, contentelement, override::Attributes, legend; kwargs...) @@ -385,7 +408,7 @@ function LegendEntry(label, contentelement, override::Attributes, legend; kwargs if isempty(elems) error("`legendelements` returned an empty list for content element of type $(typeof(contentelement)). That could mean that neither this object nor any possible child objects had a method for `legendelements` defined that returned a non-empty result.") end - LegendEntry(elems, attrs) + return LegendEntry(elems, attrs) end @@ -406,25 +429,25 @@ function LegendEntry(label, content, legend; kwargs...) else elems = legendelements(content, legend) end - LegendEntry(elems, attrs) + return LegendEntry(elems, attrs) end -function LineElement(;kwargs...) - _legendelement(LineElement, Attributes(kwargs)) +function LineElement(; kwargs...) + return _legendelement(LineElement, Attributes(kwargs)) end -function MarkerElement(;kwargs...) - _legendelement(MarkerElement, Attributes(kwargs)) +function MarkerElement(; kwargs...) + return _legendelement(MarkerElement, Attributes(kwargs)) end -function PolyElement(;kwargs...) - _legendelement(PolyElement, Attributes(kwargs)) +function PolyElement(; kwargs...) + return _legendelement(PolyElement, Attributes(kwargs)) end function _legendelement(T::Type{<:LegendElement}, a::Attributes) _rename_attributes!(T, a) - T(a) + return T(a) end _renaming_mapping(::Type{LineElement}) = Dict( @@ -461,7 +484,7 @@ function _rename_attributes!(T, a) a[newkey] = pop!(a, key) end end - a + return a end choose_scalar(attr, default) = is_scalar_attribute(to_value(attr)) ? attr : default @@ -473,98 +496,108 @@ function extract_color(@nospecialize(plot), color_default) end function legendelements(plot::Union{Lines, LineSegments}, legend) - LegendElement[LineElement( - color = extract_color(plot, legend[:linecolor]), - linestyle = choose_scalar(plot.linestyle, legend[:linestyle]), - linewidth = choose_scalar(plot.linewidth, legend[:linewidth]), - colormap = plot.colormap, - colorrange = plot.colorrange, - )] + return LegendElement[ + LineElement( + color = extract_color(plot, legend[:linecolor]), + linestyle = choose_scalar(plot.linestyle, legend[:linestyle]), + linewidth = choose_scalar(plot.linewidth, legend[:linewidth]), + colormap = plot.colormap, + colorrange = plot.colorrange, + ), + ] end function legendelements(plot::Scatter, legend) - LegendElement[MarkerElement( - color = extract_color(plot, legend[:markercolor]), - marker = choose_scalar(plot.marker, legend[:marker]), - markersize = choose_scalar(plot.markersize, legend[:markersize]), - strokewidth = choose_scalar(plot.strokewidth, legend[:markerstrokewidth]), - strokecolor = choose_scalar(plot.strokecolor, legend[:markerstrokecolor]), - colormap = plot.colormap, - colorrange = plot.colorrange, - )] + return LegendElement[ + MarkerElement( + color = extract_color(plot, legend[:markercolor]), + marker = choose_scalar(plot.marker, legend[:marker]), + markersize = choose_scalar(plot.markersize, legend[:markersize]), + strokewidth = choose_scalar(plot.strokewidth, legend[:markerstrokewidth]), + strokecolor = choose_scalar(plot.strokecolor, legend[:markerstrokecolor]), + colormap = plot.colormap, + colorrange = plot.colorrange, + ), + ] end function legendelements(plot::Union{Violin, BoxPlot, CrossBar}, legend) color = extract_color(plot, legend[:polycolor]) - LegendElement[PolyElement( - color = color, - strokecolor = choose_scalar(plot.strokecolor, legend[:polystrokecolor]), - strokewidth = choose_scalar(plot.strokewidth, legend[:polystrokewidth]), - colormap = plot.colormap, - colorrange = plot.colorrange, - )] + return LegendElement[ + PolyElement( + color = color, + strokecolor = choose_scalar(plot.strokecolor, legend[:polystrokecolor]), + strokewidth = choose_scalar(plot.strokewidth, legend[:polystrokewidth]), + colormap = plot.colormap, + colorrange = plot.colorrange, + ), + ] end function legendelements(plot::Band, legend) # there seems to be no stroke for Band, so we set it invisible - return LegendElement[PolyElement(; - polycolor = choose_scalar( - plot.color, - legend[:polystrokecolor] + return LegendElement[ + PolyElement(; + polycolor = choose_scalar( + plot.color, + legend[:polystrokecolor] + ), + polystrokecolor = :transparent, + polystrokewidth = 0, + polycolormap = plot.colormap, + polycolorrange = plot.colorrange, ), - polystrokecolor = :transparent, - polystrokewidth = 0, - polycolormap = plot.colormap, - polycolorrange = plot.colorrange, - )] + ] end function legendelements(plot::Union{Poly, Density}, legend) color = Makie.extract_color(plot, legend[:polycolor]) - LegendElement[Makie.PolyElement( - color = color, - strokecolor = Makie.choose_scalar(plot.strokecolor, legend[:polystrokecolor]), - strokewidth = Makie.choose_scalar(plot.strokewidth, legend[:polystrokewidth]), - colormap = plot.colormap, - colorrange = plot.colorrange, - linestyle = plot.linestyle, - )] + return LegendElement[ + Makie.PolyElement( + color = color, + strokecolor = Makie.choose_scalar(plot.strokecolor, legend[:polystrokecolor]), + strokewidth = Makie.choose_scalar(plot.strokewidth, legend[:polystrokewidth]), + colormap = plot.colormap, + colorrange = plot.colorrange, + linestyle = plot.linestyle, + ), + ] end # if there is no specific overload available, we go through the child plots and just stack # those together as a simple fallback function legendelements(plot, legend)::Vector{LegendElement} - reduce(vcat, [legendelements(childplot, legend) for childplot in plot.plots], init = []) + return reduce(vcat, [legendelements(childplot, legend) for childplot in plot.plots], init = []) end # Text has no meaningful legend, but it contains a linesegments for latex applications # which can surface as a line in the final legend function legendelements(plot::Text, legend)::Vector{LegendElement} - [] + return [] end -function Base.getproperty(legendelement::T, s::Symbol) where T <: LegendElement - if s in fieldnames(T) +function Base.getproperty(legendelement::T, s::Symbol) where {T <: LegendElement} + return if s in fieldnames(T) getfield(legendelement, s) else legendelement.attributes[s] end end -function Base.setproperty!(legendelement::T, s::Symbol, value) where T <: LegendElement - if s in fieldnames(T) +function Base.setproperty!(legendelement::T, s::Symbol, value) where {T <: LegendElement} + return if s in fieldnames(T) setfield!(legendelement, s, value) else legendelement.attributes[s][] = value end end -function Base.propertynames(legendelement::T) where T <: LegendElement - [fieldnames(T)..., keys(legendelement.attributes)...] +function Base.propertynames(legendelement::T) where {T <: LegendElement} + return [fieldnames(T)..., keys(legendelement.attributes)...] end -function to_entry_group(legend_defaults, contents::AbstractVector, labels::AbstractVector, title=nothing) +function to_entry_group(legend_defaults, contents::AbstractVector, labels::AbstractVector, title = nothing) if length(contents) != length(labels) error("Number of elements not equal: $(length(contents)) content elements and $(length(labels)) labels.") end @@ -574,12 +607,15 @@ end function to_entry_group( legend_defaults, contentgroups::AbstractVector{<:AbstractVector}, - labelgroups::AbstractVector{<:AbstractVector}, titles::AbstractVector) + labelgroups::AbstractVector{<:AbstractVector}, titles::AbstractVector + ) if !(length(titles) == length(contentgroups) == length(labelgroups)) error("Number of elements not equal: $(length(titles)) titles, $(length(contentgroups)) content groups and $(length(labelgroups)) label groups.") end - entries = [[LegendEntry(l, pg, legend_defaults) for (l, pg) in zip(labelgroup, contentgroup)] - for (labelgroup, contentgroup) in zip(labelgroups, contentgroups)] + entries = [ + [LegendEntry(l, pg, legend_defaults) for (l, pg) in zip(labelgroup, contentgroup)] + for (labelgroup, contentgroup) in zip(labelgroups, contentgroups) + ] return [(t, en) for (t, en) in zip(titles, entries)] end @@ -596,11 +632,13 @@ one content element. A content element can be an `AbstractPlot`, an array of `AbstractPlots`, a `LegendElement`, or any other object for which the `legendelements` method is defined. """ -function Legend(fig_or_scene, +function Legend( + fig_or_scene, contents::AbstractVector, labels::AbstractVector, title = nothing; - bbox=nothing, kwargs...) + bbox = nothing, kwargs... + ) scene = get_topscene(fig_or_scene) legend_defaults = block_defaults(:Legend, Dict{Symbol, Any}(kwargs), scene) @@ -608,11 +646,10 @@ function Legend(fig_or_scene, entrygroups = Observable(entry_groups) legend_defaults[:entrygroups] = entrygroups # Use low-level constructor to not calculate legend_defaults a second time - return _block(Legend, fig_or_scene, (), legend_defaults, bbox; kwdict_complete=true) + return _block(Legend, fig_or_scene, (), legend_defaults, bbox; kwdict_complete = true) end - """ Legend( fig_or_scene, @@ -629,18 +666,20 @@ Within each group, each content element is associated with one label. A content element can be an `AbstractPlot`, an array of `AbstractPlots`, a `LegendElement`, or any other object for which the `legendelements` method is defined. """ -function Legend(fig_or_scene, +function Legend( + fig_or_scene, contentgroups::AbstractVector{<:AbstractVector}, labelgroups::AbstractVector{<:AbstractVector}, titles::AbstractVector; - bbox=nothing, kwargs...) + bbox = nothing, kwargs... + ) scene = get_scene(fig_or_scene) - legend_defaults = block_defaults(:Legend, Dict{Symbol,Any}(kwargs), scene) + legend_defaults = block_defaults(:Legend, Dict{Symbol, Any}(kwargs), scene) entry_groups = to_entry_group(legend_defaults, contentgroups, labelgroups, titles) entrygroups = Observable(entry_groups) legend_defaults[:entrygroups] = entrygroups - return _block(Legend, fig_or_scene, (), legend_defaults, bbox; kwdict_complete=true) + return _block(Legend, fig_or_scene, (), legend_defaults, bbox; kwdict_complete = true) end @@ -656,13 +695,13 @@ If `unique` is `true`, all plot objects with the same plot type and label will b function Legend(fig_or_scene, axis::Union{Axis, Axis3, Scene, LScene}, title = nothing; merge = false, unique = false, kwargs...) plots, labels = get_labeled_plots(axis, merge = merge, unique = unique) isempty(plots) && error("There are no plots with labels in the given axis that can be put in the legend. Supply labels to plotting functions like `plot(args...; label = \"My label\")`") - Legend(fig_or_scene, plots, labels, title; kwargs...) + return Legend(fig_or_scene, plots, labels, title; kwargs...) end function get_labeled_plots(ax; merge::Bool, unique::Bool) lplots = filter(get_plots(ax)) do plot haskey(plot.attributes, :label) || - plot isa PlotList && any(x -> haskey(x.attributes, :label), plot.plots) + plot isa PlotList && any(x -> haskey(x.attributes, :label), plot.plots) end labels = map(lplots) do l l.label[] @@ -695,8 +734,10 @@ function get_labeled_plots(ax; merge::Bool, unique::Bool) if merge ulabels = Base.unique(labels) - mergedplots = [[lp for (i, lp) in enumerate(lplots) if labels[i] == ul] - for ul in ulabels] + mergedplots = [ + [lp for (i, lp) in enumerate(lplots) if labels[i] == ul] + for ul in ulabels + ] lplots, labels = mergedplots, ulabels end @@ -710,11 +751,11 @@ function get_labeled_plots(ax; merge::Bool, unique::Bool) end labels = [label isa Pair ? label[1] : label for label in labels] - lplots_with_overrides, labels + return lplots_with_overrides, labels end get_plots(p::AbstractPlot) = [p] -# NOTE: this is important, since we know that `get_plots` is only ever called on the toplevel, +# NOTE: this is important, since we know that `get_plots` is only ever called on the toplevel, # we can assume that any plotlist on the toplevel should be decomposed into individual plots. # However, if the user passes a label argument with a legend override, what do we do? get_plots(p::PlotList) = haskey(p.attributes, :label) && p.attributes[:label] isa Pair ? [p] : p.plots @@ -756,11 +797,13 @@ is true, all plot objects with the same plot type and label will be reduced to one occurrence. """ function axislegend(ax, args...; position = :rt, kwargs...) - Legend(ax.parent, args...; + return Legend( + ax.parent, args...; bbox = ax.scene.viewport, margin = (6, 6, 6, 6), legend_position_to_aligns(position)..., - kwargs...) + kwargs... + ) end function legend_position_to_aligns(s::Symbol) @@ -781,154 +824,154 @@ function legend_position_to_aligns(s::Symbol) ) haskey(valigns, p[2]) || throw(ArgumentError("Second letter can be b, t or c, not $(p[2]).")) - (halign = haligns[p[1]], valign = valigns[p[2]]) + return (halign = haligns[p[1]], valign = valigns[p[2]]) end function legend_position_to_aligns(t::Tuple{Any, Any}) - (halign = t[1], valign = t[2]) + return (halign = t[1], valign = t[2]) end function attribute_examples(::Type{Legend}) - Dict( + return Dict( :colgap => [ Example( code = """ - fig = Figure() - ax = Axis(fig[1, 1]) - lines!(ax, 1:10, linestyle = :dash, label = "Line") - poly!(ax, [(5, 0), (10, 0), (7.5, 5)], label = "Poly") - scatter!(ax, 4:13, label = "Scatter") - Legend(fig[1, 2], ax, "Default", nbanks = 2) - Legend(fig[1, 3], ax, "colgap = 40", nbanks = 2, colgap = 40) - fig - """ - ) + fig = Figure() + ax = Axis(fig[1, 1]) + lines!(ax, 1:10, linestyle = :dash, label = "Line") + poly!(ax, [(5, 0), (10, 0), (7.5, 5)], label = "Poly") + scatter!(ax, 4:13, label = "Scatter") + Legend(fig[1, 2], ax, "Default", nbanks = 2) + Legend(fig[1, 3], ax, "colgap = 40", nbanks = 2, colgap = 40) + fig + """ + ), ], :groupgap => [ Example( code = """ - fig = Figure() - ax = Axis(fig[1, 1]) - lin = lines!(ax, 1:10, linestyle = :dash) - pol = poly!(ax, [(5, 0), (10, 0), (7.5, 5)]) - sca = scatter!(ax, 4:13) - Legend(fig[1, 2], - [[lin], [pol], [sca]], - [["Line"], ["Poly"], ["Scatter"]], - ["Default", "Group 2", "Group 3"]; - - ) - Legend(fig[1, 3], - [[lin], [pol], [sca]], - [["Line"], ["Poly"], ["Scatter"]], - ["groupgap = 30", "Group 2", "Group 3"]; - groupgap = 30, - ) - fig - """ - ) + fig = Figure() + ax = Axis(fig[1, 1]) + lin = lines!(ax, 1:10, linestyle = :dash) + pol = poly!(ax, [(5, 0), (10, 0), (7.5, 5)]) + sca = scatter!(ax, 4:13) + Legend(fig[1, 2], + [[lin], [pol], [sca]], + [["Line"], ["Poly"], ["Scatter"]], + ["Default", "Group 2", "Group 3"]; + + ) + Legend(fig[1, 3], + [[lin], [pol], [sca]], + [["Line"], ["Poly"], ["Scatter"]], + ["groupgap = 30", "Group 2", "Group 3"]; + groupgap = 30, + ) + fig + """ + ), ], :patchsize => [ Example( code = """ - fig = Figure() - ax = Axis(fig[1, 1]) - lines!(ax, 1:10, linestyle = :dash, label = "Line") - poly!(ax, [(5, 0), (10, 0), (7.5, 5)], label = "Poly") - scatter!(ax, 4:13, label = "Scatter") - Legend(fig[1, 2], ax, "Default") - Legend(fig[1, 3], ax, "(40, 20)", patchsize = (40, 20)) - fig - """ - ) + fig = Figure() + ax = Axis(fig[1, 1]) + lines!(ax, 1:10, linestyle = :dash, label = "Line") + poly!(ax, [(5, 0), (10, 0), (7.5, 5)], label = "Poly") + scatter!(ax, 4:13, label = "Scatter") + Legend(fig[1, 2], ax, "Default") + Legend(fig[1, 3], ax, "(40, 20)", patchsize = (40, 20)) + fig + """ + ), ], :patchlabelgap => [ Example( code = """ - fig = Figure() - ax = Axis(fig[1, 1]) - lines!(ax, 1:10, linestyle = :dash, label = "Line") - poly!(ax, [(5, 0), (10, 0), (7.5, 5)], label = "Poly") - scatter!(ax, 4:13, label = "Scatter") - Legend(fig[1, 2], ax, "Default") - Legend(fig[1, 3], ax, "patchlabelgap\n= 20", patchlabelgap = 20) - fig - """ - ) + fig = Figure() + ax = Axis(fig[1, 1]) + lines!(ax, 1:10, linestyle = :dash, label = "Line") + poly!(ax, [(5, 0), (10, 0), (7.5, 5)], label = "Poly") + scatter!(ax, 4:13, label = "Scatter") + Legend(fig[1, 2], ax, "Default") + Legend(fig[1, 3], ax, "patchlabelgap\n= 20", patchlabelgap = 20) + fig + """ + ), ], :orientation => [ Example( code = """ - fig = Figure() - ax = Axis(fig[1, 1]) - lines!(ax, 1:10, linestyle = :dash, label = "Line") - poly!(ax, [(5, 0), (10, 0), (7.5, 5)], label = "Poly") - scatter!(ax, 4:13, label = "Scatter") - Legend(fig[2, 1], ax, "orientation\n= :horizontal", orientation = :horizontal) - Legend(fig[1, 2], ax, "orientation\n= :vertical", orientation = :vertical) - fig - """ - ) + fig = Figure() + ax = Axis(fig[1, 1]) + lines!(ax, 1:10, linestyle = :dash, label = "Line") + poly!(ax, [(5, 0), (10, 0), (7.5, 5)], label = "Poly") + scatter!(ax, 4:13, label = "Scatter") + Legend(fig[2, 1], ax, "orientation\n= :horizontal", orientation = :horizontal) + Legend(fig[1, 2], ax, "orientation\n= :vertical", orientation = :vertical) + fig + """ + ), ], :nbanks => [ Example( code = """ - fig = Figure() - ax = Axis(fig[1, 1]) - lines!(ax, 1:10, linestyle = :dash, label = "Line") - poly!(ax, [(5, 0), (10, 0), (7.5, 5)], label = "Poly") - scatter!(ax, 4:13, label = "Scatter") - grid = GridLayout(fig[1, 2], tellheight = false) - Legend(grid[1, 1], ax, "nbanks = 1", nbanks = 1, tellheight = true) - Legend(grid[1, 2], ax, "nbanks = 2", nbanks = 2, tellheight = true) - Legend(grid[2, :], ax, "nbanks = 3", nbanks = 3, tellheight = true) - fig - """ + fig = Figure() + ax = Axis(fig[1, 1]) + lines!(ax, 1:10, linestyle = :dash, label = "Line") + poly!(ax, [(5, 0), (10, 0), (7.5, 5)], label = "Poly") + scatter!(ax, 4:13, label = "Scatter") + grid = GridLayout(fig[1, 2], tellheight = false) + Legend(grid[1, 1], ax, "nbanks = 1", nbanks = 1, tellheight = true) + Legend(grid[1, 2], ax, "nbanks = 2", nbanks = 2, tellheight = true) + Legend(grid[2, :], ax, "nbanks = 3", nbanks = 3, tellheight = true) + fig + """ ), Example( code = """ - fig = Figure() - ax = Axis(fig[1, 1]) - lines!(ax, 1:10, linestyle = :dash, label = "Line") - poly!(ax, [(5, 0), (10, 0), (7.5, 5)], label = "Poly") - scatter!(ax, 4:13, label = "Scatter") - grid = GridLayout(fig[2, 1], tellwidth = false) - Legend(grid[1, 1], ax, "nbanks = 1", nbanks = 1, - orientation = :horizontal, tellwidth = true) - Legend(grid[2, 1], ax, "nbanks = 2", nbanks = 2, - orientation = :horizontal, tellwidth = true) - Legend(grid[:, 2], ax, "nbanks = 3", nbanks = 3, - orientation = :horizontal, tellwidth = true) - fig - """ + fig = Figure() + ax = Axis(fig[1, 1]) + lines!(ax, 1:10, linestyle = :dash, label = "Line") + poly!(ax, [(5, 0), (10, 0), (7.5, 5)], label = "Poly") + scatter!(ax, 4:13, label = "Scatter") + grid = GridLayout(fig[2, 1], tellwidth = false) + Legend(grid[1, 1], ax, "nbanks = 1", nbanks = 1, + orientation = :horizontal, tellwidth = true) + Legend(grid[2, 1], ax, "nbanks = 2", nbanks = 2, + orientation = :horizontal, tellwidth = true) + Legend(grid[:, 2], ax, "nbanks = 3", nbanks = 3, + orientation = :horizontal, tellwidth = true) + fig + """ ), ], :titleposition => [ Example( code = """ - fig = Figure() - ax = Axis(fig[1, 1]) - lines!(ax, 1:10, linestyle = :dash, label = "Line") - poly!(ax, [(5, 0), (10, 0), (7.5, 5)], label = "Poly") - scatter!(ax, 4:13, label = "Scatter") - Legend(fig[1, 2], ax, "titleposition\n= :top", titleposition = :top) - Legend(fig[1, 3], ax, "titleposition\n= :left", titleposition = :left) - fig - """ + fig = Figure() + ax = Axis(fig[1, 1]) + lines!(ax, 1:10, linestyle = :dash, label = "Line") + poly!(ax, [(5, 0), (10, 0), (7.5, 5)], label = "Poly") + scatter!(ax, 4:13, label = "Scatter") + Legend(fig[1, 2], ax, "titleposition\n= :top", titleposition = :top) + Legend(fig[1, 3], ax, "titleposition\n= :left", titleposition = :left) + fig + """ ), ], :rowgap => [ Example( code = """ - fig = Figure() - ax = Axis(fig[1, 1]) - lines!(ax, 1:10, linestyle = :dash, label = "Line") - poly!(ax, [(5, 0), (10, 0), (7.5, 5)], label = "Poly") - scatter!(ax, 4:13, label = "Scatter") - Legend(fig[1, 2], ax, "Default") - Legend(fig[1, 3], ax, "rowgap = 10", rowgap = 10) - fig - """ + fig = Figure() + ax = Axis(fig[1, 1]) + lines!(ax, 1:10, linestyle = :dash, label = "Line") + poly!(ax, [(5, 0), (10, 0), (7.5, 5)], label = "Poly") + scatter!(ax, 4:13, label = "Scatter") + Legend(fig[1, 2], ax, "Default") + Legend(fig[1, 3], ax, "rowgap = 10", rowgap = 10) + fig + """ ), ], ) diff --git a/src/makielayout/blocks/menu.jl b/src/makielayout/blocks/menu.jl index 7d747f63b4b..7d391ae201c 100644 --- a/src/makielayout/blocks/menu.jl +++ b/src/makielayout/blocks/menu.jl @@ -1,11 +1,11 @@ function initialize_block!(m::Menu; default = 1) blockscene = m.blockscene - listheight = Observable(0.0; ignore_equal_values=true) + listheight = Observable(0.0; ignore_equal_values = true) # the direction is auto-chosen as up if there is too little space below and if the space below # is smaller than above - _direction = Observable{Symbol}(:none; ignore_equal_values=true) + _direction = Observable{Symbol}(:none; ignore_equal_values = true) map!(blockscene, _direction, m.layoutobservables.computedbbox, m.direction) do bb, dir if dir == Makie.automatic @@ -23,18 +23,23 @@ function initialize_block!(m::Menu; default = 1) end end - scenearea = lift(blockscene, m.layoutobservables.computedbbox, listheight, _direction, m.is_open; - ignore_equal_values=true) do bbox, h, d, open + scenearea = lift( + blockscene, m.layoutobservables.computedbbox, listheight, _direction, m.is_open; + ignore_equal_values = true + ) do bbox, h, d, open !open ? round_to_IRect2D(BBox(left(bbox), right(bbox), 0, 0)) : - round_to_IRect2D(BBox( - left(bbox), - right(bbox), - d === :down ? max(0, bottom(bbox) - h) : top(bbox), - d === :down ? bottom(bbox) : min(top(bbox) + h, top(blockscene.viewport[])))) + round_to_IRect2D( + BBox( + left(bbox), + right(bbox), + d === :down ? max(0, bottom(bbox) - h) : top(bbox), + d === :down ? bottom(bbox) : min(top(bbox) + h, top(blockscene.viewport[])) + ) + ) end - menuscene = Scene(blockscene, scenearea, camera = campixel!, clear=true) + menuscene = Scene(blockscene, scenearea, camera = campixel!, clear = true) translate!(menuscene, 0, 0, 200) onany(blockscene, scenearea, listheight) do area, listheight @@ -44,9 +49,9 @@ function initialize_block!(m::Menu; default = 1) translate!(menuscene, t[1], new_y, t[3]) end - optionstrings = lift(o -> optionlabel.(o), blockscene, m.options; ignore_equal_values=true) + optionstrings = lift(o -> optionlabel.(o), blockscene, m.options; ignore_equal_values = true) - selected_text = lift(blockscene, m.prompt, m.i_selected; ignore_equal_values=true) do prompt, i_selected + selected_text = lift(blockscene, m.prompt, m.i_selected; ignore_equal_values = true) do prompt, i_selected if i_selected == 0 prompt else @@ -54,14 +59,14 @@ function initialize_block!(m::Menu; default = 1) end end - selectionarea = Observable(Rect2d(0, 0, 0, 0); ignore_equal_values=true) + selectionarea = Observable(Rect2d(0, 0, 0, 0); ignore_equal_values = true) selectionpoly = poly!( blockscene, selectionarea, color = m.selection_cell_color_inactive[]; inspectable = false ) - selectiontextpos = Observable(Point2f(0, 0); ignore_equal_values=true) + selectiontextpos = Observable(Point2f(0, 0); ignore_equal_values = true) selectiontext = text!( blockscene, selectiontextpos, text = selected_text, align = (:left, :center), fontsize = m.fontsize, color = m.textcolor, markerspace = :data, inspectable = false @@ -76,13 +81,13 @@ function initialize_block!(m::Menu; default = 1) on(blockscene, m.layoutobservables.computedbbox) do cbb selectionarea[] = Rect2d(origin(cbb), widths(cbb)) ch = height(cbb) - selectiontextpos[] = cbb.origin + Point2f(m.textpadding[][1], ch/2) + selectiontextpos[] = cbb.origin + Point2f(m.textpadding[][1], ch / 2) end - textpositions = Observable(zeros(Point2f, length(optionstrings[])); ignore_equal_values=true) + textpositions = Observable(zeros(Point2f, length(optionstrings[])); ignore_equal_values = true) - optionrects = Observable([Rect2d(0, 0, 0, 0)]; ignore_equal_values=true) - optionpolycolors = Observable(RGBAf[RGBAf(0.5, 0.5, 0.5, 1)]; ignore_equal_values=true) + optionrects = Observable([Rect2d(0, 0, 0, 0)]; ignore_equal_values = true) + optionpolycolors = Observable(RGBAf[RGBAf(0.5, 0.5, 0.5, 1)]; ignore_equal_values = true) function update_option_colors!(hovered) n = length(optionstrings[]) @@ -100,15 +105,17 @@ function initialize_block!(m::Menu; default = 1) end end end - notify(optionpolycolors) + return notify(optionpolycolors) end # the y boundaries of the list rectangles list_y_bounds = Ref(Float32[]) optionpolys = poly!(menuscene, optionrects, color = optionpolycolors, inspectable = false) - optiontexts = text!(menuscene, textpositions, text = optionstrings, align = (:left, :center), - fontsize = m.fontsize, inspectable = false) + optiontexts = text!( + menuscene, textpositions, text = optionstrings, align = (:left, :center), + fontsize = m.fontsize, inspectable = false + ) onany(blockscene, optionstrings, m.textpadding, m.layoutobservables.computedbbox) do _, pad, bbox gcs = optiontexts.plots[1][1][]::Vector{GlyphCollection} @@ -117,7 +124,7 @@ function initialize_block!(m::Menu; default = 1) heights_cumsum = [zero(eltype(heights)); cumsum(heights)] h = sum(heights) list_y_bounds[] = h .- heights_cumsum - texts_y = @views h .- 0.5 .* (heights_cumsum[1:end-1] .+ heights_cumsum[2:end]) + texts_y = @views h .- 0.5 .* (heights_cumsum[1:(end - 1)] .+ heights_cumsum[2:end]) textpositions[] = Point2f.(pad[1], texts_y) listheight[] = h w_bbox = width(bbox) @@ -125,7 +132,7 @@ function initialize_block!(m::Menu; default = 1) resize!(optionrects.val, length(bbs)) optionrects.val .= map(eachindex(bbs)) do i - BBox(0, w_bbox, h - heights_cumsum[i+1], h - heights_cumsum[i]) + BBox(0, w_bbox, h - heights_cumsum[i + 1], h - heights_cumsum[i]) end update_option_colors!(0) @@ -140,8 +147,8 @@ function initialize_block!(m::Menu; default = 1) # translation due to scrolling has to be removed first ytrans = y - translation(menuscene)[][2] return argmin( - i -> abs(ytrans - 0.5 * (list_y_bounds[][i+1] + list_y_bounds[][i])), - 1:length(list_y_bounds[])-1 + i -> abs(ytrans - 0.5 * (list_y_bounds[][i + 1] + list_y_bounds[][i])), + 1:(length(list_y_bounds[]) - 1) ) end @@ -171,7 +178,7 @@ function initialize_block!(m::Menu; default = 1) return false end - onany(blockscene, e.mouseposition, e.mousebutton; priority=64) do position, butt + onany(blockscene, e.mouseposition, e.mousebutton; priority = 64) do position, butt mp = screen_relative(menuscene, position) # track if we have been inside menu/options to clean up if we haven't been is_over_options = false @@ -240,7 +247,7 @@ function initialize_block!(m::Menu; default = 1) return Consume(false) end - on(blockscene, menuscene.events.scroll; priority=61) do (x, y) + on(blockscene, menuscene.events.scroll; priority = 61) do (x, y) if is_mouseinside(menuscene) t = translation(menuscene)[] # Hack to differentiate mousewheel and trackpad scrolling @@ -280,11 +287,12 @@ function initialize_block!(m::Menu; default = 1) end dropdown_arrow = scatter!( blockscene, symbol_pos; - marker=lift(iso -> iso ? :utriangle : :dtriangle, blockscene, m.is_open), + marker = lift(iso -> iso ? :utriangle : :dtriangle, blockscene, m.is_open), markersize = m.dropdown_arrow_size, color = m.dropdown_arrow_color, strokecolor = :transparent, - inspectable = false) + inspectable = false + ) translate!(dropdown_arrow, 0, 0, 1) @@ -316,7 +324,7 @@ function initialize_block!(m::Menu; default = 1) if i === nothing error("Initial menu selection was set to $(default) but that was not found in the option names.") end - m.i_selected[] = i + m.i_selected[] = i end notify(m.is_open) @@ -327,17 +335,17 @@ function initialize_block!(m::Menu; default = 1) end function optionlabel(option) - string(option) + return string(option) end function optionlabel(option::Tuple{Any, Any}) - string(option[1]) + return string(option[1]) end function optionvalue(option) - option + return option end function optionvalue(option::Tuple{Any, Any}) - option[2] + return option[2] end diff --git a/src/makielayout/blocks/polaraxis.jl b/src/makielayout/blocks/polaraxis.jl index efc6c2d3dcc..23917da1c9b 100644 --- a/src/makielayout/blocks/polaraxis.jl +++ b/src/makielayout/blocks/polaraxis.jl @@ -2,7 +2,7 @@ ### Main Block Initialization ################################################################################ -function initialize_block!(po::PolarAxis; palette=nothing) +function initialize_block!(po::PolarAxis; palette = nothing) # Setup Scenes cb = po.layoutobservables.computedbbox scenearea = map(po.blockscene, cb) do cb @@ -44,28 +44,28 @@ function initialize_block!(po::PolarAxis; palette=nothing) # TODO: Should we include rticks here? # OPT: only update on relevant text attributes rather than glyphcollection onany( - po.blockscene, - rticklabelplot.plots[1].text, - rticklabelplot.plots[1].fontsize, - rticklabelplot.plots[1].font, - po.rticklabelpad, - thetaticklabelplot.plots[1].text, - thetaticklabelplot.plots[1].fontsize, - thetaticklabelplot.plots[1].font, - po.thetaticklabelpad, - po.overlay.viewport - ) do _, _, _, rpad, _, _, _, tpad, area + po.blockscene, + rticklabelplot.plots[1].text, + rticklabelplot.plots[1].fontsize, + rticklabelplot.plots[1].font, + po.rticklabelpad, + thetaticklabelplot.plots[1].text, + thetaticklabelplot.plots[1].fontsize, + thetaticklabelplot.plots[1].font, + po.thetaticklabelpad, + po.overlay.viewport + ) do _, _, _, rpad, _, _, _, tpad, area # get maximum size of tick label # (each boundingbox represents a string without text.position applied) max_widths = Vec2f(0) for gc in thetaticklabelplot.plots[1].plots[1][1][] bbox = string_boundingbox(gc, Quaternionf(0, 0, 0, 1)) # no rotation - max_widths = max.(max_widths, widths(bbox)[Vec(1,2)]) + max_widths = max.(max_widths, widths(bbox)[Vec(1, 2)]) end for gc in rticklabelplot.plots[1].plots[1][1][] bbox = string_boundingbox(gc, Quaternionf(0, 0, 0, 1)) # no rotation - max_widths = max.(max_widths, widths(bbox)[Vec(1,2)]) + max_widths = max.(max_widths, widths(bbox)[Vec(1, 2)]) end max_width, max_height = max_widths @@ -80,13 +80,13 @@ function initialize_block!(po::PolarAxis; palette=nothing) # Set up the title position title_position = map( - po.blockscene, - po.target_rlims, po.target_thetalims, po.target_theta_0, po.direction, - po.rticklabelsize, po.rticklabelpad, - po.thetaticklabelsize, po.thetaticklabelpad, - po.overlay.viewport, po.overlay.camera.projectionview, - po.titlegap, po.titlesize, po.titlealign - ) do rlims, thetalims, theta_0, dir, r_fs, r_pad, t_fs, t_pad, area, pv, gap, size, align + po.blockscene, + po.target_rlims, po.target_thetalims, po.target_theta_0, po.direction, + po.rticklabelsize, po.rticklabelpad, + po.thetaticklabelsize, po.thetaticklabelpad, + po.overlay.viewport, po.overlay.camera.projectionview, + po.titlegap, po.titlesize, po.titlealign + ) do rlims, thetalims, theta_0, dir, r_fs, r_pad, t_fs, t_pad, area, pv, gap, size, align # derive y position # transform to pixel space @@ -139,10 +139,10 @@ function initialize_block!(po::PolarAxis; palette=nothing) # Since we handle ticks within out `scenearea` this only needs to reserve # space for the title protrusions = map( - po.blockscene, po.title, po.titlegap, po.titlesize - ) do title, gap, size - titlespace = po.title[] == "" ? 0f0 : Float32(2gap + size) - return GridLayoutBase.RectSides(0f0, 0f0, 0f0, titlespace) + po.blockscene, po.title, po.titlegap, po.titlesize + ) do title, gap, size + titlespace = po.title[] == "" ? 0.0f0 : Float32(2gap + size) + return GridLayoutBase.RectSides(0.0f0, 0.0f0, 0.0f0, titlespace) end connect!(po.layoutobservables.protrusions, protrusions) @@ -166,7 +166,7 @@ function polaraxis_bbox(rlims, thetalims, r0, dir, theta_0) thetamin, thetamax = thetalims rmin, rmax = max.(0.0, rlims .- r0) - if abs(thetamax - thetamin) > 3pi/2 + if abs(thetamax - thetamin) > 3pi / 2 return Rect2d(-rmax, -rmax, 2rmax, 2rmax) end @@ -191,14 +191,14 @@ function polaraxis_bbox(rlims, thetalims, r0, dir, theta_0) bb = update_boundingbox(bb, polar2cartesian(rmax, thetamax)) # only outer circle can update bb - if thetamin < -3pi/2 < thetamax || thetamin < pi/2 < thetamax - bb = update_boundingbox(bb, polar2cartesian(rmax, pi/2)) + if thetamin < -3pi / 2 < thetamax || thetamin < pi / 2 < thetamax + bb = update_boundingbox(bb, polar2cartesian(rmax, pi / 2)) end if thetamin < -pi < thetamax || thetamin < pi < thetamax bb = update_boundingbox(bb, polar2cartesian(rmax, pi)) end - if thetamin < -pi/2 < thetamax || thetamin < 3pi/2 < thetamax - bb = update_boundingbox(bb, polar2cartesian(rmax, 3pi/2)) + if thetamin < -pi / 2 < thetamax || thetamin < 3pi / 2 < thetamax + bb = update_boundingbox(bb, polar2cartesian(rmax, 3pi / 2)) end if thetamin < 0 < thetamax bb = update_boundingbox(bb, polar2cartesian(rmax, 0)) @@ -213,7 +213,7 @@ function setup_camera_matrices!(po::PolarAxis) setfield!(po, :target_rlims, Observable{Tuple{Float64, Float64}}((0.0, 10.0))) setfield!(po, :target_thetalims, Observable{Tuple{Float64, Float64}}((0.0, 2pi))) setfield!(po, :target_theta_0, map(identity, po.theta_0)) - setfield!(po, :target_r0, Observable{Float32}(po.radius_at_origin[] isa Real ? po.radius_at_origin[] : 0f0)) + setfield!(po, :target_r0, Observable{Float32}(po.radius_at_origin[] isa Real ? po.radius_at_origin[] : 0.0f0)) reset_limits!(po) onany((_, _) -> reset_limits!(po), po.blockscene, po.rlimits, po.thetalimits) @@ -251,15 +251,15 @@ function setup_camera_matrices!(po::PolarAxis) # this just aspect-aware clip space (-1 .. 1, -h/w ... h/w, -max_z ... max_z) on(po.blockscene, po.scene.viewport) do area aspect = Float32((/)(widths(area)...)) - w = 1f0 - h = 1f0 / aspect + w = 1.0f0 + h = 1.0f0 / aspect camera(po.scene).projection[] = orthographicprojection(-w, w, -h, h, -max_z, max_z) end on(po.blockscene, po.overlay.viewport) do area aspect = Float32((/)(widths(area)...)) - w = 1f0 - h = 1f0 / aspect + w = 1.0f0 + h = 1.0f0 / aspect camera(po.overlay).projection[] = orthographicprojection(-w, w, -h, h, -max_z, max_z) end @@ -271,9 +271,9 @@ function setup_camera_matrices!(po::PolarAxis) if is_mouseinside(po.scene) && (!po.rzoomlock[] || !po.thetazoomlock[]) mp = mouseposition(po.scene) r = norm(mp) - zoom_scale = (1.0 - po.zoomspeed[]) ^ scroll[2] + zoom_scale = (1.0 - po.zoomspeed[])^scroll[2] rmin, rmax = po.target_rlims[] - thetamin, thetamax = po.target_thetalims[] + thetamin, thetamax = po.target_thetalims[] # keep circumference to radial length ratio constant by default dtheta = thetamax - thetamin @@ -305,16 +305,16 @@ function setup_camera_matrices!(po::PolarAxis) # angle of mouse position normalized to range theta = po.direction[] * atan(mp[2], mp[1]) - po.target_theta_0[] thetacenter = 0.5 * (thetamin + thetamax) - theta = mod(theta, thetacenter-pi .. thetacenter+pi) + theta = mod(theta, thetacenter - pi .. thetacenter + pi) w = (theta - thetamin) / (thetamax - thetamin) dtheta = (thetamax - thetamin) - clamp(aspect * (rmax - rmin) / r, 0, 2pi) thetamin = thetamin + w * dtheta - thetamax = thetamax - (1-w) * dtheta + thetamax = thetamax - (1 - w) * dtheta if !ispressed(e, po.rzoomkey[]) && !po.thetazoomlock[] if po.normalize_theta_ticks[] - if thetamax - thetamin < 2pi - 1e-5 + if thetamax - thetamin < 2pi - 1.0e-5 po.target_thetalims[] = normalize_thetalims(thetamin, thetamax) else po.target_thetalims[] = (0.0, 2pi) @@ -324,14 +324,14 @@ function setup_camera_matrices!(po::PolarAxis) end end - # don't open a gap when zooming a full circle near the center + # don't open a gap when zooming a full circle near the center elseif r > 0.1rmax && zoom_scale < 1 # open angle on the opposite site of theta theta = po.direction[] * atan(mp[2], mp[1]) - po.target_theta_0[] theta = theta + pi + thetamin # (-pi, pi) -> (thetamin, thetamin+2pi) - dtheta = (thetamax - thetamin) - clamp(aspect * (rmax - rmin) / r, 1e-6, 2pi) + dtheta = (thetamax - thetamin) - clamp(aspect * (rmax - rmin) / r, 1.0e-6, 2pi) thetamin = theta + 0.5 * dtheta thetamax = theta + 2pi - 0.5 * dtheta @@ -358,7 +358,7 @@ function setup_camera_matrices!(po::PolarAxis) drag_state[] = ( ispressed(po.scene, po.r_translation_button[]), ispressed(po.scene, po.theta_translation_button[]), - ispressed(po.scene, po.axis_rotation_button[]) + ispressed(po.scene, po.axis_rotation_button[]), ) last_px_pos[] = Point2f(mouseposition_px(po.scene)) last_pos[] = Point2f(mouseposition(po.scene)) @@ -368,7 +368,7 @@ function setup_camera_matrices!(po::PolarAxis) drag_state[] = ( ispressed(po.scene, po.r_translation_button[]), ispressed(po.scene, po.theta_translation_button[]), - ispressed(po.scene, po.axis_rotation_button[]) + ispressed(po.scene, po.axis_rotation_button[]), ) return Consume(was_pressed) end @@ -380,13 +380,13 @@ function setup_camera_matrices!(po::PolarAxis) w = widths(po.scene) p0 = (last_px_pos[] .- 0.5w) ./ w p1 = Point2f(mouseposition_px(po.scene) .- 0.5w) ./ w - if norm(p0) * norm(p1) < 1e-6 + if norm(p0) * norm(p1) < 1.0e-6 Δθ = 0.0 else - Δθ = mod(po.direction[] * (atan(p1[2], p1[1]) - atan(p0[2], p0[1])), -pi..pi) + Δθ = mod(po.direction[] * (atan(p1[2], p1[1]) - atan(p0[2], p0[1])), -pi .. pi) end - po.target_theta_0[] = mod(po.target_theta_0[] + Δθ, 0..2pi) + po.target_theta_0[] = mod(po.target_theta_0[] + Δθ, 0 .. 2pi) last_px_pos[] = Point2f(mouseposition_px(po.scene)) last_pos[] = Point2f(mouseposition(po.scene)) @@ -396,7 +396,7 @@ function setup_camera_matrices!(po::PolarAxis) diff = pos - last_pos[] r = norm(last_pos[]) - if r < 1e-6 + if r < 1.0e-6 Δr = norm(pos) Δθ = 0.0 else @@ -413,9 +413,9 @@ function setup_camera_matrices!(po::PolarAxis) end if drag_state[][2] thetamin, thetamax = po.target_thetalims[] - if thetamax - thetamin > 2pi - 1e-5 + if thetamax - thetamin > 2pi - 1.0e-5 # full circle -> rotate view - po.target_theta_0[] = mod(po.target_theta_0[] + Δθ, 0..2pi) + po.target_theta_0[] = mod(po.target_theta_0[] + Δθ, 0 .. 2pi) else # partial circle -> rotate and adjust limits thetamin, thetamax = (thetamin, thetamax) .- Δθ @@ -424,7 +424,7 @@ function setup_camera_matrices!(po::PolarAxis) else po.target_thetalims[] = (thetamin, thetamax) end - po.target_theta_0[] = mod(po.target_theta_0[] + Δθ, 0..2pi) + po.target_theta_0[] = mod(po.target_theta_0[] + Δθ, 0 .. 2pi) end end @@ -439,7 +439,7 @@ function setup_camera_matrices!(po::PolarAxis) # Reset button onany(po.blockscene, e.mousebutton, e.keyboardbutton) do e1, e2 if ispressed(e, po.reset_button[]) && is_mouseinside(po.scene) && - (e1.action == Mouse.press) && (e2.action == Keyboard.press) + (e1.action == Mouse.press) && (e2.action == Keyboard.press) old_thetalims = po.target_thetalims[] if ispressed(e, Keyboard.left_shift) autolimits!(po) @@ -450,7 +450,7 @@ function setup_camera_matrices!(po::PolarAxis) notify(po.theta_0) else diff = 0.5 * sum(po.target_thetalims[] .- old_thetalims) - po.target_theta_0[] = mod(po.target_theta_0[] - diff, 0..2pi) + po.target_theta_0[] = mod(po.target_theta_0[] - diff, 0 .. 2pi) end return Consume(true) end @@ -522,7 +522,7 @@ function reset_limits!(po::PolarAxis) end # apply - po.target_rlims[] = ifelse.(isnothing.(rlimits), (rmin, rmax), rlimits) + po.target_rlims[] = ifelse.(isnothing.(rlimits), (rmin, rmax), rlimits) po.target_thetalims[] = ifelse.(isnothing.(po.thetalimits[]), (thetamin, thetamax), po.thetalimits[]) else # all limits set if po.target_rlims[] != rlimits @@ -544,7 +544,7 @@ end # generates large square with circle sector cutout function _polar_clip_polygon( - thetamin, thetamax, steps = 120, outer = 1e4, + thetamin, thetamax, steps = 120, outer = 1.0e4, exterior = Point2f[(-outer, -outer), (-outer, outer), (outer, outer), (outer, -outer), (-outer, -outer)] ) # make sure we have 2+ points per arc @@ -576,10 +576,10 @@ function draw_axis!(po::PolarAxis) end onany( - po.blockscene, - po.rticks, po.rminorticks, po.rtickformat, po.rtickangle, - po.direction, po.target_rlims, po.target_thetalims, po.sample_density, po.target_r0 - ) do rticks, rminorticks, rtickformat, rtickangle, + po.blockscene, + po.rticks, po.rminorticks, po.rtickformat, po.rtickangle, + po.direction, po.target_rlims, po.target_thetalims, po.sample_density, po.target_r0 + ) do rticks, rminorticks, rtickformat, rtickangle, dir, rlims, thetalims, sample_density, target_r0 # For text: @@ -602,27 +602,27 @@ function draw_axis!(po::PolarAxis) # doesn't have a lot of overlap with the inputs above so calculate this independently onany( - po.blockscene, - po.direction, po.target_theta_0, po.rtickangle, po.target_thetalims, po.rticklabelpad, - po.rticklabelrotation - ) do dir, theta_0, rtickangle, thetalims, pad, rot - angle = mod(dir * (default_rtickangle(rtickangle, dir, thetalims) + theta_0), 0..2pi) - s, c = sincos(angle - pi/2) + po.blockscene, + po.direction, po.target_theta_0, po.rtickangle, po.target_thetalims, po.rticklabelpad, + po.rticklabelrotation + ) do dir, theta_0, rtickangle, thetalims, pad, rot + angle = mod(dir * (default_rtickangle(rtickangle, dir, thetalims) + theta_0), 0 .. 2pi) + s, c = sincos(angle - pi / 2) rtick_offset[] = Point2f(pad * c, pad * s) if rot === automatic rot = (thetalims[2] - thetalims[1]) > 1.9pi ? (:horizontal) : (:aligned) end if rot === :horizontal - rtick_rotation[] = 0f0 + rtick_rotation[] = 0.0f0 scale = 1 / max(abs(s), abs(c)) # point on ellipse -> point on bbox rtick_align[] = Point2f(0.5 - 0.5scale * c, 0.5 - 0.5scale * s) elseif rot === :radial - rtick_rotation[] = angle - pi/2 + rtick_rotation[] = angle - pi / 2 rtick_align[] = Point2f(0, 0.5) elseif rot === :aligned - N = trunc(Int, div(angle + pi/4, pi/2)) % 4 - rtick_rotation[] = angle - N * pi/2 # mod(angle, -pi/4 .. pi/4) - rtick_align[] = Point2f((0.5, 0.0, 0.5, 1.0)[N+1], (1.0, 0.5, 0.0, 0.5)[N+1]) + N = trunc(Int, div(angle + pi / 4, pi / 2)) % 4 + rtick_rotation[] = angle - N * pi / 2 # mod(angle, -pi/4 .. pi/4) + rtick_align[] = Point2f((0.5, 0.0, 0.5, 1.0)[N + 1], (1.0, 0.5, 0.0, 0.5)[N + 1]) elseif rot isa Real rtick_rotation[] = rot scale = 1 / max(abs(s), abs(c)) @@ -639,10 +639,10 @@ function draw_axis!(po::PolarAxis) thetaminorgridpoints = Observable{Vector{Point2f}}() onany( - po.blockscene, - po.thetaticks, po.thetaminorticks, po.thetatickformat, po.thetaticklabelpad, - po.direction, po.target_theta_0, po.target_rlims, po.target_thetalims, po.target_r0 - ) do thetaticks, thetaminorticks, thetatickformat, px_pad, dir, theta_0, rlims, thetalims, r0 + po.blockscene, + po.thetaticks, po.thetaminorticks, po.thetatickformat, po.thetaticklabelpad, + po.direction, po.target_theta_0, po.target_rlims, po.target_thetalims, po.target_r0 + ) do thetaticks, thetaminorticks, thetatickformat, px_pad, dir, theta_0, rlims, thetalims, r0 _thetatickvalues, _thetaticklabels = get_ticks(thetaticks, identity, thetatickformat, thetalims...) @@ -762,7 +762,7 @@ function draw_axis!(po::PolarAxis) onany(po.blockscene, po.target_thetalims, po.direction, po.target_theta_0) do thetalims, dir, theta_0 thetamin, thetamax = dir .* (thetalims .+ theta_0) angle = dir > 0 ? thetamin : thetamax - rotate!.((outer_clip_plot, inner_clip_plot), (Vec3f(0,0,1),), angle) + rotate!.((outer_clip_plot, inner_clip_plot), (Vec3f(0, 0, 1),), angle) end onany(po.blockscene, po.target_rlims, po.target_r0) do lims, r0 @@ -773,9 +773,10 @@ function draw_axis!(po::PolarAxis) notify(po.target_r0) # spine traces circle sector - inner circle - spine_points = map(po.blockscene, - po.target_rlims, po.target_thetalims, po.target_r0, po.sample_density - ) do (rmin, rmax), thetalims, r0, N + spine_points = map( + po.blockscene, + po.target_rlims, po.target_thetalims, po.target_r0, po.sample_density + ) do (rmin, rmax), thetalims, r0, N thetamin, thetamax = thetalims rmin = (rmin - r0) / (rmax - r0) rmax = 1.0 @@ -783,12 +784,12 @@ function draw_axis!(po::PolarAxis) # make sure we have 2+ points per arc if abs(thetamax - thetamin) ≈ 2pi ps = Point2f.(rmax, LinRange(thetamin, thetamax, N)) - if rmin > 1e-6 + if rmin > 1.0e-6 push!(ps, Point2f(NaN)) append!(ps, Point2f.(rmin, LinRange(thetamin, thetamax, N))) end else - ps = sizehint!(Point2f[], 2N+1) + ps = sizehint!(Point2f[], 2N + 1) for angle in LinRange(thetamin, thetamax, N) push!(ps, Point2f(rmin, angle)) end @@ -884,7 +885,7 @@ function normalize_thetalims(thetamin, thetamax) diff = thetamax - thetamin if diff < 2pi # displayed limits may go from -diff .. 0 to 0 .. diff - thetamin_norm = mod(thetamin, -diff..(2pi-diff)) + thetamin_norm = mod(thetamin, -diff .. (2pi - diff)) thetamax_norm = thetamin_norm + clamp(diff, 0, 2pi) return thetamin_norm, thetamax_norm else @@ -914,7 +915,7 @@ end function tightlimits!(po::PolarAxis) po.rautolimitmargin = (0, 0) po.thetaautolimitmargin = (0, 0) - reset_limits!(po) + return reset_limits!(po) end @@ -953,7 +954,7 @@ function hiderdecorations!(ax::PolarAxis; ticklabels = true, grid = true, minorg if grid ax.rgridvisible = false end - if minorgrid + return if minorgrid ax.rminorgridvisible = false end end @@ -971,7 +972,7 @@ function hidethetadecorations!(ax::PolarAxis; ticklabels = true, grid = true, mi if grid ax.thetagridvisible = false end - if minorgrid + return if minorgrid ax.thetaminorgridvisible = false end end @@ -985,10 +986,10 @@ Keyword arguments can be used to disable hiding of certain types of decorations. See also [`hiderdecorations!`], [`hidethetadecorations!`], [`hidezdecorations!`] """ function hidedecorations!(ax::PolarAxis; ticklabels = true, grid = true, minorgrid = true) - hiderdecorations!(ax; ticklabels = ticklabels, grid = grid, minorgrid = minorgrid,) - hidethetadecorations!(ax; ticklabels = ticklabels, grid = grid, minorgrid = minorgrid) + hiderdecorations!(ax; ticklabels = ticklabels, grid = grid, minorgrid = minorgrid) + return hidethetadecorations!(ax; ticklabels = ticklabels, grid = grid, minorgrid = minorgrid) end function hidespines!(ax::PolarAxis) - ax.spinevisible = false + return ax.spinevisible = false end diff --git a/src/makielayout/blocks/scene.jl b/src/makielayout/blocks/scene.jl index 1e741594939..c1bedb34e0b 100644 --- a/src/makielayout/blocks/scene.jl +++ b/src/makielayout/blocks/scene.jl @@ -8,7 +8,7 @@ tightlimits!(::LScene) = nothing # TODO implement!? function initialize_block!(ls::LScene; scenekw = NamedTuple()) blockscene = ls.blockscene # pick a camera and draw axis. - scenekw = merge((clear = false, camera=cam3d!), scenekw) + scenekw = merge((clear = false, camera = cam3d!), scenekw) ls.scene = Scene(blockscene, lift(round_to_IRect2D, blockscene, ls.layoutobservables.computedbbox); scenekw...) on(blockscene, ls.show_axis) do show_axis @@ -31,7 +31,7 @@ function initialize_block!(ls::LScene; scenekw = NamedTuple()) end Makie.axis3d!(ls.scene, limits) # Make sure axis is always in pos 1 - sort!(ls.scene.plots, by=!Makie.isaxis) + sort!(ls.scene.plots, by = !Makie.isaxis) else ax.visible = true end @@ -47,7 +47,7 @@ end function Base.delete!(ax::LScene, plot::AbstractPlot) delete!(ax.scene, plot) - ax + return ax end Makie.cam2d!(ax::LScene; kwargs...) = Makie.cam2d!(ax.scene; kwargs...) diff --git a/src/makielayout/blocks/slider.jl b/src/makielayout/blocks/slider.jl index 28ebc809db4..429758a682a 100644 --- a/src/makielayout/blocks/slider.jl +++ b/src/makielayout/blocks/slider.jl @@ -21,12 +21,16 @@ function initialize_block!(sl::Slider) if horizontal y = bottom(bb) + h / 2 - [Point2f(left(bb) + h/2, y), - Point2f(right(bb) - h/2, y)] + [ + Point2f(left(bb) + h / 2, y), + Point2f(right(bb) - h / 2, y), + ] else x = left(bb) + w / 2 - [Point2f(x, bottom(bb) + w/2), - Point2f(x, top(bb) - w/2)] + [ + Point2f(x, bottom(bb) + w / 2), + Point2f(x, top(bb) - w / 2), + ] end end @@ -78,27 +82,35 @@ function initialize_block!(sl::Slider) [ca, ci] end - endbuttons = scatter!(topscene, endpoints, color = linecolors, - markersize = sl.linewidth, strokewidth = 0, inspectable = false, marker=Circle) + endbuttons = scatter!( + topscene, endpoints, color = linecolors, + markersize = sl.linewidth, strokewidth = 0, inspectable = false, marker = Circle + ) - linesegs = linesegments!(topscene, linepoints, color = linecolors, - linewidth = sl.linewidth, inspectable = false) + linesegs = linesegments!( + topscene, linepoints, color = linecolors, + linewidth = sl.linewidth, inspectable = false + ) button_magnification = Observable(1.0) buttonsize = lift(*, topscene, sl.linewidth, button_magnification) - button = scatter!(topscene, middlepoint, color = sl.color_active, strokewidth = 0, - markersize = buttonsize, inspectable = false, marker=Circle) + button = scatter!( + topscene, middlepoint, color = sl.color_active, strokewidth = 0, + markersize = buttonsize, inspectable = false, marker = Circle + ) mouseevents = addmouseevents!(topscene, sl.layoutobservables.computedbbox) onmouseleftdrag(mouseevents) do event dragging[] = true dif = event.px - event.prev_px - fraction = clamp(if sl.horizontal[] - (event.px[1] - endpoints[][1][1]) / (endpoints[][2][1] - endpoints[][1][1]) - else - (event.px[2] - endpoints[][1][2]) / (endpoints[][2][2] - endpoints[][1][2]) - end, 0, 1) + fraction = clamp( + if sl.horizontal[] + (event.px[1] - endpoints[][1][1]) / (endpoints[][2][1] - endpoints[][1][1]) + else + (event.px[2] - endpoints[][1][2]) / (endpoints[][2][2] - endpoints[][1][2]) + end, 0, 1 + ) newindex = closest_fractionindex(sliderrange[], fraction) if sl.snap[] @@ -148,7 +160,7 @@ function initialize_block!(sl::Slider) # trigger autosize through linewidth for first layout notify(sl.linewidth) - sl + return sl end function valueindex(sliderrange, value) @@ -157,14 +169,14 @@ function valueindex(sliderrange, value) return i end end - nothing + return nothing end function closest_fractionindex(sliderrange, fraction) n = length(sliderrange) onestepfrac = 1 / (n - 1) i = round(Int, fraction / onestepfrac) + 1 - min(max(i, 1), n) + return min(max(i, 1), n) end function closest_index(sliderrange, value) @@ -174,7 +186,7 @@ function closest_index(sliderrange, value) end end # if the value wasn't found this way try inexact - closest_index_inexact(sliderrange, value) + return closest_index_inexact(sliderrange, value) end function closest_index_inexact(sliderrange, value) @@ -187,7 +199,7 @@ function closest_index_inexact(sliderrange, value) selected_i = i end end - selected_i + return selected_i end """ @@ -200,5 +212,5 @@ mutating its value observable directly, which doesn't update the slider visually function set_close_to!(slider::Slider, value) closest = closest_index(slider.range[], value) slider.selected_index = closest - slider.range[][closest] + return slider.range[][closest] end diff --git a/src/makielayout/blocks/slidergrid.jl b/src/makielayout/blocks/slidergrid.jl index 40f857c130e..ac65804f1fe 100644 --- a/src/makielayout/blocks/slidergrid.jl +++ b/src/makielayout/blocks/slidergrid.jl @@ -25,8 +25,10 @@ function initialize_block!(sg::SliderGrid, nts::NamedTuple...) remaining_pairs = filter(pair -> pair[1] ∉ (:label, :range, :format), pairs(nt)) l = Label(sg.layout[i, 1], label, halign = :left) slider = Slider(sg.layout[i, 2]; range = range, remaining_pairs...) - vl = Label(sg.layout[i, 3], - lift(x -> apply_format(x, format), slider.value), halign = :right) + vl = Label( + sg.layout[i, 3], + lift(x -> apply_format(x, format), slider.value), halign = :right + ) push!(sg.valuelabels, vl) push!(sg.sliders, slider) push!(sg.labels, l) diff --git a/src/makielayout/blocks/textbox.jl b/src/makielayout/blocks/textbox.jl index 58f4252726c..f4bb8987d74 100644 --- a/src/makielayout/blocks/textbox.jl +++ b/src/makielayout/blocks/textbox.jl @@ -27,8 +27,10 @@ function initialize_block!(tbox::Textbox) hovering = Observable(false) realbordercolor = Observable{RGBAf}() - map!(topscene, realbordercolor, tbox.bordercolor, tbox.bordercolor_focused, - tbox.bordercolor_focused_invalid, tbox.bordercolor_hover, tbox.focused, displayed_is_valid, hovering) do bc, bcf, bcfi, bch, focused, valid, hovering + map!( + topscene, realbordercolor, tbox.bordercolor, tbox.bordercolor_focused, + tbox.bordercolor_focused_invalid, tbox.bordercolor_hover, tbox.focused, displayed_is_valid, hovering + ) do bc, bcf, bcfi, bch, focused, valid, hovering c = if focused valid ? bcf : bcfi else @@ -38,8 +40,10 @@ function initialize_block!(tbox::Textbox) end realboxcolor = Observable{RGBAf}() - map!(topscene, realboxcolor, tbox.boxcolor, tbox.boxcolor_focused, - tbox.boxcolor_focused_invalid, tbox.boxcolor_hover, tbox.focused, displayed_is_valid, hovering) do bc, bcf, bcfi, bch, focused, valid, hovering + map!( + topscene, realboxcolor, tbox.boxcolor, tbox.boxcolor_focused, + tbox.boxcolor_focused_invalid, tbox.boxcolor_hover, tbox.focused, displayed_is_valid, hovering + ) do bc, bcf, bcfi, bch, focused, valid, hovering c = if focused valid ? bcf : bcfi @@ -49,24 +53,30 @@ function initialize_block!(tbox::Textbox) return to_color(c) end - box = poly!(topscene, roundedrectpoints, strokewidth = tbox.borderwidth, + box = poly!( + topscene, roundedrectpoints, strokewidth = tbox.borderwidth, strokecolor = realbordercolor, - color = realboxcolor, inspectable = false) + color = realboxcolor, inspectable = false + ) displayed_chars = lift(ds -> [c for c in ds], topscene, tbox.displayed_string) realtextcolor = Observable{RGBAf}() - map!(topscene, realtextcolor, tbox.textcolor, tbox.textcolor_placeholder, tbox.focused, - tbox.stored_string, tbox.displayed_string) do tc, tcph, foc, cont, disp + map!( + topscene, realtextcolor, tbox.textcolor, tbox.textcolor_placeholder, tbox.focused, + tbox.stored_string, tbox.displayed_string + ) do tc, tcph, foc, cont, disp # the textbox has normal text color if it's focused # if it's defocused, the displayed text has to match the stored text in order # to be normal colored return to_color(foc || cont == disp ? tc : tcph) end - t = Label(scene, text = tbox.displayed_string, bbox = bbox, halign = :left, valign = :top, + t = Label( + scene, text = tbox.displayed_string, bbox = bbox, halign = :left, valign = :top, width = Auto(true), height = Auto(true), color = realtextcolor, - fontsize = tbox.fontsize, padding = tbox.textpadding) + fontsize = tbox.fontsize, padding = tbox.textpadding + ) textplot = t.blockscene.plots[1] displayed_charbbs = lift(topscene, textplot.text, textplot[1]) do _, _ @@ -91,7 +101,7 @@ function initialize_block!(tbox::Textbox) end if 0 < ci < length(bbs) - [leftline(bbs[ci+1])...] + [leftline(bbs[ci + 1])...] elseif ci == 0 [leftline(bbs[1])...] else @@ -149,7 +159,7 @@ function initialize_block!(tbox::Textbox) pos = state.data end closest_charindex = argmin( - [sum((pos .- center(bb)).^2) for bb in displayed_charbbs[]] + [sum((pos .- center(bb)) .^ 2) for bb in displayed_charbbs[]] ) # set cursor to index of closest char if right of center, or previous char if left of center cursorindex[] = if (pos .- center(displayed_charbbs[][closest_charindex]))[1] > 0 @@ -184,17 +194,17 @@ function initialize_block!(tbox::Textbox) empty!(displayed_chars[]) index = 1 end - newchars = [displayed_chars[][1:index-1]; c; displayed_chars[][index:end]] + newchars = [displayed_chars[][1:(index - 1)]; c; displayed_chars[][index:end]] tbox.displayed_string[] = join(newchars) - cursorindex[] = index + return cursorindex[] = index end function appendchar!(c) - insertchar!(c, length(tbox.displayed_string[])) + return insertchar!(c, length(tbox.displayed_string[])) end function removechar!(index) - newchars = [displayed_chars[][1:index-1]; displayed_chars[][index+1:end]] + newchars = [displayed_chars[][1:(index - 1)]; displayed_chars[][(index + 1):end]] if isempty(newchars) newchars = [' '] @@ -204,10 +214,10 @@ function initialize_block!(tbox::Textbox) cursorindex[] = max(0, cursorindex[] - 1) end - tbox.displayed_string[] = join(newchars) + return tbox.displayed_string[] = join(newchars) end - on(topscene, events(scene).unicode_input; priority=60) do char + on(topscene, events(scene).unicode_input; priority = 60) do char if tbox.focused[] && is_allowed(char, tbox.restriction[]) insertchar!(char, cursorindex[] + 1) return Consume(true) @@ -217,7 +227,7 @@ function initialize_block!(tbox::Textbox) function reset_to_stored() cursorindex[] = 0 - if isnothing(tbox.stored_string[]) + return if isnothing(tbox.stored_string[]) tbox.displayed_string[] = tbox.placeholder[] else tbox.displayed_string[] = tbox.stored_string[] @@ -225,17 +235,17 @@ function initialize_block!(tbox::Textbox) end function cursor_forward() - if tbox.displayed_string[] != " " + return if tbox.displayed_string[] != " " cursorindex[] = min(length(tbox.displayed_string[]), cursorindex[] + 1) end end function cursor_backward() - cursorindex[] = max(0, cursorindex[] - 1) + return cursorindex[] = max(0, cursorindex[] - 1) end - on(topscene, events(scene).keyboardbutton; priority=60) do event + on(topscene, events(scene).keyboardbutton; priority = 60) do event if tbox.focused[] ctrl_v = (Keyboard.left_control | Keyboard.right_control) & Keyboard.v if ispressed(scene, ctrl_v) @@ -286,7 +296,7 @@ function initialize_block!(tbox::Textbox) return Consume(false) end - tbox + return tbox end @@ -303,29 +313,29 @@ function charbbs(text) fr = Rect2f(Point2f(ori) + bb.origin + pos, bb.widths) push!(bbs, fr) end - bbs + return bbs end function validate_textbox(str, validator::Function) - validator(str) + return validator(str) end function validate_textbox(str, T::Type) - !isnothing(tryparse(T, str)) + return !isnothing(tryparse(T, str)) end function validate_textbox(str, validator::Regex) m = match(validator, str) # check that the validator matches the whole string - !isnothing(m) && m.match == str + return !isnothing(m) && m.match == str end function is_allowed(char, restriction::Nothing) - true + return true end function is_allowed(char, restriction::Function) - allowed::Bool = restriction(char) + return allowed::Bool = restriction(char) end """ @@ -336,7 +346,7 @@ function reset!(tb::Textbox) tb.stored_string.val = nothing tb.displayed_string = tb.placeholder[] defocus!(tb) - nothing + return nothing end """ @@ -350,7 +360,7 @@ function set!(tb::Textbox, string::String) tb.displayed_string = string tb.stored_string = string - nothing + return nothing end """ @@ -365,8 +375,10 @@ function focus!(tb::Textbox) Animations.Animation( [0, 1.0], [Colors.alphacolor(COLOR_ACCENT[], 0), Colors.alphacolor(COLOR_ACCENT[], 1)], - Animations.sineio(n = 2, yoyo = true, postwait = 0.2)), - 0.0, 0.0, 1000) + Animations.sineio(n = 2, yoyo = true, postwait = 0.2) + ), + 0.0, 0.0, 1000 + ) if !isnothing(tb.cursoranimtask) Animations.stop(tb.cursoranimtask) @@ -377,7 +389,7 @@ function focus!(tb::Textbox) tb.cursorcolor = color end end - nothing + return nothing end """ @@ -396,5 +408,5 @@ function defocus!(tb::Textbox) end tb.cursorcolor = :transparent tb.focused = false - nothing + return nothing end diff --git a/src/makielayout/blocks/toggle.jl b/src/makielayout/blocks/toggle.jl index cd7a75443d5..b3edb7badf9 100644 --- a/src/makielayout/blocks/toggle.jl +++ b/src/makielayout/blocks/toggle.jl @@ -3,30 +3,30 @@ function initialize_block!(t::Toggle) topscene = t.blockscene onany(topscene, t.orientation, t.length, t.markersize) do or, len, ms - theta = or == :horizontal ? 0 : or == :vertical ? pi/2 : or + theta = or == :horizontal ? 0 : or == :vertical ? pi / 2 : or y, x = sincos(theta) autowidth = (len - ms) * abs(x) + ms - autoheight = (len - ms) * abs(y) + ms + autoheight = (len - ms) * abs(y) + ms t.layoutobservables.autosize[] = (autowidth, autoheight) end - xfun(x, bbox, ms) = x>0 ? left(bbox) + ms / 2 : right(bbox) - ms / 2 - yfun(y, bbox, ms) = y>0 ? bottom(bbox) + ms / 2 : top(bbox) - ms / 2 + xfun(x, bbox, ms) = x > 0 ? left(bbox) + ms / 2 : right(bbox) - ms / 2 + yfun(y, bbox, ms) = y > 0 ? bottom(bbox) + ms / 2 : top(bbox) - ms / 2 button_endpoint_inactive = lift(topscene, t.orientation, t.markersize, t.layoutobservables.computedbbox) do or, ms, bbox - theta = or == :horizontal ? 0 : or == :vertical ? pi/2 : or + theta = or == :horizontal ? 0 : or == :vertical ? pi / 2 : or y, x = sincos(theta) Point2f(xfun(x, bbox, ms), yfun(y, bbox, ms)) end button_endpoint_active = lift(topscene, t.orientation, t.markersize, t.layoutobservables.computedbbox) do or, ms, bbox - theta = or == :horizontal ? 0 : or == :vertical ? pi/2 : or + theta = or == :horizontal ? 0 : or == :vertical ? pi / 2 : or y, x = sincos(theta) Point2f(xfun(-x, bbox, ms), yfun(-y, bbox, ms)) end buttonvertices = lift(topscene, t.length, t.markersize, t.cornersegments) do len, ms, cs - rect0 = GeometryBasics.HyperRectangle(-ms/2, -ms/2, len, ms) + rect0 = GeometryBasics.HyperRectangle(-ms / 2, -ms / 2, len, ms) return roundedrectvertices(rect0, ms * 0.499, cs) end @@ -38,11 +38,11 @@ function initialize_block!(t::Toggle) frame = poly!(topscene, buttonvertices, color = framecolor, inspectable = false) onany(topscene, t.markersize, t.orientation, t.layoutobservables.computedbbox, update = true) do ms, or, bbox - theta = or == :horizontal ? 0 : or == :vertical ? pi/2 : or + theta = or == :horizontal ? 0 : or == :vertical ? pi / 2 : or rotate!(frame, theta) y, x = sincos(theta) - tx = x>0 ? origin(bbox)[1] + ms/2 : origin(bbox)[1] + widths(bbox)[1] - ms/2 - ty = y>0 ? origin(bbox)[2] + ms/2 : origin(bbox)[2] + widths(bbox)[2] - ms/2 + tx = x > 0 ? origin(bbox)[1] + ms / 2 : origin(bbox)[1] + widths(bbox)[1] - ms / 2 + ty = y > 0 ? origin(bbox)[2] + ms / 2 : origin(bbox)[2] + widths(bbox)[2] - ms / 2 translate!(frame, Point2f(tx, ty)) end @@ -61,8 +61,10 @@ function initialize_block!(t::Toggle) ms * (1 - rf) * bf end - button = scatter!(topscene, buttonpos, markersize = buttonsize, - color = t.buttoncolor, strokewidth = 0, inspectable = false, marker = Circle) + button = scatter!( + topscene, buttonpos, markersize = buttonsize, + color = t.buttoncolor, strokewidth = 0, inspectable = false, marker = Circle + ) mouseevents = addmouseevents!(topscene, t.layoutobservables.computedbbox) @@ -77,12 +79,14 @@ function initialize_block!(t::Toggle) anim_posfrac = Animations.Animation( [0, t.toggleduration[]], t.active[] ? [1.0, 0.0] : [0.0, 1.0], - Animations.sineio()) + Animations.sineio() + ) coloranim = Animations.Animation( [0, t.toggleduration[]], t.active[] ? [t.framecolor_active[], t.framecolor_inactive[]] : [t.framecolor_inactive[], t.framecolor_active[]], - Animations.sineio()) + Animations.sineio() + ) t.active[] = !t.active[] @@ -92,8 +96,12 @@ function initialize_block!(t::Toggle) dt = tick.time - tstart # request endpoint values in every frame if the layout changes during # the animation - buttonpos[] = [Animations.linear_interpolate(anim_posfrac(dt), - button_endpoint_inactive[], button_endpoint_active[])] + buttonpos[] = [ + Animations.linear_interpolate( + anim_posfrac(dt), + button_endpoint_inactive[], button_endpoint_active[] + ), + ] framecolor[] = coloranim(dt) if dt >= t.toggleduration[] Observables.off(updatefunc[]) diff --git a/src/makielayout/defaultattributes.jl b/src/makielayout/defaultattributes.jl index 76c1c8420a3..8331c62c81c 100644 --- a/src/makielayout/defaultattributes.jl +++ b/src/makielayout/defaultattributes.jl @@ -1,5 +1,5 @@ function inherit(scene, attr::Symbol, default_value) - if haskey(scene.theme, attr) + return if haskey(scene.theme, attr) Observable(to_value(scene.theme[attr])) else inherit(scene.parent, attr, default_value) @@ -7,15 +7,15 @@ function inherit(scene, attr::Symbol, default_value) end function inherit(::Nothing, attr::Symbol, default_value) - default_value + return default_value end -inherit(scene, attr::NTuple{1, <: Symbol}, default_value) = inherit(scene, attr[begin], default_value) +inherit(scene, attr::NTuple{1, <:Symbol}, default_value) = inherit(scene, attr[begin], default_value) -function inherit(scene, attr::NTuple{N, <: Symbol}, default_value) where N +function inherit(scene, attr::NTuple{N, <:Symbol}, default_value) where {N} current_dict = scene.theme - for i in 1:(N-1) + for i in 1:(N - 1) if haskey(current_dict, attr[i]) current_dict = current_dict[attr[i]] else @@ -31,41 +31,41 @@ function inherit(scene, attr::NTuple{N, <: Symbol}, default_value) where N end function inherit(::Nothing, attr::NTuple{N, Symbol}, default_value::T) where {N, T} - default_value + return default_value end function generic_plot_attributes(::Type{LineAxis}) - Attributes( + return Attributes( endpoints = (Point2f(0, 0), Point2f(100, 0)), trimspine = false, - limits = (0f0, 100f0), + limits = (0.0f0, 100.0f0), flipped = false, flip_vertical_label = false, - ticksize = 6f0, - tickwidth = 1f0, + ticksize = 6.0f0, + tickwidth = 1.0f0, tickcolor = RGBf(0, 0, 0), - tickalign = 0f0, + tickalign = 0.0f0, ticks = Makie.automatic, tickformat = Makie.automatic, ticklabelalign = (:center, :top), ticksvisible = true, - ticklabelrotation = 0f0, - ticklabelsize = 20f0, + ticklabelrotation = 0.0f0, + ticklabelsize = 20.0f0, ticklabelcolor = RGBf(0, 0, 0), ticklabelsvisible = true, - spinewidth = 1f0, + spinewidth = 1.0f0, label = "label", - labelsize = 20f0, + labelsize = 20.0f0, labelcolor = RGBf(0, 0, 0), labelvisible = true, ticklabelspace = Makie.automatic, - ticklabelpad = 3f0, - labelpadding = 5f0, + ticklabelpad = 3.0f0, + labelpadding = 5.0f0, reversed = false, minorticksvisible = true, - minortickalign = 0f0, - minorticksize = 4f0, - minortickwidth = 1f0, + minortickalign = 0.0f0, + minorticksize = 4.0f0, + minortickwidth = 1.0f0, minortickcolor = :black, minorticks = Makie.automatic, scale = identity, @@ -74,11 +74,13 @@ end function attributenames(::Type{LegendEntry}) - (:label, :labelsize, :labelfont, :labelcolor, :labelhalign, :labelvalign, + return ( + :label, :labelsize, :labelfont, :labelcolor, :labelhalign, :labelvalign, :patchsize, :patchstrokecolor, :patchstrokewidth, :patchcolor, :linepoints, :linewidth, :linecolor, :linestyle, :linecolorrange, :linecolormap, :markerpoints, :markersize, :markerstrokewidth, :markercolor, :markerstrokecolor, :markercolorrange, :markercolormap, - :polypoints, :polystrokewidth, :polycolor, :polystrokecolor, :polycolorrange, :polycolormap) + :polypoints, :polystrokewidth, :polycolor, :polystrokecolor, :polycolorrange, :polycolormap, + ) end function extractattributes(attributes::Attributes, typ::Type) @@ -88,7 +90,7 @@ function extractattributes(attributes::Attributes, typ::Type) extracted[name] = attributes[name] end end - extracted + return extracted end function extractattributes(leg::Legend, typ::Type) @@ -98,5 +100,5 @@ function extractattributes(leg::Legend, typ::Type) extracted[name] = getproperty(leg, name) end end - extracted + return extracted end diff --git a/src/makielayout/geometrybasics_extension.jl b/src/makielayout/geometrybasics_extension.jl index acf870e3c42..24d88df3834 100644 --- a/src/makielayout/geometrybasics_extension.jl +++ b/src/makielayout/geometrybasics_extension.jl @@ -1,4 +1,3 @@ - left(rect::Rect2) = minimum(rect)[1] right(rect::Rect2) = maximum(rect)[1] bottom(rect::Rect2) = minimum(rect)[2] @@ -31,20 +30,20 @@ xlimits(r::Rect) = limits(r, 1) ylimits(r::Rect) = limits(r, 2) function enlarge(bbox::Rect2, l, r, b, t) - BBox(left(bbox) - l, right(bbox) + r, bottom(bbox) - b, top(bbox) + t) + return BBox(left(bbox) - l, right(bbox) + r, bottom(bbox) - b, top(bbox) + t) end function center(bbox::Rect2) - Point2((right(bbox) + left(bbox)) / 2, (top(bbox) + bottom(bbox)) / 2) + return Point2((right(bbox) + left(bbox)) / 2, (top(bbox) + bottom(bbox)) / 2) end """ Converts a point in fractions of rect dimensions into real coordinates. """ -function fractionpoint(bbox::Rect2, point::T) where T <: Point2 - T(left(bbox) + point[1] * width(bbox), bottom(bbox) + point[2] * height(bbox)) +function fractionpoint(bbox::Rect2, point::T) where {T <: Point2} + return T(left(bbox) + point[1] * width(bbox), bottom(bbox) + point[2] * height(bbox)) end function anglepoint(center::Point2, angle::Real, radius::Real) - Ref(center) .+ Ref(Point2(cos(angle), sin(angle))) .* radius + return Ref(center) .+ Ref(Point2(cos(angle), sin(angle))) .* radius end diff --git a/src/makielayout/helpers.jl b/src/makielayout/helpers.jl index 0b2c2e81212..16301e02ed6 100644 --- a/src/makielayout/helpers.jl +++ b/src/makielayout/helpers.jl @@ -7,11 +7,11 @@ function round_to_IRect2D(r::Rect{2}) newori = round.(Int, minimum(r)) othercorner = round.(Int, maximum(r)) newwidth = othercorner .- newori - Rect{2, Int}(newori, newwidth) + return Rect{2, Int}(newori, newwidth) end function sceneareanode!(finalbbox, limits, aspect) - return map(finalbbox, limits, aspect; ignore_equal_values=true) do bbox, limits, aspect + return map(finalbbox, limits, aspect; ignore_equal_values = true) do bbox, limits, aspect w = width(bbox) h = height(bbox) @@ -67,26 +67,26 @@ function roundedrectvertices(rect, cornerradius, cornersegments) htouching = height(rect) / 2 == cr cstr = if wtouching - anglepoint.(Ref(ictr), LinRange(0, pi/2, csegs), cr) + anglepoint.(Ref(ictr), LinRange(0, pi / 2, csegs), cr) else - anglepoint.(Ref(ictr), LinRange(0, pi/2, csegs)[1:end-1], cr) + anglepoint.(Ref(ictr), LinRange(0, pi / 2, csegs)[1:(end - 1)], cr) end cstl = if htouching - anglepoint.(Ref(ictl), LinRange(pi/2, pi, csegs), cr) + anglepoint.(Ref(ictl), LinRange(pi / 2, pi, csegs), cr) else - anglepoint.(Ref(ictl), LinRange(pi/2, pi, csegs)[1:end-1], cr) + anglepoint.(Ref(ictl), LinRange(pi / 2, pi, csegs)[1:(end - 1)], cr) end csbl = if wtouching - anglepoint.(Ref(icbl), LinRange(pi, 3pi/2, csegs), cr) + anglepoint.(Ref(icbl), LinRange(pi, 3pi / 2, csegs), cr) else - anglepoint.(Ref(icbl), LinRange(pi, 3pi/2, csegs)[1:end-1], cr) + anglepoint.(Ref(icbl), LinRange(pi, 3pi / 2, csegs)[1:(end - 1)], cr) end csbr = if htouching - anglepoint.(Ref(icbr), LinRange(3pi/2, 2pi, csegs), cr) + anglepoint.(Ref(icbr), LinRange(3pi / 2, 2pi, csegs), cr) else - anglepoint.(Ref(icbr), LinRange(3pi/2, 2pi, csegs)[1:end-1], cr) + anglepoint.(Ref(icbr), LinRange(3pi / 2, 2pi, csegs)[1:(end - 1)], cr) end - arr = [cstr; cstl; csbl; csbr] + return arr = [cstr; cstl; csbl; csbr] end """ @@ -97,7 +97,7 @@ Sets the autolimit margins to zero on all sides. function tightlimits!(la::Axis) la.xautolimitmargin = (0, 0) la.yautolimitmargin = (0, 0) - reset_limits!(la) + return reset_limits!(la) end """ @@ -115,35 +115,38 @@ function tightlimits!(la::Axis, sides::Union{Left, Right, Bottom, Top}...) for s in sides tightlimits!(la, s) end + return end function tightlimits!(la::Axis, ::Left) la.xautolimitmargin = Base.setindex(la.xautolimitmargin[], 0.0, 1) - autolimits!(la) + return autolimits!(la) end function tightlimits!(la::Axis, ::Right) la.xautolimitmargin = Base.setindex(la.xautolimitmargin[], 0.0, 2) - autolimits!(la) + return autolimits!(la) end function tightlimits!(la::Axis, ::Bottom) la.yautolimitmargin = Base.setindex(la.yautolimitmargin[], 0.0, 1) - autolimits!(la) + return autolimits!(la) end function tightlimits!(la::Axis, ::Top) la.yautolimitmargin = Base.setindex(la.yautolimitmargin[], 0.0, 2) - autolimits!(la) + return autolimits!(la) end function GridLayoutBase.GridLayout(scene::Scene, args...; kwargs...) - return GridLayout(args...; bbox=lift(Rect2f, viewport(scene)), kwargs...) + return GridLayout(args...; bbox = lift(Rect2f, viewport(scene)), kwargs...) end -function axislines!(scene, rect, spinewidth, topspinevisible, rightspinevisible, - leftspinevisible, bottomspinevisible, topspinecolor, leftspinecolor, - rightspinecolor, bottomspinecolor) +function axislines!( + scene, rect, spinewidth, topspinevisible, rightspinevisible, + leftspinevisible, bottomspinevisible, topspinecolor, leftspinecolor, + rightspinecolor, bottomspinecolor + ) bottomline = lift(scene, rect, spinewidth) do r, sw y = bottom(r) @@ -173,18 +176,28 @@ function axislines!(scene, rect, spinewidth, topspinevisible, rightspinevisible, [p1, p2] end - (lines!(scene, bottomline, linewidth = spinewidth, - visible = bottomspinevisible, color = bottomspinecolor), - lines!(scene, leftline, linewidth = spinewidth, - visible = leftspinevisible, color = leftspinecolor), - lines!(scene, rightline, linewidth = spinewidth, - visible = rightspinevisible, color = rightspinecolor), - lines!(scene, topline, linewidth = spinewidth, - visible = topspinevisible, color = topspinecolor)) + return ( + lines!( + scene, bottomline, linewidth = spinewidth, + visible = bottomspinevisible, color = bottomspinecolor + ), + lines!( + scene, leftline, linewidth = spinewidth, + visible = leftspinevisible, color = leftspinecolor + ), + lines!( + scene, rightline, linewidth = spinewidth, + visible = rightspinevisible, color = rightspinecolor + ), + lines!( + scene, topline, linewidth = spinewidth, + visible = topspinevisible, color = topspinecolor + ), + ) end -function interleave_vectors(vec1::Vector{T}, vec2::Vector{T}) where T +function interleave_vectors(vec1::Vector{T}, vec2::Vector{T}) where {T} n = length(vec1) @assert n == length(vec2) @@ -194,7 +207,7 @@ function interleave_vectors(vec1::Vector{T}, vec2::Vector{T}) where T vec[k + 1] = vec1[i] vec[k + 2] = vec2[i] end - vec + return vec end """ @@ -249,23 +262,37 @@ macro documented_attributes(exp) end # make a dictionary of :variable_name => docstring_expression - exp_docdict = Expr(:call, :Dict, - (Expr(:call, Symbol("=>"), QuoteNode(name), strexp) - for (name, _, strexp) in vars_and_exps)...) + exp_docdict = Expr( + :call, :Dict, + ( + Expr(:call, Symbol("=>"), QuoteNode(name), strexp) + for (name, _, strexp) in vars_and_exps + )... + ) # make a dictionary of :variable_name => docstring_expression - defaults_dict = Expr(:call, :Dict, - (Expr(:call, Symbol("=>"), QuoteNode(name), exp isa String ? "\"$exp\"" : string(exp)) - for (name, exp, _) in vars_and_exps)...) + defaults_dict = Expr( + :call, :Dict, + ( + Expr(:call, Symbol("=>"), QuoteNode(name), exp isa String ? "\"$exp\"" : string(exp)) + for (name, exp, _) in vars_and_exps + )... + ) # make an Attributes instance with of variable_name = variable_expression - exp_attrs = Expr(:call, :Attributes, - (Expr(:kw, name, exp) - for (name, exp, _) in vars_and_exps)...) + exp_attrs = Expr( + :call, :Attributes, + ( + Expr(:kw, name, exp) + for (name, exp, _) in vars_and_exps + )... + ) - esc(quote - ($exp_attrs, $exp_docdict, $defaults_dict) - end) + return esc( + quote + ($exp_attrs, $exp_docdict, $defaults_dict) + end + ) end """ @@ -278,7 +305,7 @@ function docvarstring(docdict, defaultdict) for (var, doc) in sort(collect(pairs(docdict))) print(buffer, "`$var`\\\nDefault: `$(defaultdict[var])`\\\n$doc\n\n") end - String(take!(buffer)) + return String(take!(buffer)) end @@ -287,7 +314,7 @@ function subtheme(scene, key::Symbol) if !(sub isa Attributes) error("Subtheme is not of type Attributes but is $sub") end - sub + return sub end @@ -318,14 +345,16 @@ ls = labelslider!(scene, "Voltage:", 0:10; format = x -> "\$(x)V") layout[1, 1] = ls.layout ``` """ -function labelslider!(scene, label, range; format = string, - sliderkw = Dict(), labelkw = Dict(), valuekw = Dict(), value_column_width = automatic, layoutkw...) +function labelslider!( + scene, label, range; format = string, + sliderkw = Dict(), labelkw = Dict(), valuekw = Dict(), value_column_width = automatic, layoutkw... + ) slider = Slider(scene; range = range, sliderkw...) label = Label(scene, label; labelkw...) valuelabel = Label(scene, lift(x -> apply_format(x, format), scene, slider.value); valuekw...) layout = hbox!(label, slider, valuelabel; layoutkw...) - Base.depwarn("labelslider! is deprecated and will be removed in the future. Use SliderGrid instead." , :labelslider!, force = true) + Base.depwarn("labelslider! is deprecated and will be removed in the future. Use SliderGrid instead.", :labelslider!, force = true) if value_column_width === automatic maxwidth = 0.0 @@ -344,7 +373,7 @@ function labelslider!(scene, label, range; format = string, colsize!(layout, 3, value_column_width) end - (slider = slider, label = label, valuelabel = valuelabel, layout = layout) + return (slider = slider, label = label, valuelabel = valuelabel, layout = layout) end @@ -377,16 +406,20 @@ ls = labelslidergrid!(scene, ["Voltage", "Ampere"], Ref(0:0.1:100); format = x - layout[1, 1] = ls.layout ``` """ -function labelslidergrid!(scene, labels, ranges; formats = [string], value_column_width = automatic, - sliderkw = Dict(), labelkw = Dict(), valuekw = Dict(), layoutkw...) +function labelslidergrid!( + scene, labels, ranges; formats = [string], value_column_width = automatic, + sliderkw = Dict(), labelkw = Dict(), valuekw = Dict(), layoutkw... + ) - Base.depwarn("labelslidergrid! is deprecated and will be removed in the future. Use SliderGrid instead." , :labelslidergrid!, force = true) + Base.depwarn("labelslidergrid! is deprecated and will be removed in the future. Use SliderGrid instead.", :labelslidergrid!, force = true) elements = broadcast(labels, ranges, formats) do label, range, format slider = Slider(scene; range = range, sliderkw...) label = Label(scene, label; halign = :left, labelkw...) - valuelabel = Label(scene, lift(x -> apply_format(x, format), scene, slider.value); halign=:right, - valuekw...) + valuelabel = Label( + scene, lift(x -> apply_format(x, format), scene, slider.value); halign = :right, + valuekw... + ) (; slider = slider, label = label, valuelabel = valuelabel) end @@ -420,15 +453,15 @@ function labelslidergrid!(scene, labels, ranges; formats = [string], value_colum colsize!(layout, 3, value_column_width) end - (sliders = sliders, labels = labels, valuelabels = valuelabels, layout = layout) + return (sliders = sliders, labels = labels, valuelabels = valuelabels, layout = layout) end function apply_format(value, format) - format(value) + return format(value) end function apply_format(value, formatstring::String) - Format.format(formatstring, value) + return Format.format(formatstring, value) end Makie.get_scene(ax::Axis) = ax.scene diff --git a/src/makielayout/interactions.jl b/src/makielayout/interactions.jl index 92ad8ca9ffa..2c8bd34925c 100644 --- a/src/makielayout/interactions.jl +++ b/src/makielayout/interactions.jl @@ -102,7 +102,6 @@ function process_interaction(f::Function, event, parent) end - ############################################################################ # Axis interactions # ############################################################################ @@ -152,7 +151,7 @@ function process_interaction(r::RectangleZoom, event::MouseEvent, ax::Axis) inv_transf = Makie.inverse_transform(transf) if isnothing(inv_transf) - @warn "Can't rectangle zoom without inverse transform" maxlog=1 + @warn "Can't rectangle zoom without inverse transform" maxlog = 1 # TODO, what can we do without inverse? return Consume(false) end @@ -180,7 +179,7 @@ function process_interaction(r::RectangleZoom, event::MouseEvent, ax::Axis) try r.callback(r.rectnode[]) catch e - @warn "error in rectangle zoom" exception=(e, Base.catch_backtrace()) + @warn "error in rectangle zoom" exception = (e, Base.catch_backtrace()) end r.active[] = false return Consume(true) @@ -253,7 +252,7 @@ function process_interaction(s::ScrollZoom, event::ScrollEvent, ax::Axis) mp_axscene = Vec4d((e.mouseposition[] .- pa.origin)..., 0, 1) # first to normal -1..1 space - mp_axfraction = (cam.pixel_space[] * mp_axscene)[Vec(1, 2)] .* + mp_axfraction = (cam.pixel_space[] * mp_axscene)[Vec(1, 2)] .* # now to 1..-1 if an axis is reversed to correct zoom point (-2 .* ((ax.xreversed[], ax.yreversed[])) .+ 1) .* # now to 0..1 @@ -316,10 +315,10 @@ function process_interaction(dp::DragPan, event::MouseEvent, ax) mp_axfraction, mp_axfraction_prev = map((mp_axscene, mp_axscene_prev)) do mp # first to normal -1..1 space (cam.pixel_space[] * mp)[Vec(1, 2)] .* - # now to 1..-1 if an axis is reversed to correct zoom point - (-2 .* ((ax.xreversed[], ax.yreversed[])) .+ 1) .* - # now to 0..1 - 0.5 .+ 0.5 + # now to 1..-1 if an axis is reversed to correct zoom point + (-2 .* ((ax.xreversed[], ax.yreversed[])) .+ 1) .* + # now to 0..1 + 0.5 .+ 0.5 end xscale = ax.xscale[] @@ -364,7 +363,7 @@ function process_interaction(dr::DragRotate, event::MouseEvent, ax3d::Axis3) dpx = event.px - event.prev_px ax3d.azimuth[] += -dpx[1] * 0.01 - ax3d.elevation[] = clamp(ax3d.elevation[] - dpx[2] * 0.01, -pi/2 + 0.001, pi/2 - 0.001) + ax3d.elevation[] = clamp(ax3d.elevation[] - dpx[2] * 0.01, -pi / 2 + 0.001, pi / 2 - 0.001) return Consume(true) end @@ -421,7 +420,7 @@ function process_interaction(interaction::DragPan, event::MouseEvent, ax::Axis3) p0 = ray_plane_intersection(plane, ray_from_projectionview(ax.scene, event.prev_px)) p1 = ray_plane_intersection(plane, ray_from_projectionview(ax.scene, event.px)) delta = p1 - p0 - translation = isfinite(delta) ? - inv(model[Vec(1,2,3), Vec(1,2,3)]) * delta : Point3d(0) + translation = isfinite(delta) ? - inv(model[Vec(1, 2, 3), Vec(1, 2, 3)]) * delta : Point3d(0) tlimits[] = Rect3f(mini + xyz_translate .* translation, ws) end @@ -454,7 +453,7 @@ function process_interaction(interaction::ScrollZoom, event::ScrollEvent, ax::Ax xyz_zoom = (x_zoom, y_zoom, z_zoom) end - zoom_mult = (1f0 - interaction.speed)^zoom + zoom_mult = (1.0f0 - interaction.speed)^zoom if ax.viewmode[] == :free @@ -518,7 +517,7 @@ function process_interaction(::LimitReset, event::MouseEvent, ax::Axis3) end if ispressed(ax.scene, Keyboard.left_shift) ax.axis_offset[] = Vec2d(0) - ax.elevation[] = pi/8 + ax.elevation[] = pi / 8 ax.azimuth[] = 1.275 * pi consumed = true end diff --git a/src/makielayout/lineaxis.jl b/src/makielayout/lineaxis.jl index 7a88b849ed6..c6df825ebe9 100644 --- a/src/makielayout/lineaxis.jl +++ b/src/makielayout/lineaxis.jl @@ -28,23 +28,24 @@ end function calculate_protrusion( closure_args, ticksvisible::Bool, label, labelvisible::Bool, labelpadding::Number, tickspace::Number, ticklabelsvisible::Bool, - actual_ticklabelspace::Number, ticklabelpad::Number, _...) + actual_ticklabelspace::Number, ticklabelpad::Number, _... + ) horizontal, labeltext, ticklabel_annotation_obs = closure_args label_is_empty::Bool = iswhitespace(label) real_labelsize::Float32 = if label_is_empty - 0f0 + 0.0f0 else boundingbox(labeltext, :data).widths[horizontal[] ? 2 : 1] end - labelspace::Float32 = (labelvisible && !label_is_empty) ? real_labelsize + labelpadding : 0f0 + labelspace::Float32 = (labelvisible && !label_is_empty) ? real_labelsize + labelpadding : 0.0f0 - _tickspace::Float32 = (ticksvisible && !isempty(ticklabel_annotation_obs[])) ? tickspace : 0f0 + _tickspace::Float32 = (ticksvisible && !isempty(ticklabel_annotation_obs[])) ? tickspace : 0.0f0 - ticklabelgap::Float32 = (ticklabelsvisible && actual_ticklabelspace > 0) ? actual_ticklabelspace + ticklabelpad : 0f0 + ticklabelgap::Float32 = (ticklabelsvisible && actual_ticklabelspace > 0) ? actual_ticklabelspace + ticklabelpad : 0.0f0 return _tickspace + ticklabelgap + labelspace end @@ -52,7 +53,8 @@ end function create_linepoints( pos_ext_hor, - flipped::Bool, spine_width::Number, trimspine::Union{Bool, Tuple{Bool, Bool}}, tickpositions::Vector{Point2f}, tickwidth::Number) + flipped::Bool, spine_width::Number, trimspine::Union{Bool, Tuple{Bool, Bool}}, tickpositions::Vector{Point2f}, tickwidth::Number + ) (position::Float32, extents::NTuple{2, Float32}, horizontal::Bool) = pos_ext_hor @@ -60,7 +62,7 @@ function create_linepoints( trimspine = (trimspine, trimspine) end - if trimspine == (false, false) || length(tickpositions) < 2 + return if trimspine == (false, false) || length(tickpositions) < 2 if horizontal y = position p1 = Point2f(extents[1] - 0.5spine_width, y) @@ -102,13 +104,13 @@ function calculate_real_ticklabel_align(al, horizontal, fl::Bool, rot::Number) else (fl ? :left : :right, :center) end - elseif rot ≈ pi/2 + elseif rot ≈ pi / 2 if hor (fl ? :left : :right, :center) else (:center, fl ? :top : :bottom) end - elseif rot ≈ -pi/2 + elseif rot ≈ -pi / 2 if hor (fl ? :right : :left, :center) else @@ -140,7 +142,8 @@ max_auto_ticklabel_spacing!(ax) = nothing function update_ticklabel_node( closure_args, ticklabel_annotation_obs::Observable, - labelgap::Number, flipped::Bool, tickpositions::Vector{Point2f}, tickstrings) + labelgap::Number, flipped::Bool, tickpositions::Vector{Point2f}, tickstrings + ) # tickspace is always updated before labelgap # tickpositions are always updated before tickstrings # so we don't need to lift those @@ -152,9 +155,9 @@ function update_ticklabel_node( ticklabelgap::Float32 = spinewidth[] + tickspace[] + ticklabelpad[] shift = if horizontal[] - Point2f(0f0, flipped ? ticklabelgap : -ticklabelgap) + Point2f(0.0f0, flipped ? ticklabelgap : -ticklabelgap) else - Point2f(flipped ? ticklabelgap : -ticklabelgap, 0f0) + Point2f(flipped ? ticklabelgap : -ticklabelgap, 0.0f0) end # re-use already allocated array result = ticklabel_annotation_obs[] @@ -175,14 +178,14 @@ function update_tick_obs(tick_obs, horizontal::Observable{Bool}, flipped::Observ sign::Int = flipped[] ? -1 : 1 if horizontal[] for tp in tickpositions - tstart = tp + sign * Point2f(0f0, tickalign * ticksize - 0.5f0 * spinewidth) - tend = tstart + sign * Point2f(0f0, -ticksize) + tstart = tp + sign * Point2f(0.0f0, tickalign * ticksize - 0.5f0 * spinewidth) + tend = tstart + sign * Point2f(0.0f0, -ticksize) push!(result, tstart, tend) end else for tp in tickpositions - tstart = tp + sign * Point2f(tickalign * ticksize - 0.5f0 * spinewidth, 0f0) - tend = tstart + sign * Point2f(-ticksize, 0f0) + tstart = tp + sign * Point2f(tickalign * ticksize - 0.5f0 * spinewidth, 0.0f0) + tend = tstart + sign * Point2f(-ticksize, 0.0f0) push!(result, tstart, tend) end end @@ -261,21 +264,23 @@ end function LineAxis(parent::Scene, attrs::Attributes) decorations = Dict{Symbol, Any}() - @extract attrs (endpoints, ticksize, tickwidth, + @extract attrs ( + endpoints, ticksize, tickwidth, tickcolor, tickalign, dim_convert, ticks, tickformat, ticklabelalign, ticklabelrotation, ticksvisible, ticklabelspace, ticklabelpad, labelpadding, ticklabelsize, ticklabelsvisible, spinewidth, spinecolor, label, labelsize, labelcolor, labelfont, ticklabelfont, ticklabelcolor, labelrotation, labelvisible, spinevisible, trimspine, flip_vertical_label, reversed, - minorticksvisible, minortickalign, minorticksize, minortickwidth, minortickcolor, minorticks) + minorticksvisible, minortickalign, minorticksize, minortickwidth, minortickcolor, minorticks, + ) - pos_extents_horizontal = lift(calculate_horizontal_extends, parent, endpoints; ignore_equal_values=true) + pos_extents_horizontal = lift(calculate_horizontal_extends, parent, endpoints; ignore_equal_values = true) horizontal = lift(x -> x[3], parent, pos_extents_horizontal) # Tuple constructor converts more than `convert(NTuple{2, Float32}, x)` but we still need the conversion to Float32 tuple: - limits = lift(x -> convert(NTuple{2, Float64}, Tuple(x)), parent, attrs.limits; ignore_equal_values=true) - flipped = lift(x -> convert(Bool, x), parent, attrs.flipped; ignore_equal_values=true) + limits = lift(x -> convert(NTuple{2, Float64}, Tuple(x)), parent, attrs.limits; ignore_equal_values = true) + flipped = lift(x -> convert(Bool, x), parent, attrs.flipped; ignore_equal_values = true) - ticksnode = Observable(Point2f[]; ignore_equal_values=true) + ticksnode = Observable(Point2f[]; ignore_equal_values = true) ticklines = linesegments!( parent, ticksnode, linewidth = tickwidth, color = tickcolor, linestyle = nothing, visible = ticksvisible, inspectable = false @@ -283,7 +288,7 @@ function LineAxis(parent::Scene, attrs::Attributes) decorations[:ticklines] = ticklines translate!(ticklines, 0, 0, 10) - minorticksnode = Observable(Point2f[]; ignore_equal_values=true) + minorticksnode = Observable(Point2f[]; ignore_equal_values = true) minorticklines = linesegments!( parent, minorticksnode, linewidth = minortickwidth, color = minortickcolor, linestyle = nothing, visible = minorticksvisible, inspectable = false @@ -291,22 +296,24 @@ function LineAxis(parent::Scene, attrs::Attributes) decorations[:minorticklines] = minorticklines translate!(minorticklines, 0, 0, 10) - realticklabelalign = Observable{Tuple{Symbol, Symbol}}((:none, :none); ignore_equal_values=true) + realticklabelalign = Observable{Tuple{Symbol, Symbol}}((:none, :none); ignore_equal_values = true) - map!(calculate_real_ticklabel_align, parent, realticklabelalign, ticklabelalign, horizontal, flipped, - ticklabelrotation) + map!( + calculate_real_ticklabel_align, parent, realticklabelalign, ticklabelalign, horizontal, flipped, + ticklabelrotation + ) - ticklabel_annotation_obs = Observable(Tuple{Any, Point2f}[]; ignore_equal_values=true) + ticklabel_annotation_obs = Observable(Tuple{Any, Point2f}[]; ignore_equal_values = true) ticklabels = nothing # this gets overwritten later to be used in the below - ticklabel_ideal_space = Observable(0f0; ignore_equal_values=true) + ticklabel_ideal_space = Observable(0.0f0; ignore_equal_values = true) map!(parent, ticklabel_ideal_space, ticklabel_annotation_obs, ticklabelalign, ticklabelrotation, ticklabelfont, ticklabelsvisible) do args... maxwidth = if pos_extents_horizontal[][3] - # height - ticklabelsvisible[] ? (ticklabels === nothing ? 0f0 : height(Rect2f(boundingbox(ticklabels, :data)))) : 0f0 - else - # width - ticklabelsvisible[] ? (ticklabels === nothing ? 0f0 : width(Rect2f(boundingbox(ticklabels, :data)))) : 0f0 + # height + ticklabelsvisible[] ? (ticklabels === nothing ? 0.0f0 : height(Rect2f(boundingbox(ticklabels, :data)))) : 0.0f0 + else + # width + ticklabelsvisible[] ? (ticklabels === nothing ? 0.0f0 : width(Rect2f(boundingbox(ticklabels, :data)))) : 0.0f0 end # in case there is no string in the annotations and the boundingbox comes back all NaN if !isfinite(maxwidth) @@ -315,7 +322,7 @@ function LineAxis(parent::Scene, attrs::Attributes) return maxwidth end - attrs[:actual_ticklabelspace] = 0f0 + attrs[:actual_ticklabelspace] = 0.0f0 actual_ticklabelspace = attrs[:actual_ticklabelspace] onany(parent, ticklabel_ideal_space, ticklabelspace) do idealspace, space @@ -332,25 +339,29 @@ function LineAxis(parent::Scene, attrs::Attributes) end end - tickspace = Observable(0f0; ignore_equal_values=true) + tickspace = Observable(0.0f0; ignore_equal_values = true) map!(parent, tickspace, ticksvisible, ticksize, tickalign) do ticksvisible, ticksize, tickalign - ticksvisible ? max(0f0, ticksize * (1f0 - tickalign)) : 0f0 + ticksvisible ? max(0.0f0, ticksize * (1.0f0 - tickalign)) : 0.0f0 end - labelgap = Observable(0f0; ignore_equal_values=true) - map!(parent, labelgap, spinewidth, tickspace, ticklabelsvisible, actual_ticklabelspace, - ticklabelpad, labelpadding) do spinewidth, tickspace, ticklabelsvisible, + labelgap = Observable(0.0f0; ignore_equal_values = true) + map!( + parent, labelgap, spinewidth, tickspace, ticklabelsvisible, actual_ticklabelspace, + ticklabelpad, labelpadding + ) do spinewidth, tickspace, ticklabelsvisible, actual_ticklabelspace, ticklabelpad, labelpadding return spinewidth + tickspace + - (ticklabelsvisible ? actual_ticklabelspace + ticklabelpad : 0f0) + + (ticklabelsvisible ? actual_ticklabelspace + ticklabelpad : 0.0f0) + labelpadding end - labelpos = Observable(Point2f(NaN); ignore_equal_values=true) + labelpos = Observable(Point2f(NaN); ignore_equal_values = true) - map!(parent, labelpos, pos_extents_horizontal, flipped, - labelgap) do (position, extents, horizontal), flipped, labelgap + map!( + parent, labelpos, pos_extents_horizontal, flipped, + labelgap + ) do (position, extents, horizontal), flipped, labelgap # fullgap = tickspace[] + labelgap middle = extents[1] + 0.5f0 * (extents[2] - extents[1]) @@ -360,32 +371,38 @@ function LineAxis(parent::Scene, attrs::Attributes) end # Initial values should be overwritten by map!. `ignore_equal_values` doesn't work right now without initial values - labelalign = Observable((:none, :none); ignore_equal_values=true) - map!(parent, labelalign, labelrotation, horizontal, flipped, - flip_vertical_label) do labelrotation, + labelalign = Observable((:none, :none); ignore_equal_values = true) + map!( + parent, labelalign, labelrotation, horizontal, flipped, + flip_vertical_label + ) do labelrotation, horizontal::Bool, flipped::Bool, flip_vertical_label::Bool return if labelrotation isa Automatic if horizontal (:center, flipped ? :bottom : :top) else - (:center, if flipped - flip_vertical_label ? :bottom : :top - else - flip_vertical_label ? :top : :bottom - end) + ( + :center, if flipped + flip_vertical_label ? :bottom : :top + else + flip_vertical_label ? :top : :bottom + end, + ) end else (:center, :center) end::NTuple{2, Symbol} end - labelrot = Observable(0f0; ignore_equal_values=true) - map!(parent, labelrot, labelrotation, horizontal, - flip_vertical_label) do labelrotation, + labelrot = Observable(0.0f0; ignore_equal_values = true) + map!( + parent, labelrot, labelrotation, horizontal, + flip_vertical_label + ) do labelrotation, horizontal::Bool, flip_vertical_label::Bool return if labelrotation isa Automatic if horizontal - 0f0 + 0.0f0 else (flip_vertical_label ? -0.5f0 : 0.5f0) * π end @@ -405,39 +422,43 @@ function LineAxis(parent::Scene, attrs::Attributes) # in order to prevent plot and axis overlap onany(parent, labelrotation, flipped, horizontal) do labelrotation, flipped, horizontal xs::Float32, ys::Float32 = if labelrotation isa Automatic - 0f0, 0f0 + 0.0f0, 0.0f0 else wx, wy = widths(boundingbox(labeltext, :data)) sign::Int = flipped ? 1 : -1 if horizontal - 0f0, Float32(sign * 0.5f0 * wy) + 0.0f0, Float32(sign * 0.5f0 * wy) else - Float32(sign * 0.5f0 * wx), 0f0 + Float32(sign * 0.5f0 * wx), 0.0f0 end end - translate!(labeltext, xs, ys, 0f0) + translate!(labeltext, xs, ys, 0.0f0) end decorations[:labeltext] = labeltext - tickvalues = Observable(Float64[]; ignore_equal_values=true) + tickvalues = Observable(Float64[]; ignore_equal_values = true) - tickvalues_labels_unfiltered = Observable{Tuple{Vector{Float64},Vector{Any}}}() + tickvalues_labels_unfiltered = Observable{Tuple{Vector{Float64}, Vector{Any}}}() obs = needs_tick_update_observable(dim_convert) # make sure we update tick calculation when needed - map!(parent, tickvalues_labels_unfiltered, pos_extents_horizontal, obs, limits, ticks, tickformat, - attrs.scale) do (position, extents, horizontal), _, limits, ticks, tickformat, scale + map!( + parent, tickvalues_labels_unfiltered, pos_extents_horizontal, obs, limits, ticks, tickformat, + attrs.scale + ) do (position, extents, horizontal), _, limits, ticks, tickformat, scale return get_ticks(dim_convert[], ticks, scale, tickformat, limits...) end - tickpositions = Observable(Point2f[]; ignore_equal_values=true) - tickstrings = Observable(Any[]; ignore_equal_values=true) + tickpositions = Observable(Point2f[]; ignore_equal_values = true) + tickstrings = Observable(Any[]; ignore_equal_values = true) - onany(update_tickpos_string, parent, + onany( + update_tickpos_string, parent, Observable((tickstrings, tickpositions, tickvalues, pos_extents_horizontal, limits)), - tickvalues_labels_unfiltered, reversed, attrs.scale) + tickvalues_labels_unfiltered, reversed, attrs.scale + ) - minortickvalues = Observable(Float64[]; ignore_equal_values=true) - minortickpositions = Observable(Point2f[]; ignore_equal_values=true) + minortickvalues = Observable(Float64[]; ignore_equal_values = true) + minortickpositions = Observable(Point2f[]; ignore_equal_values = true) onany(parent, tickvalues, minorticks) do tickvalues, minorticks minortickvalues[] = get_minor_tickvalues(minorticks, attrs.scale[], tickvalues, limits[]...) @@ -448,36 +469,48 @@ function LineAxis(parent::Scene, attrs::Attributes) update_minor_ticks(minortickpositions, limits, peh, mtv, attrs.scale[], reversed[]) end - onany(update_tick_obs, parent, + onany( + update_tick_obs, parent, Observable(minorticksnode), Observable(horizontal), Observable(flipped), - minortickpositions, minortickalign, minorticksize, spinewidth) + minortickpositions, minortickalign, minorticksize, spinewidth + ) - onany(update_ticklabel_node, parent, + onany( + update_ticklabel_node, parent, # we don't want to update on these, so we wrap them in an observable: Observable((horizontal, spinewidth, tickspace, ticklabelpad, tickvalues)), Observable(ticklabel_annotation_obs), - labelgap, flipped, tickpositions, tickstrings) + labelgap, flipped, tickpositions, tickstrings + ) - onany(update_tick_obs, parent, + onany( + update_tick_obs, parent, Observable(ticksnode), Observable(horizontal), Observable(flipped), - tickpositions, tickalign, ticksize, spinewidth) + tickpositions, tickalign, ticksize, spinewidth + ) - linepoints = lift(create_linepoints, parent, pos_extents_horizontal, flipped, spinewidth, trimspine, - tickpositions, tickwidth) + linepoints = lift( + create_linepoints, parent, pos_extents_horizontal, flipped, spinewidth, trimspine, + tickpositions, tickwidth + ) - decorations[:axisline] = linesegments!(parent, linepoints, linewidth = spinewidth, visible = spinevisible, - color = spinecolor, inspectable = false, linestyle = nothing) + decorations[:axisline] = linesegments!( + parent, linepoints, linewidth = spinewidth, visible = spinevisible, + color = spinecolor, inspectable = false, linestyle = nothing + ) translate!(decorations[:axisline], 0, 0, 20) - protrusion = Observable(0f0; ignore_equal_values=true) + protrusion = Observable(0.0f0; ignore_equal_values = true) - map!(calculate_protrusion, parent, protrusion, + map!( + calculate_protrusion, parent, protrusion, # we pass these as observables, to not trigger on them Observable((horizontal, labeltext, ticklabel_annotation_obs)), ticksvisible, label, labelvisible, labelpadding, tickspace, ticklabelsvisible, actual_ticklabelspace, ticklabelpad, # we don't need these as arguments to calculate it, but we need to pass it because it indirectly influences the protrusion - labelfont, labelalign, labelrot, labelsize, ticklabelfont, tickalign) + labelfont, labelalign, labelrot, labelsize, ticklabelfont, tickalign + ) # trigger whole pipeline once to fill tickpositions and tickstrings # etc to avoid empty ticks bug #69 @@ -495,7 +528,8 @@ function LineAxis(parent::Scene, attrs::Attributes) color = ticklabelcolor, visible = ticklabelsvisible, markerspace = :data, - inspectable = false) + inspectable = false + ) decorations[:ticklabels] = ticklabels @@ -524,11 +558,11 @@ function tight_ticklabel_spacing!(la::LineAxis) tls = la.elements[:ticklabels] maxwidth = if horizontal - # height - tls.visible[] ? height(Rect2f(boundingbox(tls, :data))) : 0f0 - else - # width - tls.visible[] ? width(Rect2f(boundingbox(tls, :data))) : 0f0 + # height + tls.visible[] ? height(Rect2f(boundingbox(tls, :data))) : 0.0f0 + else + # width + tls.visible[] ? width(Rect2f(boundingbox(tls, :data))) : 0.0f0 end la.attributes.ticklabelspace = maxwidth return Float64(maxwidth) @@ -545,6 +579,7 @@ function Base.delete!(la::LineAxis) delete!(d) end end + return end """ @@ -577,7 +612,7 @@ function get_ticks(ticks_and_labels::Tuple{Any, Any}, _, ::Automatic, vmin, vmax if n1 != n2 error("There are $n1 tick values in $(ticks_and_labels[1]) but $n2 tick labels in $(ticks_and_labels[2]).") end - ticks_and_labels + return ticks_and_labels end function get_ticks(tickfunction::Function, _, formatter, vmin, vmax) @@ -597,7 +632,7 @@ _logbase(::typeof(log)) = "e" function get_ticks(::Automatic, scale::LogFunctions, any_formatter, vmin, vmax) ticks = LogTicks(WilkinsonTicks(5, k_min = 3)) - get_ticks(ticks, scale, any_formatter, vmin, vmax) + return get_ticks(ticks, scale, any_formatter, vmin, vmax) end # log ticks just use the normal pipeline but with log'd limits, then transform the labels @@ -612,9 +647,9 @@ function get_ticks(l::LogTicks, scale::LogFunctions, ::Automatic, vmin, vmax) xs -> Showoff.showoff(xs, :plain), ticks_scaled ) - labels = rich.(_logbase(scale), superscript.(replace.(labels_scaled, "-" => MINUS_SIGN), offset = Vec2f(0.1f0, 0f0))) + labels = rich.(_logbase(scale), superscript.(replace.(labels_scaled, "-" => MINUS_SIGN), offset = Vec2f(0.1f0, 0.0f0))) - ticks, labels + return ticks, labels end logit_10(x) = Makie.logit(x) / log(10) @@ -644,7 +679,7 @@ get_tickvalues(tickvalues, vmin, vmax) = convert(Vector{Float64}, tickvalues) function get_tickvalues(l::LogTicks, scale, vmin, vmax) ticks_scaled = get_tickvalues(l.linear_ticks, scale(vmin), scale(vmax)) - Makie.inverse_transform(scale).(ticks_scaled) + return Makie.inverse_transform(scale).(ticks_scaled) end """ @@ -676,7 +711,7 @@ function get_ticks(m::MultiplesTicks, any_scale, ::Automatic, vmin, vmax) locs = multiples .* m.multiple labs = showoff_minus(multiples) .* m.suffix if m.strip_zero - labs = map( ((x, lab),) -> x != 0 ? lab : "0", zip(multiples, labs)) + labs = map(((x, lab),) -> x != 0 ? lab : "0", zip(multiples, labs)) end return locs, labs @@ -698,12 +733,12 @@ function get_ticks(m::AngularTicks, any_scale, ::Automatic, vmin, vmax) end end - ϵ = 1e-6 - vmin = ceil(Int, dvmin / ideal_step - ϵ) * ideal_step + ϵ = 1.0e-6 + vmin = ceil(Int, dvmin / ideal_step - ϵ) * ideal_step vmax = floor(Int, dvmax / ideal_step + ϵ) * ideal_step - multiples = collect(vmin:ideal_step:vmax+ϵ) + multiples = collect(vmin:ideal_step:(vmax + ϵ)) else - s = 360/2pi + s = 360 / 2pi multiples = Makie.get_tickvalues(LinearTicks(3), s * dvmin, s * dvmax) ./ s end @@ -717,7 +752,7 @@ end # Replaces hyphens in negative numbers with the unicode MINUS_SIGN function showoff_minus(x::AbstractVector) # TODO: don't use the `replace` workaround - replace.(Showoff.showoff(x), r"-(?=\d)" => MINUS_SIGN) + return replace.(Showoff.showoff(x), r"-(?=\d)" => MINUS_SIGN) end # identity or unsupported scales @@ -733,24 +768,24 @@ function get_minor_tickvalues(i::IntervalsBetween, scale, tickvalues, vmin, vmax prepend!(vals, v:-stepsize:vmin) end - for (lo, hi) in zip(@view(tickvalues[1:end-1]), @view(tickvalues[2:end])) + for (lo, hi) in zip(@view(tickvalues[1:(end - 1)]), @view(tickvalues[2:end])) interval = hi - lo stepsize = interval / n v = lo - for i in 1:n-1 + for i in 1:(n - 1) v += stepsize push!(vals, v) end end if i.mirror - lastinterval = tickvalues[end] - tickvalues[end-1] + lastinterval = tickvalues[end] - tickvalues[end - 1] stepsize = lastinterval / n v = tickvalues[end] + stepsize append!(vals, v:stepsize:vmax) end - vals + return vals end # for log scales, we need to step in log steps at the edges @@ -770,27 +805,27 @@ function get_minor_tickvalues(i::IntervalsBetween, scale::LogFunctions, tickvalu prepend!(vals, v:-stepsize:vmin) end - for (lo, hi) in zip(@view(tickvalues[1:end-1]), @view(tickvalues[2:end])) + for (lo, hi) in zip(@view(tickvalues[1:(end - 1)]), @view(tickvalues[2:end])) interval = hi - lo stepsize = interval / n v = lo - for i in 1:n-1 + for i in 1:(n - 1) v += stepsize push!(vals, v) end end if i.mirror - lastinterval_scaled = scale(tickvalues[end]) - scale(tickvalues[end-1]) + lastinterval_scaled = scale(tickvalues[end]) - scale(tickvalues[end - 1]) nexttick = invscale(scale(tickvalues[end]) + lastinterval_scaled) stepsize = (nexttick - tickvalues[end]) / n v = tickvalues[end] + stepsize append!(vals, v:stepsize:vmax) end - vals + return vals end function get_minor_tickvalues(v::AbstractVector{<:Real}, _, _, _, _) - Float32.(v) + return Float32.(v) end diff --git a/src/makielayout/mousestatemachine.jl b/src/makielayout/mousestatemachine.jl index c4a6e79a185..892df5a2ed5 100644 --- a/src/makielayout/mousestatemachine.jl +++ b/src/makielayout/mousestatemachine.jl @@ -76,7 +76,7 @@ function clear!(handle::MouseEventHandle) foreach(Observables.off, handle.observerfuncs) empty!(handle.observerfuncs) empty!(handle.obs.listeners) - nothing + return nothing end @@ -89,7 +89,7 @@ for eventtype in instances(MouseEventType) a MouseEvent with `event.type === $($eventtype)`. """ function $onfunctionname(f, mev::MouseEventHandle; priority = 0) - on(mev.obs, priority = priority) do event + return on(mev.obs, priority = priority) do event if event.type === $eventtype return f(event) end @@ -122,11 +122,11 @@ end """ function addmouseevents!(scene, elements...; priority = 1) is_mouse_over_relevant_area() = isempty(elements) ? Makie.is_mouseinside(scene) : mouseover(scene, elements...) - _addmouseevents!(scene, is_mouse_over_relevant_area, priority) + return _addmouseevents!(scene, is_mouse_over_relevant_area, priority) end -function addmouseevents!(scene, bbox::Observables.AbstractObservable{<: Rect2}; priority = 1) +function addmouseevents!(scene, bbox::Observables.AbstractObservable{<:Rect2}; priority = 1) is_mouse_over_relevant_area() = Makie.mouseposition_px(scene) in bbox[] - _addmouseevents!(scene, is_mouse_over_relevant_area, priority) + return _addmouseevents!(scene, is_mouse_over_relevant_area, priority) end @@ -208,7 +208,7 @@ function _addmouseevents!(scene, is_mouse_over_relevant_area, priority) last_click_was_double = Ref(false) # react to mouse position changes - mousepos_observerfunc = on(scene, events(scene).mouseposition; priority=priority) do mp + mousepos_observerfunc = on(scene, events(scene).mouseposition; priority = priority) do mp consumed = false t = time() data = mouseposition(scene) @@ -226,7 +226,8 @@ function _addmouseevents!(scene, is_mouse_over_relevant_area, priority) if drag_ongoing[] # continue the drag event = to_drag_event(mouse_downed_button[]) - x = setindex!(mouseevent, + x = setindex!( + mouseevent, MouseEvent(event, t, data, px, prev_t[], prev_data[], prev_px[]) ) consumed = consumed || x @@ -236,13 +237,15 @@ function _addmouseevents!(scene, is_mouse_over_relevant_area, priority) if mouse_downed_inside[] && norm(mouse_downed_at[] - px) >= drag_threshold drag_ongoing[] = true event = to_drag_start_event(mouse_downed_button[]) - x = setindex!(mouseevent, + x = setindex!( + mouseevent, MouseEvent(event, t, data, px, prev_t[], prev_data[], prev_px[]) ) consumed = consumed || x event = to_drag_event(mouse_downed_button[]) - x = setindex!(mouseevent, + x = setindex!( + mouseevent, MouseEvent(event, t, data, px, prev_t[], prev_data[], prev_px[]) ) consumed = consumed || x @@ -251,18 +254,21 @@ function _addmouseevents!(scene, is_mouse_over_relevant_area, priority) else if mouse_inside x = if mouse_was_inside[] - setindex!(mouseevent, + setindex!( + mouseevent, MouseEvent(MouseEventTypes.over, t, data, px, prev_t[], prev_data[], prev_px[]) ) else - setindex!(mouseevent, + setindex!( + mouseevent, MouseEvent(MouseEventTypes.enter, t, data, px, prev_t[], prev_data[], prev_px[]) ) end consumed = consumed || x else if mouse_was_inside[] - x = setindex!(mouseevent, + x = setindex!( + mouseevent, MouseEvent(MouseEventTypes.out, t, data, px, prev_t[], prev_data[], prev_px[]) ) consumed = consumed || x @@ -279,7 +285,7 @@ function _addmouseevents!(scene, is_mouse_over_relevant_area, priority) # react to mouse button changes - mousedrag_observerfunc = on(scene, events(scene).mousebutton, priority=priority) do event + mousedrag_observerfunc = on(scene, events(scene).mousebutton, priority = priority) do event consumed = false t = time() data = prev_data[] @@ -298,14 +304,16 @@ function _addmouseevents!(scene, is_mouse_over_relevant_area, priority) if mouse_was_inside[] mouse_downed_at[] = px event = to_down_event(mouse_downed_button[]) - x = setindex!(mouseevent, + x = setindex!( + mouseevent, MouseEvent(event, t, data, px, prev_t[], prev_data[], prev_px[]) ) consumed = consumed || x mouse_downed_inside[] = true else mouse_downed_inside[] = false - x = setindex!(mouseevent, + x = setindex!( + mouseevent, MouseEvent(MouseEventTypes.downoutside, t, data, px, prev_t[], prev_data[], prev_px[]) ) consumed = consumed || x @@ -324,7 +332,8 @@ function _addmouseevents!(scene, is_mouse_over_relevant_area, priority) if drag_ongoing[] event = to_drag_stop_event(mouse_downed_button[]) - x = setindex!(mouseevent, + x = setindex!( + mouseevent, MouseEvent(event, t, data, px, prev_t[], prev_data[], prev_px[]) ) consumed = consumed || x @@ -333,13 +342,15 @@ function _addmouseevents!(scene, is_mouse_over_relevant_area, priority) if mouse_was_inside[] # up after drag done over element event = to_up_event(mouse_downed_button[]) - x = setindex!(mouseevent, + x = setindex!( + mouseevent, MouseEvent(event, t, data, px, prev_t[], prev_data[], prev_px[]) ) consumed = consumed || x else # mouse could be not over elements after drag is over - x = setindex!(mouseevent, + x = setindex!( + mouseevent, MouseEvent(MouseEventTypes.out, t, data, px, prev_t[], prev_data[], prev_px[]) ) consumed = consumed || x @@ -355,14 +366,16 @@ function _addmouseevents!(scene, is_mouse_over_relevant_area, priority) mouse_downed_button[] == b_last_click[] event = to_doubleclick_event(mouse_downed_button[]) - x = setindex!(mouseevent, + x = setindex!( + mouseevent, MouseEvent(event, t, data, px, prev_t[], prev_data[], prev_px[]) ) consumed = consumed || x last_click_was_double[] = true else event = to_click_event(mouse_downed_button[]) - x = setindex!(mouseevent, + x = setindex!( + mouseevent, MouseEvent(event, t, data, px, prev_t[], prev_data[], prev_px[]) ) consumed = consumed || x @@ -374,8 +387,9 @@ function _addmouseevents!(scene, is_mouse_over_relevant_area, priority) mouse_downed_inside[] = false # up after click - event = to_up_event(mouse_downed_button[]) - x = setindex!(mouseevent, + event = to_up_event(mouse_downed_button[]) + x = setindex!( + mouseevent, MouseEvent(event, t, data, px, prev_t[], prev_data[], prev_px[]) ) consumed = consumed || x @@ -391,5 +405,5 @@ function _addmouseevents!(scene, is_mouse_over_relevant_area, priority) return Consume(consumed) end - MouseEventHandle(mouseevent, [mousepos_observerfunc, mousedrag_observerfunc]) + return MouseEventHandle(mouseevent, [mousepos_observerfunc, mousedrag_observerfunc]) end diff --git a/src/makielayout/roundedrect.jl b/src/makielayout/roundedrect.jl index 217e02e0d76..586db5c9e04 100644 --- a/src/makielayout/roundedrect.jl +++ b/src/makielayout/roundedrect.jl @@ -9,9 +9,11 @@ end function plot!(roundrect::RoundedRect) - @extract(roundrect, ( - rect, cornerradius, cornersegments, color, strokecolor - )) + @extract( + roundrect, ( + rect, cornerradius, cornersegments, color, strokecolor, + ) + ) heightattr = roundrect.height widthattr = roundrect.width @@ -27,13 +29,13 @@ function plot!(roundrect::RoundedRect) icbl = bottomleft(rect) .+ Point2(cr, cr) icbr = bottomright(rect) .+ Point2(-cr, cr) - cstr = anglepoint.(Ref(ictr), LinRange(0, pi/2, csegs), cr) - cstl = anglepoint.(Ref(ictl), LinRange(pi/2, pi, csegs), cr) - csbl = anglepoint.(Ref(icbl), LinRange(pi, 3pi/2, csegs), cr) - csbr = anglepoint.(Ref(icbr), LinRange(3pi/2, 2pi, csegs), cr) + cstr = anglepoint.(Ref(ictr), LinRange(0, pi / 2, csegs), cr) + cstl = anglepoint.(Ref(ictl), LinRange(pi / 2, pi, csegs), cr) + csbl = anglepoint.(Ref(icbl), LinRange(pi, 3pi / 2, csegs), cr) + csbr = anglepoint.(Ref(icbr), LinRange(3pi / 2, 2pi, csegs), cr) return [cstr; cstl; csbl; csbr] end - poly!(roundrect, roundedrectpoints, color = color, strokecolor = strokecolor) + return poly!(roundrect, roundedrectpoints, color = color, strokecolor = strokecolor) end diff --git a/src/makielayout/ticklocators/linear.jl b/src/makielayout/ticklocators/linear.jl index 75e6d02c133..b5cba934856 100644 --- a/src/makielayout/ticklocators/linear.jl +++ b/src/makielayout/ticklocators/linear.jl @@ -1,23 +1,23 @@ -function scale_range(vmin, vmax, n=1, threshold=100) +function scale_range(vmin, vmax, n = 1, threshold = 100) dv = abs(vmax - vmin) # > 0 as nonsingular is called before. meanv = (vmax + vmin) / 2 offset = if abs(meanv) / dv < threshold 0.0 else - copysign(10 ^ (log10(abs(meanv)) ÷ 1), meanv) + copysign(10^(log10(abs(meanv)) ÷ 1), meanv) end - scale = 10 ^ (log10(dv / n) ÷ 1) - scale, offset + scale = 10^(log10(dv / n) ÷ 1) + return scale, offset end function _staircase(steps) n = length(steps) result = Vector{Float64}(undef, 2n) - for i in 1:(n-1) + for i in 1:(n - 1) @inbounds result[i] = 0.1 * steps[i] end for i in 1:n - @inbounds result[i+(n-1)] = steps[i] + @inbounds result[i + (n - 1)] = steps[i] end result[end] = 10 * steps[2] return result @@ -33,25 +33,25 @@ struct EdgeInteger if step <= 0 error("Step must be positive") end - new(step, abs(offset)) + return new(step, abs(offset)) end end function closeto(e::EdgeInteger, ms, edge) tol = if e.offset > 0 digits = log10(e.offset / e.step) - tol = max(1e-10, 10 ^ (digits - 12)) + tol = max(1.0e-10, 10^(digits - 12)) min(0.4999, tol) else - 1e-10 + 1.0e-10 end - abs(ms - edge) < tol + return abs(ms - edge) < tol end function le(e::EdgeInteger, x) # 'Return the largest n: n*step <= x.' d, m = divrem(x, e.step) - if closeto(e, m / e.step, 1) + return if closeto(e, m / e.step, 1) d + 1 else d @@ -61,7 +61,7 @@ end function ge(e::EdgeInteger, x) # 'Return the smallest n: n*step >= x.' d, m = divrem(x, e.step) - if closeto(e, m / e.step, 0) + return if closeto(e, m / e.step, 0) d else d + 1 @@ -142,12 +142,12 @@ function locateticks(vmin, vmax, n_ideal::Int, _integer::Bool = false, _min_n_ti # 0.08000000001 instead of 0.08 # so here we round off the numbers to the required number of digits after the decimal point exponent = floor(Int, minimum(log10.(abs.(diff(vals))))) - round.(vals, digits = max(0, -exponent+1)) + return round.(vals, digits = max(0, -exponent + 1)) end function locateticks(vmin, vmax, width_px, ideal_tick_distance::Float32, _integer::Bool = false, _min_n_ticks::Int = 2) # how many ticks would ideally fit? n_ideal = round(Int, width_px / ideal_tick_distance) + 1 - locateticks(vmin, vmax, n_ideal, _integer, _min_n_ticks) + return locateticks(vmin, vmax, n_ideal, _integer, _min_n_ticks) end diff --git a/src/makielayout/ticklocators/wilkinson.jl b/src/makielayout/ticklocators/wilkinson.jl index 28d88e6e412..d56d31876c4 100644 --- a/src/makielayout/ticklocators/wilkinson.jl +++ b/src/makielayout/ticklocators/wilkinson.jl @@ -14,20 +14,22 @@ $(@doc PlotUtils.optimize_ticks) """ function WilkinsonTicks( - k_ideal::Int; - k_min = 2, k_max = 10, - Q = [(1.0, 1.0), (5.0, 0.9), (2.0, 0.7), (2.5, 0.5), (3.0, 0.2)], - granularity_weight = 1/4, - simplicity_weight = 1/6, - coverage_weight = 1/3, - niceness_weight = 1/4 -) + k_ideal::Int; + k_min = 2, k_max = 10, + Q = [(1.0, 1.0), (5.0, 0.9), (2.0, 0.7), (2.5, 0.5), (3.0, 0.2)], + granularity_weight = 1 / 4, + simplicity_weight = 1 / 6, + coverage_weight = 1 / 3, + niceness_weight = 1 / 4 + ) if !(0 < k_min <= k_ideal <= k_max) error("Invalid tick number specifications k_ideal $k_ideal, k_min $k_min, k_max $k_max") end - WilkinsonTicks(k_ideal, k_min, k_max, Q, granularity_weight, - simplicity_weight, coverage_weight, niceness_weight) + return WilkinsonTicks( + k_ideal, k_min, k_max, Q, granularity_weight, + simplicity_weight, coverage_weight, niceness_weight + ) end get_tickvalues(ticks::WilkinsonTicks, vmin, vmax) = get_tickvalues(ticks, Float64(vmin), Float64(vmax)) @@ -47,5 +49,5 @@ function get_tickvalues(ticks::WilkinsonTicks, vmin::Float64, vmax::Float64) niceness_weight = ticks.niceness_weight ) - ticklocations + return ticklocations end diff --git a/src/makielayout/types.jl b/src/makielayout/types.jl index 969b12fb4ae..32eb789e146 100644 --- a/src/makielayout/types.jl +++ b/src/makielayout/types.jl @@ -1,7 +1,6 @@ const Optional{T} = Union{Nothing, T} - struct AxisAspect aspect::Float32 end @@ -43,7 +42,7 @@ struct LinearTicks if n_ideal <= 0 error("Ideal number of ticks can't be smaller than 0, but is $n_ideal") end - new(n_ideal) + return new(n_ideal) end end @@ -100,7 +99,6 @@ struct AngularTicks end - # """ # LogitTicks{T}(linear_ticks::T) @@ -131,7 +129,7 @@ struct IntervalsBetween mirror::Bool function IntervalsBetween(n::Int, mirror::Bool) n < 2 && error("You can't have $n intervals (must be at least 2 which means 1 minor tick)") - new(n, mirror) + return new(n, mirror) end end IntervalsBetween(n) = IntervalsBetween(n, true) @@ -162,9 +160,11 @@ mutable struct RectangleZoom modifier::Any # e.g. Keyboard.left_alt, or some other button that needs to be pressed to start rectangle... Defaults to `true`, which means no modifier needed end -function RectangleZoom(callback::Function; restrict_x=false, restrict_y=false, modifier=true) - return RectangleZoom(callback, Observable(false), restrict_x, restrict_y, - nothing, nothing, Observable(Rect2d(0, 0, 1, 1)), modifier) +function RectangleZoom(callback::Function; restrict_x = false, restrict_y = false, modifier = true) + return RectangleZoom( + callback, Observable(false), restrict_x, restrict_y, + nothing, nothing, Observable(Rect2d(0, 0, 1, 1)), modifier + ) end struct ScrollZoom @@ -261,9 +261,9 @@ Axis(fig_or_scene; palette = nothing, kwargs...) "The font family of the title." titlefont = :bold "The title's font size." - titlesize::Float64 = @inherit(:fontsize, 16f0) + titlesize::Float64 = @inherit(:fontsize, 16.0f0) "The gap between axis and title." - titlegap::Float64 = 4f0 + titlegap::Float64 = 4.0f0 "Controls if the title is visible." titlevisible::Bool = true """ @@ -285,7 +285,7 @@ Axis(fig_or_scene; palette = nothing, kwargs...) "The font family of the subtitle." subtitlefont = :regular "The subtitle's font size." - subtitlesize::Float64 = @inherit(:fontsize, 16f0) + subtitlesize::Float64 = @inherit(:fontsize, 16.0f0) "The gap between subtitle and title." subtitlegap::Float64 = 0 "Controls if the subtitle is visible." @@ -303,17 +303,17 @@ Axis(fig_or_scene; palette = nothing, kwargs...) "The color of the ylabel." ylabelcolor::RGBAf = @inherit(:textcolor, :black) "The font size of the xlabel." - xlabelsize::Float64 = @inherit(:fontsize, 16f0) + xlabelsize::Float64 = @inherit(:fontsize, 16.0f0) "The font size of the ylabel." - ylabelsize::Float64 = @inherit(:fontsize, 16f0) + ylabelsize::Float64 = @inherit(:fontsize, 16.0f0) "Controls if the xlabel is visible." xlabelvisible::Bool = true "Controls if the ylabel is visible." ylabelvisible::Bool = true "The padding between the xlabel and the ticks or axis." - xlabelpadding::Float64 = 3f0 + xlabelpadding::Float64 = 3.0f0 "The padding between the ylabel and the ticks or axis." - ylabelpadding::Float64 = 5f0 # xlabels usually have some more visual padding because of ascenders, which are larger than the hadvance gaps of ylabels + ylabelpadding::Float64 = 5.0f0 # xlabels usually have some more visual padding because of ascenders, which are larger than the hadvance gaps of ylabels "The xlabel rotation in radians." xlabelrotation = Makie.automatic "The ylabel rotation in radians." @@ -327,9 +327,9 @@ Axis(fig_or_scene; palette = nothing, kwargs...) "The color of yticklabels." yticklabelcolor = @inherit(:textcolor, :black) "The font size of the xticklabels." - xticklabelsize::Float64 = @inherit(:fontsize, 16f0) + xticklabelsize::Float64 = @inherit(:fontsize, 16.0f0) "The font size of the yticklabels." - yticklabelsize::Float64 = @inherit(:fontsize, 16f0) + yticklabelsize::Float64 = @inherit(:fontsize, 16.0f0) "Controls if the xticklabels are visible." xticklabelsvisible::Bool = true "Controls if the yticklabels are visible." @@ -339,33 +339,33 @@ Axis(fig_or_scene; palette = nothing, kwargs...) "The space reserved for the yticklabels. Can be set to `Makie.automatic` to automatically determine the space needed, `:max_auto` to only ever grow to fit the current ticklabels, or a specific value." yticklabelspace::Union{Makie.Automatic, Symbol, Float64} = Makie.automatic "The space between xticks and xticklabels." - xticklabelpad::Float64 = 2f0 + xticklabelpad::Float64 = 2.0f0 "The space between yticks and yticklabels." - yticklabelpad::Float64 = 4f0 + yticklabelpad::Float64 = 4.0f0 "The counterclockwise rotation of the xticklabels in radians." - xticklabelrotation::Float64 = 0f0 + xticklabelrotation::Float64 = 0.0f0 "The counterclockwise rotation of the yticklabels in radians." - yticklabelrotation::Float64 = 0f0 + yticklabelrotation::Float64 = 0.0f0 "The horizontal and vertical alignment of the xticklabels." xticklabelalign::Union{Makie.Automatic, Tuple{Symbol, Symbol}} = Makie.automatic "The horizontal and vertical alignment of the yticklabels." yticklabelalign::Union{Makie.Automatic, Tuple{Symbol, Symbol}} = Makie.automatic "The size of the xtick marks." - xticksize::Float64 = 5f0 + xticksize::Float64 = 5.0f0 "The size of the ytick marks." - yticksize::Float64 = 5f0 + yticksize::Float64 = 5.0f0 "Controls if the xtick marks are visible." xticksvisible::Bool = true "Controls if the ytick marks are visible." yticksvisible::Bool = true "The alignment of the xtick marks relative to the axis spine (0 = out, 1 = in)." - xtickalign::Float64 = 0f0 + xtickalign::Float64 = 0.0f0 "The alignment of the ytick marks relative to the axis spine (0 = out, 1 = in)." - ytickalign::Float64 = 0f0 + ytickalign::Float64 = 0.0f0 "The width of the xtick marks." - xtickwidth::Float64 = 1f0 + xtickwidth::Float64 = 1.0f0 "The width of the ytick marks." - ytickwidth::Float64 = 1f0 + ytickwidth::Float64 = 1.0f0 "The color of the xtick marks." xtickcolor = RGBf(0, 0, 0) "The color of the ytick marks." @@ -387,15 +387,15 @@ Axis(fig_or_scene; palette = nothing, kwargs...) "Controls if rectangle zooming affects the y dimension." yrectzoom::Bool = true "The width of the axis spines." - spinewidth::Float64 = 1f0 + spinewidth::Float64 = 1.0f0 "Controls if the x grid lines are visible." xgridvisible::Bool = true "Controls if the y grid lines are visible." ygridvisible::Bool = true "The width of the x grid lines." - xgridwidth::Float64 = 1f0 + xgridwidth::Float64 = 1.0f0 "The width of the y grid lines." - ygridwidth::Float64 = 1f0 + ygridwidth::Float64 = 1.0f0 "The color of the x grid lines." xgridcolor = RGBAf(0, 0, 0, 0.12) "The color of the y grid lines." @@ -409,9 +409,9 @@ Axis(fig_or_scene; palette = nothing, kwargs...) "Controls if the y minor grid lines are visible." yminorgridvisible::Bool = false "The width of the x minor grid lines." - xminorgridwidth::Float64 = 1f0 + xminorgridwidth::Float64 = 1.0f0 "The width of the y minor grid lines." - yminorgridwidth::Float64 = 1f0 + yminorgridwidth::Float64 = 1.0f0 "The color of the x minor grid lines." xminorgridcolor = RGBAf(0, 0, 0, 0.05) "The color of the y minor grid lines." @@ -559,12 +559,12 @@ Axis(fig_or_scene; palette = nothing, kwargs...) If `true`, limits the x axis spine's extent to the outermost major tick marks. Can also be set to a `Tuple{Bool,Bool}` to control each side separately. """ - xtrimspine::Union{Bool, Tuple{Bool,Bool}} = false + xtrimspine::Union{Bool, Tuple{Bool, Bool}} = false """ If `true`, limits the y axis spine's extent to the outermost major tick marks. Can also be set to a `Tuple{Bool,Bool}` to control each side separately. """ - ytrimspine::Union{Bool, Tuple{Bool,Bool}} = false + ytrimspine::Union{Bool, Tuple{Bool, Bool}} = false "The background color of the axis." backgroundcolor::RGBAf = :white "Controls if the ylabel's rotation is flipped." @@ -610,11 +610,11 @@ Axis(fig_or_scene; palette = nothing, kwargs...) "Controls if minor ticks on the x axis are visible" xminorticksvisible::Bool = false "The alignment of x minor ticks on the axis spine" - xminortickalign::Float64 = 0f0 + xminortickalign::Float64 = 0.0f0 "The tick size of x minor ticks" - xminorticksize::Float64 = 3f0 + xminorticksize::Float64 = 3.0f0 "The tick width of x minor ticks" - xminortickwidth::Float64 = 1f0 + xminortickwidth::Float64 = 1.0f0 "The tick color of x minor ticks" xminortickcolor = :black """ @@ -629,11 +629,11 @@ Axis(fig_or_scene; palette = nothing, kwargs...) "Controls if minor ticks on the y axis are visible" yminorticksvisible::Bool = false "The alignment of y minor ticks on the axis spine" - yminortickalign::Float64 = 0f0 + yminortickalign::Float64 = 0.0f0 "The tick size of y minor ticks" - yminorticksize::Float64 = 3f0 + yminorticksize::Float64 = 3.0f0 "The tick width of y minor ticks" - yminortickwidth::Float64 = 1f0 + yminortickwidth::Float64 = 1.0f0 "The tick color of y minor ticks" yminortickcolor = :black """ @@ -689,16 +689,20 @@ end function RectangleZoom(f::Function, ax::Axis; kw...) r = RectangleZoom(f; kw...) rect_scene = Scene(ax.scene) - selection_vertices = lift(_selection_vertices, rect_scene, Observable(ax.scene), ax.finallimits, - r.rectnode) + selection_vertices = lift( + _selection_vertices, rect_scene, Observable(ax.scene), ax.finallimits, + r.rectnode + ) # manually specify correct faces for a rectangle with a rectangle hole inside faces = [1 2 5; 5 2 6; 2 3 6; 6 3 7; 3 4 7; 7 4 8; 4 1 8; 8 1 5] # plot to blockscene, so ax.scene stays exclusive for user plots # That's also why we need to pass `ax.scene` to _selection_vertices, so it can project to that space - mesh = mesh!(rect_scene, - selection_vertices, faces, space=:pixel, + mesh = mesh!( + rect_scene, + selection_vertices, faces, space = :pixel, color = (:black, 0.2), shading = NoShading, - inspectable = false, transparency=true, overdraw=true, visible=r.active) + inspectable = false, transparency = true, overdraw = true, visible = r.active + ) # translate forward so selection mesh and frame are never behind data translate!(mesh, 0, 0, 1000) return r @@ -739,23 +743,23 @@ Colorbar(fig_or_scene, contourf::Makie.Contourf; kwargs...) "The label font family." labelfont = :regular "The label font size." - labelsize = @inherit(:fontsize, 16f0) + labelsize = @inherit(:fontsize, 16.0f0) "Controls if the label is visible." labelvisible = true "The gap between the label and the ticks." - labelpadding = 5f0 + labelpadding = 5.0f0 "The label rotation in radians." labelrotation = Makie.automatic "The font family of the tick labels." ticklabelfont = :regular "The font size of the tick labels." - ticklabelsize = @inherit(:fontsize, 16f0) + ticklabelsize = @inherit(:fontsize, 16.0f0) "Controls if the tick labels are visible." ticklabelsvisible = true "The color of the tick labels." ticklabelcolor = @inherit(:textcolor, :black) "The size of the tick marks." - ticksize = 5f0 + ticksize = 5.0f0 "Controls if the tick marks are visible." ticksvisible = true "The ticks." @@ -765,19 +769,19 @@ Colorbar(fig_or_scene, contourf::Makie.Contourf; kwargs...) "The space reserved for the tick labels. Can be set to `Makie.automatic` to automatically determine the space needed, `:max_auto` to only ever grow to fit the current ticklabels, or a specific value." ticklabelspace = Makie.automatic "The gap between tick labels and tick marks." - ticklabelpad = 3f0 + ticklabelpad = 3.0f0 "The alignment of the tick marks relative to the axis spine (0 = out, 1 = in)." - tickalign = 0f0 + tickalign = 0.0f0 "The line width of the tick marks." - tickwidth = 1f0 + tickwidth = 1.0f0 "The color of the tick marks." tickcolor = RGBf(0, 0, 0) "The horizontal and vertical alignment of the tick labels." ticklabelalign = Makie.automatic "The rotation of the ticklabels." - ticklabelrotation = 0f0 + ticklabelrotation = 0.0f0 "The line width of the spines." - spinewidth = 1f0 + spinewidth = 1.0f0 "Controls if the top spine is visible." topspinevisible = true "Controls if the right spine is visible." @@ -835,11 +839,11 @@ Colorbar(fig_or_scene, contourf::Makie.Contourf; kwargs...) "Controls if minor ticks are visible" minorticksvisible = false "The alignment of minor ticks on the axis spine" - minortickalign = 0f0 + minortickalign = 0.0f0 "The tick size of minor ticks" - minorticksize = 3f0 + minorticksize = 3.0f0 "The tick width of minor ticks" - minortickwidth = 1f0 + minortickwidth = 1.0f0 "The tick color of minor ticks" minortickcolor = :black "The tick locator for the minor ticks" @@ -858,7 +862,7 @@ end "The color of the text." color::RGBAf = @inherit(:textcolor, :black) "The font size of the text." - fontsize::Float32 = @inherit(:fontsize, 16f0) + fontsize::Float32 = @inherit(:fontsize, 16.0f0) "The font family of the text." font = :regular "The justification of the text (:left, :right, :center)." @@ -870,9 +874,9 @@ end "The horizontal alignment of the text in its suggested boundingbox" halign = :center "The counterclockwise rotation of the text in radians." - rotation::Float32 = 0f0 + rotation::Float32 = 0.0f0 "The extra space added to the sides of the text boundingbox." - padding = (0f0, 0f0, 0f0, 0f0) + padding = (0.0f0, 0.0f0, 0.0f0, 0.0f0) "The height setting of the text." height = Auto() "The width setting of the text." @@ -899,7 +903,7 @@ end "The horizontal alignment of the rectangle in its suggested boundingbox" halign = :center "The line width of the rectangle's border." - strokewidth = 1f0 + strokewidth = 1.0f0 "Controls if the border of the rectangle is visible." strokevisible = true "The color of the border." @@ -1066,9 +1070,9 @@ end "The vertical alignment of the button in its suggested boundingbox" valign = :center "The extra space added to the sides of the button label's boundingbox." - padding = (8f0, 8f0, 8f0, 8f0) + padding = (8.0f0, 8.0f0, 8.0f0, 8.0f0) "The font size of the button label." - fontsize = @inherit(:fontsize, 16f0) + fontsize = @inherit(:fontsize, 16.0f0) "The text of the button label." label = "Button" "The font family of the button label." @@ -1086,7 +1090,7 @@ end "The number of poly segments used for each rounded corner." cornersegments = 10 "The line width of the button border." - strokewidth = 2f0 + strokewidth = 2.0f0 "The color of the button border." strokecolor = :transparent "The color of the button." @@ -1108,11 +1112,13 @@ end end end -const CHECKMARK_BEZIER = scale(BezierPath( - "M 81.449219,-0.08203125A 7.5,7.5 0 0 0 76.628906,3.0332031L 38.113281,58.792969 18.806641,34.650391A 7.5,7.5 0 0 0 8.265625,33.478516 7.5,7.5 0 0 0 7.0917969,44.019531L 32.697266,76.037109A 7.50075,7.50075 0 0 0 44.724609,75.615234L 88.970703,11.558594A 7.5,7.5 0 0 0 87.0625,1.125 7.5,7.5 0 0 0 81.449219,-0.08203125Z", - fit = true, - flipy = true, -), 0.85) +const CHECKMARK_BEZIER = scale( + BezierPath( + "M 81.449219,-0.08203125A 7.5,7.5 0 0 0 76.628906,3.0332031L 38.113281,58.792969 18.806641,34.650391A 7.5,7.5 0 0 0 8.265625,33.478516 7.5,7.5 0 0 0 7.0917969,44.019531L 32.697266,76.037109A 7.50075,7.50075 0 0 0 44.724609,75.615234L 88.970703,11.558594A 7.5,7.5 0 0 0 87.0625,1.125 7.5,7.5 0 0 0 81.449219,-0.08203125Z", + fit = true, + flipy = true, + ), 0.85 +) @Block Checkbox begin @attributes begin @@ -1307,7 +1313,7 @@ end "The list of options selectable in the menu. This can be any iterable of a mixture of strings and containers with one string and one other value. If an entry is just a string, that string is both label and selection. If an entry is a container with one string and one other value, the string is the label and the other value is the selection." options = ["no options"] "Font size of the cell texts" - fontsize = @inherit(:fontsize, 16f0) + fontsize = @inherit(:fontsize, 16.0f0) "Padding of entry texts" textpadding = (8, 10, 8, 8) "Color of entry texts" @@ -1365,7 +1371,7 @@ const EntryGroup = Tuple{Any, Vector{LegendEntry}} "The font family of the legend group titles." titlefont = :bold "The font size of the legend group titles." - titlesize = @inherit(:fontsize, 16f0) + titlesize = @inherit(:fontsize, 16.0f0) "The horizontal alignment of the legend group titles." titlehalign = :center "The vertical alignment of the legend group titles." @@ -1377,7 +1383,7 @@ const EntryGroup = Tuple{Any, Vector{LegendEntry}} "The group title positions relative to their groups. Can be `:top` or `:left`." titleposition = :top "The font size of the entry labels." - labelsize = @inherit(:fontsize, 16f0) + labelsize = @inherit(:fontsize, 16.0f0) "The font family of the entry labels." labelfont = :regular "The color of the entry labels." @@ -1389,9 +1395,9 @@ const EntryGroup = Tuple{Any, Vector{LegendEntry}} "The vertical alignment of the entry labels." labelvalign = :center "The additional space between the legend content and the border." - padding = (6f0, 6f0, 6f0, 6f0) + padding = (6.0f0, 6.0f0, 6.0f0, 6.0f0) "The additional space between the legend and its suggested boundingbox." - margin = (0f0, 0f0, 0f0, 0f0) + margin = (0.0f0, 0.0f0, 0.0f0, 0.0f0) "The background color of the legend. DEPRECATED - use `backgroundcolor` instead." bgcolor = nothing "The background color of the legend." @@ -1399,15 +1405,15 @@ const EntryGroup = Tuple{Any, Vector{LegendEntry}} "The color of the legend border." framecolor = :black "The line width of the legend border." - framewidth = 1f0 + framewidth = 1.0f0 "Controls if the legend border is visible." framevisible = true "The size of the rectangles containing the legend markers. It can help to increase the width if line patterns are not clearly visible with the default size." - patchsize = (20f0, 20f0) + patchsize = (20.0f0, 20.0f0) "The color of the border of the patches containing the legend markers." patchstrokecolor = :transparent "The line width of the border of the patches containing the legend markers." - patchstrokewidth = 1f0 + patchstrokewidth = 1.0f0 "The color of the patches containing the legend markers." patchcolor = :transparent "The default entry label." @@ -1539,7 +1545,7 @@ end "Controls if the textbox is defocused when a string is submitted." defocus_on_submit = true "Text size." - fontsize = @inherit(:fontsize, 16f0) + fontsize = @inherit(:fontsize, 16.0f0) "Text color." textcolor = @inherit(:textcolor, :black) "Text color for the placeholder." @@ -1555,7 +1561,7 @@ end "Color of the box when hovered." boxcolor_hover = :transparent "Color of the box border." - bordercolor = RGBf(0.80, 0.80, 0.80) + bordercolor = RGBf(0.8, 0.8, 0.8) "Color of the box border when hovered." bordercolor_hover = COLOR_ACCENT_DIMMED[] "Color of the box border when focused." @@ -1563,7 +1569,7 @@ end "Color of the box border when focused and invalid." bordercolor_focused_invalid = RGBf(1, 0, 0) "Width of the box border." - borderwidth = 1f0 + borderwidth = 1.0f0 "Padding of the text against the box." textpadding = (8, 8, 8, 8) "If the textbox is focused and receives text input." @@ -1618,7 +1624,7 @@ end "The alignment of the scene in its suggested bounding box." alignmode = Inside() "The elevation (up / down) angle of the camera. Possible values are between -pi/2 (looking from the bottom up) and +pi/2 (looking from the top down)." - elevation = pi/8 + elevation = pi / 8 """ The azimuth (left / right) angle of the camera. @@ -1632,9 +1638,9 @@ end be avoided because it makes interpreting the data correctly harder. It can be of use, however, if aesthetics are more important than neutral presentation. """ - perspectiveness = 0f0 + perspectiveness = 0.0f0 "Sets the minimum value for `near`. Increasing this value will make objects close to the camera clip earlier. Reducing this value too much results in depth values becoming inaccurate. Must be > 0." - near = 1e-3 + near = 1.0e-3 """ Controls the lengths of the three axes relative to each other. @@ -1644,7 +1650,7 @@ end where a cube in data space looks like a cube and not a cuboid. - `:equal` which is a shorthand for `(1, 1, 1)` """ - aspect = (1.0, 1.0, 2/3) # :data :equal + aspect = (1.0, 1.0, 2 / 3) # :data :equal """ The view mode affects the final projection of the axis by fitting the axis cuboid into the available space in different ways. @@ -1698,11 +1704,11 @@ end "Controls if the z ticks are visible" zticksvisible = true "The x label size" - xlabelsize = @inherit(:fontsize, 16f0) + xlabelsize = @inherit(:fontsize, 16.0f0) "The y label size" - ylabelsize = @inherit(:fontsize, 16f0) + ylabelsize = @inherit(:fontsize, 16.0f0) "The z label size" - zlabelsize = @inherit(:fontsize, 16f0) + zlabelsize = @inherit(:fontsize, 16.0f0) "The x label font" xlabelfont = :regular "The y label font" @@ -1734,11 +1740,11 @@ end "The z ticklabel color" zticklabelcolor = @inherit(:textcolor, :black) "The x ticklabel size" - xticklabelsize = @inherit(:fontsize, 16f0) + xticklabelsize = @inherit(:fontsize, 16.0f0) "The y ticklabel size" - yticklabelsize = @inherit(:fontsize, 16f0) + yticklabelsize = @inherit(:fontsize, 16.0f0) "The z ticklabel size" - zticklabelsize = @inherit(:fontsize, 16f0) + zticklabelsize = @inherit(:fontsize, 16.0f0) "The x ticklabel pad" xticklabelpad = 5 "The y ticklabel pad" @@ -1798,7 +1804,7 @@ end "The color of y spine 3 opposite of the ticks" yspinecolor_3 = :black "The color of z spine 3 opposite of the ticks" - zspinecolor_3 = :black + zspinecolor_3 = :black "Controls if the 4. Spines are created to close the outline box" front_spines = false "The color of x spine 4" @@ -1856,9 +1862,9 @@ end "The font family of the title." titlefont = :bold "The title's font size." - titlesize = @inherit(:fontsize, 16f0) + titlesize = @inherit(:fontsize, 16.0f0) "The gap between axis and title." - titlegap = 4f0 + titlegap = 4.0f0 "Controls if the title is visible." titlevisible = true "The horizontal alignment of the title." @@ -1989,7 +1995,7 @@ end "The direction of rotation. Can be -1 (clockwise) or 1 (counterclockwise)." direction::Int = 1 "The angular offset for (1, 0) in the PolarAxis. This rotates the axis." - theta_0::Float32 = 0f0 + theta_0::Float32 = 0.0f0 "Sets the radius at the origin of the PolarAxis such that `r_out = r_in - radius_at_origin`. Can be set to `automatic` to match rmin. Note that this will affect the shape of plotted objects." radius_at_origin = automatic "Controls the argument order of the Polar transform. If `theta_as_x = true` it is (θ, r), otherwise (r, θ)." @@ -2031,7 +2037,7 @@ end "The color of the outline of `r` ticks. By default this uses the background color." rticklabelstrokecolor = automatic "Padding of the `r` ticks label." - rticklabelpad::Float32 = 4f0 + rticklabelpad::Float32 = 4.0f0 "Controls if the `r` ticks are visible." rticklabelsvisible::Bool = inherit(scene, (:Axis, :xticklabelsvisible), true) "The angle in radians along which the `r` ticks are printed." @@ -2051,7 +2057,7 @@ end # Theta ticks "The specifier for the angular (`theta`) ticks, similar to `yticks` for a normal Axis." - thetaticks = AngularTicks(180/pi, "°") # ((0:45:315) .* pi/180, ["$(x)°" for x in 0:45:315]) + thetaticks = AngularTicks(180 / pi, "°") # ((0:45:315) .* pi/180, ["$(x)°" for x in 0:45:315]) "The specifier for the minor `theta` ticks." thetaminorticks = IntervalsBetween(2) "The formatter for the `theta` ticks." @@ -2063,7 +2069,7 @@ end "The color of the `theta` tick labels." thetaticklabelcolor = inherit(scene, (:Axis, :yticklabelcolor), inherit(scene, :textcolor, :black)) "Padding of the `theta` ticks label." - thetaticklabelpad::Float32 = 4f0 + thetaticklabelpad::Float32 = 4.0f0 "The width of the outline of `theta` ticks. Setting this to 0 will remove the outline." thetaticklabelstrokewidth::Float32 = 0.0 "The color of the outline of `theta` ticks. By default this uses the background color." diff --git a/src/patterns.jl b/src/patterns.jl index 5bf56409bc5..f28104ef689 100644 --- a/src/patterns.jl +++ b/src/patterns.jl @@ -10,11 +10,11 @@ abstract type AbstractPattern{T} <: AbstractArray{T, 2} end # for print_array because we defined it as <: Base.AbstractArray function Base.show(io::IO, p::AbstractPattern) - print(io, typeof(p)) + return print(io, typeof(p)) end function Base.show(io::IO, ::MIME"text/plain", p::AbstractPattern) - print(io, typeof(p)) + return print(io, typeof(p)) end struct ImagePattern <: AbstractPattern{RGBAf} @@ -32,10 +32,10 @@ Creates an `ImagePattern` from an `image` (a matrix of colors) or a `mask` texture it. If a `mask` is passed, one can specify to colors between which colors are interpolated. """ -Pattern(img::Array{<: Colorant, 2}) = ImagePattern(img) +Pattern(img::Array{<:Colorant, 2}) = ImagePattern(img) -function Pattern(mask::Matrix{<: Real}; color1=RGBAf(0,0,0,1), color2=RGBAf(1,1,1,0)) - img = map(x -> to_color(color1) * x + to_color(color2) * (1-x), mask) +function Pattern(mask::Matrix{<:Real}; color1 = RGBAf(0, 0, 0, 1), color2 = RGBAf(1, 1, 1, 0)) + img = map(x -> to_color(color1) * x + to_color(color2) * (1 - x), mask) return ImagePattern(img) end @@ -69,9 +69,9 @@ Multiple `direction`s, `width`s and `shift`s can also be given to create more complex patterns, e.g. a cross-hatching pattern. """ function LinePattern(; - direction = Vec2f(1), width = 2f0, tilesize = (10,10), - shift = map(w -> Vec2f(0.5 - 0.5(w%2)), width), - linecolor = RGBAf(0,0,0,1), background_color = RGBAf(1,1,1,0) + direction = Vec2f(1), width = 2.0f0, tilesize = (10, 10), + shift = map(w -> Vec2f(0.5 - 0.5(w % 2)), width), + linecolor = RGBAf(0, 0, 0, 1), background_color = RGBAf(1, 1, 1, 0) ) N = 1 direction isa Vector{<:Vec2} && (N = length(direction)) @@ -96,18 +96,18 @@ to the keyword arguments for `LinePattern`. """ Pattern(style::String; kwargs...) = Pattern(style[1]; kwargs...) function Pattern(style::Char = '/'; kwargs...) - if style == '/' - LinePattern(direction=Vec2f(1); kwargs...) + return if style == '/' + LinePattern(direction = Vec2f(1); kwargs...) elseif style == '\\' - LinePattern(direction=Vec2f(1, -1); kwargs...) + LinePattern(direction = Vec2f(1, -1); kwargs...) elseif style == '-' - LinePattern(direction=Vec2f(1, 0); kwargs...) + LinePattern(direction = Vec2f(1, 0); kwargs...) elseif style == '|' - LinePattern(direction=Vec2f(0, 1); kwargs...) + LinePattern(direction = Vec2f(0, 1); kwargs...) elseif style == 'x' - LinePattern(direction=[Vec2f(1), Vec2f(1, -1)]; kwargs...) + LinePattern(direction = [Vec2f(1), Vec2f(1, -1)]; kwargs...) elseif style == '+' - LinePattern(direction=[Vec2f(1, 0), Vec2f(0, 1)]; kwargs...) + LinePattern(direction = [Vec2f(1, 0), Vec2f(0, 1)]; kwargs...) else LinePattern(; kwargs...) end @@ -123,31 +123,31 @@ function to_image(p::LinePattern) # m = dx / dy; x = m * (y-1) + 1 m = dir[1] / dir[2] for y in 1:tilesize[2] - cx = m * (y-shift[2]) + shift[1] - r = floor(Int64, cx-0.5width):ceil(Int64, cx+0.5width) - for x in r[2:end-1] + cx = m * (y - shift[2]) + shift[1] + r = floor(Int64, cx - 0.5width):ceil(Int64, cx + 0.5width) + for x in r[2:(end - 1)] mask[mod1(x, tilesize[1]), y] = 1.0 end - mask[mod1(r[1], tilesize[1]), y] = 1 - abs(cx-0.5width - r[1]) - mask[mod1(r[end], tilesize[1]), y] = 1 - abs(cx+0.5width - r[end]) + mask[mod1(r[1], tilesize[1]), y] = 1 - abs(cx - 0.5width - r[1]) + mask[mod1(r[end], tilesize[1]), y] = 1 - abs(cx + 0.5width - r[end]) end else # m = dy / dx; y = m * (x-1) + 1 m = dir[2] / dir[1] for x in 1:tilesize[1] - cy = m * (x-shift[1]) + shift[2] - r = floor(Int64, cy-0.5width):ceil(Int64, cy+0.5width) - for y in r[2:end-1] + cy = m * (x - shift[1]) + shift[2] + r = floor(Int64, cy - 0.5width):ceil(Int64, cy + 0.5width) + for y in r[2:(end - 1)] mask[x, mod1(y, tilesize[2])] = 1.0 end - mask[x, mod1(r[1], tilesize[2])] = 1 - abs(cy-0.5width - r[1]) - mask[x, mod1(r[end], tilesize[2])] = 1 - abs(cy+0.5width - r[end]) + mask[x, mod1(r[1], tilesize[2])] = 1 - abs(cy - 0.5width - r[1]) + mask[x, mod1(r[end], tilesize[2])] = 1 - abs(cy + 0.5width - r[end]) end end full_mask .+= mask end return map(full_mask) do x - return convert(RGBAf, p.colors[1] * clamp(x, 0, 1) + p.colors[2] * (1-clamp(x, 0, 1))) + return convert(RGBAf, p.colors[1] * clamp(x, 0, 1) + p.colors[2] * (1 - clamp(x, 0, 1))) end end diff --git a/src/precompiles.jl b/src/precompiles.jl index c76599dafe5..3290f2379ed 100644 --- a/src/precompiles.jl +++ b/src/precompiles.jl @@ -1,58 +1,66 @@ -using PrecompileTools - -macro compile(block) - return quote - let - $(esc(block)) - return nothing - end - end -end - -precompile(Makie.initialize_block!, (Axis,)) -precompile(_get_glyphcollection_and_linesegments, - (LaTeXStrings.LaTeXString, Int64, Float32, - FreeTypeAbstraction.FTFont, Attributes, - Tuple{Symbol,Symbol}, Quaternion{Float64}, - MakieCore.Automatic, Float64, - ColorTypes.RGBA{Float32}, ColorTypes.RGBA{Float32}, - Int64, Int64, Vec{2,Float32})) - -precompile(Makie.apply_alignment_and_justification!, (Vector{Vector{Makie.GlyphInfo}}, MakieCore.Automatic, - Tuple{Symbol,Symbol})) - -precompile(MakieCore.convert_arguments, (Type{Scatter}, UnitRange{Int64})) -precompile(Makie.assemble_colors, (UnitRange{Int64}, Any, Any)) -let - @compile_workload begin - icon() - logo() - f = Figure() - ax = Axis(f[1, 1]) - Makie.initialize_block!(ax) - base_path = normpath(joinpath(dirname(pathof(Makie)), "..", "precompile")) - shared_precompile = joinpath(base_path, "shared-precompile.jl") - include(shared_precompile) - empty!(FONT_CACHE) - empty!(DEFAULT_FONT) - empty!(ALTERNATIVE_FONTS) - Makie.CURRENT_FIGURE[] = nothing - end - nothing -end - -for T in (DragPan, RectangleZoom, LimitReset) - precompile(process_interaction, (T, MouseEvent, Axis)) -end -precompile(process_axis_event, (Axis, MouseEvent)) -precompile(process_interaction, (ScrollZoom, ScrollEvent, Axis)) -precompile(el32convert, (Vector{Int64},)) -precompile(translate, (MoveTo, Vec2{Float64})) -precompile(scale, (MoveTo, Vec{2,Float32})) -precompile(append!, (Vector{FreeType.FT_Vector_}, Vector{FreeType.FT_Vector_})) -precompile(convert_command, (MoveTo,)) -precompile(plot!, (MakieCore.Text{Tuple{Vector{Point{2, Float32}}}},)) -precompile(Vec2{Float64}, (Tuple{Int64,Int64},)) -precompile(MakieCore._create_plot, (typeof(scatter), Dict{Symbol,Any}, UnitRange{Int64})) -precompile(BezierPath, (String,)) -precompile(BezierPath, (String, Bool, Nothing, Bool, Bool, Bool)) +using PrecompileTools + +macro compile(block) + return quote + let + $(esc(block)) + return nothing + end + end +end + +precompile(Makie.initialize_block!, (Axis,)) +precompile( + _get_glyphcollection_and_linesegments, + ( + LaTeXStrings.LaTeXString, Int64, Float32, + FreeTypeAbstraction.FTFont, Attributes, + Tuple{Symbol, Symbol}, Quaternion{Float64}, + MakieCore.Automatic, Float64, + ColorTypes.RGBA{Float32}, ColorTypes.RGBA{Float32}, + Int64, Int64, Vec{2, Float32}, + ) +) + +precompile( + Makie.apply_alignment_and_justification!, ( + Vector{Vector{Makie.GlyphInfo}}, MakieCore.Automatic, + Tuple{Symbol, Symbol}, + ) +) + +precompile(MakieCore.convert_arguments, (Type{Scatter}, UnitRange{Int64})) +precompile(Makie.assemble_colors, (UnitRange{Int64}, Any, Any)) +let + @compile_workload begin + icon() + logo() + f = Figure() + ax = Axis(f[1, 1]) + Makie.initialize_block!(ax) + base_path = normpath(joinpath(dirname(pathof(Makie)), "..", "precompile")) + shared_precompile = joinpath(base_path, "shared-precompile.jl") + include(shared_precompile) + empty!(FONT_CACHE) + empty!(DEFAULT_FONT) + empty!(ALTERNATIVE_FONTS) + Makie.CURRENT_FIGURE[] = nothing + end + nothing +end + +for T in (DragPan, RectangleZoom, LimitReset) + precompile(process_interaction, (T, MouseEvent, Axis)) +end +precompile(process_axis_event, (Axis, MouseEvent)) +precompile(process_interaction, (ScrollZoom, ScrollEvent, Axis)) +precompile(el32convert, (Vector{Int64},)) +precompile(translate, (MoveTo, Vec2{Float64})) +precompile(scale, (MoveTo, Vec{2, Float32})) +precompile(append!, (Vector{FreeType.FT_Vector_}, Vector{FreeType.FT_Vector_})) +precompile(convert_command, (MoveTo,)) +precompile(plot!, (MakieCore.Text{Tuple{Vector{Point{2, Float32}}}},)) +precompile(Vec2{Float64}, (Tuple{Int64, Int64},)) +precompile(MakieCore._create_plot, (typeof(scatter), Dict{Symbol, Any}, UnitRange{Int64})) +precompile(BezierPath, (String,)) +precompile(BezierPath, (String, Bool, Nothing, Bool, Bool, Bool)) diff --git a/src/recording.jl b/src/recording.jl index db4f705f399..7a0925b7bfa 100644 --- a/src/recording.jl +++ b/src/recording.jl @@ -1,4 +1,3 @@ - """ Stepper(scene, path; format = :jpg) @@ -26,21 +25,21 @@ mutable struct RamStepper format::Symbol end -function Stepper(figlike::FigureLike; backend=current_backend(), format=:png, visible=false, connect=false, screen_kw...) - config = Dict{Symbol,Any}(screen_kw) +function Stepper(figlike::FigureLike; backend = current_backend(), format = :png, visible = false, connect = false, screen_kw...) + config = Dict{Symbol, Any}(screen_kw) get!(config, :visible, visible) get!(config, :start_renderloop, false) screen = getscreen(backend, get_scene(figlike), config, JuliaNative) - display(screen, figlike; connect=connect) + display(screen, figlike; connect = connect) return RamStepper(figlike, screen, Matrix{RGBf}[], format) end -function Stepper(figlike::FigureLike, path::String, step::Int; format=:png, backend=current_backend(), visible=false, connect=false, screen_kw...) - config = Dict{Symbol,Any}(screen_kw) +function Stepper(figlike::FigureLike, path::String, step::Int; format = :png, backend = current_backend(), visible = false, connect = false, screen_kw...) + config = Dict{Symbol, Any}(screen_kw) get!(config, :visible, visible) get!(config, :start_renderloop, false) screen = getscreen(backend, get_scene(figlike), config, JuliaNative) - display(screen, figlike; connect=connect) + display(screen, figlike; connect = connect) return FolderStepper(figlike, screen, path, format, step) end @@ -76,6 +75,7 @@ function FileIO.save(dir::String, s::RamStepper) for (i, img) in enumerate(s.images) FileIO.save(joinpath(dir, "step-$i.$(s.format)"), img) end + return end """ @@ -145,14 +145,14 @@ end """ function record(func, figlike::FigureLike, path::AbstractString; kw_args...) format = lstrip(splitext(path)[2], '.') - io = Record(func, figlike; format=format, visible=true, kw_args...) - save(path, io) + io = Record(func, figlike; format = format, visible = true, kw_args...) + return save(path, io) end function record(func, figlike::FigureLike, path::AbstractString, iter; kw_args...) format = lstrip(splitext(path)[2], '.') - io = Record(func, figlike, iter; format=format, kw_args...) - save(path, io) + io = Record(func, figlike, iter; format = format, kw_args...) + return save(path, io) end @@ -172,7 +172,7 @@ function Record(func, figlike, iter; kw_args...) for i in iter func(i) recordframe!(io) - @debug "Recording" progress=i/length(iter) + @debug "Recording" progress = i / length(iter) yield() end return io @@ -184,7 +184,7 @@ function Base.show(io::IO, ::MIME"text/html", vs::VideoStream) error("Expected Screen to hold a reference to a Scene but got $(repr(scene))") end w, h = size(scene) - mktempdir() do dir + return mktempdir() do dir path = save(joinpath(dir, "video.mp4"), vs) #