Public
Edited
Nov 5
Insert cell
md`# Izbori test`
Insert cell
height = width / 1.2
Insert cell
Insert cell
mapaRvacke = {
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]);
var isTooltipHidden = true;

const paths = svg
.selectAll("path")
.data(
hrvatska.features.filter(
(d) => d.properties.zupanija == "Istarska županija"
)
)
.enter()
.append("path")
//.attr('fill', (d, i) => color2(d3.randomUniform(-1, 1)()))
// .attr('fill', (d, i) => color2(d3.randomNormal(0, 0.1)() + 0.15))
.attr("fill", (d, i) => {
var glasovi =
sumiranoGrupirano[d.properties.naziv]["Marino Baldini".toUpperCase()] +
sumiranoGrupirano[d.properties.naziv]["Monika Udovičić".toUpperCase()] +
sumiranoGrupirano[d.properties.naziv]["Valter Flego".toUpperCase()];

return d3.interpolateGreens(
sumiranoGrupirano[d.properties.naziv]["Valter Flego".toUpperCase()] /
glasovi
);
})
.style("cursor", "pointer")
.attr("stroke", "white")
.attr("stroke-width", 1.5)
.attr("id", (d, i) => `opcina${i}`)
.attr("stroke-linejoin", "round")
.attr("d", path)
.on("mouseout", handleMouseOut)
.on("mousemove", handleMouseMove)
.on("mouseover", handleMouseOver);

const citiesGroup = svg
.selectAll(".cities")
.data(mjesta)
.enter()
.append("g")
.attr(
"transform",
(d) =>
`translate(${projection(d.coordinates)[0]},${
projection(d.coordinates)[1]
})`
);

citiesGroup.append("circle").attr("r", 4).attr("fill", "white");
citiesGroup.append("circle").attr("r", 2);

citiesGroup
.append("text")
.attr("class", "text-shadow")
.attr("dx", 5)
.style("stroke", "white")
.style("stroke-width", 2.5)
.style("opacity", 0.9)
.style("pointer-events", "none")
.text((d) => d.name);

citiesGroup
.append("text")
.attr("dx", 5)
.attr("class", "text-black")
.style("pointer-events", "none")
.text((d) => d.name);

function handleMouseOver(event, d) {
d3.select(this).attr("stroke", "black").raise();

var centroid = path.centroid(d);

isTooltipHidden = !isTooltipHidden;

loadTooltipContent(d);

//ovo radi
//d3.select(event.currentTarget).attr('fill', 'purple');

let topOrBottom = "top";
if (event.y > height / 2) topOrBottom = "bottom";
tooltip
.style("top", `${event.y}px`)
.style("left", `${event.x}px`)
.style("visibility", isTooltipHidden ? "hidden" : "visible");

citiesGroup.raise();
}

function handleMouseMove(event, d) {
tooltip.style("top", `${event.y + 50}px`).style("left", `${event.x}px`);
}

function handleMouseOut(event, d) {
d3.select(this).attr("stroke", "white").lower();

isTooltipHidden = true;
tooltip.style("visibility", isTooltipHidden ? "hidden" : "visible");
}

function loadTooltipContent(d) {
var name = d.properties.naziv
.toLowerCase()
.split(" ")
.map((word) => {
return word[0].toUpperCase() + word.substring(1);
})
.join(" ");

var glasovi =
sumiranoGrupirano[d.properties.naziv]["Marino Baldini".toUpperCase()] +
sumiranoGrupirano[d.properties.naziv]["Monika Udovičić".toUpperCase()] +
sumiranoGrupirano[d.properties.naziv]["Valter Flego".toUpperCase()];

var htmlContent = "<div>";
htmlContent += `<h4>${name}<\/h4>`;
htmlContent += `<h6 style='color:grey;padding-bottom:20px'>${d.properties.zupanija}<\/h6>`;
// htmlContent += `<table style='border-collapse:separate; color: grey; font-size:12px;border-spacing: 5px;'>
htmlContent += `<table style='border-collapse:collapse; color: grey; font-size:12px;'>
<tr style="border-bottom: 1px solid lightgrey;">
<th>Kandidat</th>
<th >Stranka</th>
<th style='text-align:right'>Ukupno</th>
<th style='text-align:right'>Postotak</th>
<th style='text-align:right'></th>
</tr> `;
htmlContent += `<tr>
<td class="color-box"><span class="ids"></span>Valter Flego</td>
<td>IDS</td>
<td align="right">${countFormat(
sumiranoGrupirano[d.properties.naziv]["Valter Flego".toUpperCase()]
)}</td>
<td align="right" style="font-weight: bold;">${percentFormat(
(sumiranoGrupirano[d.properties.naziv]["Valter Flego".toUpperCase()] /
glasovi) *
100
)}</td>
<td>%<td/>
<tr/>`;
htmlContent += `<tr>
<td class="color-box"><span class="sdp"></span>Marino Baldini</td>
<td>SDP</td>
<td align="right">${countFormat(
sumiranoGrupirano[d.properties.naziv]["Marino Baldini".toUpperCase()]
)}</td>
<td align="right" style="font-weight: bold;">${percentFormat(
(sumiranoGrupirano[d.properties.naziv]["Marino Baldini".toUpperCase()] /
glasovi) *
100
)}</td>
<td><td/>
</tr>`;
htmlContent += `<tr>
<td class="color-box"><span class="hdz"></span>Monika Udovičić</td>
<td>HDZ</td>
<td align="right">${countFormat(
sumiranoGrupirano[d.properties.naziv]["Monika Udovičić".toUpperCase()]
)}</td>
<td align="right" style="font-weight: bold;">${percentFormat(
(sumiranoGrupirano[d.properties.naziv]["Monika Udovičić".toUpperCase()] /
glasovi) *
100
)}</td>
<td><td/>
</tr>`;

// htmlContent += `<img src="${marino}" style="border-radius: 50%; max-height: 40px"><span style="line-height:40px; vertical-align: middle;">Marino Bladini<span/><br/>`;
// htmlContent += `<img src="${monika}" style="border-radius: 50%; max-height: 40px">Monika Udovičić<br/>`;
// htmlContent += `<img src="${valter}" style="border-radius: 50%; max-height: 40px">Valter Flego<br/>`;

//

// htmlContent += `<p>${JSON.stringify(
// sumiranoGrupirano[d.properties.naziv]
// )}<\/h6>`;
htmlContent += "</table>";
htmlContent += '<p style="font-size:10px">100% prebrojanih glasova.</p>';
htmlContent += "</div>";
tooltip.html(htmlContent);
}

var tooltip = d3
.select("body")
.append("div")
.attr("class", "tooltip")
.style("position", "absolute")
.style("display", "block")
.style("pointer-events", "none")

.style("padding", "10px")
.style("z-index", "10")
.style("width", "400px")
// .style("height", "150px")
.style("background-color", "rgba(255, 255, 255, 0.95)")
.style("border-radius", "3px")
.style("box-shadow", "2px 2px 6px rgba(0,0,0,.5)")
.style("visibility", "hidden")
.text("");

return svg.node();
}
Insert cell
hrvatska.features.filter(d => d.properties.zupanija == 'Istarska županija')
Insert cell
style = html`<style>
.color-box span {
padding: 1px;
padding-left: 10px;
margin: 0px;
margin-right: 10px;
}
.color-box {
padding: 4px;
padding-right: 100px;
}
.ids {
background-color: #0CB14B;
}
.sdp {
background-color: #ED1C24;
}
.hdz {
background-color: #295BA5;
}

<style/>
`
Insert cell
projection(mjesta[0].coordinates)
Insert cell
mjesta = [
{ name: "Pula", coordinates: [13.843699, 44.871084] },
{ name: "Rovinj", coordinates: [13.629852, 45.083819] },
{ name: "Poreč", coordinates: [13.591656, 45.227690] },
{ name: "Pazin", coordinates: [13.940013, 45.238145] },
{ name: "Umag", coordinates: [13.524964, 45.436742] }
]
Insert cell
percentFormat(12.22)
Insert cell
percentFormat = d3.format('.2f')
Insert cell
countFormat = d3.format(',')
Insert cell
borderRadius = '20%'
Insert cell
marino = await FileAttachment('marino.jpg').url()
Insert cell
monika = await FileAttachment('monika.jpg').url()
Insert cell
valter = await FileAttachment('valter.jpg').url()
Insert cell
callout = (g, value) => {
if (!value) return g.style("display", "none");

g.style("display", null)
.style("pointer-events", "none")
.style("font", "10px sans-serif");

const path = g
.selectAll("path")
.data([null])
.join("path")
.attr("fill", "white");
// .attr("stroke", "black");

const text = g
.selectAll("text")
.data([null])
.join("text")
.call(text =>
text
.selectAll("tspan")
.data((value + "").split(/\n/))
.join("tspan")
.attr("x", 0)
.attr("y", (d, i) => `${i * 1.1}em`)
.style("font-weight", (_, i) => (i ? null : "bold"))
// .text(d => d)
.text('gigimil')
);

const { x, y, width: w, height: h } = text.node().getBBox();

text.attr("transform", `translate(${-w / 2},${15 - y})`);
path.attr(
"d",
`M${-w / 2 - 10},5H-5l5,-5l5,5H${w / 2 + 10}v${h + 20}h-${w + 20}z`
);
}
Insert cell
d3.interpolateGreens(0)
Insert cell
d3.interpolateGreens(1)
Insert cell
color2 = {
const max = 1;
return d3
.scaleSqrt()
.domain([-max, 0, max])
.range([-1, 0, 1])
.interpolate((a, b) =>
a < 0 ? t => d3.interpolateBlues(1 - t) : t => d3.interpolateReds(t)
);
}
Insert cell
path = d3.geoPath(projection)
Insert cell
zupani = d3.csvParse(await FileAttachment('18_zupani@3.csv').text())
Insert cell
zupani.filter(d => d['Grad/općina'] == "FAŽANA - FASANA")
Insert cell
sumiranoGrupirano = {
const retval = new Map();
zupani.forEach(bm => {
const grad = bm['Grad/općina'];
if (retval[grad] == null) {
retval[grad] = {
'MARINO BALDINI': 0,
'VALTER FLEGO': 0,
'MONIKA UDOVIČIĆ': 0
};
}
retval[grad]['MARINO BALDINI'] += +bm['MARINO BALDINI'];
retval[grad]['VALTER FLEGO'] += +bm['VALTER FLEGO'];
retval[grad]['MONIKA UDOVIČIĆ'] += +bm['MONIKA UDOVIČIĆ'];
});

return retval;
}
Insert cell
istra = Object.assign({
type: 'FeatureCollection',
features: hrvatska.features.filter(
d => d.properties.zupanija == 'Istarska županija'
)
})
Insert cell
topo = await FileAttachment("croazia2.topo.json").json()
Insert cell
hrvatska = topojson.feature(topo, topo.objects.hrvaska)
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