Skip to content

Instantly share code, notes, and snippets.

@chrpr
Created April 12, 2016 22:47
Show Gist options
  • Save chrpr/19def9a743dc4bcafd8c5add806e5d6f to your computer and use it in GitHub Desktop.
Save chrpr/19def9a743dc4bcafd8c5add806e5d6f to your computer and use it in GitHub Desktop.
Wordcount Fingerprints, with log values for scale
d3.starPlot = function() {
var width = 200,
margin = {
top: 0,
right: 0,
bottom: 0,
left: 0
},
labelMargin = 20,
includeGuidelines = true,
includeLabels = true,
properties = [],
scales = [],
labels = nop,
title = nop,
g,
datum,
radius = width / 2,
origin = [radius, radius],
radii = properties.length,
radians = 2 * Math.PI / radii,
scale = d3.scale.linear()
.domain([0, 100])
.range([0, radius])
function chart(selection) {
datum = selection.datum();
g = selection
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
if (includeGuidelines) {
drawGuidelines();
}
drawChart();
if (includeLabels) {
drawLabels();
}
}
function drawGuidelines() {
var r = 0;
properties.forEach(function(d, i) {
var l, x, y;
l = radius;
x = l * Math.cos(r);
y = l * Math.sin(r);
g.append('line')
.attr('class', 'star-axis')
.attr('x1', origin[0])
.attr('y1', origin[1])
.attr('x2', origin[0] + x)
.attr('y2', origin[1] + y)
r += radians;
})
}
function drawLabels() {
var r = 0;
properties.forEach(function(d, i) {
var l, x, y;
l = radius;
x = (l + labelMargin) * Math.cos(r);
y = (l + labelMargin) * Math.sin(r);
g.append('text')
.attr('class', 'star-label')
.attr('x', origin[0] + x)
.attr('y', origin[1] + y)
.text(typeof labels == "function" ? labels(datum, i) : labels[i])
.style('text-anchor', 'middle')
.style('dominant-baseline', 'central')
r += radians;
})
}
function drawChart() {
g.append('circle')
.attr('class', 'star-origin')
.attr('cx', origin[0])
.attr('cy', origin[1])
.attr('r', 2)
var path = d3.svg.line.radial()
var pathData = [];
var r = Math.PI / 2;
properties.forEach(function(d, i) {
var userScale = scales[i] || scales[0];
pathData.push([
scale(userScale(datum[d])),
r
])
r += radians;
});
g.append('path')
.attr('class', 'star-path')
.attr('transform', 'translate(' + origin[0] + ',' + origin[1] + ')')
.attr('d', path(pathData) + 'Z');
g.append('text')
.attr('class', 'star-title')
.attr('x', origin[0])
.attr('y', -(margin.top / 2))
.text(title(datum))
.style('text-anchor', 'middle')
}
function drawInteraction() {
var path = d3.svg.line.radial();
// `*Interaction` variables are used to build the interaction layer.
// `*Extent` variables are used to compute (and return) the x,y
// positioning of the attribute extents. `*Value` variables are used
// for the attribute values.
var rInteraction = Math.PI / 2;
var rExtent = 0;
properties.forEach(function(d, i) {
var lInteraction, xInteraction, yInteraction;
var lExtent, xExtent, yExtent;
lInteraction = radius;
xInteraction = lInteraction * Math.cos(rInteraction);
yInteraction = lInteraction * Math.sin(rInteraction);
lExtent = radius + labelMargin;
xExtent = lExtent * Math.cos(rExtent) + origin[0] + margin.left;
yExtent = lExtent * Math.sin(rExtent) + origin[1] + margin.top;
var userScale = scales[i] || scales[0];
lValue = scale(userScale(datum[d]));
x = lValue * Math.cos(rExtent) + origin[0] + margin.left;
y = lValue * Math.sin(rExtent) + origin[1] + margin.top;
var halfRadians = radians / 2;
var pathData = [
[0, rInteraction - halfRadians],
[lInteraction, rInteraction - halfRadians],
[lInteraction, rInteraction + halfRadians]
];
var datumToBind = {
xExtent: xExtent,
yExtent: yExtent,
x: x,
y: y,
key: properties[i],
datum: datum
};
g.append('path')
.datum(datumToBind)
.attr('class', 'star-interaction')
.attr('transform', 'translate(' + origin[0] + ',' + origin[1] + ')')
.attr('d', path(pathData) + 'Z');
rInteraction += radians;
rExtent += radians;
})
}
function nop() {
return;
}
chart.interaction = function() {
drawInteraction();
};
chart.properties = function(_) {
if (!arguments.length) return properties;
properties = _;
radii = properties.length;
radians = 2 * Math.PI / radii;
return chart;
};
chart.scales = function(_) {
if (!arguments.length) return scales;
if (Array.isArray(_)) {
scales = _;
} else {
scales = [_];
}
return chart;
};
chart.width = function(_) {
if (!arguments.length) return width;
width = _;
radius = width / 2;
origin = [radius, radius];
scale.range([0, radius])
return chart;
};
chart.margin = function(_) {
if (!arguments.length) return margin;
margin = _;
origin = [radius, radius];
return chart;
};
chart.labelMargin = function(_) {
if (!arguments.length) return labelMargin;
labelMargin = _;
return chart;
};
chart.title = function(_) {
if (!arguments.length) return title;
title = _;
return chart;
};
chart.labels = function(_) {
if (!arguments.length) return labels;
labels = _;
return chart;
};
chart.includeGuidelines = function(_) {
if (!arguments.length) return includeGuidelines;
includeGuidelines = _;
return chart;
};
chart.includeLabels = function(_) {
if (!arguments.length) return includeLabels;
includeLabels = _;
return chart;
};
return chart;
}
<!DOCTYPE>
<meta charset="utf-8">
<style>
body {
width: 960px;
margin: auto;
font-family: Arial;
background-color: rgb(224,216,201);
}
#target {
margin: 40px 0;
}
.wrapper {
position: relative;
display: inline-block;
}
.chart {
margin-bottom: 40px;
}
.star-title {
font-size: 12px;
}
.star-label {
font-size: 11px;
pointer-events: none;
}
.star-origin {
fill: #333;
}
.star-axis {
stroke: #333;
stroke-opacity: 0.3;
stroke-width: 2px;
stroke-dasharray: 4 5;
}
.star-path {
stroke: #444;
stroke-width: 2px;
fill: #709CB1;
fill-opacity: 0.6;
}
.star-interaction {
opacity: 0;
}
.interaction {
pointer-events: none;
}
.interaction.label {
position: absolute;
font-size: 11px;
text-shadow: 0 1px 0 #FFF, 0 -1px 0 #FFF, 1px 0 #FFF, -1px 0 #FFF;
}
.interaction.circle {
fill: #444;
fill-opacity: 0.6;
stroke: #444;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="d3-starPlot.js"></script>
<script>
var margin = {
top: 32,
right: 50,
bottom: 20,
left: 50
};
var width = 240 - margin.left - margin.right;
var height = 240 - margin.top - margin.bottom;
var labelMargin = 8;
var scale = d3.scale.linear()
.domain([0, 5])
.range([0, 100])
d3.csv('word.fingers.csv')
.row(function(d) {
d.contributor = +d.contributor;
d.creator = +d.creator;
d.date = +d.date;
d.description = +d.description;
d.extent = +d.extent;
d.format = +d.format;
d.relation = +d.relation;
d.spatial = +d.spatial;
d.subject = +d.subject;
d.temporal = +d.temporal;
return d;
})
.get(function(error, rows) {
var star = d3.starPlot()
.width(width)
.properties([
'contributor',
'creator',
'date',
'description',
'extent',
'format',
'relation',
'spatial',
'subject',
'temporal'
])
.scales(scale)
.labels([
'contributor',
'creator',
'date',
'description',
'extent',
'format',
'relation',
'spatial',
'subject',
'temporal'
])
.title(function(d) { return d.Provider; })
.margin(margin)
.labelMargin(labelMargin)
rows.forEach(function(d, i) {
star.includeLabels(i % 4 === 0 ? true : false);
var wrapper = d3.select('#target').append('div')
.attr('class', 'wrapper')
var svg = wrapper.append('svg')
.attr('class', 'chart')
.attr('width', width + margin.left + margin.right)
.attr('height', width + margin.top + margin.bottom)
var starG = svg.append('g')
.datum(d)
.call(star)
.call(star.interaction)
var interactionLabel = wrapper.append('div')
.attr('class', 'interaction label')
var circle = svg.append('circle')
.attr('class', 'interaction circle')
.attr('r', 5)
var interaction = wrapper.selectAll('.interaction')
.style('display', 'none');
svg.selectAll('.star-interaction')
.on('mouseover', function(d) {
svg.selectAll('.star-label')
.style('display', 'none')
interaction
.style('display', 'block')
circle
.attr('cx', d.x)
.attr('cy', d.y)
$interactionLabel = $(interactionLabel.node());
interactionLabel
.text(d.key + ': ' + d.datum[d.key])
.style('left', d.xExtent - ($interactionLabel.width() / 2))
.style('top', d.yExtent - ($interactionLabel.height() / 2))
})
.on('mouseout', function(d) {
interaction
.style('display', 'none')
svg.selectAll('.star-label')
.style('display', 'block')
})
});
});
</script>
<div id='target'></div>
</body>
Provider collection contributor creator date description extent format identifier isPartOf language publisher relation rights spatial specType stateLocatedIn subject temporal thumb title type
ARTstor 1.00 0.00 0.86 0.84 0.82 0.00 1.56 0.00 0.00 0.00 1.00 0.00 0.80 0.00 0.00 0.00 1.65 0.00 0.00 0.99 0.09
Biodiversity Heritage Library 1.00 0.00 1.67 0.50 0.47 0.00 0.00 0.00 0.00 1.03 1.01 0.00 0.00 0.00 0.00 0.00 3.47 0.00 0.00 1.00 1.00
David Rumsey 1.00 0.00 2.51 1.00 2.56 0.00 0.00 0.00 0.00 0.00 1.05 0.00 1.00 2.53 0.00 0.00 0.52 0.00 0.00 2.81 1.00
Harvard Library 1.00 0.32 0.64 0.98 1.48 0.76 0.73 0.25 0.00 0.59 0.45 1.25 0.98 0.52 0.00 1.00 2.00 0.19 0.00 1.00 0.86
HathiTrust 0.00 0.52 0.87 0.98 1.21 0.94 2.13 4.31 0.00 1.02 0.97 0.06 1.00 0.41 1.14 0.00 1.44 0.09 0.00 1.03 1.00
Internet Archive 1.00 0.00 1.57 0.93 2.27 0.64 0.00 1.64 0.15 1.00 0.90 0.00 1.00 0.19 0.00 0.00 1.95 0.00 0.00 1.00 0.99
J. Paul Getty Trust 1.00 0.06 1.02 1.00 2.75 1.06 0.93 1.21 0.00 0.02 0.02 2.37 0.20 0.00 0.99 0.00 0.47 0.00 0.00 1.06 1.03
National Archives and Records Administration 1.00 0.08 0.99 0.79 0.01 0.02 1.20 2.81 0.00 0.00 0.00 1.33 1.00 0.05 0.00 1.00 0.33 0.00 0.00 1.00 0.98
Smithsonian Institution 1.85 0.00 0.21 0.73 2.21 0.09 0.27 0.42 0.00 0.01 0.00 0.00 0.28 0.78 0.00 1.00 5.96 0.82 0.00 1.00 0.99
The New York Public Library 1.00 0.23 0.43 0.72 0.28 0.20 0.00 0.02 0.00 0.12 0.16 1.00 1.00 0.28 0.00 1.00 1.92 0.00 0.00 1.00 1.00
US Government Publishing Office (GPO) 0.00 0.16 0.67 1.00 4.38 0.90 1.99 4.07 0.00 1.01 1.00 0.56 1.00 0.97 2.00 0.00 3.19 0.02 0.00 1.00 1.00
University of Illinois at Urbana-Champaign 0.98 0.05 0.63 0.79 3.47 0.02 0.79 0.03 0.00 0.21 0.02 2.00 1.04 0.49 0.03 0.00 3.72 0.08 0.00 1.01 0.80
University of Southern California. Libraries 0.00 0.18 0.11 0.29 0.21 0.00 0.86 0.00 0.00 0.18 0.37 1.13 1.57 0.91 0.00 0.00 0.96 0.00 0.00 1.04 0.71
University of Virginia Library 1.00 0.00 1.15 0.90 0.22 0.25 0.93 0.87 0.00 0.32 0.37 0.00 0.78 0.77 0.00 1.00 2.87 0.00 0.00 1.00 1.00
Content Hub Total 0.65 0.25 0.64 0.77 1.08 0.41 1.05 1.89 0.00 0.45 0.49 0.52 0.93 0.49 0.43 0.43 2.16 0.16 0.00 1.03 0.94
California Digital Library 0.67 0.32 0.54 0.82 1.55 0.33 0.94 1.95 0.00 0.63 0.70 3.37 1.63 1.12 0.33 1.00 3.82 0.04 0.00 1.02 1.00
Digital Commonwealth 1.00 0.24 0.62 0.96 1.95 0.76 1.94 1.34 0.00 0.22 0.29 1.55 1.00 1.82 0.00 1.00 2.43 0.02 0.00 1.00 1.00
Digital Library of Georgia 1.00 0.00 0.50 0.92 2.32 0.00 0.24 0.00 0.00 0.08 0.00 0.49 1.42 1.04 0.08 0.97 3.93 0.00 0.00 1.08 0.99
Empire State Digital Network 0.40 0.06 0.66 0.49 0.69 0.00 0.87 0.12 0.00 0.55 0.19 0.46 0.99 0.42 0.00 0.00 2.73 0.00 0.00 1.00 0.58
Indiana Memory 1.00 0.00 0.00 0.75 0.91 0.00 0.40 0.00 0.00 0.16 0.67 0.00 1.23 1.06 0.17 1.00 2.00 0.00 0.00 1.02 1.00
Kentucky Digital Library 0.00 0.00 1.00 0.67 0.01 0.00 1.00 0.00 0.00 1.00 0.00 0.00 1.00 0.35 0.00 0.00 0.18 0.00 0.00 1.26 1.00
Minnesota Digital Library 0.74 0.08 0.71 0.93 0.90 0.13 0.92 0.00 0.00 0.35 0.00 0.11 1.00 0.42 0.00 0.41 2.52 0.00 0.00 1.01 0.73
Missouri Hub 0.00 0.00 0.76 0.87 0.89 0.02 0.62 1.61 0.00 0.54 0.56 1.49 0.98 0.50 0.39 1.00 2.10 0.02 0.00 1.19 0.68
Mountain West Digital Library 1.00 0.00 0.83 0.77 1.22 0.16 0.00 1.00 1.00 0.28 0.00 0.85 0.99 0.49 0.00 1.00 3.28 0.18 0.00 1.00 0.88
North Carolina Digital Heritage Center 1.00 0.30 0.76 0.80 0.86 0.00 1.41 1.84 0.77 0.62 0.51 0.00 0.95 1.05 0.01 1.00 3.75 0.00 0.00 1.08 0.92
South Carolina Digital Library 0.56 0.36 0.64 0.70 0.80 0.00 0.95 0.00 0.00 0.33 0.00 0.59 0.99 1.35 0.01 0.45 2.99 0.00 0.00 1.00 1.01
The Portal to Texas History 1.32 0.22 0.71 0.90 1.96 0.00 1.00 4.59 0.00 0.88 0.66 0.06 1.00 1.44 0.53 0.00 11.23 0.00 0.00 1.97 1.00
University of Washington 1.81 0.00 0.68 0.86 0.79 0.00 1.14 1.97 0.00 0.00 0.00 0.04 0.84 0.99 0.00 0.00 1.29 0.00 0.00 1.04 0.94
Service Hub Total 0.88 0.12 0.70 0.81 1.32 0.12 0.73 1.36 0.29 0.46 0.25 0.70 1.08 0.88 0.13 0.63 4.28 0.05 0.00 1.18 0.89
Grand Total 0.73 0.20 0.66 0.79 1.16 0.31 0.94 1.71 0.10 0.45 0.40 0.59 0.99 0.63 0.32 0.50 2.90 0.12 0.00 1.08 0.93
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment