Skip to content

Instantly share code, notes, and snippets.

@Overbryd
Last active November 25, 2015 10:52
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 Overbryd/a93ddc3ea2ccff05f438 to your computer and use it in GitHub Desktop.
Save Overbryd/a93ddc3ea2ccff05f438 to your computer and use it in GitHub Desktop.
object_constancy_in_visualisations (see http://bl.ocks.org/Overbryd/raw/a93ddc3ea2ccff05f438/)
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.axis text {
font: 1.1em sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
// our data
var data = [
{
"name": "palevioletred",
"sum": 2
},
{
"name": "orchid",
"sum": 2
},
{
"name": "slateblue",
"sum": 4
},
{
"name": "goldenrod",
"sum": 4
},
{
"name": "cyan",
"sum": 1
},
{
"name": "springgreen",
"sum": 6
}
];
// D3 margin convention
var margin = {top: 50, right: 50, bottom: 50, left: 50};
var width = window.innerWidth - margin.left - margin.right;
var height = window.innerHeight - margin.top - margin.bottom;
// append and setup the svg element
var 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 + ")");
// scale our x axis ordinally from 0 to our max width
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
// our x axis drawing generator
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
// append and position x axis container
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0, " + height + ")");
// scale values on the y-axis linearly from 0 to our max height
var y = d3.scale.linear()
.range([height, 0]);
// our y axis drawing generator
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
// append and position y axis container
svg.append("g")
.attr("class", "y axis");
// helper function to render a whole dataset
function render(data) {
// set our ordinal x domain
var colors = data.map(function(d) { return d.name; })
x.domain(colors);
// set y domain
var max = d3.max(data, function(d) { return d.sum; });
y.domain([0, max]);
// delay function that increments for each item
var delay = function(d, i) { return i * 250; };
// D3 SELECT and JOIN
// select and join elements with data
// supplying a key function to identify a datum
var bars = svg.selectAll(".bar")
.data(data, function(d) { return d.name; });
// D3 ENTER
// declaration to create new bars
bars
.enter()
.append("rect")
.attr("class", "bar")
.attr("fill", function(d) { return d.name; })
.attr("x", function(d) { return x(d.name); })
.attr("width", x.rangeBand() - 1)
.attr("y", height)
.attr("height", 0)
.transition()
.duration(1500)
.delay(delay)
.attr("y", function(d) { return y(d.sum); })
.attr("height", function(d) { return height - y(d.sum); });
// D3 UPDATE
// declaration to update existing bars
bars
.transition()
.duration(1500)
.delay(delay)
.attr("height", function(d) { return height - y(d.sum); })
.attr("y", function(d) { return y(d.sum); })
.attr("x", function(d) { return x(d.name); })
.attr("width", x.rangeBand() - 1);
// D3 EXIT
// declaration to remove bars
bars
.exit()
.transition()
.duration(1500)
.attr("height", 0)
.attr("y", height)
.style("opacity", 0)
.remove();
// call x axis generator
svg.select(".x.axis")
.transition()
.duration(1500)
.call(xAxis)
.selectAll("g").delay(delay);
// call y axis generator
svg.select(".y.axis")
.transition()
.duration(1500)
.call(yAxis);
};
// call render initially
render(data);
// helper function to update or add a value
function update(color, sum) {
var found = false;
data.forEach(function(d) {
if (d.name != color) { return; }
d.sum = sum;
found = true;
});
if (!found) {
data.push({name: color, sum: sum});
}
render(data);
};
// helper function to remove a color from the dataset
function remove(color) {
data = data.filter(function(d) { return d.name != color; });
render(data);
};
// helper function to sort by value or name
function sort(byName) {
if (byName) {
data.sort(function(a, b) { return d3.ascending(a.name, b.name); });
} else {
data.sort(function(a, b) { return b.sum - a.sum; });
}
render(data);
};
</script>
<!DOCTYPE html>
<meta charset="utf-8">
<style>
rect:hover {
cursor: pointer;
opacity: 0.9;
}
.axis text {
font: 1.2em sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
// margin convention
var margin = {top: 50, right: 20, bottom: 0, left: 0};
var width = window.innerWidth - margin.left - margin.right;
var height = window.innerHeight - margin.top - margin.bottom;
// create our svg element
var 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 + ")");
var colors = ["palevioletred", "orchid", "slateblue", "goldenrod", "cyan", "springgreen"]
var dataMap = {};
colors.forEach(function(color) {
dataMap[color] = 0;
});
var size = width / colors.length;
var scale = d3.scale.ordinal()
.rangeRoundBands([0, width], .1)
.domain(colors);
// Render rectangles
svg.selectAll("rect")
.data(colors)
.enter()
.append("rect")
.attr("fill", function(d) { return d; })
.attr("x", function(d) { return scale(d); })
.attr("width", scale.rangeBand())
.attr("height", scale.rangeBand())
.on("click", function(d) {
dataMap[d] = dataMap[d] + 1;
var data = [];
for (k in dataMap) {
data.push({name: k, sum: dataMap[k]});
}
console.log(JSON.stringify(data, null, " "));
});
// Render labels
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0, " + (scale.rangeBand() + 10) + ")")
.call(d3.svg.axis().scale(scale).orient("bottom"));
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment