import { useQuery } from "@tanstack/react-query"; import { BarController, BarElement, CategoryScale, Chart as ChartJS, Tooltip as ChartTooltip, Legend, LinearScale, LineElement, PointElement, Title, } from 'chart.js'; import { Line } from "react-chartjs-2"; import { api } from "../api.js"; ChartJS.register( CategoryScale, BarController, PointElement, LineElement, LinearScale, BarElement, Title, ChartTooltip, Legend ); const GRAPH_LABELS_MAP= { target_dist_shap: "Расстояние до ближайшего постамата Мой постамат", target_post_cnt_shap: "Кол-во точек Мой постамат*", target_cnt_ao_mean_shap: "Средний трафик в точках Мой постамат в АО", rival_pvz_cnt_shap: "Кол-во ПВЗ*", rival_post_cnt_shap: "Кол-во постаматов конкурентов *", metro_dist_shap: "Расстояние до метро", property_price_bargains_shap: "Цена сделок жилой недвижимости*", property_price_offers_shap: "Цена предложений жилой недвижимости*", property_mean_floor_shap: "Средняя этажность застройки*", property_era_shap: "Эпоха жилой недвижимости*", flats_cnt_shap: "Кол-во квартир*", popul_home_shap: "Численность проживающего населения*", popul_job_shap: "Численность работающего населения*", yndxfood_sum_shap: "Сумма заказов Яндекс.Еда*", yndxfood_cnt_shap: "Кол-во заказов Яндекс.Еда*", school_cnt_shap: "Кол-во школ*", kindergar_cnt_shap: "Кол-во детсадов*", public_stop_cnt_shap: "Кол-во остановок общ. транспорта*", sport_center_cnt_shap: "Кол-во спортивных центров*", pharmacy_cnt_shap: "Кол-во аптек*", supermarket_cnt_shap: "Кол-во супермаркетов*", supermarket_premium_cnt_shap: "Кол-во премиальных супермаркетов*", clinic_cnt_shap: "Кол-во поликлиник*", bank_cnt_shap: "Кол-во банков*", reca_cnt_shap: "Кол-во точек общепита*", lab_cnt_shap: "Кол-во лабораторий*", culture_cnt_shap: "Кол-во объектов культуры*", attraction_cnt_shap: "Кол-во достопримечательностей*", mfc_cnt_shap: "Кол-во МФЦ*", bc_cnt_shap: "Кол-во бизнес-центров*", tc_cnt_shap: "Кол-во торговых центров*", business_activity_shap: "Бизнес активность", } export const PointChart = ({ point }) => { const { data: meanData } = useQuery( ["mean-data"], async () => { const { data } = await api.get( `https://postamates.spatialsystems.ru/api/avg_bi_values/` ); return data; }, { refetchOnWindowFocus: false, refetchOnMount: false } ); const options = { indexAxis: 'y', elements: { bar: { borderWidth: 0, borderRadius: 5, pointStyle: 'circle' }, }, plugins: { legend: { display: false }, tooltip: { displayColors: false, yAlign: "top", callbacks: { label: function(context) { const label = [] const shap_key = Object.keys(GRAPH_LABELS_MAP).find(key => GRAPH_LABELS_MAP[key] === context.label); const key = shap_key.substring(0, shap_key.length - 5) if (context.datasetIndex === 0) label.push("Значение: " + point[key]); if (context.parsed.x !== null) { let labelText = ""; if (context.datasetIndex === 0) labelText = "Вклад в прогноз, %: "; if (context.datasetIndex === 1) labelText = "Минимальный вклад в прогноз, %: "; if (context.datasetIndex === 2) labelText = "Максимальный вклад в прогноз, %: "; label.push(labelText + context.parsed.x); } return label; }, body: () => { return "Вклад в прогноз, %:" } } }, }, scales: { y: { stacked: true, }, x: { title: { display: true, text: 'Вклад в прогноз, %', }, grid: { color: function(context) { if (context.tick.value === 0) { return "#000000"; } return "#E5E5E5"; }, }, } } }; const labels = Object.keys(GRAPH_LABELS_MAP).sort((a, b) => { if (Math.abs(point[a]) < Math.abs(point[b])) return 1; else return -1; }).slice(0, 15); const data = { labels: labels.map((l) => GRAPH_LABELS_MAP[l]), datasets: [ { data: labels.map((l) => point[l]), backgroundColor: labels.map((l) => point[l]).map(v => v <= 0 ? '#CC2500' : '#278211'), hoverBackgroundColor: labels.map((l) => point[l]).map(v => v <= 0 ? '#F22C00' : '#2DB20C'), type: 'line', showLine: false, }, { data: labels.map((l) => meanData ? meanData[`min_${l}`] : 0), backgroundColor: "#cccccc", hoverBackgroundColor: "#aaaaaa", type: 'bar', showLine: false, }, { data: labels.map((l) => meanData ? meanData[`max_${l}`] : 0), backgroundColor: "#cccccc", hoverBackgroundColor: "#aaaaaa", type: 'bar', showLine: false, }, ], }; return }