apexcharts / apexcharts.js

📊 Interactive JavaScript Charts built on SVG
https://apexcharts.com
MIT License
14.22k stars 1.29k forks source link

Give datapoint and series indexes to "click" chart event. #1017

Closed ThinkSalat closed 2 years ago

ThinkSalat commented 4 years ago

I'm trying to set an annotation on the x axis that displays the date where ever the user clicks.

It's a date, so I need the data from my series, something like how other events give you access to the series and the datapoint and series indices.

The arguments we have access to are event, context, and config. I can't seem to figure out how to access the actual data using that information.

mikedotJS commented 4 years ago

I kind of have a similar problem.

Something strange happened, i used to use the dataPointIndex property to render specific data and it worked pretty well but i discovered after seeing that i rendered no data that the config property didn't contain the dataPointIndex property anymore, it only contains config and globals.

I did not update the package.

Is there a condition for config to give dataPointIndex ?

junedchhipa commented 4 years ago

@mikedotJS Which event you used to get dataPointIndex? The click event?

mikedotJS commented 4 years ago

Yes, the click event from a Bar typed chart.

junedchhipa commented 4 years ago

It provides the correct seriesIndex and dataPointIndex when I tried on a column/bar chart. Can you please provide your code?

mikedotJS commented 4 years ago

The code, working pretty well until recently.

  const handleBarClick = ({ clientX, clientY }, chartContext, { dataPointIndex ) => {
    setAreDetailsVisible(areVisible => {
      if (!areVisible) {
        setDetailsStyle({
          ...detailsDefaultStyle,
          left: clientX,
          top: clientY,
        });
        setCurrentDataPointIndex(dataPointIndex);
      }
      return !areVisible;
    });
  };

  const barOptions = {
    chart: {
      events: {
        click: handleBarClick,
      },
    },
    plotOptions: {
      bar: {
        horizontal: true,
      },
    },
    colors,
    dataLabels: {
      enabled: true,
    },
    xaxis: {
      categories: personaeNames,
    },
  };

const barSeries = [
    {
      data: personaeIndexes,
    },
  ];

<Chart
   height="100%"
   options={barOptions}
   series={barSeries}
   type="bar"
   width="100%"
/>
mikedotJS commented 4 years ago

image

mikedotJS commented 4 years ago

I just tested on a brand new CodeSandbox and it worked as it did formerly for me.

image

So now the question is : what in my context makes them disappear ?

ThinkSalat commented 4 years ago

const handleBarClick = ({ clientX, clientY }, chartContext, { dataPointIndex ) => {

Whoa. Just tried destructuring the way you did and it worked! Amazing!

Now I'm having another issue. I'm adding annotations using ApexCharts.exec(chartId, 'addXaxisAnnotation', params) in the onClick event.

I also check if there is an existing annotations using context.config.annotations.xaxis

However, the annotations I'm adding are not showing up here.

instead of switching the date and location of the annotation, it's just adding a bunch of new ones, and none of them show up in the context. how can we access the current annotations from the click event?

mraghuram commented 4 years ago

I have a question, the dataPointIndex is -1 for the first item. Shouldn't this be 0?

amstrad commented 4 years ago

Hi, i´m using vue-apex-chart and i can´t sadly get dataPointIndex when using click event.. it does on dataPointSelection event..but sadly that only works when i click over the bar with data, not good experience for low or zero heigh bars...maybe i´m doing something wrong or should i check something else than click/dataPointIndex Would appreciate any idea Captura de pantalla 2019-11-05 a las 18 37 49

sleleko commented 4 years ago

Hi! How open other detailed chart when I get seriesIndex and dataPointIndex? And how send it's for open new chart with more detailed info? May be any were exist some example ?

sleleko commented 4 years ago

Hi, i´m using vue-apex-chart and i can´t sadly get dataPointIndex when using click event.. it does on dataPointSelection event..but sadly that only works when i click over the bar with data, not good experience for low or zero heigh bars...maybe i´m doing something wrong or should i check something else than click/dataPointIndex Would appreciate any idea Captura de pantalla 2019-11-05 a las 18 37 49

Hi! try use example from doc (https://apexcharts.com/docs/options/chart/events/) chart: { events: { click: function(event, chartContext, config) { // The last parameter config contains additional information likeseriesIndexanddataPointIndexfor cartesian charts } } }

In config you can find dataPointIndex . But how work with him? I,m use vue-apexcharts too

github-actions[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Gloriazira commented 11 months ago

hi everyone. i am a newbie to reacjs apex chart. I have this graph. the first grap is for LGAs in that state and the second graph for the wards in a particular lga. i want to add a click event to the first bar chart. that when I click a bar for a particular lga, the second graph will show the graph for all the wards in that lga. how can I achieve this?

Annotation 2023-10-04 145704

this the chart component : import React from 'react'; import ReactApexChart from 'react-apexcharts';

const StackedBarChart = ({ data, width, chartTitle, onBarClick }) => { const options = { chart: { type: 'bar', height: 600, stacked: true, toolbar: { show: false, }, }, // xaxis: { // categories: data.map((item) => item.name), // title: { // text: 'LGA\'s', // }, // },

    xaxis: {
        categories: data.map((item) => item.name),
        title: {
            text: chartTitle,
        },
    },

    yaxis: {
        title: {
            text: 'Number of Employees',
        },
        min: 0,
        max: 1000,
        tickAmount: 10
    },
    grid: {
        show: false,
    },
    colors: ['#007BFF', '#FF3366'],
    plotOptions: {
        bar: {
            horizontal: false,
            barWidth: '10px',
            dataLabels: {
                total: {
                    enabled: true,
                    style: {
                        fontSize: '16px',
                        fontWeight: 900
                    }
                }
            },
            events: {
                dataPointSelection: (event, chartContext, config) => {
                    if (onBarClick) {
                        const selectedLabel = config.w.config.labels[config.dataPointIndex];
                        onBarClick(selectedLabel);
                    }
                },
            },

        },

    },
    dataLabels: {
        enabled: true,
        style: {
            fontSize: '14px',
            fontWeight: 500
        }
    },
    legend: {
        show: false,
    },
    responsive: [
        {
            breakpoint: 768,
            options: {
                xaxis: {
                    labels: {
                        rotate: -45,
                    },
                },
            },
        },
    ],
    states: {
        hover: {
            filter: {
                type: 'none', // Disable hover effect (solid colors)
            },
        },
    },
};

const series = [
    {
        name: 'Males',
        data: data.map((item) => item.males),
    },
    {
        name: 'Females',
        data: data.map((item) => item.females),
    },
];

return (
    <div className="stacked-bar-chart" style={{ width: width }}>
        <ReactApexChart options={options} series={series} type="bar" height={400} />
    </div>
);

};

export default StackedBarChart; import React from 'react'; import ReactApexChart from 'react-apexcharts';

const StackedBarChart = ({ data, width, chartTitle, onBarClick }) => { const options = { chart: { type: 'bar', height: 600, stacked: true, toolbar: { show: false, }, }, // xaxis: { // categories: data.map((item) => item.name), // title: { // text: 'LGA\'s', // }, // },

    xaxis: {
        categories: data.map((item) => item.name),
        title: {
            text: chartTitle,
        },
    },

    yaxis: {
        title: {
            text: 'Number of Employees',
        },
        min: 0,
        max: 1000,
        tickAmount: 10
    },
    grid: {
        show: false,
    },
    colors: ['#007BFF', '#FF3366'],
    plotOptions: {
        bar: {
            horizontal: false,
            barWidth: '10px',
            dataLabels: {
                total: {
                    enabled: true,
                    style: {
                        fontSize: '16px',
                        fontWeight: 900
                    }
                }
            },
            events: {
                dataPointSelection: (event, chartContext, config) => {
                    if (onBarClick) {
                        const selectedLabel = config.w.config.labels[config.dataPointIndex];
                        onBarClick(selectedLabel);
                    }
                },
            },

        },

    },
    dataLabels: {
        enabled: true,
        style: {
            fontSize: '14px',
            fontWeight: 500
        }
    },
    legend: {
        show: false,
    },
    responsive: [
        {
            breakpoint: 768,
            options: {
                xaxis: {
                    labels: {
                        rotate: -45,
                    },
                },
            },
        },
    ],
    states: {
        hover: {
            filter: {
                type: 'none', // Disable hover effect (solid colors)
            },
        },
    },
};

const series = [
    {
        name: 'Males',
        data: data.map((item) => item.males),
    },
    {
        name: 'Females',
        data: data.map((item) => item.females),
    },
];

return (
    <div className="stacked-bar-chart" style={{ width: width }}>
        <ReactApexChart options={options} series={series} type="bar" height={400} />
    </div>
);

};

export default StackedBarChart;

and this is the parent component:

import React, { useState, useEffect } from "react"; import { useNavigate } from "react-router-dom"; import admin from "../../../class/admin.class"; import { useQuery } from 'react-query'; import { toast } from "react-toastify"; import StackedBarChart from "./DashboardAnalyticBarchart"; import './dasboardanalytics.css'; import DonutPieChart from "./DashboardPieChart"; import dataOBJs from "../../../class/data.class"; import AdminEmployeeFilterComponent from "../admin_employee_list_page/AdminEmployeeFilterComponent";

const fetchDataSummary = async (key) => {

try {

    const res = await admin.getDataCount();

    return res

} catch (error) {

    toast.error(error?.error);
}

};

const fetchWardsData = async (key) => { try { const [wardData] = await Promise.all([

        dataOBJs.getWards(),
    ]);
    return {
        wardData,
    };
} catch (error) {
    toast.error(error?.error);
}

};

export default function DashboardAnalytics() {

const { data, status } = useQuery(['fetchDataSummary'], fetchDataSummary);

const [selectedLGA, setSelectedLGA] = useState(null);

const handleLGAClick = (lgaName) => {
    // Set the selected LGA when a bar chart is clicked
    setSelectedLGA(lgaName);
};

const localGovernmentData = [

    {
        name: 'Fufore',
        males: 500,
        females: 250,
    },
    {
        name: 'Guyuk',
        males: 400,
        females: 600,
    },

];

const localGovernmentWardsData = [
    {
        id: 1,
        title: "Fufore",
        wards: [
            {
                name: 'Yadim',
                males: 300,
                females: 100,
            },
            {
                name: 'Gushim',
                males: 200,
                females: 150,
            },
        ],
    },
    {
        id: 2,
        title: "Guyuk",
        wards: [
            {
                name: 'chikila',
                males: 180,
                females: 450,
            },
            {
                name: 'Gushim',
                males: 120,
                females: 150,
            },
        ],
    },
];

const maleCount = 250;
const femaleCount = 350;
const socuCount = 150;
const nonsocuCount = 50;

return (
    <div className="dashboard-analytic-section">

        <div>
            <div className="d-flex align-items-center justify-content-between summary-card">

                <div className="card">
                    <h1 className="number">{data?.data?.beneficiaryCount}</h1>
                    <p>Total Beneficiaries</p>
                </div>
                <div className="card">
                    <h1 className="number">{data?.data?.lgaCount}</h1>
                    <p>Total LGA's</p>
                </div>

                <div className="card">
                    <h1 className="number">2</h1>
                    <p>Total Wards</p>
                </div>
            </div>
        </div>

        <div className=" d-flex justify-content-around dashboard-analytic-graps mt-5 ">
            <div className="container-fluid p-3 mt-3">
                <div className="d-flex align-items-center justify-content-between filter-dashboard-analytic">
                    <h1 className="">{data?.data?.beneficiaryCount}</h1>
                    <AdminEmployeeFilterComponent showLastSelect={false} />
                </div>
                <div className="dashboard-analytic-barchart mt-5">
                    {/* <StackedBarChart data={getChartData()} onBarClick={handleLGAClick} /> */}

                    <StackedBarChart data={localGovernmentData} chartTitle="LGA" />

                    <StackedBarChart data={localGovernmentWardsData} chartTitle="Ward" onBarClick={handleLGAClick} />

                </div>
            </div>

            <div className=" dashboard-analytic-pie px-3" >

                <div className="d-flex flex-column align-items-center donut-pie-chart-div">
                    <p>Gender Representation</p>

                    <DonutPieChart data={[
                        { label: 'Male', value: maleCount },
                        { label: 'Female', value: femaleCount },
                    ]}
                        colors={['#007BFF', '#FF3366']} />
                </div>

                <div className="d-flex flex-column align-items-center donut-pie-chart-div">
                    <p>SOCU and Non-SOCU Representation</p>
                    <DonutPieChart
                        data={[
                            { label: 'SOCU', value: socuCount },
                            { label: 'Non-SOCU', value: nonsocuCount },
                        ]}
                        colors={['#F99C39', '#231d18']}
                    />
                </div>
            </div>
        </div>
    </div>
)

}