Skip to content

Instantly share code, notes, and snippets.

@RalucaNicola
Last active November 22, 2019 21:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RalucaNicola/0ad77ee982166a3ed72daed1157756a2 to your computer and use it in GitHub Desktop.
Save RalucaNicola/0ad77ee982166a3ed72daed1157756a2 to your computer and use it in GitHub Desktop.
Prototype for elections map
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<style>
body {
font-family: Arial, Helvetica, sans-serif;
color: #444;
}
#g1,
.red-party {
color: #e83a66;
}
#g2,
.blue-party {
color: #3a7de8;
}
div.tooltip {
position: absolute;
text-align: center;
font: 1em;
background: white;
padding: 0.5em;
pointer-events: none;
display: none;
}
</style>
</head>
<body>
<p>Imagine this is a map of elections. Each point is a municipality or simply put, an administrative unit.
The circle radius is proportional to the number of votes (I should change this to make the area proportional to no of votes).
The gray area represents votes that are obtained by the red party and the blue party.
You can think of it as votes that cancel each other.
The red party has <span class="red-party" id="red-votes"></span> votes.
The blue party has <span class="blue-party" id="blue-votes"></span> votes.
</p>
<button id="filter-red">Show only red party</button>
<button id="filter-blue">Show only blue party</button>
<button id="reset-filter">Reset filter</button>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
const margin = { top: 10, right: 30, bottom: 30, left: 30 };
const width = 960 - margin.left - margin.right;
const height = 600 - margin.top - margin.bottom;
const svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
const tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// generate random data
const data = [];
for (i = 0; i < 1000; i++) {
data.push({ g1: Math.floor(Math.random() * 35), g2: Math.floor(Math.random() * 45) })
}
const opacity = 0.9;
const red = "#e83a66";
const blue = "#3a7de8";
const gray = "#ddd";
const cols = 50;
const municipality = svg.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function () { return "translate(" + Math.random() * width + ", " + Math.random() * width + ")"; })
.on("mousemove", function (d, i) {
tooltip.transition()
.duration(100)
.style("opacity", .9)
.style("display", "inherit");
tooltip.html("<span class='red-party'>" + d.g1 + " red votes</span> | <span class='blue-party'>" + d.g2 + " blue votes</span>")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 30) + "px");
})
.on("mouseout", function (d, i) {
tooltip.transition()
.duration(300)
.style("opacity", 0)
.style("display", "none");
});
municipality.append("circle")
/* .attr("cy", function (d, i) { return Math.floor(i / cols) * 30 + 30; })
.attr("cx", function (d, i) { return i % cols * 30 + 30; }) */
.attr("cy", 0)
.attr("cx", 0)
.attr("r", function (d) { return d.g1 > d.g2 ? d.g1 / 2 : d.g2 / 2; })
.attr("class", function (d) { return d.g1 > d.g2 ? "red" : "blue"; })
.style("fill", function (d) { return d.g1 > d.g2 ? red : blue; })
.style("opacity", opacity);
municipality.append("circle")
/* .attr("cy", function (d, i) { return Math.floor(i / cols) * 30 + 30; })
.attr("cx", function (d, i) { return i % cols * 30 + 30; }) */
.attr("cy", 0)
.attr("cx", 0)
.attr("r", function (d) { return d.g1 > d.g2 ? d.g2 / 2 : d.g1 / 2; })
.attr("class", function (d) { return d.g1 < d.g2 ? "small red" : "small blue"; })
.style("fill", function (d) { return gray; });
sumG1 = data.reduce(function (s, e) { return s + e.g1 }, 0);
sumG2 = data.reduce(function (s, e) { return s + e.g2 }, 0);
d3.select("#red-votes").text(sumG1.toString());
d3.select("#blue-votes").text(sumG2.toString());
d3.select("#filter-red").on("click", function () {
d3.selectAll(".red")
.transition()
.style("fill", red)
.style("opacity", opacity)
.duration(2000);
d3.selectAll(".blue")
.transition()
.style("opacity", 0)
.duration(2000);
});
d3.select("#filter-blue").on("click", function () {
d3.selectAll(".blue")
.transition().style("fill", blue)
.style("opacity", opacity)
.duration(2000);
d3.selectAll(".red")
.transition()
.style("opacity", 0)
.duration(2000);
});
d3.select("#reset-filter").on("click", function () {
d3.selectAll(".red")
.transition().style("fill", red)
.style("opacity", opacity);
d3.selectAll(".blue")
.transition().style("fill", blue)
.style("opacity", opacity);
d3.selectAll(".small")
.transition().style("fill", gray)
.style("opacity", 1);
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment