Built with blockbuilder.org
forked from sxywu's block: Selections: Data example
forked from sxywu's block: Selections: Enter example
forked from sxywu's block: Selections: Update-Exit example
license: mit |
Built with blockbuilder.org
forked from sxywu's block: Selections: Data example
forked from sxywu's block: Selections: Enter example
forked from sxywu's block: Selections: Update-Exit example
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<style> | |
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
svg { | |
width: 100%; | |
height: 100%; | |
} | |
</style> | |
</head> | |
<body> | |
<svg></svg> | |
<script> | |
var rectWidth = 100; | |
var height = 300; | |
var data = [ | |
[100, 250, 175, 200, 120], | |
[230, 120, 300, 145, 75, 250], | |
[240, 250, 100] | |
]; | |
var colors = d3.scaleOrdinal(d3.schemeCategory10); | |
var svg = d3.select('svg'); | |
// How to account for data changing? | |
// If 3 rectanges, and 5 data elements? | |
// Something changes to that data? Second dataset has less data points than first dataset? | |
// Object constancy. If you have data that changes between states, you want to make sure, the user has a way of following that data one state to the next | |
// We want to transistion between these dataset. | |
// Transitioning in and out | |
// Data points are the same, and some are leaving. | |
// | |
function updateBars(data) { | |
var bars = svg.selectAll('rect') | |
.data(data, d => d); // key function loops through the data, returns the identifying key should be. The data that should be passed in is an array of integers. Should return unique strings or integers. You need unique key/ids. If you don't provide a key function, .data assumes applys a key for each of them as the index. The key provides the data and index. | |
// First calculation .data does is update selection. 120 maps to 120. 250 maps to 250. They remain on the screen. For 230, 300, 145, 75, need to creat 4 rectanges to match the data. 100, 175, 200 needs to be removed from the screen. | |
// Manipulating data, look at lodash. | |
// Sort function -- d3 selection.sort | |
// Describing things that don't yet exist is confusing | |
// Data dictates what should appear on the screen | |
// React is smart in figuring out how to get from one state to the next. | |
// D3 gives you all control for enter, update and exit | |
// D3 gives you what your set of selections should be. | |
// exit | |
bars.exit().remove(); // Exit selection | |
// enter | |
// // Add things that don't depend on data change | |
var enter = bars.enter().append('rect') | |
.attr('width', rectWidth) // Things that don't depend on the data so you don't need to re-render the DOM. Width will always be rectWidth | |
.attr('stroke', '#fff'); // Stroke is white always. Don't need to update border white ever | |
// enter + update | |
// What's left on the screen once you've removed the extraneous. | |
// Merge what is displayed -- what's added and what's remaining. | |
// Add things that should be re-rendered with data change. | |
bars = enter.merge(bars) // Combines 2 selections into one | |
.attr('x', (d, i) => i * rectWidth) | |
.attr('y', d => height - d) | |
.attr('height', d => d) | |
.attr('fill', d => colors(d)); | |
} | |
var index = 0; | |
setInterval(() => { | |
updateBars(data[index % 3]); | |
index += 1; | |
}, 2500); | |
</script> | |
</body> |