Skip to content

Instantly share code, notes, and snippets.

@aitee
Last active August 27, 2019 19:33
Show Gist options
  • Save aitee/1db30487d5cee6e752420fc5dc44c120 to your computer and use it in GitHub Desktop.
Save aitee/1db30487d5cee6e752420fc5dc44c120 to your computer and use it in GitHub Desktop.
fresh block
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<style>
body{
background-color:#1B222D;
}
svg { background: #010B17; }
.xaxis path {
stroke:white;
}
.xaxis line {
stroke:grey;
}
.xaxis text {
fill:white;
}
</style>
<body>
<script>
var margin = {
top: 20,
right: 80,
bottom: 30,
left: 50
};
var width = 900 - margin.left - margin.right
var height = 400 - margin.top - margin.bottom;
var xscale = d3.scaleLinear()
.domain([0, 100])
.range([0, width]);
var xaxis = d3.axisBottom(xscale).tickSize(-height);
var onCursorUpdate = function(x)
{
console.log("onCursorUpdate: " + x + " -> " + xscale(x));
};
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "xaxis")
.attr("transform", "translate(0," + (height) + ")")
.call(xaxis);
// Will need to ensure panning uses event.preventDefault(); to allow d3 to not intepret drag as a click.
var ignoreDrag = d3.drag();
svg.append('svg:rect')
.attr('width', width)
.attr('height', height)
.attr('fill', 'none')
.attr('pointer-events', 'all')
.call(ignoreDrag)
.on('click', function()
{
//ignore drags
if (d3.event.defaultPrevented){
return;
}
// d3.event.x isn't quite right here (its relative to svg element instead of the plot area (svg variable is actually the plot area)
var coord = d3.mouse(svg.node());
console.log(coord[0]);
UpdateCursorPosition(coord[0], true);
});
function GrabberPathDataAt(x){
var grabberSize = 6;
return "M " + (x-grabberSize) + ",-1" + " " + (x+grabberSize) + ",-1 " + x + ", " + (grabberSize*Math.sqrt(2)) + " Z";
}
function CursorLine(x)
{
return "M" + x + ","+height+ " " + x + ", 0 Z"
}
function SetCursorPosition(x)
{
UpdateCursorPosition(xscale(x));
}
function UpdateTextValues()
{
var data = valover.selectAll(".text-values")
.data([60, 60, 61,61, 62, 63]);
data
.text(function(d){ return (d+Math.random()*2).toFixed(2);});
}
var wasLessThanHalf = false;
var isLessThanHalf = true;
var updateCounter = -1;
function UpdateCursorPosition(pixelx, animate)
{
if (updateCounter % 10 === 0){
UpdateTextValues();
}
updateCounter+=1;
var t = 'translate(' + (0*width/4) + ')';
isLessThanHalf = xscale.invert(pixelx) < 50;
if (isLessThanHalf && wasLessThanHalf === false){
t = 'translate(' + (3*width/4) + ')';
}
if (wasLessThanHalf !== isLessThanHalf){
svg.select(".value-overlay")
.transition()
.duration(500)
.ease(d3.easeQuadOut)
.attr('transform',t);
}
wasLessThanHalf = isLessThanHalf;
var speed = 0;
var ease = d3.easeCubicOut;
var cl = svg.select(".cursor-line")
if (animate){
cl = cl.transition()
.duration(speed)
.ease(ease);
}
cl.attr("d", CursorLine(pixelx));
svg.select(".cursor-line-hotspot").attr("d", CursorLine(pixelx));
var grabber = svg.select(".grabber");
if (animate){
grabber = grabber
.transition()
.duration(speed)
.ease(ease);
}
grabber.attr("d", GrabberPathDataAt(pixelx));
}
var startPosition = 10;
var drag = d3.drag()
.on("start", function(d)
{
})
.on("drag", function(d){
UpdateCursorPosition(d3.event.x)
onCursorUpdate(xscale.invert(d3.event.x));
})
.on("end", function(d)
{
onCursorUpdate(xscale.invert(d3.event.x));
});
svg.append("path")
.attr("cursor", "ew-resize")
.attr("class", "cursor-line")
.attr("stroke", "white")
.style("stroke-width", "1px");
svg.append("path")
.attr("cursor", "ew-resize")
.attr("class", "cursor-line-hotspot")
.attr('d', CursorLine(xscale(startPosition)))
.attr("stroke", "transparent")
.style("stroke-width", "20px")
.call(drag);
svg.append("path")
.attr("class", "grabber")
.attr('d', GrabberPathDataAt(xscale(startPosition)))
.attr("cursor", "ew-resize")
.attr("stroke-width", "1px")
.attr("fill", "white")
.call(drag);
var initialValueOverlayTransform = 'translate(' + (3*width/4) + ')';
var valover = svg.append("g").attr('class', 'value-overlay')
.attr('transform', initialValueOverlayTransform);
valover.append("rect")
.attr('class', 'value-overlay-bk')
.attr('opacity', 0.7)
.attr('width', width/4+20)
.attr('height', height)
.attr('stroke', 'white');
var data = valover.selectAll(".text-values")
.data([60, 60, 61,61, 62, 63]);
data
.attr("fill", "white")
.text(function(d){ return Math.round(d+Math.random()*2).toFixed(2);})
.enter().append("text")
.attr("class", "text-values")
.attr("fill", "white")
.text(function(d){ return (d+Math.random()*2).toFixed(2);})
.attr("transform", function(d, i){return "translate(10, "+(i*30+20)+")";})
;
svg.select(".cursor-line")
.attr('d', CursorLine(xscale(startPosition)))
.call(drag);
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment