apexchartsreact-apexcharts

Line chart combination numeric x-Axis and discrete markers throws error


I am trying to create a line chart that has an numeric axis scales, I want to apply conditional styling to the marker points, I know that this is done with the property markers.discrete but I'm having trouble applying it:

here is an example sandbox: https://codesandbox.io/p/sandbox/apexcharts-responsiveness-px56nz#

Basically I'm trying to set a standard size of 6 for all markers and for one of the lines it should only display the markers at the Integer values:

markers: { size: 6, discrete: [ { seriesIndex: 0, dataPointIndex: [2, 3, 5, 6, 8, 9, 10], size: 6, },

rendered chart for the example

Still all markers are being displayed? How would I do this correctly?

Any help is really appreciated. :)


Solution

  • There are two issues with your code:

    With these, the solution would be:

    {    
        // ........ other settings
        markers: {
            size: [0, 6],
            discrete: [
                ...[2, 3, 5, 6, 8, 9, 10].map((index) => ({
                    seriesIndex: 0,
                    dataPointIndex: index,
                    fillColor: "#008FFB",
                    size: 6,
                }))
            ]
        }
    }
    

    This however doesn't work, for what seems to be a series of bugs in apexcharts. Firstly, when hovering a zero sized marker, there an error pointsArr is undefined in Position.moveDynamicPointOnHover (jsFiddle). Secondly, if we use size 1 instead of 0 (or a value smaller than 1 to make it not visible), the hover size is computed for the first series using the base size of 1 (or whatever value was set in markers.size[0], never using the discrete value of 6 for those markers that have it set.

    Then, a solution that works, is to set the discrete properties for all the markers of the first series:

    {    
        // ........ other settings
        markers: {
            size: 6,
            discrete: [
                ...Array.from({length: 12}, (_, index) => ({
                    seriesIndex: 0,
                    dataPointIndex: index,
                    fillColor: "#008FFB",
                    strokeColor: "#FFF", // use background color
                    size: [2, 3, 5, 6, 8, 9, 10].includes(index) ? 6 : 0
                }))
            ]
        }
    }
    

    This might need some tinkering with the tooltip, depending on what result one expects to have, for instance on a marker of size zero.

    Stack snippet demo:

    const chartData = {
        series: [
            {
                name: "Actual",
                data: [
                    [1, 2],
                    [2, 3],
                    [3, 4],
                    [4, 2],
                    [5, 5],
                    [6, 4],
                    [7, 5],
                    [8, 5],
                    [9, 6],
                    [10, 5],
                    [11, 4],
                    [12, 3],
                ],
            },
            {
                name: "Target",
                data: [
                    [1.5, 3],
                    [2, 3],
                    [3, 3],
                    [4.5, 3],
                    [5, 4],
                    [5.5, 3],
                    [6, 4],
                    [7.5, 4.5],
                    [8, 4],
                    [9, 4],
                    [10, 4],
                    [11, 4.5],
                ],
            },
        ],
        //options: {
            chart: {
                type: "line",
                height: 350,
            },
            xaxis: {
                type: "numeric",
            },
            legend: {
                show: true,
            },
            markers: {
                size: 6,
                discrete: [
                    ...Array.from({length: 12}, (_, index) => ({
                        seriesIndex: 0,
                        dataPointIndex: index,
                        fillColor: "#008FFB",
                        strokeColor: "#FFF",
                        size: [2, 3, 5, 6, 8, 9, 10].includes(index) ? 6 : 0
                    })),
                ]
            },
        //},
    };
    
    const chart = new ApexCharts(document.querySelector("#chart"), chartData);
    chart.render();
    <div id="chart"></div>
    <script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>