Git Product home page Git Product logo

gapitio / gapit-htmlgraphics-panel Goto Github PK

View Code? Open in Web Editor NEW
61.0 5.0 8.0 17.38 MB

Grafana panel for displaying metric sensitive HTML or SVG graphics.

Home Page: https://gapit-htmlgraphics-panel.gapit.io/

License: MIT License

JavaScript 9.96% TypeScript 59.96% SCSS 0.68% CSS 1.97% MDX 25.44% Dockerfile 1.60% Shell 0.39%
grafana graphics html svg panel grafana-panel html-graphics svg-graphics

gapit-htmlgraphics-panel's Introduction

gapit-htmlgraphics-panel's People

Contributors

dependabot[bot] avatar flesa avatar zuperzee avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

gapit-htmlgraphics-panel's Issues

Collapsible code editors in panel options

What would you like to be added:

The code editors in the panel options should be collapsible.

Why is this needed:

  • Many times I have to edit the html and the onInit. In this case I have to scroll many times over the onRender block.
  • If I want to scroll over the code blocks, I have to move my mouse outside of the code blocks to not scroll in the code.

HTML Graphics plugin - configuration screen locked in “loading”

What happened: I'm using the HTML graphics plugin, at first the component enables the encoding option normally, after a few accesses the configuration screen is locked in "loading".

What you expected to happen: I expected the components to render correctly and the code option to be enabled.

How to reproduce it (as minimally and precisely as possible): When entering the panel and entering the HTML graphical plugin configuration screen, the code inputs are not rendered and are "loading" infinitely.

Anything else we need to know?: I already cleared the page cache and the problem persisted.

Environment:

  • Grafana version: Grafana v8.0.3 (cae5c5e46b)
  • Plugin (gapit-htmlgraphics-panel) version: 1.3.3
  • Data source type & version: InfluxDB 2.0
  • OS Grafana is installed on: CentOS Linux 8 / podman version 3.0.2-dev
  • User OS & Browser: Chrome
  • Grafana plugins: gapit-htmlgraphics-panel @ 1.3.3 , grafana-clock-panel @ 1.1.3
  • Others:
    image

Dynamic data makes the data object in onRender also dynamic (kinda).

What happened:

Creating a setInterval in onRender and logging the value shows an updated value if the panel is refreshed with new data.

Image below shows logs from 3 refreshes.
image

  1. section the correct value is 50.75233615317692
  2. section the correct value is 86.88475047267275
  3. section the correct value is 52.55294827227271

But the 1. section has the data value as 52.55294827227271

What you expected to happen:

The data object shouldn't be dynamic in onRender.

How to reproduce it (as minimally and precisely as possible):

Panel options

{
    "calcsMutation": "standard",
    "reduceOptions": {
        "calcs": [
            "lastNotNull",
            "last",
            "first",
            "firstNotNull",
            "min",
            "max",
            "mean",
            "sum",
            "count",
            "range",
            "delta",
            "step",
            "diff",
            "logmin",
            "allIsZero",
            "allIsNull",
            "diffperc"
        ]
    },
    "add100Percentage": true,
    "centerAlignContent": true,
    "overflow": "visible",
    "SVGBaseFix": true,
    "codeData": "{\n  \"text\": \"Random text\"\n}",
    "rootCSS": "",
    "css": "",
    "html": "",
    "renderOnMount": true,
    "onRender": "console.log(\"RELOAD\");\n\nconst calcs = data.series[0].fields[1].state.calcs\n\nconst interval = setInterval(() => {\n  console.log(\"---\");\n  console.log(\"Data value\", data.series[0].fields[1].state.calcs.last);\n  console.log(\"Correct value\", calcs.last);\n}, 1000);\n\nhtmlNode.onpanelwillunmount = () => {\n  clearInterval(interval);\n}\n",
    "dynamicData": true,
    "dynamicHtmlGraphics": false,
    "dynamicFieldDisplayValues": false,
    "dynamicProps": false,
    "panelupdateOnMount": true,
    "onInitOnResize": false,
    "onInit": ""
}

Refresh a few times.
Open the console.

Anything else we need to know?:

Environment:

  • Grafana version: v8.3.3
  • Plugin (gapit-htmlgraphics-panel) version: v2.0.0
  • Data source type & version:
  • OS Grafana is installed on:
  • User OS & Browser:
  • Grafana plugins:
  • Others:

The default onRender code causes error if it can't find the metric value

What happened:

The default onRender code causes error if it can't find the metric value

What you expected to happen:

The onRender code should check if the metric exists before retrieving the value.

How to reproduce it (as minimally and precisely as possible):

Make a panel
Remove the metric ("Remove query")

Anything else we need to know?:

Environment:

  • Grafana version: v8.2.2
  • Plugin (gapit-htmlgraphics-panel) version: v1.4.0
  • Data source type & version:
  • OS Grafana is installed on:
  • User OS & Browser:
  • Grafana plugins:
  • Others:

onRender and onInit share the same "references" in the code editor

What happened:
Writing code in onRender or onInit makes variables show in the other as references.
image

The code crashes if they are used.
image

What you expected to happen:
The editors shouldn't reference each other.

How to reproduce it (as minimally and precisely as possible):

  1. Create a variable in onInit
  2. Type out the variable in onRender
  3. Press ctrl + space (doesn't have to be the full variable name)

Panel options

{
    "onRender": "otherFile",
    "onInit": "const otherFile = \"Hey\";"
}

Anything else we need to know?:

Environment:

  • Grafana version: v8.2.0
  • Plugin (gapit-htmlgraphics-panel) version: v1.3.3
  • Data source type & version:
  • OS Grafana is installed on: Windows 10 (Ubuntu WSL)
  • User OS & Browser: Chrome
  • Grafana plugins:
  • Others:

Instructions to creating bundlers with external JS libraries

Hi! I tried to add some code with sheetjs to my html-panel and found out that it doesn't allow to import dependencies in <script> tag.
I looked at other issues and understood that I need to use bundler to add dependencies. But when I look on the page of bundlers I see few bundlers for popular frameworks and libraries and nothing about how to create own.

Please, any instructions to how to add own dependencies to a panel. Thanks in advance!

An exception is thrown immediately after selecting HTML graphics

What happened:
After installing the plugin and selecting the HTML graphics, an exception is thrown immediately:

An unexpected error happened
Detail:
Error: Illegal value for token color: #fff

at me (http://localhost:3000/public/build/react-monaco-editor.fb13e4673cc0c41043f4.js:1:15930)
at Ps (http://localhost:3000/public/build/467.fb13e4673cc0c41043f4.js:2162:3757)
at div
at Ls (http://localhost:3000/public/build/467.fb13e4673cc0c41043f4.js:2162:5745)
at WithTheme(undefined)
at div
at w (http://localhost:3000/public/plugins/gapit-htmlgraphics-panel/module.js:1:16459)
at _ (http://localhost:3000/public/plugins/gapit-htmlgraphics-panel/module.js:1:19510)
at div
at div
at p (http://localhost:3000/public/build/467.fb13e4673cc0c41043f4.js:422:27)
at div
at div
at http://localhost:3000/public/build/DashboardPage.fb13e4673cc0c41043f4.js:199:2304
at div
at div
at div
at t (http://localhost:3000/public/build/2256.fb13e4673cc0c41043f4.js:2:775078)
at u (http://localhost:3000/public/build/467.fb13e4673cc0c41043f4.js:290:968)
at div
at div
at zn (http://localhost:3000/public/build/DashboardPage.fb13e4673cc0c41043f4.js:275:590)
at div
at div
at tr (http://localhost:3000/public/build/DashboardPage.fb13e4673cc0c41043f4.js:393:507)
at div
at t (http://localhost:3000/public/build/DashboardPage.fb13e4673cc0c41043f4.js:426:3209)
at div
at t (http://localhost:3000/public/build/DashboardPage.fb13e4673cc0c41043f4.js:426:5160)
at _r (http://localhost:3000/public/build/DashboardPage.fb13e4673cc0c41043f4.js:426:10770)
at div
at div
at ia (http://localhost:3000/public/build/DashboardPage.fb13e4673cc0c41043f4.js:486:6031)
at g (http://localhost:3000/public/build/2256.fb13e4673cc0c41043f4.js:2:1083974)
at div
at Mi (http://localhost:3000/public/build/DashboardPage.fb13e4673cc0c41043f4.js:574:3583)
at DashboardPage
at g (http://localhost:3000/public/build/2256.fb13e4673cc0c41043f4.js:2:1083974)
at n (http://localhost:3000/public/build/2256.fb13e4673cc0c41043f4.js:2:1053444)
at so (http://localhost:3000/public/build/467.fb13e4673cc0c41043f4.js:6608:181)
at t (http://localhost:3000/public/build/2256.fb13e4673cc0c41043f4.js:2:1101712)
at t (http://localhost:3000/public/build/2256.fb13e4673cc0c41043f4.js:2:1103733)
at main
at t (http://localhost:3000/public/build/2256.fb13e4673cc0c41043f4.js:2:1098330)
at div
at Qs (http://localhost:3000/public/build/467.fb13e4673cc0c41043f4.js:2171:1055)
at d (http://localhost:3000/public/build/467.fb13e4673cc0c41043f4.js:4495:26220)
at _l (http://localhost:3000/public/build/467.fb13e4673cc0c41043f4.js:2883:467)
at Nl (http://localhost:3000/public/build/467.fb13e4673cc0c41043f4.js:2883:1023)
at l (http://localhost:3000/public/build/2256.fb13e4673cc0c41043f4.js:2:1081540)
at Ho (http://localhost:3000/public/build/467.fb13e4673cc0c41043f4.js:6688:384)

What you expected to happen:
Show the panel edit page.

How to reproduce it (as minimally and precisely as possible):

  1. Install the plugin using command line:
    grafana-cli --pluginsDir "/Users/lyh/dev/src/grafana/plugins" plugins install gapit-htmlgraphics-panel
  2. Create a panel.
  3. Select HTML graphics in the dropdown list.

Anything else we need to know?:

Environment:

  • Grafana version: 8.3.3
  • Plugin (gapit-htmlgraphics-panel) version: 2.0.1
  • Data source type & version: build in datasource --Grafana--
  • OS Grafana is installed on: macOS Monterey 12.1
  • User OS & Browser: 97.0.4692.71 arm64
  • Grafana plugins:
  • Others:

Error loading: gapit-htmlgraphics-panel

What happened:
Installed the plugin via CLI. Went to add a new panel and selected the HTML panel. The error in the preview immediately shows: "Error loading: gapit-htmlgraphics-panel". The properties pane shows none of the expected settings either.
What you expected to happen:
Expected the panel to load with defaults.
How to reproduce it (as minimally and precisely as possible):
Install it via CLI on Grafana Enterprise v8.3.4
Create new dashboard
Add new panel
Select Html
Anything else we need to know?:
Using Grafana Enterprise is that maybe not supported?
Environment:
K8, Linux

  • Grafana version: Enterprise v8.3.4
  • Plugin (gapit-htmlgraphics-panel) version: 2.0.1

Imported panel options doesn't update options

What happened:

When changing the panel options in "Import/export" then saving (clicking outside or ctrl+s), the options doesn't update. This also happens when you import as a file.
Seems like the panel options values change, but not the options on the side.

import-save-bug

What you expected to happen:

The options should update when panel options in "Import/export" has been changed.

How to reproduce it (as minimally and precisely as possible):

  1. Change a value in panel-options in "Import/export"
  2. Save the change (ctrl+s or click outside)

Anything else we need to know?:

Saving twice updates the options.

Environment:

  • Grafana version: v7.4.0
  • Data source type & version:
  • OS Grafana is installed on: Ubuntu 20.04.2 LTS
  • User OS & Browser: Ubuntu 20.04.2 LTS & Chrome v88.0.4324.150
  • Grafana plugins:
  • Others:

Import interfaces instead of copying interfaces

What would you like to be added:

The interfaces in /src/components/CodeEditor/declarations are copied from the grafana library.

Why is this needed:

  • Duplicated code is not good
  • Adding new libraries would be easier (like d3)

Is this possible in principle?

How to change colors with SVG

What happened:
I'm trying to use a SVG image and change colors with "onRender" based on my values:
image

SVG:

<svg xmlns="http://www.w3.org/2000/svg" id="Outline" viewBox="0 0 24 24" width="512" height="512">
  <path id="linePath" d="M23.121,9.069,15.536,1.483a5.008,5.008,0,0,0-7.072,0L0.879,9.069A2.978,2.978,0,0,0,0,11.19v9.817a3,3,0,0,0,3,3H21a3,3,0,0,0,3-3V11.19A2.978,2.978,0,0,0,23.121,9.069ZM15,22.007H9V18.073a3,3,0,0,1,6,0Zm7-1a1,1,0,0,1-1,1H17V18.073a5,5,0,0,0-10,0v3.934H3a1,1,0,0,1-1-1V11.19a1.008,1.008,0,0,1,.293-.707L9.878,2.9a3.008,3.008,0,0,1,4.244,0l7.585,7.586A1.008,1.008,0,0,1,22,11.19Z"/>
</svg>

What you expected to happen:
I use this in SVG plugin and I'm trying to migrate to HTML Graphics

Javascript code that I use in SVG Plugin:

console.clear();
var S = Snap(svgnode);
serviceAlert();

function serviceAlert(){
    var n;
    var pn;
    n=1;
    pn=2;
    console.log(ctrl)
    for (var i=1;i<=ctrl.series.length;i++){
        var dados;
        server = ctrl.series[i-1].alias.replace(/:.*/,"").replaceAll(/[-\(\)']+/g, '').replaceAll(/ +/g, "-").replace(/[\u0300-\u036f]/g, '');
        item = ctrl.series[i-1].alias.replace(/.*: /,"").replaceAll(/( %|[\(\),]|\/)+/g, '').replaceAll(/ +/g, "-").replace(/[\u0300-\u036f]/g, '');
        alias = ctrl.series[i-1].alias.replace(/.*: /,"").replaceAll(/( %|[\(\)]|\/)+/g, '');
        serviceName = '#trg_'+server+'_'+item.replaceAll("-in","");
        tdataName = '#srv_'+server+'_'+item.replaceAll("-in","");
        service = S.select(serviceName);
        tdata = S.select(tdataName);
        zbxItem = /^(Zabbix busy|Utilization)/.test(alias);
    console.log(serviceName);
    console.log(tdataName);
        if (alias == "Replication Seconds Behind Master"){

            dados = (ctrl.series[i-1].stats.current);
            mysqlRep = S.select('#mysqlrep');
            p_mysqlRep = S.select('#p_mysqlrep');
            
            if (dados > 1800){
                 mysqlRep.attr({"stroke": "#E02F44"});
                 p_mysqlRep.attr({"stroke": "#E02F44"});
            }else if(dados > 180){
                 mysqlRep.attr({"stroke": "#ED8128"});
                 p_mysqlRep.attr({"stroke": "#ED8128"});
            }else if((dados >= 0) && (dados < 180) ){
                 mysqlRep.attr({"stroke": "#00e5b5"});
                 p_mysqlRep.attr({"stroke": "#00e5b5"});
            }else{
                 mysqlRep.attr({"stroke": "#aca793"});
                 p_mysqlRep.attr({"stroke": "#aca793"});
            }
        } else if (alias == "Zabbix busy housekeeper processes, in"){
            dados = (ctrl.series[i-1].stats.current);
            if (dados == "100"){
                value = 0;
            }
            dados = dados.toFixed(value);
            dados=dados+'%';
            tdata.attr({"#text": dados });
            service.attr({"fill": "#299c46"});
			else {
            dados = (ctrl.series[i-1].stats.current);
            if (dados === null){
                dados = 9999999999;
            }
            dados = dados.toFixed(2);
            threshold(dados,'menor',20,10);
            dados=dados+'%';    
            tdata.attr({"#text": dados });
        }
    }
}

function threshold(data, criterio,warning, critical) {
    if(criterio == "maior"){
        if (data >= critical){
            return service.attr({"fill": "#E02F44"});
        }else if(data >= warning){
            return service.attr({"fill": "#ED8128"});
        }else if((data >= 0) && (data < warning) ){
            return service.attr({"fill": "#299c46"});
        }else{
            return service.attr({"fill": "#aca793"});
        }
    }else if(criterio == "menor"){
        if(data <= warning){
            return service.attr({"fill": "#ED8128"});
        }else if (data <= critical){
            return service.attr({"fill": "#E02F44"});
        }
        else if(data > warning) {
            return service.attr({"fill": "#299c46"});
        }else{
            return service.attr({"fill": "#aca793"});
        }
    }else{
        return service.attr({"fill": "#aca793"});
    }
}

Console Info:
image

Example in SVG:
image

How to reproduce it (as minimally and precisely as possible):

Anything else we need to know?:

Environment:

  • Grafana version: 10.0.1
  • Plugin (gapit-htmlgraphics-panel) version: 2.1.1
  • Data source type & version: Static/Zabbix
  • OS Grafana is installed on: RHEL 7
  • User OS & Browser: Google Chrome
  • Grafana plugins:
  • Others:

Disabling of updating fieldDisplayValues.

What would you like to be added:

A toggle to disable updating of fieldDisplayValues.

Why is this needed:

Performance.
If a lot of metrics are used fieldDisplayValues takes a while to update.

Replace deprecated getLocationSrv

What would you like to be added:

locationService should be added to the available Elements in the code blocks and getLocationSrv should be removed

Why is this needed:

getLocationSrv is deprecated.

Execute script tags in the html

What would you like to be added:

Execute script tags in the html

Why is this needed:

Makes it easier to add external dependencies and below code would work

<script>
  function test() {
    // Something
  }
</script>
<button onclick="test">Click me</button>

Support for componentWillUnmount.

I use "setInterval" in "OnInit".
Hope to have a chance to "clearInterval" just befor the panel will be destroyed.

On the same time, I want to know how to share timerid between "OnInit" and other code.

Custom user error interface

Discussed in #91

Originally posted by tillsteinbach February 23, 2022
I can throw new Error() but it will display something like "error in onRender". Would be great if there is a real interface to show errors to the user.

Load SVG from file or url

What would you like to be added:
I would like the ability to load a SVG from a file or url.
The ability to load different svg files based on a user variable. (This could be a follow on.) Would like a single file first.

Why is this needed:
I've been creating some very large svg files and it would be helpful to load from a file instead of cut and paste.
Also sharing dashboards could be made easier.
Dynamic dashboards which could pull up different svg based on a user variable.

This plugin has been a great help for what I've been doing. Thanks.

fieldDisplayValues is undefined when dynamicHtmlGraphics is true.

What happened:

htmlGraphics.fieldDisplayValues returns undefined

What you expected to happen:

htmlGraphics.fieldDisplayValues should retrieve the values.

How to reproduce it (as minimally and precisely as possible):

Set Dynamic htmlGraphics to true.

Add the following onInit code

console.log(htmlGraphics.fieldDisplayValues)

Reload the page.

Anything else we need to know?:

Environment:

  • Grafana version: v8.3.3
  • Plugin (gapit-htmlgraphics-panel) version: v2.0.0
  • Data source type & version:
  • OS Grafana is installed on:
  • User OS & Browser:
  • Grafana plugins:
  • Others:

The fonts are not served from the subpath

What happened:

When Grafana is served from sub path the font files are not served from the sub path.
image
image

What you expected to happen:

The fonts should be served from the sub path.

Like editor.main.js
image

How to reproduce it (as minimally and precisely as possible):

Dockerfile

version: '2'
services:

  grafana:
    image: grafana/grafana:8.0.3
    container_name: grafana
    restart: always
    networks:
      - grafana
    ports:
      - 3000:3000
    environment:
      - GF_INSTALL_PLUGINS=gapit-htmlgraphics-panel
      - GF_SERVER_ROOT_URL=%(protocol)s://%(domain)s:%(http_port)s/grafana/
      - GF_SERVER_SERVE_FROM_SUB_PATH=true

networks:
    grafana:
      external:
            name: grafana

Anything else we need to know?:

Environment:

  • Grafana version: 8.0.3
  • Plugin (gapit-htmlgraphics-panel) version: 1.3.3
  • Data source type & version:
  • OS Grafana is installed on: Ubuntu 20.10 (docker)
  • User OS & Browser: Ubuntu 20.10 & Chrome v91
  • Grafana plugins:
  • Others:

Access to props

Hope to have a way to access props to get attributes such as :

  • width of the panel
  • height of the panel
  • eventBus.

OnRender not executing for new data

What happened:
We have an HTML Graphics panel used as the main header for all of our dashboards. It just displays a banner, but under the covers runs some complex queries that are beyond what is supported through the Query variable definition interfaces and stores the values into Constant variables that are then available to other panels (essentially externally loaded Query variables).

The banner displays the currently selected time range, retrieving it from the Grafana global variables, formatting it and updating the HTML. The JavaScript for this is contained in the onRender section, which, as we understand it, should execute whenever new data is available, such as a change in the time range selection. However, the panel does NOT refresh the majority of the time when the time range changes (meaning the variables are not being updated to reflect the range change). I even added a panelupdate event listener in the JS to try to force it, but it is still not executing.

What you expected to happen:
When the time range is changes, the panel should execute the JS in the onRender, which would refresh the variables and the displayed time.

How to reproduce it (as minimally and precisely as possible):
I have attached an importable dashboard with a stripped-down version of the panel which still includes the time refresh code (but without the queries or variable updates).

Header Not Refreshing Issue-1713546520774.json

Anything else we need to know?:
Nothing I can think of pending any questions.

Environment:

  • Grafana version: v10.4.0
  • Plugin (gapit-htmlgraphics-panel) version: 2.1.1
  • Data source type & version: None
  • OS Grafana is installed on: RHEL 8.9
  • User OS & Browser: Windows/Chrome
  • Grafana plugins: N/A
  • Others: N/A

Code editor type suggestions aren't working in v8.4.0+

What happened:

Using v8.4.0 makes the "cutstom" code editor suggestions not show
image

What you expected to happen:

Suggestions to work like in v8.3.6 and below

How to reproduce it (as minimally and precisely as possible):

Type html in the onRender or onInit code editor

Anything else we need to know?:

This was working in v8.3.6, most likely a change from Grafana.

Environment:

  • Grafana version: v8.4.0
  • Plugin (gapit-htmlgraphics-panel) version: v2.0.3
  • Data source type & version:
  • OS Grafana is installed on:
  • User OS & Browser:
  • Grafana plugins:
  • Others:

Don't save importedPanelOptions.

What would you like to be added:

Don't save importedPanelOptions. Just use the options already in use.

Why is this needed:

This halves the size of the settings stored. Making the payload smaller for the users.

Only load declarations when they are needed

What would you like to be added:

Only load declarations when they are needed.

Why is this needed:

Currently the declarations are bundled into the module.js file which causes the file size to be ~3 times larger.
With declarations: ~73 KB
Without declarations: ~27 KB

Call initialize(or onInit) after resize the panel

What would you like to be added:
Call initialize(or onInit) after resizing the panel.

Why is this needed:
I change HTML according to the aspect of the panel.
For example
vertical slider for portrait,
horizontal one for landscape view.

However I need to save and reload the dashboard to take effect after resizing the panel.

On the same time. I hope to have the recent version of this plugin in the official panel repository!

Make props dynamic (in onInit)

What would you like to be added:

Props should be dynamic like data (in onInit).

Why is this needed:

props like width and height doesn't update when the panel is resized.

Download as json file stopped working

What happened:

Pressing download as json file doesn't work after v2.0.0 update.

What you expected to happen:

The json file should download

How to reproduce it (as minimally and precisely as possible):

Click "Download as JSON file" in the Panel options Import/export section.

Anything else we need to know?:

Environment:

  • Grafana version: v8.3.3
  • Plugin (gapit-htmlgraphics-panel) version: v2.0.0
  • Data source type & version:
  • OS Grafana is installed on:
  • User OS & Browser:
  • Grafana plugins:
  • Others:

Feature: add css to be loaded outside the shadowroot

What would you like to be added:

Add CSS that will be loaded outside the shadowroot to be able to use @import and @font-face

Why is this needed:

@import and @font-face will be able to be loaded and custom fonts and icons can be used.

Neovis.js html code

Hi i have a neo4j graph using neovis.js library in an html file. And i was looking to visualize this graph in grafana. Is possible to do this with html graphics plugin?

Custom fonts

I have an SVG (made in draw.io) that contains custom font "Roboto":

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
    width="65px" height="32px" viewBox="-0.5 -0.5 65 32" style="background-color: rgb(24, 27, 31);">
    <defs>
        <style type="text/css">@import
            url(https://fonts.googleapis.com/css2?family=Roboto:wght@400;500);&#xa;</style>
    </defs>
    <g>
        <g id="cell-1xWRqdkjeC1Q69flhg9z-545"
            content="&lt;object label=&quot;-%&quot; name=&quot;one_a_src_fill_text&quot;/&gt;"
            data-label="-%" data-name="one_a_src_fill_text">
            <rect x="0" y="-0.38" width="64.84" height="31.21" fill="none" stroke="none"
                pointer-events="all" />
            <g transform="translate(-0.5 -0.5)">
                <switch>
                    <foreignObject pointer-events="none" width="100%" height="100%"
                        requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"
                        style="overflow: visible; text-align: left;">
                        <div xmlns="http://www.w3.org/1999/xhtml"
                            style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 63px; height: 1px; padding-top: 15px; margin-left: 1px;">
                            <div data-drawio-colors="color: #FBFBFA; "
                                style="box-sizing: border-box; font-size: 0px; text-align: center;">
                                <div
                                    style="display: inline-block; font-size: 22px; font-family: Roboto; color: rgb(251, 251, 250); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
                                    -%</div>
                            </div>
                        </div>
                    </foreignObject>
                    <text x="32" y="22" fill="#FBFBFA" font-family="Roboto" font-size="22px"
                        text-anchor="middle">-%</text>
                </switch>
            </g>
        </g>
    </g>
    <switch>
        <g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" />
        <a transform="translate(0,-5)"
            xlink:href="https://www.drawio.com/doc/faq/svg-export-text-problems" target="_blank">
            <text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot
                display</text>
        </a>
    </switch>
</svg>

When rendering with the htmlgraphics visual, it falls back to another default font.
image

Am I doing something wrong, is this a bug, or is this simply not supported yet?

Thanks for the help!

Best,
Sander

Export html/js data

A button to export all javascript and html/svg data. Can be downloaded as several files into a local computer.

This is needed to speed up moving data from one instance to another. F.ex if testing and development is done on a local computer but the finished version should be transferred to a server

Can we include external js or /and css ?

Can we include external js or /and css ?

If we want to create a interactive form using this panel , it will be of immense help to include external css and js files

Wrong default calcs.

What happened:

When first creating a HTMLGraphics panel the default calcs is wrong. It says standard, but last is the only one added.
image

What you expected to happen:

All the standard calcs should be added.

How to reproduce it (as minimally and precisely as possible):

Create a HTMLGraphics panel.

log htmlGraphics.fieldDisplayValues

onRender

console.log(htmlGraphics.fieldDisplayValues);

Anything else we need to know?:

Environment:

  • Grafana version: v8.3.3
  • Plugin (gapit-htmlgraphics-panel) version: v2.0.0
  • Data source type & version:
  • OS Grafana is installed on:
  • User OS & Browser:
  • Grafana plugins:
  • Others:

Panel unmount only triggers on the edit panel

What happened:

Going in and out of edit mode doesn't trigger the non edit panel's onpanelunmount event.

What you expected to happen:

The edit and the non edit panel should trigger the onpanelunmount event.

How to reproduce it (as minimally and precisely as possible):

Create a new panel will below panel options

{
    "calcsMutation": "standard",
    "reduceOptions": {
        "calcs": [
            "lastNotNull",
            "last",
            "first",
            "firstNotNull",
            "min",
            "max",
            "mean",
            "sum",
            "count",
            "range",
            "delta",
            "step",
            "diff",
            "logmin",
            "allIsZero",
            "allIsNull",
            "diffperc"
        ]
    },
    "add100Percentage": true,
    "centerAlignContent": true,
    "overflow": "visible",
    "SVGBaseFix": true,
    "codeData": "{\n  \"text\": \"Random text\"\n}",
    "rootCSS": "",
    "css": "* {\n  font-family: Open Sans;\n}\n",
    "html": "<button>Dispatch event</button>\n",
    "renderOnMount": true,
    "onRender": "",
    "dynamicData": false,
    "dynamicHtmlGraphics": false,
    "dynamicFieldDisplayValues": false,
    "dynamicProps": false,
    "panelupdateOnMount": true,
    "onInit": "const buttonElt = htmlNode.querySelector('button');\n\nbuttonElt.onclick = () => document.dispatchEvent(htmlGraphicsEvent);\n\nconst doSomething = () => {\n  console.log(\"Event dispatched\");\n}\n\nhtmlGraphicsEvent = new CustomEvent('htmlgraphics');\ndocument.addEventListener('htmlgraphics', doSomething);\n\nhtmlNode.onpanelwillunmount = () => {\n  document.removeEventListener('htmlgraphics', doSomething);\n}\n"
}

Press e on the panel a few times and check the console.

It should only log "Event dispatched" once

Anything else we need to know?:

Edit panel is the panel where you can see the options.
The non edit panel is the one without the options on the side.

Environment:

  • Grafana version: v8.2.2
  • Plugin (gapit-htmlgraphics-panel) version: v1.4.1
  • Data source type & version:
  • OS Grafana is installed on:
  • User OS & Browser:
  • Grafana plugins:
  • Others:

Errors are not logged in the console

What happened:

An error in the code didn't get logged in the console.

What you expected to happen:

The error should be logged in the console.

How to reproduce it (as minimally and precisely as possible):

Create an error in onRender or onInit.
onRender:
a

Anything else we need to know?:

Environment:

  • Grafana version: v7.5.3
  • Plugin (gapit-htmlgraphics-panel) version: v1.3.2
  • Data source type & version:
  • OS Grafana is installed on: Windows 10
  • User OS & Browser: Windows 10, Chrome v89.0.4389.114
  • Grafana plugins:
  • Others:

Docs example for changing SVG properties

I've made some changes to your html example but for SVG, I don't know if it would be helpful for anyone - am happy for it to be added to the website if you think it would be useful

HTML/SVG document:

<button id="testButton" style="background:green;color:white;"></button>

<svg width="100" height="100">
  <circle id = "testSVG" cx="50" cy="50" r="40" stroke="green" stroke-width="4" style="fill:red;" />
</svg>

onInit

// For Grafana v8.3.0+ the variable needs to be wrapped in ${}
const { testVariable } = customProperties;
const testVariableName = testVariable.replace(/[${}]/g, "");
const buttonElt = htmlNode.querySelector('button');
const buttonID = htmlNode.querySelector('#testButton');
const svgID = htmlNode.querySelector('#testSVG');

/*
  Update a grafana variable

  More information in the grafana docs
  https://grafana.com/docs/grafana/v9.1/developers/plugins/add-support-for-variables/
*/
function updateGrafanaVariable(variableName, value) {
  getLocationSrv().update({
    query: {
      [`var-${variableName}`]: value,
    },
    partial: true, // partial: true makes the update only affect the query parameters listed in query, and leaves the other query parameters unchanged.
    replace: true, // replace: true tells Grafana to update the current URL state, rather than creating a new history entry.
  });
}

function getGrafanaVariableValue(variable) {
  return getTemplateSrv().replace(variable);
}

function updateButtonText() {
  buttonElt.textContent = `${testVariableName}'s current value is: ${getGrafanaVariableValue(testVariable)}`;
}

buttonElt.onclick = function () {
  updateGrafanaVariable(testVariableName, getGrafanaVariableValue(testVariable) == 'b' ? 'a' : 'b');
};

/*
  When the variable changes panelupdate will trigger.
  The panelupdate is used to update the button text so the text is the same as the variable.
  Call updateButtonText() when the variable changes
*/
htmlNode.addEventListener('panelupdate', () => {
  updateButtonText();
  if (getGrafanaVariableValue(testVariable) == 'a'){
    svgID.style.fill = 'Blue';
  } else {
    svgID.style.fill = 'Green';
  }
    if (getGrafanaVariableValue(testVariable) == 'a'){
    buttonID.style.background = 'Blue';
  } else {
    buttonID.style.background = 'Red';
  }
});

testVariable
${testVariable}

Panel Options

{
    "calcsMutation": "standard",
    "reduceOptions": {
        "calcs": [
            "lastNotNull",
            "last",
            "first",
            "firstNotNull",
            "min",
            "max",
            "mean",
            "sum",
            "count",
            "range",
            "delta",
            "step",
            "diff",
            "logmin",
            "allIsZero",
            "allIsNull",
            "diffperc"
        ]
    },
    "add100Percentage": true,
    "centerAlignContent": true,
    "overflow": "visible",
    "useGrafanaScrollbar": true,
    "SVGBaseFix": true,
    "codeData": "{\n  \"testVariable\": \"${testVariable}\"\n}",
    "rootCSS": "",
    "css": "",
    "html": "<button id=\"testButton\" style=\"background:green;color:white;\"></button>\n\n<svg width=\"100\" height=\"100\">\n  <circle id = \"testSVG\" cx=\"50\" cy=\"50\" r=\"40\" stroke=\"green\" stroke-width=\"4\" style=\"fill:red;\" />\n</svg>\n",
    "renderOnMount": true,
    "onRender": "",
    "panelupdateOnMount": true,
    "dynamicHtmlGraphics": false,
    "dynamicData": false,
    "dynamicFieldDisplayValues": false,
    "dynamicProps": false,
    "onInitOnResize": false,
    "onInit": "// For Grafana v8.3.0+ the variable needs to be wrapped in ${}\nconst { testVariable } = customProperties;\nconst testVariableName = testVariable.replace(/[${}]/g, \"\");\nconst buttonElt = htmlNode.querySelector('button');\nconst buttonID = htmlNode.querySelector('#testButton');\nconst svgID = htmlNode.querySelector('#testSVG');\n\n/*\n  Update a grafana variable\n\n  More information in the grafana docs\n  https://grafana.com/docs/grafana/v9.1/developers/plugins/add-support-for-variables/\n*/\nfunction updateGrafanaVariable(variableName, value) {\n  getLocationSrv().update({\n    query: {\n      [`var-${variableName}`]: value,\n    },\n    partial: true, // partial: true makes the update only affect the query parameters listed in query, and leaves the other query parameters unchanged.\n    replace: true, // replace: true tells Grafana to update the current URL state, rather than creating a new history entry.\n  });\n}\n\nfunction getGrafanaVariableValue(variable) {\n  return getTemplateSrv().replace(variable);\n}\n\nfunction updateButtonText() {\n  buttonElt.textContent = `${testVariableName}'s current value is: ${getGrafanaVariableValue(testVariable)}`;\n}\n\nbuttonElt.onclick = function () {\n  updateGrafanaVariable(testVariableName, getGrafanaVariableValue(testVariable) == 'b' ? 'a' : 'b');\n};\n\n/*\n  When the variable changes panelupdate will trigger.\n  The panelupdate is used to update the button text so the text is the same as the variable.\n  Call updateButtonText() when the variable changes\n*/\nhtmlNode.addEventListener('panelupdate', () => {\n  updateButtonText();\n  if (getGrafanaVariableValue(testVariable) == 'a'){\n    svgID.style.fill = 'Blue';\n  } else {\n    svgID.style.fill = 'Green';\n  }\n    if (getGrafanaVariableValue(testVariable) == 'a'){\n    buttonID.style.background = 'Blue';\n  } else {\n    buttonID.style.background = 'Red';\n  }\n});\n"
}

What would you like to be added:

Why is this needed:

How to import external js resources

What would you like to be added:Import external js resources

Why is this needed:When using grafana, I need to insert live video surveillance, the native tag <video> does not support this

E.g:<script src=“http: //vjs.zencdn.net/5.8.8/video.js”></script>

htmlNode.createElement("option") not working

var json = JSON.parse(xhr.responseText);
var selected_eport = htmlNode.getElementById("select_report");
selected_eport.innerHTML = "";
var option = htmlNode.createElement("option");
option.text = "== SELECT REPORT ==";
selected_eport.add(option);
for (var i = 0; i < json.length; i++) {
var option = htmlNode.createElement("option");
option.text = json[i].REPORT_NAME;
option.value = json[i].REPORT_ID;
selected_eport.add(option);
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.