Skip to content

Instantly share code, notes, and snippets.

@chrisbrich
Forked from anonymous/data.json
Last active December 14, 2015 06:48
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 chrisbrich/5044999 to your computer and use it in GitHub Desktop.
Save chrisbrich/5044999 to your computer and use it in GitHub Desktop.

This is an example of a reusable component for displaying error bars. It's messy. Please don't judge.

[{"x":26,"y":93.4,"s":0.3999999761581421},{"x":84,"y":64.4,"s":0.7483314871788025},{"x":53,"y":80.6,"s":0.5099019408226013},{"x":12,"y":91.4,"s":0.5099019408226013},{"x":79,"y":4.0,"s":0.4472135901451111},{"x":83,"y":87.4,"s":0.7483314871788025},{"x":91,"y":23.0,"s":0.8944271802902222},{"x":98,"y":45.6,"s":0.8124037981033325},{"x":48,"y":27.8,"s":0.5830951929092407},{"x":60,"y":51.8,"s":0.4898979663848877},{"x":25,"y":92.8,"s":0.4898979663848877},{"x":74,"y":73.6,"s":0.8124037981033325},{"x":76,"y":57.8,"s":0.37416574358940125},{"x":33,"y":40.0,"s":0.8366600275039673},{"x":4,"y":51.6,"s":0.3999999761581421},{"x":80,"y":49.0,"s":0.8366600275039673},{"x":88,"y":4.8,"s":0.6633249521255493},{"x":32,"y":17.4,"s":0.6000000238418579},{"x":89,"y":72.4,"s":0.8124037981033325},{"x":85,"y":13.0,"s":0.4472135901451111},{"x":5,"y":12.6,"s":0.6000000238418579},{"x":86,"y":77.6,"s":0.3999999761581421},{"x":39,"y":47.6,"s":0.6782329678535461},{"x":31,"y":83.0,"s":0.547722578048706},{"x":63,"y":81.8,"s":0.7348468899726868},{"x":55,"y":82.4,"s":0.6782329678535461},{"x":14,"y":59.6,"s":0.6000000238418579},{"x":24,"y":50.8,"s":0.7348468899726868},{"x":17,"y":28.6,"s":0.5099019408226013},{"x":66,"y":40.0,"s":0.4472135901451111},{"x":67,"y":49.0,"s":0.8366600275039673},{"x":54,"y":4.0,"s":0.774596631526947},{"x":44,"y":76.2,"s":0.4898979663848877},{"x":64,"y":86.4,"s":0.6000000238418579},{"x":57,"y":55.0,"s":0.8944271802902222},{"x":36,"y":10.2,"s":0.5830951929092407},{"x":97,"y":51.8,"s":0.5830951929092407},{"x":66,"y":86.8,"s":0.4898979663848877},{"x":16,"y":32.4,"s":0.7483314871788025},{"x":75,"y":7.0,"s":0.8366600275039673},{"x":0,"y":21.6,"s":0.7483314871788025},{"x":20,"y":30.0,"s":0.547722578048706},{"x":64,"y":84.0,"s":0.547722578048706},{"x":91,"y":41.0,"s":0.4472135901451111},{"x":3,"y":65.4,"s":0.6000000238418579},{"x":30,"y":17.2,"s":0.5830951929092407},{"x":50,"y":80.0,"s":0.7071067690849304},{"x":1,"y":79.8,"s":0.7999999523162842},{"x":59,"y":45.4,"s":0.7483314871788025},{"x":42,"y":4.4,"s":0.24494898319244385},{"x":76,"y":100.4,"s":0.6782329678535461},{"x":40,"y":82.6,"s":0.8124037981033325},{"x":50,"y":69.4,"s":0.6782329678535461},{"x":59,"y":12.0,"s":0.7071067690849304},{"x":27,"y":85.0,"s":0.547722578048706},{"x":15,"y":68.2,"s":0.7348468899726868},{"x":23,"y":12.4,"s":0.3999999761581421},{"x":4,"y":81.2,"s":0.37416574358940125},{"x":50,"y":16.6,"s":0.3999999761581421},{"x":8,"y":72.2,"s":0.9165151119232178},{"x":94,"y":21.4,"s":0.6000000238418579},{"x":2,"y":76.2,"s":0.7348468899726868},{"x":26,"y":72.4,"s":0.5099019408226013},{"x":4,"y":34.6,"s":0.24494898319244385},{"x":56,"y":94.0,"s":0.547722578048706},{"x":3,"y":24.0,"s":0.547722578048706},{"x":16,"y":37.4,"s":0.8124037981033325},{"x":8,"y":64.4,"s":0.24494898319244385},{"x":60,"y":77.8,"s":0.6633249521255493},{"x":1,"y":13.6,"s":0.3999999761581421},{"x":35,"y":99.6,"s":0.3999999761581421},{"x":69,"y":91.4,"s":0.24494898319244385},{"x":20,"y":70.4,"s":0.6000000238418579},{"x":46,"y":66.2,"s":0.6633249521255493},{"x":73,"y":40.6,"s":0.6782329678535461},{"x":24,"y":45.4,"s":0.5099019408226013},{"x":21,"y":36.0,"s":0.4472135901451111},{"x":4,"y":93.4,"s":0.8124037981033325},{"x":94,"y":15.0,"s":0.8944271802902222},{"x":81,"y":47.8,"s":0.7999999523162842},{"x":6,"y":71.8,"s":0.37416574358940125},{"x":75,"y":5.8,"s":0.7348468899726868},{"x":37,"y":23.2,"s":0.9165151119232178},{"x":25,"y":80.8,"s":0.4898979663848877},{"x":93,"y":85.2,"s":0.4898979663848877},{"x":11,"y":86.6,"s":0.5099019408226013},{"x":14,"y":66.0,"s":0.7071067690849304},{"x":25,"y":41.4,"s":0.7483314871788025},{"x":26,"y":88.4,"s":0.9797959327697754},{"x":53,"y":87.2,"s":0.7999999523162842},{"x":64,"y":46.6,"s":0.8124037981033325},{"x":86,"y":5.0,"s":0.774596631526947},{"x":65,"y":38.4,"s":0.3999999761581421},{"x":22,"y":96.4,"s":0.5099019408226013},{"x":92,"y":9.8,"s":0.7348468899726868},{"x":34,"y":67.4,"s":0.24494898319244385},{"x":90,"y":70.0,"s":0.6324555277824402},{"x":82,"y":89.8,"s":0.5830951929092407},{"x":53,"y":73.4,"s":0.3999999761581421},{"x":49,"y":42.0,"s":0.547722578048706},{"x":87,"y":10.4,"s":0.6782329678535461},{"x":12,"y":21.2,"s":0.7348468899726868},{"x":47,"y":48.6,"s":0.6000000238418579},{"x":30,"y":40.6,"s":0.3999999761581421},{"x":50,"y":93.0,"s":0.8366600275039673},{"x":67,"y":24.6,"s":0.3999999761581421},{"x":99,"y":101.0,"s":0.547722578048706},{"x":9,"y":55.4,"s":0.6782329678535461},{"x":29,"y":27.8,"s":0.19999998807907104},{"x":26,"y":97.4,"s":0.6000000238418579},{"x":5,"y":27.8,"s":0.7999999523162842},{"x":91,"y":93.0,"s":0.774596631526947},{"x":27,"y":69.4,"s":0.6782329678535461},{"x":58,"y":54.4,"s":0.5099019408226013},{"x":65,"y":80.8,"s":0.5830951929092407},{"x":73,"y":32.2,"s":0.6633249521255493},{"x":29,"y":66.2,"s":0.7999999523162842},{"x":95,"y":95.8,"s":0.5830951929092407},{"x":71,"y":18.8,"s":0.7348468899726868},{"x":44,"y":69.6,"s":0.7483314871788025},{"x":6,"y":41.4,"s":0.6782329678535461},{"x":35,"y":13.0,"s":0.6324555277824402},{"x":17,"y":77.6,"s":0.5099019408226013},{"x":78,"y":40.6,"s":0.7483314871788025},{"x":84,"y":34.8,"s":0.7348468899726868},{"x":23,"y":95.0,"s":0.7071067690849304},{"x":25,"y":49.0,"s":0.6324555277824402},{"x":11,"y":23.0,"s":0.547722578048706},{"x":13,"y":51.2,"s":0.7348468899726868},{"x":7,"y":31.8,"s":0.7348468899726868},{"x":71,"y":77.2,"s":0.37416574358940125},{"x":29,"y":23.6,"s":0.3999999761581421},{"x":98,"y":97.0,"s":0.3162277638912201},{"x":69,"y":47.4,"s":0.6782329678535461},{"x":38,"y":28.4,"s":0.5099019408226013},{"x":71,"y":2.6,"s":0.7483314871788025},{"x":83,"y":44.0,"s":0.547722578048706},{"x":43,"y":66.4,"s":0.6000000238418579},{"x":96,"y":36.8,"s":0.5830951929092407},{"x":19,"y":101.6,"s":0.7483314871788025},{"x":49,"y":92.8,"s":0.7348468899726868},{"x":18,"y":87.4,"s":0.5099019408226013},{"x":58,"y":93.2,"s":0.5830951929092407},{"x":90,"y":64.2,"s":0.19999998807907104},{"x":39,"y":54.4,"s":0.24494898319244385},{"x":72,"y":47.4,"s":0.6782329678535461},{"x":0,"y":86.0,"s":0.774596631526947},{"x":95,"y":94.8,"s":0.5830951929092407},{"x":4,"y":90.0,"s":0.774596631526947},{"x":29,"y":39.8,"s":0.5830951929092407},{"x":19,"y":89.2,"s":0.7348468899726868},{"x":10,"y":8.8,"s":0.37416574358940125},{"x":52,"y":60.6,"s":0.3999999761581421},{"x":77,"y":23.6,"s":0.6000000238418579},{"x":5,"y":30.2,"s":0.5830951929092407},{"x":45,"y":59.4,"s":0.8124037981033325},{"x":6,"y":50.2,"s":0.7348468899726868},{"x":83,"y":80.0,"s":0.8366600275039673},{"x":50,"y":64.8,"s":0.4898979663848877},{"x":78,"y":78.2,"s":0.5830951929092407},{"x":46,"y":11.0,"s":0.6324555277824402},{"x":5,"y":55.6,"s":0.7483314871788025},{"x":45,"y":39.2,"s":0.5830951929092407},{"x":59,"y":78.6,"s":0.6782329678535461},{"x":51,"y":75.0,"s":0.6324555277824402},{"x":32,"y":92.6,"s":0.5099019408226013},{"x":29,"y":52.0,"s":0.8366600275039673},{"x":9,"y":82.4,"s":0.3999999761581421},{"x":42,"y":95.0,"s":0.774596631526947},{"x":67,"y":84.0,"s":0.6324555277824402},{"x":82,"y":85.2,"s":0.4898979663848877},{"x":20,"y":21.2,"s":0.5830951929092407},{"x":37,"y":87.6,"s":0.6782329678535461},{"x":82,"y":16.4,"s":0.3999999761581421},{"x":87,"y":99.0,"s":0.7071067690849304},{"x":14,"y":75.2,"s":0.19999998807907104},{"x":68,"y":60.6,"s":0.7483314871788025},{"x":36,"y":48.2,"s":0.5830951929092407},{"x":20,"y":46.8,"s":0.7348468899726868},{"x":67,"y":2.8,"s":0.4898979663848877},{"x":5,"y":7.4,"s":0.8124037981033325},{"x":45,"y":56.6,"s":0.7483314871788025},{"x":93,"y":58.6,"s":0.5099019408226013},{"x":91,"y":75.6,"s":0.6000000238418579},{"x":67,"y":91.2,"s":0.7999999523162842},{"x":91,"y":82.6,"s":0.3999999761581421},{"x":19,"y":63.8,"s":0.7348468899726868},{"x":20,"y":59.4,"s":0.5099019408226013},{"x":64,"y":60.6,"s":0.6000000238418579},{"x":13,"y":15.8,"s":0.37416574358940125},{"x":61,"y":10.8,"s":0.7999999523162842},{"x":24,"y":78.6,"s":0.7483314871788025},{"x":37,"y":80.8,"s":0.4898979663848877},{"x":87,"y":58.6,"s":0.7483314871788025},{"x":30,"y":74.8,"s":0.5830951929092407},{"x":28,"y":95.6,"s":0.5099019408226013},{"x":35,"y":98.6,"s":0.3999999761581421},{"x":0,"y":24.6,"s":0.87177973985672},{"x":92,"y":15.6,"s":0.3999999761581421},{"x":31,"y":33.4,"s":0.7483314871788025},{"x":33,"y":86.2,"s":0.7999999523162842},{"x":65,"y":11.4,"s":0.3999999761581421},{"x":83,"y":61.4,"s":0.7483314871788025},{"x":59,"y":51.6,"s":0.3999999761581421},{"x":44,"y":47.8,"s":0.7348468899726868},{"x":91,"y":22.2,"s":0.37416574358940125},{"x":94,"y":67.2,"s":0.9165151119232178},{"x":95,"y":67.2,"s":0.37416574358940125},{"x":17,"y":9.2,"s":0.9165151119232178},{"x":61,"y":31.4,"s":0.8124037981033325},{"x":43,"y":29.6,"s":0.6782329678535461},{"x":94,"y":58.4,"s":0.5099019408226013},{"x":74,"y":1.4,"s":0.5099019408226013},{"x":3,"y":98.8,"s":0.4898979663848877},{"x":68,"y":63.6,"s":0.7483314871788025},{"x":65,"y":22.6,"s":0.9797959327697754},{"x":64,"y":38.4,"s":0.5099019408226013},{"x":30,"y":47.2,"s":0.37416574358940125},{"x":89,"y":5.2,"s":0.7999999523162842},{"x":69,"y":34.8,"s":0.37416574358940125},{"x":76,"y":99.6,"s":0.8124037981033325},{"x":56,"y":90.6,"s":0.6782329678535461},{"x":67,"y":15.4,"s":0.5099019408226013},{"x":62,"y":8.0,"s":0.8944271802902222},{"x":76,"y":27.2,"s":0.37416574358940125},{"x":49,"y":97.4,"s":0.6000000238418579},{"x":70,"y":63.8,"s":0.4898979663848877},{"x":31,"y":84.4,"s":0.7483314871788025},{"x":48,"y":68.0,"s":0.7071067690849304},{"x":64,"y":86.2,"s":0.7348468899726868},{"x":44,"y":72.8,"s":0.5830951929092407},{"x":81,"y":47.8,"s":0.5830951929092407},{"x":68,"y":101.6,"s":0.6782329678535461},{"x":90,"y":45.2,"s":0.5830951929092407},{"x":81,"y":58.8,"s":0.7999999523162842},{"x":71,"y":28.6,"s":0.7483314871788025},{"x":32,"y":63.0,"s":0.0},{"x":62,"y":86.2,"s":0.7348468899726868},{"x":77,"y":71.6,"s":0.5099019408226013},{"x":38,"y":41.2,"s":0.5830951929092407},{"x":47,"y":28.8,"s":0.7999999523162842},{"x":27,"y":99.4,"s":0.6782329678535461},{"x":53,"y":100.6,"s":0.6782329678535461},{"x":20,"y":64.0,"s":0.8944271802902222},{"x":80,"y":81.2,"s":0.5830951929092407},{"x":55,"y":4.0,"s":0.7071067690849304},{"x":12,"y":98.8,"s":0.7999999523162842},{"x":85,"y":5.2,"s":0.7348468899726868},{"x":0,"y":65.0,"s":0.7071067690849304},{"x":9,"y":65.0,"s":0.7071067690849304},{"x":62,"y":53.2,"s":0.7999999523162842},{"x":39,"y":53.6,"s":0.5099019408226013},{"x":17,"y":23.6,"s":0.7483314871788025},{"x":28,"y":77.0,"s":0.7071067690849304},{"x":28,"y":76.6,"s":0.5099019408226013},{"x":71,"y":96.6,"s":0.5099019408226013},{"x":28,"y":14.4,"s":0.9797959327697754},{"x":88,"y":45.8,"s":0.4898979663848877},{"x":84,"y":45.4,"s":0.7483314871788025},{"x":43,"y":89.0,"s":0.774596631526947},{"x":96,"y":66.2,"s":0.6633249521255493},{"x":71,"y":19.4,"s":0.6782329678535461},{"x":71,"y":84.0,"s":0.3162277638912201},{"x":88,"y":54.4,"s":0.87177973985672},{"x":10,"y":37.2,"s":0.7999999523162842},{"x":61,"y":13.8,"s":0.37416574358940125},{"x":17,"y":89.0,"s":0.7071067690849304},{"x":29,"y":3.6,"s":0.8124037981033325},{"x":78,"y":5.4,"s":0.6782329678535461},{"x":44,"y":94.6,"s":0.6000000238418579},{"x":46,"y":73.0,"s":0.8944271802902222},{"x":88,"y":35.0,"s":0.547722578048706},{"x":0,"y":83.2,"s":0.7999999523162842},{"x":89,"y":64.8,"s":0.37416574358940125},{"x":64,"y":96.8,"s":0.5830951929092407},{"x":71,"y":31.2,"s":0.5830951929092407},{"x":9,"y":36.8,"s":0.4898979663848877},{"x":23,"y":4.2,"s":0.5830951929092407},{"x":71,"y":99.6,"s":0.6782329678535461},{"x":86,"y":17.4,"s":0.6782329678535461},{"x":0,"y":92.2,"s":0.6633249521255493},{"x":88,"y":24.4,"s":0.8124037981033325},{"x":67,"y":37.6,"s":0.24494898319244385},{"x":41,"y":94.2,"s":0.7348468899726868},{"x":40,"y":86.8,"s":0.7348468899726868},{"x":41,"y":92.6,"s":0.6782329678535461},{"x":18,"y":59.0,"s":0.8366600275039673},{"x":0,"y":93.4,"s":0.9797959327697754},{"x":43,"y":69.6,"s":0.5099019408226013},{"x":92,"y":39.2,"s":0.7348468899726868},{"x":31,"y":35.2,"s":0.37416574358940125},{"x":19,"y":50.2,"s":0.5830951929092407},{"x":3,"y":93.8,"s":0.7999999523162842},{"x":20,"y":45.8,"s":0.7999999523162842},{"x":82,"y":54.6,"s":0.3999999761581421},{"x":63,"y":58.2,"s":0.7348468899726868},{"x":63,"y":52.2,"s":0.7348468899726868},{"x":50,"y":11.2,"s":0.7999999523162842},{"x":19,"y":93.2,"s":0.7348468899726868},{"x":66,"y":7.6,"s":0.8124037981033325}]
function errorBar(){
//TODO
//- Think of an additional way to represent error bars, maybe just the orthognal case (i.e. use width not height)
//- Does ordinal scale even make sense here? May need to remove.
var size = 5,
xError = function(d) {return exists(d[0].s);},
yError = function(d) {return exists(d[1].s);},
errormarker = null, //points will inherit from g.dataset
xValue = function(d) {return (d[0].x === undefined)?d[0]:d[0].x;},
yValue = function(d) {return (d[1].x === undefined)?d[1]:d[1].x;},
oldXScale, //probably can give these smarter defaults
oldYScale,
xScale,
yScale;
function marks(datapoints){
datapoints.each(function(d,i) {
var g = d3.select(this),
//Use color/errormarker defined.
errormarker = errormarker || exists(g.datum().errormarker);
//Error
var err = g.selectAll(".err")
.data(function(d){return (!(xError(d) === null) || !(yError(d) === null))?[d]:[]},xValue),
errEnter,
errExit,
errUpdate;
switch (errormarker) {
case null: {
errEnter = err.enter().append("path").attr("class","err")
errExit = d3.transition(err.exit()).remove(),
errUpdate = d3.transition(err),
errTransform = function(selection,a,b){
selection.attr("d", function(d){
var h = (yError(d) === null)?[-size,size]:[(b(yValue(d) - yError(d)) - b(yValue(d))),(b(yValue(d) + yError(d)) - b(yValue(d)))],
w = (xError(d) === null)?[-size,size]:[(a(xValue(d) - xError(d)) - a(xValue(d))),(a(xValue(d) + xError(d)) - a(xValue(d)))];
return "M 0," + h[0] +
" L 0," + h[1] +
" M " + w[0] + "," + h[1] +
" L " + w[1] + "," + h[1] +
" M " + w[0] + "," + h[0] +
" L " + w[1] + "," + h[0]
})};;
break;
}
case errormarker: { //Normalize custom errors to 1px in their definition. Will be scaled back up here by size.
err.append("use").attr("class",marker + " err");
err.selectAll("use").attr("xlink:href","#" + marker)
.attr("transform",function(d){return "scale(" + xError(d) + "," + yError(d) + ")"});
break;
}
};
// For quantitative scales:
// - enter new ticks from the old scale
// - exit old ticks to the new scale
if (xScale.ticks) {
errEnter.call(errTransform, oldXScale, oldYScale);
errUpdate.call(errTransform, xScale, yScale);
errExit.call(errTransform, xScale, yScale);
}
// For ordinal scales:
// - any entering ticks are undefined in the old scale
// - any exiting ticks are undefined in the new scale
// Therefore, we only need to transition updating ticks.
else {
var dx = xScale.rangeBand() / 2, x = function(d) { return xScale(d) + dx; };
var dy = yScale.rangeBand() / 2, y = function(d) { return yScale(d) + dy; };
errEnter.call(errTransform, x, y);
errUpdate.call(errTransform, x, y);
}
});
}
marks.size = function(_) {
if (!arguments.length) return size;
size = _;
return marks;
};
marks.xError = function(_) {
if (!arguments.length) return xError;
xError = _;
return marks;
};
marks.yError = function(_) {
if (!arguments.length) return yError;
yError = _;
return marks;
};
marks.oldXScale = function(_) {
if (!arguments.length) return oldXScale;
oldXScale = _;
return marks;
};
marks.oldYScale = function(_) {
if (!arguments.length) return oldYScale;
oldYScale = _;
return marks;
};
marks.xScale = function(_) {
if (!arguments.length) return xScale;
xScale = _;
return marks;
};
marks.yScale = function(_) {
if (!arguments.length) return yScale;
yScale = _;
return marks;
};
marks.xValue = function(_) {
if (!arguments.length) return xValue;
xValue = _;
return marks;
};
marks.yValue = function(_) {
if (!arguments.length) return yValue;
yValue = _;
return marks;
};
marks.errormarker = function(_) {
if (!arguments.length) return errormarker;
errormarker = _;
return marks;
};
return marks;
};
function exists(a){
return (a === undefined)?null:a;
};
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<style>
svg {
font: 10px sans-serif;
}
.axis path, .axis line {
shape-rendering: crispEdges;
fill: none;
stroke: lightgrey;
}
path.err {
stroke-width: 1.5px;
stroke: blue;
}
</style>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="errorbar.js"></script>
<script>
var m = [10, 10, 10, 30],
w = 960 - m[1] - m[3],
h = 450 - m[0] - m[2],
x = d3.scale.linear().range([0,w]),
y = d3.scale.linear().range([h,0]),
xaxis = d3.svg.axis().scale(x).orient("bottom").tickSize(-h),
yaxis = d3.svg.axis().scale(y).orient("left").tickSize(-w),
eb = errorBar()
.oldXScale(x)
.xScale(x)
.oldYScale(y)
.yScale(y)
.yValue(function(d){return d.y})
.xValue(function(d){return d.x})
.xError(function(d){return null})
.yError(function(d){return d.s});
var svg = d3.select("body").append("svg")
.attr("width", w + m[1] + m[3])
.attr("height", h + m[0] + m[2])
.append("g")
.attr("class","container")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
d3.json("data.json", function(error,data) {
if (error) return console.warn(error);
x.domain(d3.extent(data.map(function(d){return d.x})));
y.domain(d3.extent(data.map(function(d){return d.y})));
var d = svg.selectAll("g").data(data),
dEnter = d.enter().append("g")
.attr("transform",function(d){return "translate(" + x(d.x) + "," + y(d.y) + ")"})
.attr("fill","blue");
dEnter.append("circle")
.attr("r",2);
dEnter.call(eb);
svg.append("g")
.attr("class","axis x")
.attr("transform", "translate(0," + y.range()[0] + ")")
.call(xaxis);
svg.append("g")
.attr("class","axis y")
.attr("transform", "translate(" + x.range()[0] + ",0)")
.call(yaxis);
});
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment