Published
Edited
May 27, 2021
Insert cell
Insert cell
Insert cell
vote_bubble_map = {
const svg = d3.select(DOM.svg(width, height)).style("background", "white");
addDefsAndBlurs(svg);

const canvasRectWidth = width * 0.73;
svg
.append("rect")
.attr("width", width)
.attr("x", 0)
.attr("y", 0)
.attr("height", height)
.attr("fill", "#FFF8E7");

const labelOffset = 120;
svg
.append("text")
.attr("x", labelOffset)
.attr("y", 40)
.attr("fill", "#546767")
.attr("text-anchor", "start")
.attr("font-size", 24)
.style("opacity", 1)
.text(`Lokalni izbori 2021. (prvi krug)`);

svg
.append("text")
.attr("x", labelOffset)
.attr("y", 65)
.attr("fill", "#546767")
.attr("text-anchor", "start")
.attr("font-size", 16)
.style("opacity", 1)
.text(`Veličina kruga odgovara broju glasova relativnog pobjednika.`);

let credit = svg
.append("text")
.attr("x", labelOffset)
.attr("y", 85)
.attr("fill", "#546767")
.attr("text-anchor", "start")
.attr("font-size", 12)
.style("opacity", 1)
.text(`Autor: @velimirgasp`);

const mapGroup = svg.append("g").attr("transform", "translate(30,50)");

const paths = mapGroup
.selectAll("path")
.data(topojson.feature(croatia, croatia.objects["hrvatska"]).features)
.enter()
.append("path")
.attr("fill", "white")
.attr("stroke", "lightgrey")
.attr("stroke-linejoin", "round")
.attr("d", path);

mapGroup
// .append("g")
.selectAll("circle")
.data(municipalities)
.enter()
.append("circle")
.attr("opacity", 0.7)
.attr("naziv", (d) => d.properties.name)
.attr("fill", (county, index) => {
if (!county.properties.votes.pobjednik) {
console.log("nemam:", county);
return "none";
} else if (
county.properties.votes.pobjednik.stranke.indexOf("HDZ") > -1
) {
return "grey";
} else if (
county.properties.votes.pobjednik.stranke.indexOf("SDP") > -1
) {
return "grey";
} else if (
county.properties.votes.pobjednik.stranke.indexOf("IDS") > -1
) {
return "grey";
} else {
return "#d09e00";
}
})
.attr("cx", (d) => (d.properties.centroid ? d.properties.centroid[0] : 0))
.attr("cy", (d) => (d.properties.centroid ? d.properties.centroid[1] : 0))
.attr("r", (d) => {
let retval = d.properties.radius;
if (!retval || retval < 1) console.log("nemam radius", d);
return retval;
})
.style("stroke", "white")
.style("stroke-width", 0.4)
.append("title")
.text((d) => {
let retval = d.properties.name;
if (d.properties.votes.pobjednik) {
retval += `
${d.properties.votes.pobjednik.stranke}
${d3.format(",")(d.properties.votes.pobjednik.glasova)}`;
}

return retval;
});

return svg.node();
}
Insert cell
spread_vote_bubble = {
const svg = d3.select(DOM.svg(width, height)).style("background", "white");
addDefsAndBlurs(svg);

const canvasRectWidth = width * 0.73;
svg
.append("rect")
.attr("width", width)
.attr("x", 0)
.attr("y", 0)
.attr("height", height)
.attr("fill", "#FFF8E7");

const labelOffset = 120;
svg
.append("text")
.attr("x", labelOffset)
.attr("y", 40)
.attr("fill", "#546767")
.attr("text-anchor", "start")
.attr("font-size", 24)
.style("opacity", 1)
.text(`Lokalni izbori 2021. (prvi krug)`);

svg
.append("text")
.attr("x", labelOffset)
.attr("y", 65)
.attr("fill", "#546767")
.attr("text-anchor", "start")
.attr("font-size", 16)
.style("opacity", 1)
.text(`Veličina kruga odgovara broju glasova relativnog pobjednika.`);

let credit = svg
.append("text")
.attr("x", labelOffset)
.attr("y", 85)
.attr("fill", "#546767")
.attr("text-anchor", "start")
.attr("font-size", 12)
.style("opacity", 1)
.text(`Autor: @velimirgasp`);

const mapGroup = svg.append("g").attr("transform", "translate(30,50)");

mapGroup
.append("g")
.selectAll("circle")
.data(spreadMunicipalities)
.enter()
.append("circle")
.attr("opacity", 0.7)
.attr("naziv", (d) => d.properties.name)
.attr("fill", (county, index) => {
if (!county.properties.votes.pobjednik) {
console.log("nemam:", county);
return "none";
} else if (
county.properties.votes.pobjednik.stranke.indexOf("HDZ") > -1
) {
return "grey";
} else if (
county.properties.votes.pobjednik.stranke.indexOf("SDP") > -1
) {
return "grey";
} else if (
county.properties.votes.pobjednik.stranke.indexOf("IDS") > -1
) {
return "grey";
} else {
return "#d09e00";
}
})
.attr("cx", (d) => d.x)
.attr("cy", (d) => d.y)
.attr("r", (d) => {
let retval = d.properties.radius;
if (!retval || retval < 1) console.log("nemam radius", d);
return retval;
})
.style("stroke", "white")
.style("stroke-width", 0.4)
.append("title")
.text((d) => {
let retval = d.properties.name;
if (d.properties.votes.pobjednik) {
retval += `
${d.properties.votes.pobjednik.stranke}
${d3.format(",")(d.properties.votes.pobjednik.glasova)}`;
}

return retval;
});

return svg.node();
}
Insert cell
Insert cell
Insert cell
jlsData = d3.csvParse(await FileAttachment('jls@1.csv').text(), d3.autoType)
Insert cell
municipalities.filter(d => d.properties.name == 'ZAGREB')
Insert cell
Insert cell
radiusScale = {
const votesMax = d3.max(votingData, d => d.pobjednik.glasova);
return d3
.scaleSqrt()
.domain([0, votesMax])
.range([2, maxRadius]);
}
Insert cell
Insert cell
projection = d3
.geoAlbers()
.rotate([-15, 0])
.fitExtent(
[[20, 70], [width * 0.85, height * 0.85]],
topojson.feature(croatia, croatia.objects['hrvatska'])
)
Insert cell
height = 800
Insert cell
Insert cell
populations = {
let retval = new Array();
croatia.objects.hrvatska.geometries.forEach(opcina => {
let opcinaFound = populationData.find(
d => d.Name.toUpperCase() == opcina.properties.NAME_2.toUpperCase()
);

retval.push({
id: opcina.properties.ID_2,
name: opcina.properties.NAME_2,
found: opcinaFound ? true : false,
population: opcinaFound ? opcinaFound.Population : 0
});
});
return retval;
}
Insert cell
Insert cell
zagreb = {
let raw = lokalniIzbori.filter(
d => d.izboriOznaka == "15" && d.zupNaziv == 'GRAD ZAGREB'
)[0];
raw.gropNaziv = 'Zagreb';
return raw;
}
Insert cell
gradonacelniciData = [
...lokalniIzbori.filter(d => d.izboriOznaka == "17"),
zagreb
]
Insert cell
votingData = gradonacelniciData.map(d => {
return {
zupNaziv: d.zupNaziv,
gropNaziv: d.gropNaziv,
count: d.lista
.map(d => d.glasova)
.reduce((accumulator, currentValue) => accumulator + currentValue),
pobjednik: d.lista[0]
// kgk: d.lista.find(d => d.jedinstvenaSifra == 2).glasova,
// zoky: d.lista.find(d => d.jedinstvenaSifra == 1).glasova,
// diff:
// d.lista.find(d => d.jedinstvenaSifra == 2).glasova -
// d.lista.find(d => d.jedinstvenaSifra == 1).glasova
};
})
Insert cell
lokalniIzbori = await FileAttachment("izboriClean.json").json()
Insert cell
Insert cell
populationData = d3.csvParse(
await FileAttachment('stanovnistvo_povrsina@2.csv').text(),
d3.autoType
)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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