Public
Edited
May 2
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
vis1 = by_area("Електроенергія")
Insert cell
data = (await FileAttachment("top200_2024@6.csv").csv())
.map((d) => {
return {
...d,
diff: ((+d.r24 - d.r23) / +d.r23) * 100,
r23: +d.r23,
r24: +d.r24,
area2:
d.area2 == "Енергетика"
? "Електроенергія"
: d.area2 == "ІТ"
? "ІТ, фінанси"
: d.area2,
name: d.FIRM_NAME.replace(/.+(«|\s")/, "").replace(/(«|»|")/, "")
};
})
.filter(
(d) =>
![
"45088078",
"45179093",
"24083083",
"31366355",
"43746250",
"42751590",
"44763104",
"44800308",
"45241449",
"40623600",
"44445949",
"44624498"
].includes(d.code)
)
// .slice(0, 100)
Insert cell
vis2 = by_area("Нафта і газ")
Insert cell
vis3 = by_area("АПК")
Insert cell
vis4 = by_area("Рітейл")
Insert cell
vis5 = by_area("ГМК")
Insert cell
vis6 = by_area("Тютюн")
Insert cell
vis7 = by_area("Промисловість")
Insert cell
vis8 = by_area("Транспорт і логістика")
Insert cell
vis9 = by_area("Дистрибуція")
Insert cell
vis10 = by_area("Фарма")
Insert cell
vis11 = by_area("Автоторгівля")
Insert cell
vis12 = by_area("Зв'язок")
Insert cell
vis13 = by_area("ІТ, фінанси")
Insert cell
vis14 = by_area("Будівництво")
Insert cell
function by_area(area) {
const data1 = data.filter((d) => d.area2 == area);

const max_y = d3.max(
data.filter((d) => d.area2 == area),
(d) => d.diff
);

console.log(isFinite(max_y));
let r23 = d3.sum(data1, (d) => d.r23);
let r24 = d3.sum(data1, (d) => d.r24);
let change = (((r24 - r23) / r23) * 100).toFixed(1);
// console.log("data1", area, change);

let dy = yy ? { domain: [-50, 300] } : null;

return Plot.plot({
style: { fontSize: 13, fontWeight: 400 },
marginLeft: 45,
marginBottom: 40,
marginTop: 40,
marginRight: 40,
width: 350,
height: 300,
x: {
label: "Сумарна виручка сектору",
tickFormat: (d) => d / 1000000 + " млрд",
nice: true,
labelArrow: null
// domain: [0, 1200000000]
},
y: {
// dy,
grid: true,
tickFormat: (d) => d + "%",
label: "Зміна виручки\nв 2024 році",
labelArrow: null
},
marks: [
Plot.text(["↑ Зміни виручки\n→Розмір компанії"], {
frameAnchor: "top-right",
fontWeight: 300,
dy: 20,
fill: "grey",
stroke: "#fff"
}),
Plot.text([area], {
frameAnchor: "top",
fontWeight: 700,
dy: -30,
fontSize: 15
}),
Plot.text([change], {
frameAnchor: "top",
fontWeight: 300,
dy: -15,
fontSize: 14,
text: (d) => "Середнє зростання: " + d + "%"
}),

Plot.rectY(
data1,
Plot.stackX({
// filter: (d) => ["N", "A"].includes(d.CoverageType),
fill: (d) =>
d.name.toLowerCase().includes(text.toLowerCase())
? "orange"
: "#72AADF",
x: "r24",
order: "diff",
reverse: true,
// tip: "xy",
y2: (d) => d.diff, // y2 to avoid stacking by y
// title: (d) =>
// `${d.name}\n${(d.r24 / 1000000).toFixed(
// 1
// )} млрд грн (${d.diff.toFixed(1)}%)`,
insetLeft: 0.2,
insetRight: 0.2,
opacity: 0.8
})
),
Plot.rectY(
data1,
Plot.pointer(
Plot.stackX({
// filter: (d) => ["N", "A"].includes(d.CoverageType),
x: "r24",
order: "diff",
reverse: true,
// y1: (d) => 0,
y2: (d) => d.diff, // y2 to avoid stacking by y
insetLeft: 0.2,
insetRight: 0.2,
fill: null,
stroke: "orange",
strokeWidth: 2
})
)
),
Plot.ruleY([0]),
Plot.tip(
data1,
Plot.stackX(
Plot.pointerX({
x: "r24",
y1: 0,
y2: "diff",
stroke: "#aaa",
tip: "xy",
title: (d) =>
`${d.name}\n${(d.r24 / 1000000).toFixed(
1
)} млрд грн (${d.diff.toFixed(1)}%)`
})
)
)
]
});
}
Insert cell
area = (await FileAttachment("top200_2024_area@4.csv").csv())
.map((d) => {
return { ...d, diff: +d.diff, r24: +d.r24 };
})
.filter((d) => d.area != "Фінанси")
.filter((d) => d.diff < 100)
Insert cell
Plot.plot({
style: { fontSize: 14, fontWeight: 400 },
marginBottom: 40,
marginTop: 50,
// marginLeft: 100,
width: 950,
height: 500,
x: {
label: "Сумарна виручка ТОП-200 компаній в 2024 році склала 5,5 трлн грн",
tickFormat: (d) => d / 1000000 + " млрд"
},
y: {
ticks: 10,
grid: true,
tickFormat: (d) => d + "%",
label: "Зміна виручки в 2024 році,\nпорівняно з 2023 роком"
// tickRotate: -90
},
marks: [
Plot.text(["↑ Зміни виручки\n→Розмір сектору"], {
frameAnchor: "top",
fontWeight: 600
}),
Plot.rectY(
area,
Plot.stackX({
// filter: (d) => ["N", "A"].includes(d.CoverageType),
// fill: (d) =>
// d.name.toLowerCase().includes(text.toLowerCase()) ? "red" : "#333",
x: "r24",
order: "diff",
reverse: true,
tip: true,
y2: (d) => d.diff, // y2 to avoid stacking by y
title: (d) => `${d.area2}\n${d.diff.toFixed(1)}%`,
insetLeft: 0.2,
insetRight: 0.2,
opacity: 0.6
})
),
Plot.textX(
[
{ type: "АПК", x: 1000000000, y: 35 },
{ type: "Електроенергія", x: 2000000000, y: 25 },
{ type: "ГМК", x: 2850000000, y: 24 },
{ type: "Нафта і газ", x: 3500000000, y: 22 },
{ type: "Рітейл", x: 4800000000, y: 14 }
],
{
// opacity: (d) => (d.r24 > 100000000 ? 1 : 0.1),
x: (d) => d.x,
y: (d) => d.y,
text: (d) => d.type
}
),

// Plot.rectY(
// data,
// Plot.pointer(
// Plot.stackX({
// // filter: (d) => ["N", "A"].includes(d.CoverageType),
// x: "r24",
// order: "diff",
// reverse: true,
// tip: true,
// y2: (d) => d.diff, // y2 to avoid stacking by y
// title: (d) => `${d.name}\n${d.diff.toFixed(1)}%`,
// insetLeft: 0.2,
// insetRight: 0.2,
// fill: null,
// stroke: "red"
// })
// )
// ),
Plot.ruleY([0])
]
})
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more