Skip to content

Instantly share code, notes, and snippets.

@tomgp
Last active December 24, 2015 13:49
Show Gist options
  • Save tomgp/6807822 to your computer and use it in GitHub Desktop.
Save tomgp/6807822 to your computer and use it in GitHub Desktop.
Control patch line

trying a line to emphasise that the user can edit the values in a kind of pseudo-continuos way

<html>
<head>
<title>Control patch</title>
</head>
<style type="text/css">
body{
font-family: sans-serif;
}
.ui-patch{
fill-opacity:0;
stroke-width:1px;
stroke:none;
cursor: url(editcursor.png);
}
.bar{
stroke:#fff;
stroke-width:2px;
}
#line{
fill:none;
stroke:#666;
}
#pale-line{
fill:none;
stroke:#ccc;
}
text{
stroke:#333;
font-family: sans-serif;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.container{
position: relative;
width:500px;
}
.prompt{
background-image: url(editicon.png);
width: 64px;
height: 44px;
position: absolute;
right:0;
z-index: -100;
}
</style>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="patch.js"></script>
<body>
<div class="container">
<div class="prompt"></div>
<svg id='ui' width='600' height='600'></svg>
</div>
</body>
<script type="text/javascript">
var xScale = d3.scale.linear()
.domain([0, 19])
.range([0, 500])
.clamp(true);
var yScale = d3.scale.linear()
.domain([-100, 100])
.range([0, 500])
.clamp(true);
var barData = [80,75,70,60,40,10,-10,-40,-60,-70,-75,-80,-82,-80,-75,-60,-40,-10,10,40];
d3.select('#ui').append('g').attr('id','bar-chart');
makePatch(xScale, yScale, '#ui', function(index, percent){
barData[Math.floor(index)] = percent;
transition();
});
var line, paleLine, chart, labels;
drawData();
function transition(){
chartline1.transition()
.duration(50)
.attr("d", line);
chartline2.transition()
.duration(50)
.attr("d", paleLine);
labels = d3.select('#bar-chart').selectAll('text')
.data(barData);
labels.transition()
.duration(50)
.text(function(d){
return(Math.round(-d));
})
.attr('y', function(d,i){
var adj = (d<0) ? 0:10;
return yScale(d) + adj;
});
}
function drawData(){
line = d3.svg.line()
.x(function(d,i) { return xScale(i + 0.5); })
.y(function(d) { return yScale(d); });
paleLine = d3.svg.line()
.x(function(d,i) { return xScale(i + 0.5); })
.y(function(d) { return yScale(d); })
.interpolate('basis');
chartline2 = d3.select('#bar-chart').append('path').attr("id", "pale-line")
.datum(barData);
chartline1 = d3.select('#bar-chart').append('path').attr("id", "line")
.datum(barData);
labels = d3.select('#bar-chart').selectAll('text')
.data(barData);
labels.enter()
.append('text')
.text(function(d){
return(-d)
})
.attr('x', function(d,i){
return xScale(i) + xScale(0.5);
})
.attr('y', function(d,i){
var adj = (d<0) ? 0:10;
return yScale(d) + adj;
})
.attr('text-anchor','middle');
transition();
}
</script>
</html>
function makePatch(xScale, yScale, parent, callback){
var parent = d3.select(parent);
var xRange = xScale.range(),
yRange = yScale.range();
var container = parent.append('g');
if(!callback){
var callback = function(x,y){
console.log(x,y);
}
}
var drag = d3.behavior.drag()
.origin(patch)
.on("drag", function(d){
callback(xScale.invert(d3.event.x), yScale.invert(d3.event.y));
})
var patch = container.append('rect')
.attr('x', Math.min(xRange[0], xRange[1]) )
.attr('y', Math.min(yRange[0], yRange[1]) )
.attr('width', Math.abs(xRange[1] - xRange[0]))
.attr('height', Math.abs(yRange[1] - yRange[0]))
.attr('class', 'ui-patch')
.on('click', function(d){
callback(xScale.invert(d3.event.x), yScale.invert(d3.event.y))
})
.call(drag);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment