This d3fc example demonstrates how to render a bubble chart with data that shows the relationship between life expectancy and wealth, obtained via Gapminder. The chart is constructed from the following components:
d3.json
component is used to load the data from a JSON file.size
of each point defined via another linear scale.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@5.5.0"></script>
<script src="https://unpkg.com/d3fc@14.0.41"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.18.0/d3-legend.min.js"></script>
<meta charset="utf-8">
<style>
body {
font: 14px sans-serif;
}
.chart-label {
font-size: 25px;
}
.y-axis-label {
white-space: nowrap;
}
#bubble-chart .legend {
position: absolute;
bottom: 40px;
right: 0;
left: auto;
width: 170px;
height: 110px;
}
#bubble-chart {
position: relative;
height: 480px;
}
#bubble-chart .point {
stroke: transparent;
}
#bubble-chart text.label {
stroke: none;
fill: #000;
font: 12px sans-serif;
}
.container {
position: relative;
}
#legend {
position: absolute;
bottom: 0;
right: 0;
}
</style>
<div class='container'>
<div id='bubble-chart' class='chart'>
Loading ...
</div>
<svg id='legend'/>
</div>
<script type='text/babel'>
d3.json('data.json').then(data => {
// convert string properties to numbers
data.forEach(function(d) {
d.income = Number(d.income);
d.population = Number(d.population);
d.lifeExpectancy = Number(d.lifeExpectancy);
});
var regions = d3.set(data.map(d => d.region));
var color = d3.scaleOrdinal(d3.schemeCategory10)
.domain(regions.values());
var legend = d3.legendColor()
.scale(color);
d3.select('#legend')
.call(legend);
var size = d3.scaleLinear().range([40, 1600])
.domain(fc.extentLinear()
.accessors([d => d.population])(data));
var pointSeries = fc.seriesSvgPoint()
.crossValue(d => d.income)
.mainValue(d => d.lifeExpectancy)
.size(d => size(d.population))
.decorate((sel) => {
sel.enter()
.attr('fill', d => color(d.region));
});
var chart = fc.chartCartesian(
d3.scaleLog(),
d3.scaleLinear()
)
.xDomain(fc.extentLinear()
.accessors([d => d.income])(data))
.yDomain(fc.extentLinear()
.accessors([d => d.lifeExpectancy])(data))
.chartLabel('The Wealth & Health of Nations')
.xLabel('Income (dollars)')
.yLabel('Life expectancy (years)')
.xTickFormat(d3.format(',d'))
.xTicks(2)
.yOrient('left')
.svgPlotArea(pointSeries);
d3.select('#bubble-chart')
// remove the loading text from the container
.text(null)
.datum(data)
.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@5.5.0
https://unpkg.com/d3fc@14.0.41
https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.18.0/d3-legend.min.js