Fun with custom:button-card

const fill = 'rgba(255,255,255,0.8)';
const width = 40;
const height = 30;
const x = 5; 
const y = 10; 
const borderRadius = 5; 
return `
  <svg viewBox="0 0 50 50">
    <rect x="${x}" y="${y}" width="${width}" height="${height}" 
      rx="${borderRadius}" ry="${borderRadius}"
      stroke="#d9d9d9" stroke-width="2" fill="${fill}" />
  </svg>`;
2 Likes

Thank you!!

This is how far I got:

  Round: |
    [[[
        const fill = 'rgba(255,255,255,0.8)';
        const radius = 12; 
        return `
          <svg viewBox="0 0 100 100">
            <rect x="8" y="8" width="80px" height="25px" 
              rx="12" ry="12"
              stroke="#d9d9d9" stroke-width="2" fill="${fill}" />
          </svg>`;
    ]]]
 
  Percentage: |
    [[[
        {var percentage = Math.round(states['sensor.afzuigkap_programma_voortgang'].state/1.00);
        var rgb = (entity.state === 'on')
                ? entity.attributes.rgb_color : '211,211,211';
        var rgba = 'rgba(' + rgb + ',0.2)';
        var fill = (entity.attributes.rgb_color) ? rgba : 'rgba(255,255,255,0.8)';
        const radius = 12.0;
        const circumference = radius * 2 * Math.PI;
        return `
          <svg viewBox="0 0 100 100">
            <rect x="8" y="8" width="80px" height="25px"
              rx="12" ry="12"
              stroke="green" stroke-width="2" fill="${fill}"
              style="transform: rotate(0deg);transform-origin: 50% 50%;
              stroke-dasharray: ${circumference};
              stroke-dashoffset: ${circumference - percentage / 100 * circumference};" />
            <text x="50%" y="23%" fill="var(--text-color-on)" font-size="15" font-weight= "normal"
              text-anchor="middle" alignment-baseline="middle">
              ${states['sensor.afzuigkap_programma_voortgang'].state}<tspan font-size="15" alignment-baseline="middle">%</tspan>
            </text>
          </svg>`;}
    ]]]

style:

  custom_fields:
    Round:
      - position: absolute
      - right: 0px
      - top: 0px
      - width: 70px
      - overflow: hidden
    Percentage:
      - position: absolute
      - right: 0px
      - top: 0px
      - width: 70px
      - overflow: hidden
      - z-index: 1

But the text is no longer in the middle, it does not fit anymore.
Times also not correct.Sorry I never worked with this ‘language’

timer

  - type: custom:button-card
    show_state: false
    show_name: false
    show_icon: false
    entity: input_number.cover_position
    aspect_ratio: 1/1
    custom_fields:
      rect: >
        [[[
          const fill = 'rgba(255,255,255,0.8)';
          const width = 40;
          const height = 30;
          const x = 5;
          const y = 10;
          const borderRadius = 5;
          const strokeColor = '#4caf50'; // Color for the filled part
          const strokeBgColor = '#d9d9d9'; // Background stroke color
          const textColor = '#333'; // Text color
          const dashArray = 2 * (width + height); // Total stroke length
          const value = Math.abs(entity.state);
          const dashOffset = dashArray * (1 - value / 100); 

          return `
            <svg viewBox="0 0 50 50">
              <!-- Background stroke -->
              <rect x="${x}" y="${y}" width="${width}" height="${height}"
                rx="${borderRadius}" ry="${borderRadius}"
                stroke="${strokeBgColor}" stroke-width="2" fill="${fill}" />
              <!-- Foreground stroke (colored part) -->
              <rect x="${x}" y="${y}" width="${width}" height="${height}"
                rx="${borderRadius}" ry="${borderRadius}"
                stroke="${strokeColor}" stroke-width="2" fill="none"
                stroke-dasharray="${dashArray}" stroke-dashoffset="${dashOffset}" />
              <!-- Text value in the middle -->
              <text x="25" y="25" fill="${textColor}" font-size="14" text-anchor="middle" dominant-baseline="middle">
                ${value}%
              </text>
            </svg>`;
        ]]]
    styles:
      custom_fields:
        rect:
          - position: absolute
          - top: 8px
          - right: 8px
          - width: 30%
          - height: auto

adjust the values to your needs…

2025-01-14 04.38.38

3 Likes

Thank you very much! :smiley:

Hi Everybody,
I think I tried everything but I struggle with mini-graph styling inside custom:button-card. I want to have my mini-graph background transparent in my button-card but I can’t achieve it. I’m ready to listen everyone and try everything because I’m on it for a week now. Thank for your time.
In my Dashboard, I have 3 cards :

  • 1st one is a mini-graph with transparent background : :white_check_mark:
  • 2nd one is a button-card with a mini-graph inside :red_circle:
  • 3rd one is a button_card_template and model has the same config as the second one :red_circle:
    Here is my card.
button_card_templates:
  room:
    custom_fields:
      graph:
        card:
          type: custom:mini-graph-card
          entities:
            - entity: sensor.thermometre_buanderie_temperature
            - entity: sensor.thermometre_buanderie_humidite
              y_axis: secondary
          card_mod: 
            style: |
              ha-card {
                --ha-card-background: rgba(50,50,50,0.1);
                border: none;
              }
    styles:
      card:
        - background-color: '#AA4787'
views:
  - title: Home
    sections:
      - type: grid
        cards:
          - type: custom:mini-graph-card
            entities:
              - sensor.thermometre_buanderie_temperature
            card_mod: 
              style: |
                ha-card {
                  --ha-card-background: rgba(50,50,50,0.1);
                  border: none;
                }
          - type: custom:button-card
            entity: sensor.lumieres_salon_count
            custom_fields:
              graph:
                card:
                  type: custom:mini-graph-card
                  entities:
                    - entity: sensor.thermometre_buanderie_temperature
                    - entity: sensor.thermometre_buanderie_humidite
                      y_axis: secondary
                  style: |
                    ha-card {
                      --ha-card-background: rgba(50,50,50,0.1);
                      background: #68957D;
                      color: black;
                      box-shadow: none;
                      border: none;
                    }
                    .header, .states, ha-icon {
                      color: white;
                    }
            styles:
              card:
                - background-color: '#AA4787'
          - type: custom:button-card
            entity: sensor.lumieres_salon_count
            template: room
    background:
      opacity: 33
      alignment: center
      size: cover
      repeat: repeat
      attachment: fixed
      image: /api/image/serve/64be908f395d615a7f3e29afd1bf76c7/original
    cards: []

Have everything working now :slight_smile:
One more question, is it also possible to style the color depending on the state of %?
Like:

if entity.name_of_entity >= 0 {
  const strokeColor = 'red';
}else if entity.name_of_entity >= 25 {
  const strokeColor = 'orange';
}else if entity.name_of_entity >= 50 {
  const strokeColor = 'green';
}

I tried the if and els after the ‘const’ and before the ‘return’, but it did not work.

First else needs to be an elif, and need an endif at the end after the else.

1 Like
1 Like

So i need to change it to a VAR.

This seems to work:

    [[[ 
      const fill = 'rgba(255,255,255,0.7)';
      const bgColor = '#d9d9d9';
      var bgActiveColor = '#4caf50';
      const width = 60;
      const height = 26;
      const dashArray = 2 * (width + height); // Total stroke length
      const value = Math.abs(states['sensor.kia_sportage_gt_ev_battery_level'].state);
      const dashOffset = dashArray * (1 - value / 100); 

    if (entity.state === 'home') {
      var bgActiveColor = '#000';
    } 
    else if (entity.state === 'home2') {
      var bgActiveColor = '#100';
    }
    
      return `

:smiley:

You can use it more simply like this…

  const colorMap = {
    'home': '#000',
    'home2': '#100',
  };

  let bgActiveColor = colorMap[entity.state] || '#4caf50'; // use default color if state is not in colorMap
  const state = states['senor.some_sensor'].state;
  let stateColor;
  if (state >= 75) {
    stateColor = '#FF5722'; // Highest priority
  } else if (state >= 45) {
    stateColor = '#FFEB3B';
  } else if (state >= 35) {
    stateColor = '#8BC34A';
  } else if (state >= 1) {
    stateColor = '#4CAF50';
  } else {
    stateColor = '#000000'; // Default color if no condition is met
  }
1 Like

or create a dedicated template sensor in HA, and use the state of that sensor entity.
that way you can easily use it everywhere you want to have that same color (eg in card-mod)

it’s by far the easiest way to do things like this, without blowing those configs out of proportion

example Is it possible to change header card icon based on entity state? - #10 by Mariusthvdb
check volgende_afval_kleur

1 Like

Thanks a lot both!

I now have this for my battery charging sensors:

custom_fields:
  RectP: |
    [[[ 
      const state = states['sensor.kia_sportage_gt_ev_battery_level'].state;
      let bgActiveColor;
        if (state >= 65) {
          bgActiveColor = '#00ae5b';
        } else if (state >= 25) {
          bgActiveColor = '#ff9532';
        } else if (state >= 0) {
          bgActiveColor = '#ff3e3e';
        } else {
          bgActiveColor = '#d9d9d9';
        }
      const fill = 'rgba(255,255,255,0.7)';
      const bgColor = '#d9d9d9';
      const width = 60;
      const height = 26;
      const dashArray = 2 * (width + height); // Total stroke length
      const value = Math.abs(states['sensor.kia_sportage_gt_ev_battery_level'].state);
      const dashOffset = dashArray * (1 - value / 100); 

      return `
      <svg viewBox="0 0 75 75">
        <rect x="8" y="8" width="${width}" height="${height}"
          rx="12" ry="12"
          stroke="${bgColor}" stroke-width="1" fill="${fill}" />
        <rect x="8" y="8" width="${width}" height="${height}"
          rx="12" ry="12"
          stroke="${bgActiveColor}" stroke-width="2" fill="none"
          stroke-dasharray="${dashArray}" stroke-dashoffset="${dashOffset}" />
        <text x="38" y="23" fill="rgba(62, 62, 62, 1.0);" 
          font-weight="normal" font-size="16" font-family="Sans-serif" 
          text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle">
          ${value}%
        </text>
      </svg>`;
    ]]]
  custom_fields:
    RectP:
      - position: absolute
      - top: 2px
      - right: 1px
      - width: 40%
      - height: auto

charging

Sounds easier to adapt in the cards.

You mean to create a template sensor that has the color settings in the template (amount % is color… )
and use that sensor in the card? but than i have to link that template sensor to the state of the sensor i use in the card.

            state-display {
              color: {{states('sensor.volgende_afval_kleur')}};
              text-transform: capitalize

have to put card_mod inside button_card in my case.

There is one “problem” with the active stroke, it is already full around 85%
I think that is because the start of the active border is not in the middle (but on the left) of the rect?

image

custom_fields:
  RectP: |
    [[[ 
      const state = states['sensor.afzuigkap_programma_voortgang'].state;
      let bgActiveColor;
        if (state >= 90) {
          bgActiveColor = '#00ae5b';
        } else if (state >= 50) {
          bgActiveColor = '#ffbe3e';
        } else if (state >= 25) {
          bgActiveColor = '#ff9532';
        } else if (state >= 0) {
          bgActiveColor = '#ff3e3e';
        } else {
          bgActiveColor = 'rgba(217,217,217,0.1)';
        }
      const value = Math.abs(states['sensor.afzuigkap_programma_voortgang'].state);
      const fill = 'rgba(255,255,255,0.7)';
      const bgColor = '#d9d9d9';
      const width = 60;
      const height = 26;
      const dashArray = 2 * (width + height);
      const dashOffset = dashArray * (1 - value / 100); 

      return `
      <svg viewBox="0 0 75 75">
        <rect x="8" y="8" width="${width}" height="${height}"
          rx="12" ry="12"
          stroke="${bgColor}" stroke-width="1" fill="${fill}" />
        <rect x="8" y="8" width="${width}" height="${height}"
          rx="12" ry="12"
          stroke="${bgActiveColor}" stroke-width="2" fill="none"
          stroke-dasharray="${dashArray}" stroke-dashoffset="${dashOffset}" />
        <text x="38" y="23" fill="rgba(62, 62, 62, 1.0);" 
          font-weight="normal" font-size="16" font-family="Sans-serif" 
          text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle">
          ${value}%
        </text>
      </svg>`;
    ]]]

no, not at all. you can use that same entity in the javascript .

seems to me you are way over your head here, creating difficult configs, while not understanding things.
simply c&p stuff we make for you wont help you in the long run

please educate yourself step by step, and make progress doing so.

playing with entities across the board in the various configurations is basic and required knowledge you should grasp first.

1 Like

Because you manipulate the border radius, the total stroke length is cut off…

const dashArray = 2 * ((width - 6) + (height - 5))
1 Like

This is partly true, I had an education in HTML, PHP and learned some GML(gamemaker) when i was 15 years.
I never did Javascript. I now made a lot of templates etc for HA now. I can say for my doing i run an “advanced” home assistant server now.
Starting with the help of the forum here and now I can do much more myself.
However, shit happens, and that made it very hard for me to learn total new things again.

So I am very great full for the help and things others can edit or explain to me in the community here. I learn to edit and change things and use this to make own new things again. I simply can not write new things from scratch again. But bit by bit i still make my HA the way i would like it :slight_smile:

:man_facepalming: yes of course haha
Thanks again! have it all working now :smiley:

care to have a look at New badges and card-mod customisation - #67 by Mariusthvdb please?

Seeking the border percentage on a badge is just a but more involved…