85 lines
2.7 KiB
JavaScript
85 lines
2.7 KiB
JavaScript
import { formatMoney } from "../../utils/format.js";
|
|
|
|
export function createGeoOption(items) {
|
|
const points = items
|
|
.filter((item) => Array.isArray(item.geo_point) && item.geo_point.length === 2)
|
|
.filter((item) => Number(item.recharge_usd_minor) > 0)
|
|
.map((item) => [...item.geo_point, Number(item.recharge_usd_minor) || 0, item.country]);
|
|
const max = Math.max(...points.map((item) => item[2]), 1);
|
|
const min = Math.min(...points.map((item) => item[2]), max);
|
|
return {
|
|
animationDuration: 650,
|
|
geo: {
|
|
center: [38, 12],
|
|
emphasis: { disabled: true },
|
|
itemStyle: {
|
|
areaColor: "#18354e",
|
|
borderColor: "rgba(62, 139, 184, 0.52)",
|
|
borderWidth: 0.65
|
|
},
|
|
label: { show: false },
|
|
layoutCenter: ["50%", "51%"],
|
|
layoutSize: "112%",
|
|
map: "databi-world",
|
|
roam: false,
|
|
silent: true,
|
|
zoom: 1.04
|
|
},
|
|
series: [
|
|
{
|
|
coordinateSystem: "geo",
|
|
data: points,
|
|
itemStyle: {
|
|
color: ({ value }) => colorByValue(value[2], min, max, 0.2),
|
|
shadowBlur: 28,
|
|
shadowColor: "rgba(39, 228, 245, 0.6)"
|
|
},
|
|
silent: true,
|
|
symbolSize: (value) => 14 + (value[2] / max) * 32,
|
|
type: "scatter",
|
|
z: 2
|
|
},
|
|
{
|
|
coordinateSystem: "geo",
|
|
data: points,
|
|
itemStyle: {
|
|
borderColor: "rgba(232, 255, 255, 0.9)",
|
|
borderWidth: 1.5,
|
|
color: ({ value }) => colorByValue(value[2], min, max, 1),
|
|
shadowBlur: 24,
|
|
shadowColor: "rgba(39, 228, 245, 0.74)"
|
|
},
|
|
rippleEffect: { brushType: "stroke", number: 3, scale: 3.6 },
|
|
symbolSize: (value) => 6 + (value[2] / max) * 15,
|
|
type: "effectScatter",
|
|
z: 3
|
|
}
|
|
],
|
|
tooltip: {
|
|
backgroundColor: "#08243a",
|
|
borderColor: "#1a5f82",
|
|
formatter: ({ value }) => `${value[3]}<br/>${formatMoney(value[2])}`,
|
|
textStyle: { color: "#e9f6ff" }
|
|
}
|
|
};
|
|
}
|
|
|
|
function colorByValue(value, min, max, alpha = 1) {
|
|
const strength = normalizeStrength(value, min, max);
|
|
const low = [66, 129, 255];
|
|
const mid = [39, 228, 245];
|
|
const high = [36, 215, 159];
|
|
const from = strength < 0.55 ? low : mid;
|
|
const to = strength < 0.55 ? mid : high;
|
|
const local = strength < 0.55 ? strength / 0.55 : (strength - 0.55) / 0.45;
|
|
const [red, green, blue] = from.map((channel, index) => Math.round(channel + (to[index] - channel) * local));
|
|
return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
|
|
}
|
|
|
|
function normalizeStrength(value, min, max) {
|
|
if (max <= min) {
|
|
return 1;
|
|
}
|
|
return Math.min(Math.max((Math.sqrt(value) - Math.sqrt(min)) / (Math.sqrt(max) - Math.sqrt(min)), 0), 1);
|
|
}
|