javascriptplotlygrafanaplotly.js

Plotly in grafana, avoid clashing plot and legend


I have a grafana dashboard giving my an overview of the electricity usage in my house, from the grid and produced by solar panels. One of the plots is the cumultative production over the day. I made it initially as a grafana time series plot. On the time series plot, it was not possible to get the xaxis fixed for a certain time interval, so I had to give it a lot of air as the plot slid across the panel over the day. So I have recreated the plot using plotly for grafana. This works well, but I have some issues with how the legend is showing. The figure shows the time series panel on the top left and the plotly one at the bottom: (there is a thick cloud layer and even some snow on the panels today, so not much production)

enter image description here

This is not too bad, but I would like to have the plotly panel the same size as the present time series panel, if I do this, it gets messed up:

enter image description here

Is it possible to make the lines on the legend shorter so it could still fit in the same vertical size (preferably), or can I somehow make the graph area auto shrink to give space to the legend?

In case it helps, the data query from a postgresql database, the time field is the time stamp for the measurement, ppv_total is the momentary power production. as I get a datapoint each 5 min, I divide by 12 to get a kWh estimate, the now()::date+time::time is to move all the last days measurement into todays timeframe.

select to_char(time::date,'YYYY-mm-dd') as parameter, now()::date+time::time as time,
sum(ppv_total/12) over (partition by time::date order by time) as " "
from pv where pv.time > now()::date - interval '7 days'
order by time;

The result from this query is then handeled as a time series in grafana, basically doing a pivot table having the values from "parameter" as new column headers. A snippet of the table looks like this:

grafana time series table

This is then run through this script ("data" is the input from grafana).

let dataset = []
for (set =1; set<9; set++){
  let x = [];
  let y = [];
  data.series[0].fields[set].values.forEach(function (item, index) {
    if (item > ''){ // must get rid of empty values
        y.push(item/1000); // I want kWh, having production in Watt
        x.push(data.series[0].fields[0].values[index]);
    }
  }); 
  if (set == 8){ // Todays line should stand out
    line={width:4,
    color: "yellow"};
  }else{
    line={width:1};
  }
  let serie = {
  x : x,
  y : y,
  name : data.series[0].fields[set].labels.parameter,
  line: line
  };
  dataset.push(serie)
}
return {
  data : dataset,
  config : {
    displayModeBar: false
  }
}

The layout object as defined in grafana is:

{
  "yaxis": {
    "gridcolor": "#344",
    "autorange": true,
    "color": "#444",
    "type": "linear",
    "range": [
      -0.3900152777777779,
      7.49179027777778
    ]
  },
  "xaxis": {
    "type": "date",
    "gridwidth": 1,
    "gridcolor": "#444",
    "autorange": true,
    "color": "#444",
    "range": [
      "2024-03-26 07:49:19",
      "2024-03-26 19:40:08"
    ]
  },
  "annotations": [
    {
      "showarrow": false,
      "text": "kWh",
      "textangle": -90,
      "x": -0.03,
      "xanchor": "right",
      "xref": "paper",
      "y": 0.5,
      "yanchor": "right",
      "yref": "paper"
    }
  ],
  "font": {
    "color": "darkgrey"
  },
  "hovermode": "closest",
  "margin": {
    "b": 10,
    "t": 15,
    "r": 10,
    "l": 40
  },
  "paper_bgcolor": "rgba(0,0,0,0)",
  "plot_bgcolor": "rgba(0,0,0,0)",
  "legend": {
    "orientation": "h",
    "yanchor": "bottom",
    "y": -0.5,
    "xanchor": "mid",
    "x": 0,
    "entrywidth": 20
  }
}

Solution