Skip to content

Instantly share code, notes, and snippets.

@curran
Last active October 5, 2017 15:26
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 curran/65bb295d224a09f83fad6f9942ee4639 to your computer and use it in GitHub Desktop.
Save curran/65bb295d224a09f83fad6f9942ee4639 to your computer and use it in GitHub Desktop.
Basic General Update Pattern
license: mit
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Shopping App Tester</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<svg width="960" height="500"></svg>
<script src="visualization.js"></script>
<script>
const props = {
width: 300,
height: 500,
data: [
{ name: 'banana', price: 1 },
{ name: 'eggs', price: 2 },
{ name: 'peanut butter', price: 4 }
]
};
const svg = d3.select('svg');
const selection = svg.append('g')
.attr('transform', `translate(${+svg.attr('width') / 2 - props.width / 2})`);
visualization(selection, props);
// Test the problem: bars don't update when price changes.
setTimeout(() => {
props.data[1].price = 3;
visualization(selection, props);
}, 1000);
// Test the problem: bars don't update correctly after an item is removed.
setTimeout(() => {
props.data = [
{ name: 'banana', price: 1 },
{ name: 'eggs', price: 2 },
];
visualization(selection, props);
}, 2000);
</script>
</body>
</html>
function visualization(selection, props){
const { width, height, data } = props;
const yValue = d => d.name;
const xValue = d => d.price;
const yScale = d3.scaleBand()
.domain(data.map(yValue))
.range([height, 0]);
const xScale = d3.scaleLinear()
.domain([0, d3.max(data, xValue)])
.range([0, width]);
// Create the data join.
const bars = selection.selectAll('rect').data(data);
// Handle the ENTER case - when elements first get added.
const barsEnter = bars
.enter().append('rect')
.attr('x', 0); // The x values won't change, so we can set it on ENTER.
// Set the bar position and dimensions on ENTER and UPDATE.
barsEnter
.merge(bars)
.attr('y', d => yScale(yValue(d)))
.attr('width', d => xScale(xValue(d)))
.attr('height', yScale.bandwidth());
// Remove bars for which there are no longer any corresponding data elements.
bars.exit().remove();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment