An example chart which combines JPMorgan's Perspective, which D3 and Scott Logic's d3fc.
Built with blockbuilder.org
license: mit |
An example chart which combines JPMorgan's Perspective, which D3 and Scott Logic's d3fc.
Built with blockbuilder.org
<!DOCTYPE html> | |
<html> | |
<head> | |
<!-- include polyfills for custom event, Symbol and Custom Elements --> | |
<script src="//unpkg.com/babel-polyfill@6.26.0/dist/polyfill.js"></script> | |
<script src="//unpkg.com/custom-event-polyfill@0.3.0/custom-event-polyfill.js"></script> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/document-register-element/1.8.0/document-register-element.js"></script> | |
<!-- | |
use babel so that we can use arrow functions and other goodness in this block! | |
--> | |
<script src="//unpkg.com/babel-standalone@6/babel.min.js"></script> | |
<script src="//unpkg.com/d3@5.5.0"></script> | |
<script src="//unpkg.com/d3fc@14.0.1"></script> | |
<!-- perspective! --> | |
<script src="https://unpkg.com/@jpmorganchase/perspective/build/perspective.js"></script> | |
<style> | |
body { | |
font-family: sans-serif; | |
font-size: 1.2em; | |
} | |
.tick { | |
font-size: 1.2em; | |
} | |
#chart { | |
width: 100%; | |
height: 500px; | |
position: relative; | |
} | |
.x-axis .domain { | |
display: none; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="chart"></div> | |
<script src="index.js" type="text/babel"></script> | |
</body> | |
</html> |
const color = d3 | |
.scaleOrdinal() | |
.range([ | |
"#FFD700", | |
"#C0C0C0", | |
"#CD7F32" | |
]); | |
const yExtent = fc | |
.extentLinear() | |
.accessors([d => d.map(e => e[1])]) | |
.include([0]); | |
const url = | |
"https://raw.githubusercontent.com/ag-grid/ag-grid/master/packages/ag-grid-docs/src/olympicWinnersSmall.json"; | |
const xhr = new XMLHttpRequest(); | |
xhr.open("GET", url, true); | |
xhr.onload = async () => { | |
const table = perspective.worker().table(JSON.parse(xhr.response)); | |
const aggregates = ["gold", "silver", "bronze"]; | |
const view = table.view({ | |
row_pivot: ["year"], | |
aggregate: aggregates.map(column => ({ | |
column, | |
op: "sum" | |
})), | |
filter: [["country", "==", "United States"]] | |
}); | |
const columnarData = await view.to_columns(); | |
// convert the columnar data into a shape which is more | |
// compatible with D3 | |
const series = aggregates.map(key => | |
columnarData[key] | |
.slice(1) | |
.map((d, i) => [columnarData.__ROW_PATH__[i + 1][0], d]) | |
); | |
color.domain(aggregates); | |
const groupedBar = fc | |
.seriesSvgGrouped(fc.seriesSvgBar()) | |
.crossValue(d => d[0]) | |
.mainValue(d => d[1]) | |
.bandwidth(120) | |
.decorate((sel, data, index) => { | |
sel | |
.enter() | |
.select("path") | |
.attr("fill", color(aggregates[index])); | |
}); | |
const chart = fc | |
.chartSvgCartesian(d3.scalePoint(), d3.scaleLinear()) | |
.xDomain(series[0].map(s => s[0])) | |
.xPadding(0.5) | |
.yDomain(yExtent(series)) | |
.yTickFormat(d3.format(".2s")) | |
.yOrient("left") | |
.plotArea(groupedBar) | |
.chartLabel("Medals won by the United States"); | |
d3.select("#chart") | |
.datum(series) | |
.call(chart); | |
}; | |
xhr.send(null); |