Skip to content

Instantly share code, notes, and snippets.

@kristw
Last active August 19, 2016 01:06
Show Gist options
  • Save kristw/7eef5cb21f3dfc1c0a4c to your computer and use it in GitHub Desktop.
Save kristw/7eef5cb21f3dfc1c0a4c to your computer and use it in GitHub Desktop.
d3Kit.Skeleton

This is an example of the d3Kit Skeleton, which

  • scaffold a chart skeleton for you based on d3's margin convention
  • catch resize events and make it convenient to redraw the chart after resizing.
  • and many more...

Try it by open in new window and resize.

<!DOCTYPE html>
<html>
<head>
<title>d3Kit.Skeleton</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" type="text/javascript"></script>
<script src="https://rawgit.com/kristw/75b61f9beeab9b530612/raw/389e984e4041117a9185cf6edad9f6b85a38097a/d3kit.min.js" type="text/javascript"></script>
<script src="main.js"></script>
</body>
</html>
var chart = new d3Kit.Skeleton('#chart', {
margin: {top: 60, right: 60, bottom: 60, left: 60},
initialWidth: 800,
initialHeight: 460
})
.autoResize('width')
.on('resize', visualize)
.on('data', visualize);
// Everything you need to setup your chart is above this line.
// The code below are just used to display the diagram above.
var svg = chart.getSvg();
var g = chart.getRootG();
var options = chart.options();
var layers = chart.getLayerOrganizer();
layers.create(['content', 'x-axis', 'y-axis', {label: ['innerWidth', 'innerHeight', 'width', 'height']}]);
var x = d3.scale.identity()
.domain([0, chart.getInnerWidth()]);
var y = d3.scale.identity()
.domain([0, chart.getInnerHeight()]);
var xAxis = d3.svg.axis()
.scale(x)
.orient('bottom');
var yAxis = d3.svg.axis()
.scale(y)
.orient('right');
var defs = svg.append('defs');
defs.append('marker')
.attr('id', 'triangle-end')
.attr('viewBox', '0 0 10 10')
.attr('refX', 10)
.attr('refY', 5)
.attr('markerWidth', 6)
.attr('markerHeight', 6)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 0 0 L 10 5 L 0 10 z');
var innerRect = layers.get('content').append('rect')
.attr('class', 'inner');
var lines = {
origin: svg.append('line')
.attr('class', 'arrow')
.attr('marker-end', 'url(#triangle-end)'),
top: svg.append('line')
.attr('class', 'arrow')
.attr('marker-end', 'url(#triangle-end)'),
bottom: svg.append('line')
.attr('class', 'arrow')
.attr('marker-end', 'url(#triangle-end)'),
left: svg.append('line')
.attr('class', 'arrow')
.attr('marker-end', 'url(#triangle-end)'),
right: svg.append('line')
.attr('class', 'arrow')
.attr('marker-end', 'url(#triangle-end)'),
};
svg.append('circle')
.attr('class', 'origin')
.attr('r', 4.5);
svg.append('text')
.text('origin')
.attr('x', 15)
.attr('y', 12);
g.append('text')
.text('translate(margin.left, margin.top)')
.attr('y', -8);
createCenterLabel(layers.get('label.innerWidth'), 'skeleton.getInnerWidth()');
createLeftLabel(layers.get('label.innerHeight'), 'skeleton.getInnerHeight()');
createLeftLabel(layers.get('label.width'), 'skeleton.width()');
createLeftLabel(layers.get('label.height'), 'skeleton.height()');
function visualize(){
x.domain([0, chart.getInnerWidth()]);
y.domain([0, chart.getInnerHeight()]);
innerRect
.attr('width', chart.getInnerWidth())
.attr('height', chart.getInnerHeight());
layers.get('x-axis')
.attr('transform', 'translate(0,' + chart.getInnerHeight() + ')')
.call(xAxis);
layers.get('y-axis')
.attr('transform', 'translate(' + chart.getInnerWidth() + ',0)')
.call(yAxis);
lines.origin
.attr('x2', options.margin.left)
.attr('y2', options.margin.top);
lines.top
.attr('x1', chart.width() / 2)
.attr('x2', chart.width() / 2)
.attr('y2', options.margin.top);
lines.bottom
.attr('x1', chart.width() / 2)
.attr('x2', chart.width() / 2)
.attr('y1', chart.height())
.attr('y2', chart.height() - options.margin.bottom);
lines.left
.attr('x2', options.margin.left)
.attr('y1', chart.height() / 2)
.attr('y2', chart.height() / 2);
lines.right
.attr('x1', chart.width())
.attr('x2', chart.width() - options.margin.right)
.attr('y1', chart.height() / 2)
.attr('y2', chart.height() / 2);
layers.get('label.innerWidth')
.attr('transform', 'translate('+(chart.getInnerWidth()/2)+','+(20+3)+')');
layers.get('label.innerHeight')
.attr('transform', 'translate('+(10)+','+(chart.getInnerHeight()/2+3)+')');
layers.get('label.width')
.attr('transform', 'translate('+(chart.getInnerWidth()/2 + 10)+','+(20 - options.margin.top)+')');
layers.get('label.height')
.attr('transform', 'translate('+(10 - options.margin.left)+','+(chart.getInnerHeight()/2 - 23)+')');
}
function createCenterLabel(container, text){
var label = container
.append('text')
.classed('skeleton-label', true)
.text(text)
.style('text-anchor', 'middle');
var bbox = label.node().getBBox();
container
.insert('rect', ':first-child')
.attr('x', -bbox.width/2 - 4)
.attr('y', -bbox.height/2 - 8)
.attr('width', bbox.width + 8)
.attr('height', bbox.height + 8)
.style('fill', '#D1625B');
}
function createLeftLabel(container, text){
var label = container
.append('text')
.classed('skeleton-label', true)
.text(text);
var bbox = label.node().getBBox();
container
.insert('rect', ':first-child')
.attr('x', - 4)
.attr('y', -bbox.height/2 - 8)
.attr('width', bbox.width + 8)
.attr('height', bbox.height + 8)
.style('fill', '#D1625B');
}
body {
font: 10px sans-serif;
}
#chart{
margin: 20px;
background: #eee;
border: 1px solid #222;
}
.x-axis-layer line, .y-axis-layer line,
.x-axis-layer path, .y-axis-layer path {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.arrow {
stroke: #000;
stroke-width: 1.5px;
}
.outer,
.inner {
shape-rendering: crispEdges;
}
.outer {
fill: none;
stroke: #000;
}
.inner {
fill: #ccc;
stroke: #000;
stroke-dasharray: 3, 4;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment