7

How can I change the maximum width/height an item bar has in Apexcharts? (https://apexcharts.com/)

I have an horizontal bar chart whose data are loaded dynamically and the number of users (items) varies. When there are few or only one user the bar looks very huge, I would like to set the height to max 50px.

The code:

    var timeChart = {
            formatter: function (value) {
              var v = formatFromSeconds(value);
              return v;
            }
          };    
    var desv_time = function (value) {
      var v = formatFromSeconds(value);
      if (value>0)return "+"+v;
      else return v;
    }

    //CHART
    var chart1 = new ApexCharts( document.querySelector("#chart-desv"),
    {
      chart: {
          id: 'chart1',
          type: 'bar'
      },
      plotOptions: {
          bar: {
            horizontal: true,
          },
      },
      dataLabels: {
        enabled: true,
        formatter: desv_time,
        style: {
          colors: ["#000"]
        }
      },
      series: [],
      xaxis: {labels: {
        formatter: desv_time,
      }},
      tooltip: {
        followCursor: true,
        x: {
          formatter: function(value) {
            return value;
          },
        },
        y: {
            formatter: desv_time,
            title: {formatter: (seriesName) => 'Time difference',}
        },
        marker: {show:false}
      },
      title: { text: "Usual workday duration: 08:00", align: "center" }
    });
    chart1.render();

Screenshot (very huge bar with one user):

enter image description here

LauraEld
  • 327
  • 1
  • 3
  • 13

4 Answers4

11

I'm using an approach similar to @Oscar Schafer's

I've found that, for my case, the width could be based on the length of my series.

The premises are:

  • When we have few items, e.g. 1 or 2, the chart width will be filled with only these columns. Then, if I have few items, the columnWidth should be proportionally smaller (close to 20% in my case)

enter image description here

  • When we have more items, they all share the chart width and fill it more smoothly. Then, if I have a lot of items, the column should be proportionally larger (close to 80%)

enter image description here

I've used the LOGISTIC-GROWTH MODEL as a function to calculate the bar width

enter image description here

Here is the code for to calculate the column width:

// f(x) = c / (1 + a*exp(-x*b)) -> LOGISTIC GROWTH MODEL
var optimalColumnWidthPercent = 20 + (60 / (1 + 30*Math.exp(-seriesLength /3)));

// 20: minimum width should be close to 20 (when only one item)
// 20+60: maximum width should be close 80
// 30 and 3: the a and b from the function, I've selected after testing some cenarios from seriesLength from 1 to 12 and finding which worked for me

...

plotOptions: {
  bar: {
    columnWidth: optimalColumnWidthPercent + "%"
  },
},
4

For a horizontal bar chart, you can use the barHeight property to set the height of the bars. Unfortunately it can't be set as a pixel value but instead is "the percentage of the available height in the grid-rect" (from docs).

Effectively it works as a maximum height, so the bars will shrink if there's more data that needs to fit.

plotOptions: {
      bar: {
          barHeight: '70%'
      }
}
Oscar Schafer
  • 1,215
  • 1
  • 12
  • 25
3

Here's how I achieve this behaviour in VueJS.

Template part

<apexchart :options="barChartOptions" :series="series"></apexchart>

Script Part

computed() {
    chartOptions() {
        return {
            chart: {
                type: 'bar',
                height: 100 + this.myData.length() * barWidth,
            }
        }
    }
}

Where myData is an array of data that contains the information to be plotted and barWidth is the width of each bar that I want. Note that this essentially fixes the width of each bar and then resizes the height of the chart as a linear function of the number of bars.

Arjan Singh Bal
  • 133
  • 1
  • 8
3

For a horizontal bar chart, you can use the columnWidth property to set the widthof the bars. Unfortunately it can't be set as a pixel value but instead is "the percentage of the available widthin the grid-rect" (from docs).

Effectively it works as a maximum width, so the bars will shrink if there's more data that needs to fit. here,

plotOptions: { bar: { horizontal: false, borderRadius: 10, columnWidth: '45%', }, },

raseeth
  • 31
  • 1