skip to Main Content

I want to create a graph similar to below in react apllication. But not getting option
to move text on left an right in highchart.

  1. Parameter avaialble in highchart (align) either left or right.
  2. Customize legend to appear on left and right based on requriement.
    Anyone aware how can we achieve below chart in highchart?
    [![Chart to be created][1]][1]
const options: Highcharts.Options = {
    chart: {
        type: 'bar',
        height: 125,
    },
    title: {
        text: '',
    },
    xAxis: {
        categories: ['basket compostion'],
        visible: false,
    },
    yAxis: {
        labels: {
            enabled: false,
        },
        visible: false,
        min: 0,
        title: {
            text: null,
        },
    },
    tooltip: {
        pointFormat:
            '<span style="color:{series.color}">{series.name}</span>: <b>' + '{point.percentage:.0f}%</b><br/>',
        shared: true,
    },
    legend: {
        align: 'right',
        verticalAlign: 'bottom',
        labelFormatter() {
            const alignment = this.index === this.chart.series.length - 1 ? 'Right Aligned' : 'Left Aligned';
            return `<div>${this.name} (${alignment})<div>`;
        },
        itemStyle: {
            fontSize: '14px',
        },
    },
    plotOptions: {
        bar: {
            stacking: 'percent',
            dataLabels: {
                enabled: true,
                align: 'left',
            },
            borderRadius: 5,
        },
    },
    series: [
        {
            name: 'other products',
            color: '#5041af',
            type: 'bar',
            data: [
                {
                    y: 81.2,
                    custom: { info: 47.29 },
                },
            ],
        },
        {
            name: 'focus',
            index: 0,
            color: '#21145f',
            type: 'bar',
            className: 'series-data-label',
            data: [
                {
                    y: 18.2,
                    custom: { info: 10.14 },
                },
            ],
        },
    ],
};

return (
    <div>
        <HighchartsReact highcharts={Highcharts} options={options} />
    </div>
);


  [1]: https://i.sstatic.net/9bTeAFKN.png

2

Answers


  1. Chosen as BEST ANSWER

    I was able to achive it by formatting datalabel

    const options: Highcharts.Options = {
            chart: {
                type: 'bar',
                height: 100,
                spacing: [0, 0, 0, 0],
            },
            title: {
                text: '',
            },
            xAxis: {
                categories: ['product Size'],
                visible: false,
            },
            yAxis: {
                labels: {
                    enabled: true,
                },
                visible: false,
                min: 0,
                title: {
                    text: null,
                },
            },
            tooltip: {
                outside: true,
            },
            legend: {
                floating: true,
                layout: 'horizontal',
                align: 'center',
                verticalAlign: 'bottom',
                itemStyle: {
                    fontSize: '14px',
                },
            },
            plotOptions: {
                bar: {
                    stacking: 'percent',
                    pointWidth: 32,
                },
            },
            series: [
                {
                    name: 'focus',
                    index: 1,
                    legendIndex: 0,
                    showInLegend: false,
                    color: '#5041af',
                    type: 'bar',
                    className: 'series-data-label',
                    data: [
                        {
                            y: 18.2,
                            custom: { info: 10.14 },
                        },
                    ],
                    dataLabels: {
                        padding: 0,
                        align: 'left',
                        enabled: true,
                        inside: true,
                        useHTML: true,
                        formatter() {
                            return `<div style="text-align: center;display:flex;flex-direction:column;align-items:start;font-size:20px;font-wight:500;margin-top: -5px;gap : 11px;font-family: var(--font-face)">
                            <div style="color: #1E1E1E;margin-bottom:3px;line-height:28 px">Focus</div>
                            <div style="font-size:16px;font-wight:500;;line-height:32px;adding-left:15px">10.14</div>
                            <div style="color: var(--disabled-L20);font-size:14px;font-wight:400;line-height:20 px">18.2% of total basket</div>                        
                            </div>`;
                        },
                    },
                    tooltip: {
                        pointFormat:
                            '<span style="color:{series.color}">' +
                            '{series.name}</span><br/><b>{point.y}</b> ' +
                            '({point.change}%)<br/>',
                        valueDecimals: 2,
                    },
                    label: {
                        enabled: true,
                    },
                },
                {
                    name: 'other products',
                    color: '#21145f',
                    type: 'bar',
                    index: 0,
                    legendIndex: 1,
                    showInLegend: false,
                    data: [
                        {
                            y: 81.2,
                            custom: { info: 47.29 },
                        },
                    ],
                    dataLabels: {
                        padding: 0,
                        align: 'right',
                        enabled: true,
                        inside: true,
                        useHTML: true,
                        formatter() {
                            return `<div style="text-align: center;display:flex;flex-direction:column;align-items:flex-end;font-size:20px;font-wight:500;margin-top: -5px;gap : 11px;font-family: var(--font-face)">
                            <div style="color: #1E1E1E;margin-bottom:3px;line-height:28 px;">Rest of Basket</div>
                            <div style="font-size:16px;font-wight:500;line-height:32px;padding-right:16px;">10.14</div>
                            <div style="color: var(--disabled-L20);font-size:14px;font-wight:400;line-height:20 px;">18.2% of total basket</div>                        
                            </div>`;
                        },
                    },
                    tooltip: {
                        pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>81.2</b><br/>',
                    },
                },
            ],
        };
    
    

  2. There isn’t a direct API option to achieve this, but you can simulate the alignment by translating the legend items.

      chart: {
        events: {
          render: function () {
            const chart = this,
              legend = chart.legend,
              items = legend.allItems
    
            const leftItem = items[0],
              rightItem = items[1]
    
            const leftItemBBox = leftItem.legendItem.group.element.getBBox(),
              rightItemBBox = rightItem.legendItem.group.element.getBBox()
    
            leftItem.legendItem.group.attr({
              translateX:
                -chart.plotWidth / 2 + chart.plotLeft + leftItemBBox.width,
            })
    
            rightItem.legendItem.group.attr({
              translateX:
                chart.plotWidth / 2 - chart.plotLeft + rightItemBBox.width,
            })
          },
        },
      },
    

    Demo:
    https://jsfiddle.net/BlackLabel/pm5wotu6/

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search