Skip to content

Instantly share code, notes, and snippets.

@ColinEberhardt
Last active November 15, 2018 17:21
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 ColinEberhardt/58bbf2df7b45ebcb2f48ee73ddd2c18a to your computer and use it in GitHub Desktop.
Save ColinEberhardt/58bbf2df7b45ebcb2f48ee73ddd2c18a to your computer and use it in GitHub Desktop.
Perspective + d3fc
license: mit
<!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);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment