You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
5.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 <Line options={options} data={data} />
}