<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Box Plot</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<!-- A functional reactive model library. github.com/curran/model -->
<script src="https://curran.github.io/model/cdn/model-v0.2.4.js"></script>
<!-- Chiasm core and plugins. github.com/chiasm-project -->
<script src="https://chiasm-project.github.io/chiasm/chiasm-v0.2.0.js"></script>
<script src="https://chiasm-project.github.io/chiasm-component/chiasm-component-v0.2.1.js"></script>
<script src="https://chiasm-project.github.io/chiasm-layout/chiasm-layout-v0.2.2.js"></script>
<script src="https://chiasm-project.github.io/chiasm-links/chiasm-links-v0.2.0.js"></script>
<script src="https://chiasm-project.github.io/chiasm-dataset-loader/chiasm-dataset-loader-v0.3.1.js"></script>
<script src="boxPlot.js"></script>
<style>
body {
background-color: black;
}
/* Make the chart container fill the page using CSS. */
#chiasm-container {
background-color: white;
position: fixed;
left: 20px;
right: 20px;
top: 20px;
bottom: 20px;
}
</style>
</head>
<body>
<div id="chiasm-container"></div>
<script>
var chiasm = Chiasm();
chiasm.plugins.layout = ChiasmLayout;
chiasm.plugins.links = ChiasmLinks;
chiasm.plugins.dsvDataset = ChiasmDatasetLoader;
chiasm.plugins.boxPlot = BoxPlot;
chiasm.setConfig({
"layout": {
"plugin": "layout",
"state": {
"containerSelector": "#chiasm-container",
"layout": "boxPlot"
}
},
"boxPlotData": {
"plugin": "dsvDataset",
"state": {
"path": "iris"
}
},
"boxPlot": {
"plugin": "boxPlot",
"state": {
"xColumn": "class",
"yColumn": "petal_length"
}
},
"links": {
"plugin": "links",
"state": {
"bindings": [
"boxPlotData.data -> boxPlot.data"
]
}
}
});
</script>
</body>
</html>
// This is an example Chaism plugin that uses D3 to make a box plot.
// Draws from this Box Plot example http://bl.ocks.org/mbostock/4061502
function BoxPlot() {
var my = ChiasmComponent({
margin: {
left: 30,
top: 30,
right: 30,
bottom: 30
},
xColumn: Model.None,
yColumn: Model.None,
fill: "white",
stroke: "black",
strokeWidth: "1px"
});
var xScale = d3.scale.ordinal();
var yScale = d3.scale.linear();
var rScale = d3.scale.sqrt();
var g = d3.select(my.initSVG()).append("g");
// Respond to changes in size and margin.
// Inspired by D3 margin convention from http://bl.ocks.org/mbostock/3019563
my.when(["box", "margin"], function(box, margin){
my.innerBox = {
width: box.width - margin.left - margin.right,
height: box.height - margin.top - margin.bottom
};
g.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
});
my.when(["data", "xColumn", "yColumn"], function (data, xColumn, yColumn){
if(xColumn !== Model.None && yColumn !== Model.None){
var getX = function (d){ return d[xColumn]; };
var getY = function (d){ return d[yColumn]; };
my.boxPlotData = d3.nest().key(getX).entries(data)
.map(function (d){
var sorted = d.values.map(getY).sort();
d.quartileData = quartiles(sorted);
d.whiskerData = [sorted[0], sorted[sorted.length - 1]];
return d;
});
}
});
function quartiles(d) {
return [
d3.quantile(d, .25),
d3.quantile(d, .5),
d3.quantile(d, .75)
];
}
my.when(["boxPlotData", "innerBox", "xColumn"], function (boxPlotData, innerBox, xColumn){
if(xColumn !== Model.None){
// The key here corresponds to the unique values in the X column.
xScale
.domain(boxPlotData.map(function (d){ return d.key; }))
.rangeBands([0, innerBox.width], 0.5);
}
});
my.when(["data", "innerBox", "yColumn"], function (data, innerBox, yColumn){
if(yColumn !== Model.None){
yScale
.domain(d3.extent(data, function (d){ return d[yColumn]; }))
.range([innerBox.height, 0]);
}
});
my.when([ "boxPlotData", "fill", "stroke", "strokeWidth" ],
function (boxPlotData, fill, stroke, strokeWidth){
// The center lines that span the whiskers.
var center = g.selectAll("line.center").data(boxPlotData);
center.enter().append("line").attr("class", "center");
center.exit().remove();
center
.attr("x1", function (d){ return xScale(d.key) + (xScale.rangeBand() / 2); })
.attr("x2", function (d){ return xScale(d.key) + (xScale.rangeBand() / 2); })
.attr("y1", function (d){ return yScale(d.whiskerData[0]); })
.attr("y2", function (d){ return yScale(d.whiskerData[1]); })
.style("stroke", stroke)
.style("stroke-width", strokeWidth);
// The top whiskers.
var whiskerTop = g.selectAll("line.whisker-top").data(boxPlotData);
whiskerTop.enter().append("line").attr("class", "whisker-top");
whiskerTop.exit().remove();
whiskerTop
.attr("x1", function (d){ return xScale(d.key); })
.attr("x2", function (d){ return xScale(d.key) + xScale.rangeBand(); })
.attr("y1", function (d){ return yScale(d.whiskerData[0]); })
.attr("y2", function (d){ return yScale(d.whiskerData[0]); })
.style("stroke", stroke)
.style("stroke-width", strokeWidth);
// The bottom whiskers.
var whiskerBottom = g.selectAll("line.whisker-bottom").data(boxPlotData);
whiskerBottom.enter().append("line").attr("class", "whisker-bottom");
whiskerBottom.exit().remove();
whiskerBottom
.attr("x1", function (d){ return xScale(d.key); })
.attr("x2", function (d){ return xScale(d.key) + xScale.rangeBand(); })
.attr("y1", function (d){ return yScale(d.whiskerData[1]); })
.attr("y2", function (d){ return yScale(d.whiskerData[1]); })
.style("stroke", stroke)
.style("stroke-width", strokeWidth);
// The box that shows the upper and lower quartiles.
var boxRect = g.selectAll("rect.box").data(boxPlotData);
boxRect.enter().append("rect").attr("class", "box");
boxRect.exit().remove();
boxRect
.attr("x", function (d){ return xScale(d.key); })
.attr("width", xScale.rangeBand())
.attr("y", function (d){ return yScale(d.quartileData[2]); })
.attr("height", function (d){ return yScale(d.quartileData[0]) - yScale(d.quartileData[2]); })
.style("stroke", stroke)
.style("stroke-width", strokeWidth)
.style("fill", fill);
// The horizontal line inside the box that shows the median.
var median = g.selectAll("line.median").data(boxPlotData);
median.enter().append("line").attr("class", "median");
median.exit().remove();
median
.attr("x1", function (d){ return xScale(d.key) })
.attr("x2", function (d){ return xScale(d.key) + xScale.rangeBand(); })
.attr("y1", function (d){ return yScale(d.quartileData[1]); })
.attr("y2", function (d){ return yScale(d.quartileData[1]); })
.style("stroke", stroke)
.style("stroke-width", strokeWidth);
});
return my;
}
sepal_length,sepal_width,petal_length,petal_width,class
5.1,3.5,1.4,0.2,setosa
4.9,3.0,1.4,0.2,setosa
4.7,3.2,1.3,0.2,setosa
4.6,3.1,1.5,0.2,setosa
5.0,3.6,1.4,0.2,setosa
5.4,3.9,1.7,0.4,setosa
4.6,3.4,1.4,0.3,setosa
5.0,3.4,1.5,0.2,setosa
4.4,2.9,1.4,0.2,setosa
4.9,3.1,1.5,0.1,setosa
5.4,3.7,1.5,0.2,setosa
4.8,3.4,1.6,0.2,setosa
4.8,3.0,1.4,0.1,setosa
4.3,3.0,1.1,0.1,setosa
5.8,4.0,1.2,0.2,setosa
5.7,4.4,1.5,0.4,setosa
5.4,3.9,1.3,0.4,setosa
5.1,3.5,1.4,0.3,setosa
5.7,3.8,1.7,0.3,setosa
5.1,3.8,1.5,0.3,setosa
5.4,3.4,1.7,0.2,setosa
5.1,3.7,1.5,0.4,setosa
4.6,3.6,1.0,0.2,setosa
5.1,3.3,1.7,0.5,setosa
4.8,3.4,1.9,0.2,setosa
5.0,3.0,1.6,0.2,setosa
5.0,3.4,1.6,0.4,setosa
5.2,3.5,1.5,0.2,setosa
5.2,3.4,1.4,0.2,setosa
4.7,3.2,1.6,0.2,setosa
4.8,3.1,1.6,0.2,setosa
5.4,3.4,1.5,0.4,setosa
5.2,4.1,1.5,0.1,setosa
5.5,4.2,1.4,0.2,setosa
4.9,3.1,1.5,0.1,setosa
5.0,3.2,1.2,0.2,setosa
5.5,3.5,1.3,0.2,setosa
4.9,3.1,1.5,0.1,setosa
4.4,3.0,1.3,0.2,setosa
5.1,3.4,1.5,0.2,setosa
5.0,3.5,1.3,0.3,setosa
4.5,2.3,1.3,0.3,setosa
4.4,3.2,1.3,0.2,setosa
5.0,3.5,1.6,0.6,setosa
5.1,3.8,1.9,0.4,setosa
4.8,3.0,1.4,0.3,setosa
5.1,3.8,1.6,0.2,setosa
4.6,3.2,1.4,0.2,setosa
5.3,3.7,1.5,0.2,setosa
5.0,3.3,1.4,0.2,setosa
7.0,3.2,4.7,1.4,versicolor
6.4,3.2,4.5,1.5,versicolor
6.9,3.1,4.9,1.5,versicolor
5.5,2.3,4.0,1.3,versicolor
6.5,2.8,4.6,1.5,versicolor
5.7,2.8,4.5,1.3,versicolor
6.3,3.3,4.7,1.6,versicolor
4.9,2.4,3.3,1.0,versicolor
6.6,2.9,4.6,1.3,versicolor
5.2,2.7,3.9,1.4,versicolor
5.0,2.0,3.5,1.0,versicolor
5.9,3.0,4.2,1.5,versicolor
6.0,2.2,4.0,1.0,versicolor
6.1,2.9,4.7,1.4,versicolor
5.6,2.9,3.6,1.3,versicolor
6.7,3.1,4.4,1.4,versicolor
5.6,3.0,4.5,1.5,versicolor
5.8,2.7,4.1,1.0,versicolor
6.2,2.2,4.5,1.5,versicolor
5.6,2.5,3.9,1.1,versicolor
5.9,3.2,4.8,1.8,versicolor
6.1,2.8,4.0,1.3,versicolor
6.3,2.5,4.9,1.5,versicolor
6.1,2.8,4.7,1.2,versicolor
6.4,2.9,4.3,1.3,versicolor
6.6,3.0,4.4,1.4,versicolor
6.8,2.8,4.8,1.4,versicolor
6.7,3.0,5.0,1.7,versicolor
6.0,2.9,4.5,1.5,versicolor
5.7,2.6,3.5,1.0,versicolor
5.5,2.4,3.8,1.1,versicolor
5.5,2.4,3.7,1.0,versicolor
5.8,2.7,3.9,1.2,versicolor
6.0,2.7,5.1,1.6,versicolor
5.4,3.0,4.5,1.5,versicolor
6.0,3.4,4.5,1.6,versicolor
6.7,3.1,4.7,1.5,versicolor
6.3,2.3,4.4,1.3,versicolor
5.6,3.0,4.1,1.3,versicolor
5.5,2.5,4.0,1.3,versicolor
5.5,2.6,4.4,1.2,versicolor
6.1,3.0,4.6,1.4,versicolor
5.8,2.6,4.0,1.2,versicolor
5.0,2.3,3.3,1.0,versicolor
5.6,2.7,4.2,1.3,versicolor
5.7,3.0,4.2,1.2,versicolor
5.7,2.9,4.2,1.3,versicolor
6.2,2.9,4.3,1.3,versicolor
5.1,2.5,3.0,1.1,versicolor
5.7,2.8,4.1,1.3,versicolor
6.3,3.3,6.0,2.5,virginica
5.8,2.7,5.1,1.9,virginica
7.1,3.0,5.9,2.1,virginica
6.3,2.9,5.6,1.8,virginica
6.5,3.0,5.8,2.2,virginica
7.6,3.0,6.6,2.1,virginica
4.9,2.5,4.5,1.7,virginica
7.3,2.9,6.3,1.8,virginica
6.7,2.5,5.8,1.8,virginica
7.2,3.6,6.1,2.5,virginica
6.5,3.2,5.1,2.0,virginica
6.4,2.7,5.3,1.9,virginica
6.8,3.0,5.5,2.1,virginica
5.7,2.5,5.0,2.0,virginica
5.8,2.8,5.1,2.4,virginica
6.4,3.2,5.3,2.3,virginica
6.5,3.0,5.5,1.8,virginica
7.7,3.8,6.7,2.2,virginica
7.7,2.6,6.9,2.3,virginica
6.0,2.2,5.0,1.5,virginica
6.9,3.2,5.7,2.3,virginica
5.6,2.8,4.9,2.0,virginica
7.7,2.8,6.7,2.0,virginica
6.3,2.7,4.9,1.8,virginica
6.7,3.3,5.7,2.1,virginica
7.2,3.2,6.0,1.8,virginica
6.2,2.8,4.8,1.8,virginica
6.1,3.0,4.9,1.8,virginica
6.4,2.8,5.6,2.1,virginica
7.2,3.0,5.8,1.6,virginica
7.4,2.8,6.1,1.9,virginica
7.9,3.8,6.4,2.0,virginica
6.4,2.8,5.6,2.2,virginica
6.3,2.8,5.1,1.5,virginica
6.1,2.6,5.6,1.4,virginica
7.7,3.0,6.1,2.3,virginica
6.3,3.4,5.6,2.4,virginica
6.4,3.1,5.5,1.8,virginica
6.0,3.0,4.8,1.8,virginica
6.9,3.1,5.4,2.1,virginica
6.7,3.1,5.6,2.4,virginica
6.9,3.1,5.1,2.3,virginica
5.8,2.7,5.1,1.9,virginica
6.8,3.2,5.9,2.3,virginica
6.7,3.3,5.7,2.5,virginica
6.7,3.0,5.2,2.3,virginica
6.3,2.5,5.0,1.9,virginica
6.5,3.0,5.2,2.0,virginica
6.2,3.4,5.4,2.3,virginica
5.9,3.0,5.1,1.8,virginica
{
"columns": [
{ "name": "sepal_length", "type": "number" },
{ "name": "sepal_width", "type": "number" },
{ "name": "petal_length", "type": "number" },
{ "name": "petal_width", "type": "number" },
{ "name": "class", "type": "string" }
]
}