Skip to content

Instantly share code, notes, and snippets.

@curran
Last active April 19, 2023 04: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 curran/6b5a43a958e7d9adea657a984ce1fbd6 to your computer and use it in GitHub Desktop.
Save curran/6b5a43a958e7d9adea657a984ce1fbd6 to your computer and use it in GitHub Desktop.
Marks and Channels

A port of VizHub: Marks and Channels to vanilla JavaScript.

A demonstration of basic D3 usage to implement the concept of Marks and Channels. Includes usage of:

  • Point Marks by X, Y, Size
  • Line mark varying in length
  • Scaling factors
  • SVG Rectangles
  • selection.each()
  • SVG Path Elements
  • d3.symbol()
  • SVG attributes transform and fill
  • D3 Color Schemes
  • JavaScript Modules

Part of the Constructing Visualizations Playlist.

<!DOCTYPE html>
<html>
<head>
<title>Marks and Channels</title>
<script src="https://unpkg.com/d3@7.6.1/dist/d3.min.js"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const xPosition = (
selection,
{ data, height }
) => {
selection
.selectAll('circle')
.data(data)
.join('circle')
.attr('cx', (d) => d * 70 + 60)
.attr('cy', height / 2)
.attr('r', 30);
};
const yPosition = (
selection,
{ data, width }
) => {
selection
.selectAll('circle')
.data(data)
.join('circle')
.attr('cx', width / 2)
.attr('cy', (d) => d * 28 + 20)
.attr('r', 12);
};
const length = (
selection,
{ data, height }
) => {
const barHeight = (d) => d * 25 + 10;
selection
.selectAll('rect')
.data(data)
.join('rect')
.attr('x', (d) => d * 80 + 20)
.attr('y', (d) => height / 2 - barHeight(d))
.attr('width', 50)
.attr('height', barHeight);
};
const size = (
selection,
{ data, height }
) => {
selection
.selectAll('circle')
.data(data)
.join('circle')
.attr('cx', (d) => d * 70 + 60)
.attr('cy', height / 2)
.attr('r', (d) => Math.sqrt(d * 200) + 1);
};
const shape = (
selection,
{ data, height }
) => {
const symbolGenerator = d3.symbol();
selection
.selectAll('path')
.data(data)
.join('path')
.attr(
'transform',
(d) =>
`translate(${d * 70 + 60},${height / 2})`
)
.attr('d', (d, i) =>
symbolGenerator
.type(d3.symbolsFill[i])
.size(2000)()
);
};
const hue = (
selection,
{ data, height }
) => {
selection
.selectAll('circle')
.data(data)
.join('circle')
.attr('cx', (d) => d * 70 + 60)
.attr('cy', height / 2)
.attr('r', 30)
.attr('fill', (d, i) => d3.schemeCategory10[i]);
};
const data = [0, 1, 2, 3, 4];
const height = 150;
const width = 400;
const viz = (container) => {
const svg = d3.select(container)
.selectAll('svg')
.data([
xPosition,
yPosition,
size,
length,
shape,
hue,
])
.join('svg')
.attr('width', width)
.attr('height', height)
.each(function (d) {
d(d3.select(this), { data, width, height });
});
};
const container = d3.select('#app').node();
viz(container);
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment