MarcusCalidus / marcuscalidus-svg-panel

Grafana panel for displaying metric sensitive SVG images using the snap svg library
MIT License
62 stars 28 forks source link

Getting SVG for panel from external URL #30

Open yuyutime opened 5 years ago

yuyutime commented 5 years ago

This is both a question and/or feature suggestion:

It would be nice to add an option to load source of main SVG object on panel init from external URL instead of just copy-paste/edit it in SVG tab. This loaded svg can either replace original(default) svg object <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 1000 1000"></svg> in panel or be embedded into it.

Form entry for external svg URL can be added to editor_builder.html and minor changes needed in module.html. URL string can be either static or support dashboard template variables for maximum flexibility.

Now the only way to avoid copy/paste to SVG tab is using something like this in onInit() or onHandleMetric() handlers:

$('svg.svg-object').load("http://example.com/path/to/external.svg");

Is it correct? Are there better alternatives?


PS: Also it would be great to be able to add some custom html markup inside panel's TD cell with svg - for buttons, text, links, etc (similar to grafana's standard text panel).

MarcusCalidus commented 5 years ago

Thank you for your good suggestion. The thing with external ressources is that most browsers do not support linking external SVGs the SVG style. As I am informed only Firefox can do something like:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet href="style.css" type="text/css"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"    width="1000" height="1000">
    <use xlink:href="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/Steps.svg#board" />
</svg>

Chrome will tell you Unsafe attempt to load URL <URL> from frame with URL <URL>. Domains, protocols and ports must match.

The options remaining are the one you mentioned or doing it the Snap way via Snap.load(). I would prefer the Snap.load() option since it gives the developer all flexibility on how many SVGs to load and where to place them, extracting something from them (sprites) etc.

http://snapsvg.io/docs/#Snap.load

example in onInit

var s = Snap(svgnode);
Snap.load("https://kenoleon.github.io/Front-End-Web-Dev-UI-UX/assets/images/simplePoly.svg", 
          (data) => {
            geom = data.select("#mrCube");
            s.append( data );
            geom.attr({ stroke: "cornflowerblue",
            fill: "khaki"});
          });

As for your PS. I am not quite sure what you mean. Could you please draw a little mockup how you think this would look?

yuyutime commented 5 years ago

By custom markup I mean that in module.html instead of simple its good to have some custom html. In onInit or onHandleMetrics events handlers can be hooked to buttons and links, option can control animation/layers visibility in svg or whatever. Example mockup picture and pseudo-code for it:

mockup

MarcusCalidus commented 5 years ago

This is something you can actually already do. To insert a HTML button for example insert the following code into your SVG:

    <foreignObject x="20" y="0" width="150" height="200">
        <button class="btn btn-inverse gf-form-btn" onClick="alert('yay')">Click me</button>
    </foreignObject>
yuyutime commented 5 years ago

Thanks. foreignObject will do the trick.

A little drawback I see in it is that extra markup has to be embedded into every SVG or inserted dynamically by JS code. Scenario I had in mind was to have dashboard template variable for many svg urls (or a list of them in panel options) and one common(shared) wrapper markup in panel. Possible use-cases are drilldown from overvue svg to detailed one, cycle through a list of svgs, etc.

MarcusCalidus commented 5 years ago

you are right. If you want to change something in like let's say 20 panels. there is awful lot of work. I will keep this issue open. At the moment I don't have the resources to look into it. Maybe someone has time and energy?