web-humas-fe/components/ui/maps-charts.tsx

138 lines
3.3 KiB
TypeScript

import React, { useEffect, useRef, useState } from "react";
import * as echarts from "echarts";
import indonesiaGeo from "../../public/assets/geo/indonesia.json";
const IndonesiaMap = (props: { data: any }) => {
const chartRef = useRef<HTMLDivElement>(null);
const myChart = useRef<echarts.EChartsType | null>(null);
const [selectedProvince, setSelectedProvince] = useState("");
const selectedProvinceRef = useRef<string | null>(null);
const chartOptionRef = useRef<any>(null);
const option = {
backgroundColor: "#d3d3d3",
title: {
text: "Sebaran Data",
left: "center",
textStyle: { color: "#000" },
},
visualMap: {
min: 0,
max: 100,
show: true,
seriesIndex: 0,
inRange: {
color: ["#ff0000", "#ffffff"],
},
},
series: [
{
type: "map",
map: "indonesia",
roam: true,
zoom: 1.2,
center: [118, -2],
label: {
show: false,
color: "#000",
},
itemStyle: {
borderColor: "#999",
},
emphasis: {
label: {
show: true,
color: "#000",
},
itemStyle: {
areaColor: "#ffcccc",
},
},
data: props.data,
},
],
};
useEffect(() => {
if (!chartRef.current) return;
(window as any).echarts = echarts;
const fixedGeo = {
...indonesiaGeo,
features: indonesiaGeo.features.map((f) => ({
...f,
properties: {
...f.properties,
name: f.properties.PROVINSI,
},
})),
};
echarts.registerMap("indonesia", fixedGeo as any);
const chart = echarts.init(chartRef.current);
myChart.current = chart;
chart.on("click", (params: any) => {
highlightProvince(params.name);
});
chartOptionRef.current = option;
chart.setOption(option);
return () => {
chart.dispose();
};
}, []);
const highlightProvince = (name: string) => {
if (!myChart.current || !chartOptionRef.current) return;
myChart.current.clear();
myChart.current.setOption(chartOptionRef.current);
myChart.current.dispatchAction({
type: "highlight",
name,
});
myChart.current.dispatchAction({
type: "showTip",
name,
});
selectedProvinceRef.current = name;
};
return (
<div className="flex flex-col lg:flex-row gap-6 w-full pr-2 md:pr-0">
<div className="w-screen md:w-[70%] h-[360px] lg:h-[600px]">
<div ref={chartRef} style={{ height: "100%", width: "100%" }} />
</div>
<div className="w-screen md:w-[30%] h-[360px] lg:h-[600px] overflow-auto flex flex-col">
{props.data.map((list: any) => (
<a
key={list.name}
onClick={() => highlightProvince(list.name)}
className={`w-full flex flex-row cursor-pointer gap-2 ${
selectedProvince === list.name ? "bg-slate-300" : ""
}`}
>
<p className="w-4/5">{list.name}</p>{" "}
<p
className={`w-1/5 ${
selectedProvince === list.name ? "bg-slate-300" : "bg-[#a9d7e4]"
} text-black border-white text-center`}
>
{list.value}
</p>
</a>
))}
</div>
</div>
);
};
export default IndonesiaMap;