Public
Edited
Feb 26
Insert cell
Insert cell
vis1 = Plot.plot({
subtitle: "Як змінилися доходи компаній залежно від країни походження",
style: { fontSize: 14, fontWeight: 400 },
marginTop: 60,
marginLeft: 115,
marginRight: 50,
y: { grid: true, label: null, tickSize: 0 },
x: { label: "млн дол", labelArrow: null, tickFormat: (d) => "$" + d },
width: width > 650 ? 650 : 350,
// x: { domain: [0, 65000] },
// color: {
// type: "categorical",
// domain: [-1, 1],
// unknown: "#aaa",
// transform: Math.sign,
// tickFormat: (c) => (c < 0 ? "female" : "male"),
// legend: true
// },
marks: [
// Plot.ruleX([0]),
Plot.link(data1, {
y: "Country of HQ2",
x1: (d) => d.rev21,
x2: (d) => d.rev23,
markerStart: "dot",
markerEnd: "arrow",
sort: { y: "-x1" },
stroke: (d) => (+d.rev23 - d.rev21 > 0 ? "#F2AC59" : "#81C081"),
strokeWidth: 2.5
}),
// Plot.arrow([0], {
// x1: (d) => 10,
// x2: (d) => 10000,
// y1: "Austria",
// y2: "Austria",
// sweep: "-y",
// bend: 90,
// headLength: 0,
// reverse: true
// }),

Plot.text(
data1.filter((d) => d.rev21 > 2000),
{
// frameAnchor: "top",
// textAnchor: "end",
bend: true,
dx: 27,
dy: 0,
fontSize: 11,
fontWeight: 300,
y: "Country of HQ2",
x: (d) => +d.rev21,
text: (d) => "$" + Math.round(d.rev21 / 1000) + " млрд"
}
),
Plot.text(
data1.filter((d) => d.rev23 > 10000),
{
// frameAnchor: "top",
// textAnchor: "end",
bend: true,
dx: -27,
dy: 0,
fontSize: 11,
fontWeight: 300,
y: "Country of HQ2",
x: (d) => +d.rev23,
text: (d) => "$" + Math.round(d.rev23 / 1000) + " млрд"
}
),
Plot.text(
[
`Виручка американських компаній у РФ впала майже вдвічі: з 64 млрд дол. у 2021 році до 30 млрд у 2023 році.\n↓`
],
{
frameAnchor: "top",
textAnchor: "middle",
bend: true,
dx: width > 650 ? 100 : 10,
dy: -50,
lineWidth: 22
// stroke: "#fff",
// fill: "#000"
}
),
Plot.text([`2023`], {
frameAnchor: "top",
textAnchor: "end",
bend: true,
dx: 0,
dy: -3,
lineWidth: 12,
fontWeight: 700
}),
Plot.text([`2021`], {
frameAnchor: "top-right",
textAnchor: "end",
bend: true,
dx: 20,
dy: -3,
lineWidth: 12,
fontWeight: 700
}),
Plot.arrow([0], {
x1: 1000,
x2: 5000,
y1: 1.3,
y2: 1.17,
bend: 30,
dx: width > 650 ? 0 : 10,
strokeWidth: 1
})
]
})
Insert cell
data1 = {
const countryTranslations = {
USA: "США",
Germany: "Німеччина",
France: "Франція",
Switzerland: "Швейцарія",
Japan: "Японія",
"Great Britain": "Велика Британія",
"South Korea": "Південна Корея",
Sweden: "Швеція",
Netherlands: "Нідерланди",
Italy: "Італія",
Finland: "Фінляндія",
Austria: "Австрія",
Turkey: "Туреччина",
Denmark: "Данія",
Spain: "Іспанія",
Poland: "Польща",
Greece: "Греція",
"South Africa": "ПАР",
Latvia: "Латвія",
Thailand: "Таїланд",
Ireland: "Ірландія",
Slovenia: "Словенія",
Belgium: "Бельгія",
Lithuania: "Литва",
Israel: "Ізраїль"
};

let data = (await FileAttachment("exitru1@1.csv").csv()).map((d) => {
return {
...d,
rev21: +d["GrossRevenueinRF2021,USDm"],
rev23: +d["GrossRevenueinRF2023,USDm"]
};
});

const updatedData = data.map((item) => ({
...item,
"Country of HQ2":
countryTranslations[item["Country of HQ"]] || item["Country of HQ"]
}));

return updatedData;
}
Insert cell
data2 = (await FileAttachment("exitru2.csv").csv()).map((d) => {
return {
...d,
rev21: +d["GrossRevenueinRF2021,USDm"],
rev23: +d["GrossRevenueinRF2023,USDm"]
};
})
Insert cell
vis2 = Plot.plot({
subtitle:
"Як змінилися доходи компаній із США, що залишилися працювати в Росії",
style: { fontSize: 14, fontWeight: 400 },
marginTop: 20,
marginLeft: 130,
marginRight: 60,
y: { grid: true, label: null, tickSize: 0 },
x: { label: "млн дол", labelArrow: null, tickFormat: (d) => "$" + d },
width: width > 650 ? 650 : 350,
// x: { domain: [0, 65000] },
// color: {
// type: "categorical",
// domain: [-1, 1],
// unknown: "#aaa",
// transform: Math.sign,
// tickFormat: (c) => (c < 0 ? "female" : "male"),
// legend: true
// },
marks: [
// Plot.ruleX([0]),
Plot.link(data2, {
y: "Company name",
x1: (d) => d.rev21,
x2: (d) => d.rev23,
markerStart: "dot",
markerEnd: "arrow",
sort: { y: "-x2" },
stroke: (d) => (+d.rev23 - d.rev21 > 0 ? "#F2AC59" : "#81C081"),
strokeWidth: 2.5
}),
Plot.text(
data2.filter((d) => d.rev21 > 2500 && d["Company name"] !== "Mars"),
{
// frameAnchor: "top",
// textAnchor: "end",
bend: true,
dx: 30,
dy: 0,
fontSize: 11,
fontWeight: 300,
y: "Company name",
x: (d) => +d.rev21,
text: (d) => "$" + Math.round(d.rev21 / 1) + " млн"
}
),
Plot.text(
[
`За час війни компанія Mars збільшила дохід в Росії з 2,2 до 2,9 млрд дол США`
],
{
frameAnchor: "top-left",
textAnchor: "start",
bend: true,
dx: width > 650 ? 185 : 70,
dy: 55,
lineWidth: width > 650 ? 18 : 10
// stroke: "#fff",
// fill: "#000"
}
),
Plot.text(
data2.filter((d) => d.rev23 > 2000 && d["Company name"] !== "Mars"),
{
// frameAnchor: "top",
// textAnchor: "end",
bend: true,
dx: -30,
dy: 0,
fontSize: 11,
fontWeight: 300,
y: "Company name",
x: (d) => +d.rev23,
text: (d) => "$" + Math.round(d.rev23 / 1) + " млн"
}
),
Plot.text([`2023`], {
frameAnchor: "top-left",
textAnchor: "end",
bend: true,
dx: 190,
dy: 40,
lineWidth: 12,
fontWeight: 700,
opacity: width > 650 ? 1 : 0
}),
Plot.text([`2021`], {
frameAnchor: "top-left",
textAnchor: "end",
bend: true,
dx: 140,
dy: 40,
lineWidth: 12,
fontWeight: 700,
opacity: width > 650 ? 1 : 0
}),
Plot.text([`2021·→2023`], {
frameAnchor: "top-left",
textAnchor: "end",
bend: true,
dx: 140,
dy: -15,
lineWidth: 12,
fontWeight: 700,
opacity: width > 650 ? 0 : 1
})
]
})
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