Calculation of height on oh-grid

Hi,

I’ve got a widget with a ‘upgraded’ linechart that I use to display several items on a dashboard with a 8 columns x 5 rows setup. Sometime the widget tile is a 1x1, sometimes a 2x1, sometimes a 2x2, etc. It works but it sizes bad. Depending on the chosen layout it keeps large blanc space at the bottom, fits perfect or overflows (and the axis is hidden).

As a simple solution I created a height property that I can use. I can use it in the oh-chart, also with formulas (the *2 just for the demo):

    - component: oh-chart
      config:
        height: = props.height*2+"px"

This partially solves the issue, but to make it perfect I also need the calculate the oh-grid. This seems not to be possible or I use the wrong syntax.

works without formula:

        grid:
          - component: oh-chart-grid
            config:
              height: 77%

or

        grid:
          - component: oh-chart-grid
            config:
              height: 200

fails (think it defaults to 100% if it doesn’t understand)


        grid:
          - component: oh-chart-grid
            config:
              height: (50+50)+"%"


        grid:
          - component: oh-chart-grid
            config:
              height: 200+200

tried all variations like
height: "200+200"
height: = "200+200"
height:  "=200+200"
height:  "=(200+200)"
height:  "=calc(200+200)"
etc

So that’s my question, is this possible or a limitation? Maybe have to use one of the f7-variables? Another tick? If important, didn’t do the upgrade yet so on version 4.1.

Limitation, I suspect. When you get inside a chart, the components work a little differently. They are no longer rendered by vue, but are instead processed by the eCharts library. That used to mean that even some of the basic features of the component system such as expressions didn’t actually translate over to many of the chart components and their properties. That should have been fixed, and all chart component properties should now accept expressions, but it’s possible that this one is obscure enough that it fell through the cracks.

From the brief description of the problem, however, it’s not clear why you need to worry about calculating anything. Why are you not just using % values in the chart grid height?

Well, it seems that when the widget becomes small the spacing of components makes errors. So on a 1 rows tile, it needs 87%. Two rows 90%. Three rows is fine with 100%. So a fixed percentage doesn’t work.

Then it sounds like the next thing I would try would be to work on keeping the charts with some % (or 'auto') height and make the responsiveness of the container the chart is in more accurate.

So far no luck, using the developer tools in chrome on the graph the problem area is between plain html (maybe openHAB) and a canvas (maybe the e-charts framework). The canvas is also an absolute position element. Where it derives it height is unknown to me, it listens to the grid height property (that doesn’t accept formulas). The HTML changes on the height of the oh-chart but the resulting height is not the base value for the canvas 100% (or whatever you use).

<div style="position: relative; width: 398px; height: 250px; padding: 0px; margin: 0px; border-width: 0px; cursor: default;">
  <canvas data-zr-dom-id="zr_0" width="447" height="281" style="position: absolute; left: 0px; top: 0px; width: 398px; height: 250px; user-select: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); padding: 0px; margin: 0px; border-width: 0px;" class="">
  </canvas>
</div>

So trying to discover what makes the 100% for the canvas. If anyone knows … please let me know.

It shouldn’t be necessary to to mess with any of the echarts derived elements. Just put the oh-chart in some container you have more fine control over and then set the charts height to 100%.

True, but the result of not messing is not as pretty a I would like. This isthe result of a widget with default width/height settings. For small tiles the whitespace is not acceptable …

At this point, if you need more specific help, you’ll need to share your actual widget code and page configuration.

Hi @JustinG . You’re right. I was hoping for a quick option/property that I missed ;-).

Some background information. In the meantime I did the upgrade to 4.2, so I got the latest version of openHAB (didn’t solve this). My usecase is a wall mounted tablet where I use a gridlayout with tiles, sliders and popups to create kind of a single page app as a dashboard and control to my home. At the moment I have copies of widgets for 1,2 or 3 row tiles because of this layouy issue. I was trying to merge them to one.

So to make is as easy as possible I removed most of the configuration to get to a minimal setup to reproduce the issue. Below the configuration for the gridlayout page. It’s setup to the max resolution on the tablet that displays without scroll bars. But on my laptop (HD resolution) it behaves the same.

config:
  colNum: 8
  fixedType: grid
  hideNavbar: false
  label: Demo
  layoutType: fixed
  margin: 5
  scale: false
  screenHeight: 773
  screenWidth: 1275
  showFullscreenIcon: true
  sidebar: true
  style:
    --f7-card-bg-color: "#202020"
    --f7-navbar-bg-color: "#202020"
    --f7-navbar-border-color: "#101010"
    --f7-page-bg-color: black
    --f7-theme-color: gray
blocks: []
grid:
  - component: oh-grid-item
    config:
      h: 2
      w: 3
      x: 3
      y: 0
    slots:
      default:
        - component: widget:lineTest
          config:
            average: netto_totaal_avg
  - component: oh-grid-item
    config:
      h: 1
      w: 2
      x: 3
      y: 2
    slots:
      default:
        - component: widget:lineTest
          config:
            average: netto_totaal_avg

Did the same for the widget, killed everything except a basic linegraph for 1 item.

uid: lineTest
tags: []
props:
  parameters:
    - context: item
      description: The average value
      label: Average
      name: average
      required: true
      type: TEXT
  parameterGroups: []
timestamp: Aug 1, 2024, 7:58:01 AM
component: f7-card
slots:
  default:
    - component: oh-chart
      config:
        height: 100%
        options:
          backgroundColor: transparent
        period: 2h
        periodVisible: false
      slots:
        grid:
          - component: oh-chart-grid
            config:
              height: 100%
        series:
          - component: oh-time-series
            config:
              areaStyle:
                opacity: 0.6
              item: =props.average
              itemStyle:
                color: rgb(50, 50, 150)
              type: line
        tooltip:
          - component: oh-chart-tooltip
            config:
              trigger: axis
        xAxis:
          - component: oh-time-axis
            config:
              axisLabel:
                show: true
              boundaryGap: false
              gridIndex: 0
              splitNumber: 3
              type: time
        yAxis:
          - component: oh-value-axis
            config:
              axisLabel:
                show: true
              axisTick:
                inside: true
              boundaryGap:
                - 0%
                - 0%
              gridIndex: 0
              splitLine: true
              type: value

On both tablet and PC this produces the same, the linegraph becomes bigger than the tile. the smaller the tile, the more the overflow. Screenshot below.

As a update on my quest:

  • The chart (in the canvas) does scale with (the root div) of the tile. But 100% is the size of the tile + an absolute value. That at least explains the behaviour. If the tile gets smaller, the absolute addition takes a bigger part. So more of the graph is lost. That’s why in my copy solution for a 1 row the height percentage of the grid must be the smallest to make it fit. Wild thought on this is using css on that root div and give it a inset/margin/border to match this absolute vale and allowing the chart to overflow it’s container. Hopefully the canvas will only use the height and be tricked by this. But that’s kind of a complex workaround. Would be easier to put in a change request to also allow formulas in this height propertie and wait for this.
  • Googling of echarts shows more people have this issue with several configuration hints (properties). Scaling might be default with a fixed aspect ratio (maybe the horizontal size is the limitation that sets the vertical size). All suggested properties are not openHAB standard, Maybe they can be used anyway, but didn’t find to proper place to put them in the yaml. Do you now if all is passed anyway? Of does openHAB ‘filter’ the yaml so they can’t be used anyway?

My best guess for the found echart props (put them all in, not working)

    - component: oh-chart
      config:
        height: 100%
        options:
          backgroundColor: transparent
          maintainAspectRatio: false
          responsive: true
          scaleSize: 20
          radius: [20, 180]

Wel thats it. Hope this helps you (or someone else of course) in a brainwave for a solution

Ah, I never use a grid layout, so I wasn’t 100% following initially. Now I understand.

You want to do a couple of things:

  1. Make sure you set the height of the card in the widget (e.g. 100%)
  2. Don’t set the height on the grid
  3. Change the grid top and bottom from their default values to % values (e.g. 10% to match the left and right defaults)
  4. Set the grid containLabel option to true
component: f7-card
config:
  style:
    height: 100%
slots:
  default:
    - component: oh-chart
      config:
        height: 100%
        options:
          backgroundColor: transparent
        period: 2h
        periodVisible: false
      slots:
        grid:
          - component: oh-chart-grid
            config:
              top: 10%
              bottom: 10%
              containLabel: true

Probably still a good idea to do this anyway. But I think you can get what you want without it, if I now understand the issue better.

@JustinG , you are my hero! This works like a charm. Some small modifications made it perfect:

  • Removed the height: 100% on the oh-card. The 100% works but in the widget development tool/screen it won’t display the preview with this setting. Probably using 100% of 0px in the preview. Removing it makes the preview work and also displays at 100% in the tile in the grid dashboard.
  • Changed the % a bit, also on right and left to use the little tile space best. Funny is needs more on the right (else the label with the fime will overflow and be clipped.
  • There’s no f7-card in my widget, I assume that was your test setup. Your solution still works without it.

So to summarize I got:

slots:
  default:
    - component: oh-chart
      config:
        options:
          backgroundColor: transparent
        period: =props.period
        periodVisible: false
      slots:
        grid:
          - component: oh-chart-grid
            config:
              containLabel: true
              top: 10%
              bottom: 5%
              left: 2%
              right: 5%
        series:
          - component: oh-time-series

And now it’s perfectly responsive in a one, two or three row tile! I think I’ll have a look at workarounds in other widgets and check if the top/bottom percentages also do magic in them.

Thanx again for your help!