A demonstration of the d3fc-label-layout component.
Built with blockbuilder.org
xxxxxxxxxx
<!-- include polyfills for custom event and Symbol (for IE) -->
<script src="https://unpkg.com/babel-polyfill@6.26.0/dist/polyfill.js"></script>
<script src="https://unpkg.com/custom-event-polyfill@0.3.0/custom-event-polyfill.js"></script>
<!-- use babel so that we can use arrow functions and other goodness in this block! -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script src="https://unpkg.com/d3@4.6.0"></script>
<script src="https://unpkg.com/d3fc@13.1.1"></script>
<style>
body {
font: 16px sans-serif;
}
.chart {
height: 480px;
}
.line {
stroke: purple;
}
.area {
fill: lightgreen;
fill-opacity: 0.5;
}
rect {
fill: none;
}
.y-axis-label {
white-space: nowrap;
}
</style>
<div id='chart' class='chart'></div>
<script type='text/babel'>
d3.csv('repos-users-dump.csv', (githubData) => {
// count the organisations / users for each language
const scatter = d3.nest()
.key(d => d.language)
.entries(githubData)
.map(lang => ({
language: lang.key,
orgs: lang.values.filter(d => d.type === 'Organization').length,
users: lang.values.filter(d => d.type === 'User').length
}))
.filter(d => d.language);
// Use the text label component for each datapoint. This component renders both
// a text label and a circle at the data-point origin. For this reason, we don't
// need to use a scatter / point series.
const labelPadding = 2;
const textLabel = fc.layoutTextLabel()
.padding(2)
.value(d => d.language);
// a strategy that combines simulated annealing with removal
// of overlapping labels
const strategy = fc.layoutRemoveOverlaps(fc.layoutGreedy());
// create the layout that positions the labels
const labels = fc.layoutLabel(strategy)
.size((d, i, g) => {
// measure the label and add the required padding
const textSize = g[i].getElementsByTagName('text')[0].getBBox();
return [
textSize.width,
textSize.height
];
})
.position((d) => {
return [
d.users,
d.orgs
]
})
.component(textLabel);
const yExtent = fc.extentLinear()
.accessors([d => d.orgs])
.pad([0.1, 0.1]);
const xExtent = fc.extentLinear()
.accessors([d => d.users])
.pad([0.05, 0.2]);
// create a chart
const chart = fc.chartSvgCartesian(
d3.scaleLinear(),
d3.scaleLinear())
.yDomain(yExtent(scatter))
.xDomain(xExtent(scatter))
.yOrient('left')
.xLabel('GitHub Users')
.yLabel('GitHub Organisations')
.chartLabel('GitHub Organizations vs. Individuals')
.plotArea(labels);
// render
d3.select('#chart')
.datum(scatter)
.call(chart);
});
</script>
https://unpkg.com/babel-polyfill@6.26.0/dist/polyfill.js
https://unpkg.com/custom-event-polyfill@0.3.0/custom-event-polyfill.js
https://unpkg.com/babel-standalone@6/babel.min.js
https://unpkg.com/d3@4.6.0
https://unpkg.com/d3fc@13.1.1