|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<title>Interactive Bar Chart</title> |
|
|
|
<!-- Load the Chiasm stack. --> |
|
<script src="http://curran.github.io/model/cdn/model-v0.2.4.js"></script> |
|
<script src="http://chiasm-project.github.io/chiasm-component/chiasm-component-v0.2.3.js"></script> |
|
<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> |
|
<script src="http://chiasm-project.github.io/chiasm/chiasm-v0.3.0.js"></script> |
|
<script src="http://chiasm-project.github.io/chiasm-layout/chiasm-layout-v0.2.2.js"></script> |
|
<script src="http://chiasm-project.github.io/chiasm-dataset-loader/chiasm-dataset-loader-v0.3.1.js"></script> |
|
<script src="http://chiasm-project.github.io/chiasm-links/chiasm-links-v0.2.1.js"></script> |
|
<script src="http://chiasm-project.github.io/chiasm-data-reduction/chiasm-data-reduction-v0.3.0.js"></script> |
|
<script src="http://chiasm-project.github.io/chiasm-charts/chiasm-charts-v0.1.3.js"></script> |
|
|
|
<!-- Make the container fill the page and have a 20px black border. --> |
|
<style> |
|
|
|
body { |
|
background-color: black; |
|
} |
|
|
|
#chiasm-container { |
|
background-color: white; |
|
position: fixed; |
|
left: 20px; |
|
right: 20px; |
|
top: 20px; |
|
bottom: 20px; |
|
} |
|
|
|
.axis { |
|
font: 0.8em sans-serif; |
|
} |
|
|
|
.axis path, |
|
.axis line { |
|
fill: none; |
|
stroke: #000; |
|
shape-rendering: crispEdges; |
|
} |
|
|
|
/* Custom CSS for axis labels. */ |
|
.axis-label { |
|
text-anchor: middle; |
|
font-size: 1.3em; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
|
|
<!-- Chiasm component DOM elements will be injected into this div. --> |
|
<div id="chiasm-container"></div> |
|
|
|
<!-- Define a custom Chaism component for selecting columns. --> |
|
<script> |
|
function ColumnSelector() { |
|
|
|
var my = ChiasmComponent(); |
|
|
|
var div = my.initDIV(); |
|
var select = d3.select(div).append("select"); |
|
|
|
my.when(["dataset", "selected"], function (dataset, selected){ |
|
|
|
var columns = dataset.metadata.columns; |
|
|
|
var options = select.selectAll(".column-option").data(columns); |
|
options.enter().append("option").attr("class", "column-option"); |
|
options.exit().remove(); |
|
options |
|
.attr("value", function (d){ return d.name; }) |
|
.text(function (d){ return d.label; }); |
|
|
|
select.node().value = selected; |
|
|
|
my.selectedColumn = dataset.metadata.columns.filter(function (d){ |
|
return d.name === selected; |
|
})[0]; |
|
|
|
// TODO get rid of this hack. |
|
// https://github.com/chiasm-project/chiasm-charts/issues/13 |
|
my.selectedLabel = my.selectedColumn.label; |
|
}); |
|
|
|
select.on("change", function (){ |
|
my.selected = this.value; |
|
}); |
|
|
|
return my; |
|
} |
|
|
|
</script> |
|
|
|
<!-- Define a custom Chaism component for a slider. --> |
|
<script> |
|
// Draws from http://bl.ocks.org/curran/6eccfa89906e65707ffe |
|
function Slider() { |
|
var my = ChiasmComponent({ |
|
min: 1, |
|
max: 200, |
|
value: 50, |
|
|
|
// The number of pixels away from the edge of the outer box |
|
// where the slider line ends. |
|
padding: 20, |
|
|
|
// The radius of the slider handle in pixels. |
|
radius: 5, |
|
|
|
// The stroke width (in pixels) of the slider line. |
|
strokeWidth: 2, |
|
|
|
fill: "black" |
|
}); |
|
|
|
var svg = d3.select(my.initSVG()); |
|
|
|
var drag = d3.behavior.drag() |
|
.origin(function(d) { return d; }); |
|
|
|
var line = svg.append("line") |
|
.style("stroke", "black") |
|
.style("stroke-linecap", "round"); |
|
|
|
var circle = svg.append("circle") |
|
.style("cursor", "ew-resize") |
|
.call(drag); |
|
|
|
my.when(["box", "padding"], function (box, padding){ |
|
my.x1 = padding; |
|
my.x2 = box.width - padding; |
|
my.y = box.height / 2; |
|
}); |
|
|
|
my.when(["x1", "x2", "y"], function (x1, x2, y){ |
|
line |
|
.attr("x1", x1) |
|
.attr("x2", x2) |
|
.attr("y1", y) |
|
.attr("y2", y); |
|
}); |
|
|
|
my.when("radius", function (radius){ |
|
circle.attr("r", radius); |
|
}); |
|
|
|
my.when("fill", function (fill){ |
|
circle.attr("fill", fill); |
|
}); |
|
|
|
my.when("strokeWidth", function (strokeWidth){ |
|
line.style("stroke-width", strokeWidth); |
|
}); |
|
|
|
my.when(["min", "max", "x1", "x2"], function (min, max, x1, x2){ |
|
my.scale = d3.scale.linear() |
|
.domain([min, max]) |
|
.range([x1, x2]); |
|
}); |
|
|
|
my.when(["scale", "value", "y"], function (scale, value, y){ |
|
circle |
|
.datum({ x: scale(value), y: y }) |
|
.attr("cy", function(d) { return d.y; }) |
|
.attr("cx", function(d) { return d.x; }) |
|
}); |
|
|
|
my.when(["scale", "x1", "x2"], function (scale, x1, x2){ |
|
drag.on("drag", function (d) { |
|
|
|
// Get the updated X location computed by the drag behavior. |
|
var x = d3.event.x; |
|
|
|
// Constrain x to be between x1 and x2 (the ends of the line). |
|
x = x < x1 ? x1 : x > x2 ? x2 : x; |
|
|
|
// This assignment is necessary for multiple drag gestures. |
|
// It makes the drag.origin function yield the correct value. |
|
d.x = x; |
|
|
|
my.value = scale.invert(x); |
|
}); |
|
}); |
|
|
|
return my; |
|
} |
|
</script> |
|
|
|
<!-- Define a custom Chaism component for constructing the aggregation parameters. --> |
|
<script> |
|
function AggregationParameters() { |
|
|
|
var my = ChiasmComponent(); |
|
|
|
my.when(["selectedColumn", "numBins"], function (selectedColumn, numBins){ |
|
my.aggregate = { |
|
dimensions: [{ |
|
"column": selectedColumn.name, |
|
"histogram": selectedColumn.type === "number", |
|
"numBins": numBins |
|
}], |
|
measures: [{ |
|
"outColumn": "count", |
|
"operator": "count" |
|
}] |
|
}; |
|
}); |
|
|
|
return my; |
|
} |
|
|
|
</script> |
|
<!-- This is the main program that sets up the Chiasm application. --> |
|
<script> |
|
|
|
// Create a new Chiasm instance. |
|
var chiasm = new Chiasm(); |
|
|
|
// Register plugins that the configuration can access. |
|
chiasm.plugins.layout = ChiasmLayout; |
|
chiasm.plugins.links = ChiasmLinks; |
|
chiasm.plugins.datasetLoader = ChiasmDatasetLoader; |
|
chiasm.plugins.dataReduction = ChiasmDataReduction; |
|
chiasm.plugins.barChart = ChiasmCharts.components.barChart; |
|
chiasm.plugins.columnSelector = ColumnSelector; |
|
chiasm.plugins.slider = Slider; |
|
chiasm.plugins.aggregationParameters = AggregationParameters; |
|
|
|
// Set the Chaism configuration. |
|
chiasm.setConfig({ |
|
"layout": { |
|
"plugin": "layout", |
|
"state": { |
|
"containerSelector": "#chiasm-container", |
|
"layout": { |
|
"orientation": "vertical", |
|
"children": [ |
|
{ |
|
"orientation": "horizontal", |
|
"size": "15px", |
|
"children": [ |
|
"xColumnSelector", |
|
"numBinsSlider" |
|
] |
|
}, |
|
"vis" |
|
] |
|
}, |
|
"sizes": { |
|
"numBinsSlider": { |
|
"size": 2 |
|
} |
|
} |
|
} |
|
}, |
|
"loader": { |
|
"plugin": "datasetLoader", |
|
"state": { |
|
"path": "auto-mpg" |
|
} |
|
}, |
|
"vis": { |
|
"plugin": "barChart", |
|
"state": { |
|
"xColumn": "mpg", |
|
"yColumn": "count", |
|
"xAxisLabelTextOffset": 8, |
|
"yAxisLabelTextOffset": 25, |
|
"yAxisLabelText": "Count", |
|
"margin": { top: 15, right: 15, bottom: 50, left: 80 }, |
|
} |
|
}, |
|
"reduction": { |
|
"plugin": "dataReduction" |
|
}, |
|
"xColumnSelector": { "plugin": "columnSelector" }, |
|
"numBinsSlider": { "plugin": "slider" }, |
|
"aggregationParams": { "plugin": "aggregationParameters" }, |
|
"myLinks": { |
|
"plugin": "links", |
|
"state": { |
|
"bindings": [ |
|
"loader.dataset -> reduction.datasetIn", |
|
"reduction.datasetOut -> vis.dataset", |
|
"loader.dataset -> xColumnSelector.dataset", |
|
"loader.dataset -> yColumnSelector.dataset", |
|
|
|
"vis.xColumn <-> xColumnSelector.selected", |
|
"xColumnSelector.selectedColumn -> aggregationParams.selectedColumn", |
|
"numBinsSlider.value -> aggregationParams.numBins", |
|
|
|
"aggregationParams.aggregate -> reduction.aggregate", |
|
// TODO get rid of this hack. |
|
// https://github.com/chiasm-project/chiasm-charts/issues/13 |
|
"xColumnSelector.selectedLabel -> vis.xAxisLabelText" |
|
] |
|
} |
|
} |
|
}); |
|
|
|
// chiasm.getComponent("myScatterPlot").then(function (scatterPlotDataLoader){ |
|
// console.log(scatterPlotDataLoader) |
|
// scatterPlotDataLoader.when("dataset", function(dataset){ |
|
// console.log(dataset) |
|
// }); |
|
// }); |
|
|
|
</script> |
|
</body> |
|
</html> |