DataInspector + bonito

How can I get an interactive html that show the label of scatter using DataInspector ? @sdanisch


## interactive plot works
function makie_plot_2()
fig=Figure()
ax=Axis(fig[1,1],title = "test")
scatter!(ax,rand(10),rand(10),inspector_label =(self,a,b) -> "point $a")
DataInspector(current_axis())
fig
end
makie_plot_2()

#####
using Bonito
app = App() do
    PCard(p) = Card(p, padding="0px", margin="0px")
    return Grid(
        PCard(makie_plot_2());
        columns="repeat(auto-fit, minmax(300px, 1fr))", justify_items="center")
end

export_static("test.html", app)

Thanks !

You need the javascript based tooltips for an offline export:

They’re sadly more of a prototype, but quite a bit can be done with them.

1 Like

Exactly what I needed !

By the way is it possible to keep some kind of zoom interactivity because I have 2 scatter points really close and it could be hard to click on one of them to get the tooltips ?

Hm not easily…
Although, it’s not that difficult to implement a simple on scroll event, which modifies the camera matrix of the axis scene directly in Javascript:

function attach_js_zoom(scene)
    return js"""
        // I need to improve the $(scene) operation, to do the below:
        function get_scene() {
            return new Promise(resolve => (function check() {
                $(scene).then(scene => scene ? resolve(scene) : setTimeout(check, 50));
            })());
        }
        get_scene().then(scene => {
            const camera = scene.wgl_camera;
            const view_uniform = camera.view; // Three.js Uniform
            const factor = 1.1; // Zoom sensitivity
            window.addEventListener("wheel", event => {
                event.preventDefault();
                const zoom = event.deltaY < 0 ? factor : 1 / factor;
                // Clone the current view matrix to avoid mutating the original reference
                const new_view = view_uniform.value.clone();
                new_view.elements[0] *= zoom;
                new_view.elements[5] *= zoom;
                new_view.elements[10] *= zoom;

                view_uniform.value = new_view; // Assign the new matrix
                camera.calculate_matrices()
            }, { passive: false });
        });
    """
end

begin 
    app = App() do session 
        f, ax, pl = scatter(1:4)
        evaljs(session, attach_js_zoom(ax.scene))
        evaljs(session, attach_js_zoom(ax.blockscene))
        DOM.div(f)
    end
    Bonito.export_static("test-cam.html", app)
end

Note, that this zooms the whole thing, since it’s kind of difficult to update the gridlines and ticks accordingly.
It would not be impossible, though, by updating the plot objects in JS directly.

Anyways, the above needs quite a bit more work, since it doesn’t consider the mouseposition as the center of zooming - and you likely want panning as well :wink:
If you have a bit of time to dabble in this, I’m happy to help! I’ve been wanting to have this for quite some time, but never found the time to get serious about it, but I’d have some time to help you along.