import React, { useState, useCallback, useEffect, useRef } from "react"; import ReactApexChart from "react-apexcharts"; import ApexCharts from "apexcharts"; import { init } from "next/dist/compiled/webpack/webpack"; const wilayah = ["sumut", "bali", "jateng", "jabar", "metro", "papua", "riau"]; type TypeItem = { year: number; month: number; user: { list: { name: string; count: number }[]; }[]; }; interface MappedData { result: { x: string; y: number }[] | []; details: { name: string; count: number }[][]; } const generateDummyData = () => { const getDaysInMonth = (year: number, month: number) => { return new Date(year, month, 0).getDate(); }; const dummy = []; for (let month = 1; month <= 7; month++) { const userData = []; const year = new Date().getFullYear(); const daysInMonth = getDaysInMonth(year, month); for (let day = 1; day <= daysInMonth; day++) { // Buat 2-4 wilayah acak per hari const regionCount = Math.floor(Math.random() * 3) + 2; const usedRegions = wilayah .sort(() => 0.5 - Math.random()) .slice(0, regionCount); const list = usedRegions.map((name) => ({ name, count: Math.floor(Math.random() * 10) + 1, })); userData.push({ list }); } dummy.push({ year: year, month, user: userData, }); } return dummy; }; const dummy = generateDummyData(); const colors = ["#008FFB"]; export const makeDataByMonth = ( data: TypeItem[], month: number ): MappedData => { const result: { x: string; y: number }[] = []; const details: { name: string; count: number }[][] = []; const filtered = data.find((entry) => entry.month === month); if (!filtered) return { result: [], details: [] }; filtered.user.forEach((u, idx) => { const total = u.list.reduce((sum, item) => sum + item.count, 0); details.push(u.list); console.log("u.list", u.list); result.push({ x: (idx + 1).toString(), y: total, }); }); return { result, details }; }; export const makeDataByRange = ( data: TypeItem[], startMonth: number, startDay: number, endMonth: number, endDay: number ) => { const user: number[] = []; const labels: string[] = []; const details = []; const result: { x: string; y: number }[] = []; const sortedData = data.sort((a, b) => a.month - b.month); for (const monthData of sortedData) { const { month, user: u } = monthData; if (month < startMonth || month > endMonth) continue; let startIndex = 0; let endIndex = u.length - 1; if (month === startMonth) startIndex = startDay - 1; if (month === endMonth) endIndex = endDay - 1; for (let i = startIndex; i <= endIndex; i++) { const userEntry = u[i]; if (!userEntry) continue; const total = userEntry.list.reduce((sum, item) => sum + item.count, 0); user.push(total); details.push(userEntry.list); const label = `${(i + 1).toString().padStart(2, "0")} - ${month .toString() .padStart(2, "0")}`; labels.push(label); } } for (let i = 0; i < user.length; i++) { result.push({ x: labels[i], y: user[i] }); } return { result, details }; }; const ApexChartDynamic = (props: { type: string; date: string; range: { start: any; end: any }; }) => { const { date, type, range } = props; const [state, setState] = useState<{ series: ApexAxisChartSeries; options: ApexCharts.ApexOptions; seriesQuarter: ApexAxisChartSeries; }>({ series: [{ data: [] }], options: { chart: { id: "barYear", height: 600, width: "100%", type: "bar", events: { dataPointSelection: function (e, chart, opts) { const quarterChartEl = document.querySelector("#chart-quarter"); const yearChartEl = document.querySelector("#chart-year"); if (!quarterChartEl || !yearChartEl) return; if (opts.selectedDataPoints[0].length === 1) { if (quarterChartEl.classList.contains("active")) { updateQuarterChart(chart, "barQuarter"); } else { yearChartEl.classList.add("chart-quarter-activated"); quarterChartEl.classList.add("active"); updateQuarterChart(chart, "barQuarter"); } } else { updateQuarterChart(chart, "barQuarter"); } if (opts.selectedDataPoints[0].length === 0) { yearChartEl.classList.remove("chart-quarter-activated"); quarterChartEl.classList.remove("active"); } }, updated: function (chart) { updateQuarterChart(chart, "barQuarter"); }, }, }, plotOptions: { bar: { distributed: true, horizontal: true, barHeight: "100%", dataLabels: { position: "bottom", }, }, }, dataLabels: { enabled: true, textAnchor: "start", style: { colors: ["#fff"], }, formatter: function (_val, opt) { return opt.w.globals.labels[opt.dataPointIndex]; }, offsetX: 0, dropShadow: { enabled: true, }, }, colors: colors, states: { normal: { filter: { type: "desaturate", }, }, active: { allowMultipleDataPointsSelection: false, filter: { type: "darken", value: 1, }, }, }, legend: { show: false, }, tooltip: { x: { show: false }, y: { title: { formatter: ((_seriesName: string, opts: any) => opts.w.globals.labels[opts.dataPointIndex]) as ( seriesName: string ) => string, }, }, }, yaxis: { labels: { show: false, }, }, }, seriesQuarter: [{ data: [] }], }); const [years, setYear] = useState(""); const [datas, setDatas] = useState([]); const [details, setDetails] = useState<{ name: string; count: number }[][]>( [] ); const detailsRef = useRef(details); useEffect(() => { detailsRef.current = details; }, [details]); useEffect(() => { initFetch(); }, [date, range.start, range.end, type]); const initFetch = async () => { const splitDate = date.split(" "); const splitDateDaily = String(range.start.year); const currentYear = type === "monthly" ? splitDate[1] : splitDateDaily; let data = []; if (currentYear === years) { console.log("if", datas); data = datas; } else { // const res = await getStatisticMonthly( // type === "monthly" ? splitDate[1] : splitDateDaily // ); // data = res?.data?.data; data = dummy; console.log("dataaa", data); setDatas(data); setYear(currentYear); } // console.log("datas", data); if (data) { if (type == "monthly") { const mappedData: MappedData = makeDataByMonth( data, Number(splitDate[0]) ); console.log("mapped month", mappedData); setDetails(mappedData.details); setState((prev) => ({ ...prev, series: [{ data: mappedData.result }], })); } if (type == "daily") { const mappedData = makeDataByRange( data, range.start.month, range.start.day, range.end.month, range.end.day ); console.log("mmapped,", mappedData.details); setDetails(mappedData.details); setState((prev) => ({ ...prev, series: [{ data: mappedData.result }], })); } } else { setState((prev) => ({ ...prev, series: [{ data: [] }], })); } }; const updateQuarterChart = useCallback( (chart: any, id: string) => { const selectedIndex = chart?.w?.config?.series[0]?.data?.findIndex( (d: any, i: number) => { return chart.w.globals.selectedDataPoints[0]?.includes(i); } ); if (selectedIndex !== -1) { const counts = detailsRef.current[selectedIndex]; console.log("countres", counts, detailsRef); const quarterData = [ { name: `${selectedIndex + 1}`, data: counts, }, ]; ApexCharts.exec(id, "updateSeries", quarterData); setState((prev: any) => ({ ...prev, seriesQuarter: quarterData, })); } }, [detailsRef] ); return (
{state.seriesQuarter[0].data.map((list: any, index) => (

{list?.name} :

{list?.count}

))}
); }; export default ApexChartDynamic;