One option would be to calculate the data distance covered by some pixel width by listening to ax.finallimits
and ax.scene.px_area
. Then you can calculate the line and text position in pixel space for the axis scene, and update accordingly. This only works when there’s no axis scale applied.
using DelimitedFiles
volcano = readdlm(Makie.assetpath("volcano.csv"), ',', Float64)
f = Figure()
ax = Axis(f[1, 1])
co = contourf!(volcano, levels = 10, colormap = :Blues)
relpoints = Observable(Point2f[(0, 0), (1, 1)])
label = Observable("label")
width_px = Observable(50.0)
offset_px = Observable(20.0)
linesegments!(ax, relpoints, space = :pixel, color = :black, linewidth = 5)
text!(ax, @lift(($relpoints[1] + $relpoints[2]) * 0.5), space = :pixel, align = (:center, :bottom), text = label, offset = (0, 5))
onany(ax.finallimits, ax.scene.px_area, width_px, offset_px) do lims, pxa, width_px, offset_px
xmin, xmax = extrema(lims)[1]
br = Makie.bottomright(pxa) - pxa.origin
width_data = width_px / widths(pxa)[1] * widths(lims)[1]
label[] = "$(round(width_data, sigdigits = 3)) km"
relpoints[] = [
br + Point2f(-width_px - offset_px, offset_px),
br + Point2f(-offset_px, offset_px),
]
end
notify(ax.finallimits)
f