D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
ezzaouia
Full window
Github gist
double head slider
Built with
blockbuilder.org
<!DOCTYPE html> <head> <meta charset="utf-8"> <script src="https://d3js.org/d3.v4.min.js"></script> <style> body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } .track { stroke: #777; stroke-opacity: .2; stroke-width: 5; } .track-overlay { pointer-events: stroke; stroke-width: 20px; } .slider-circle-time-from, .slider-circle-time-to { cursor: pointer; } </style> </head> <body> <script> var sqrt3 = Math.sqrt(3); var svg = d3.select("body").append("svg") .attr("width", 960) .attr("height", 500) .append('g') .attr('transform', 'translate(32, 100)'); var triangleRight = { draw: function (context, size) { var x = -Math.sqrt(size / (sqrt3 * 3)); context.moveTo(-x * 2, 0); context.lineTo(x, -sqrt3 * x); context.lineTo(x, sqrt3 * x); context.closePath(); } }; var triangleLeft = { draw: function (context, size) { var x = -Math.sqrt(size / (sqrt3 * 3)); context.moveTo(x * 2, 0); context.lineTo(-x, -sqrt3 * x); context.lineTo(-x, sqrt3 * x); context.closePath(); } }; let leftTrgl = d3.symbol().type(triangleLeft) .size(180); let rightTrgl = d3.symbol().type(triangleRight) .size(180); let xScale = d3.scaleLinear() .domain([0, 60 * 60]) .range([0, 469]) .clamp(true); let slider = svg.append('line') .attr('class', 'track') .attr('x1', xScale.range()[0]) .attr('x2', xScale.range()[1]) .attr('y1', 0) .attr('y2', 0) let head1 = svg.append('path') .attr('d', leftTrgl) .style('fill', 'red') .style('stroke', 'none') .classed('slider-circle-time-from', true) .attr('transform', 'translate(32, 0)') .call(d3.drag() .on('start.interrupt', function () { head1.interrupt(); }) .on('start drag', function () { // d3.event.x : get x position of the mouse click let xTimeTo = Number(d3.select('.slider-circle-time-to').attr('transform').split('translate(')[1].split(',')[0]); let xTimeFrom = Number(d3.select('.slider-circle-time-from').attr('transform').split('translate(')[1].split(',')[0]) console.log('from , to', xTimeFrom, xTimeTo, xScale.range()[1]) if (xTimeFrom + 13 >= xScale.range()[1]) return; handleGragHead1(xScale.invert(d3.event.x)) if (xTimeFrom + 13 > xTimeTo) { console.log('== BIM') handleGragHead2(xScale.invert(d3.event.x + 13)) } })); let head2 = svg.append('path') .attr('d', rightTrgl) .style('fill', 'green') .style('stroke', 'none') .classed('slider-circle-time-to', true) .attr('transform', 'translate(32, 0)') .call(d3.drag() .on('start.interrupt', function () { head2.interrupt(); }) .on('start drag', function () { // d3.event.x : get x position of the mouse click let xTimeTo = Number(d3.select('.slider-circle-time-to').attr('transform').split('translate(')[1].split(',')[0]); let xTimeFrom = Number(d3.select('.slider-circle-time-from').attr('transform').split('translate(')[1].split(',')[0]) if (xTimeTo <= 13) return; handleGragHead2(xScale.invert(d3.event.x)); if (xTimeTo < xTimeFrom + 13) { console.log('== BOM') handleGragHead1(xScale.invert(d3.event.x - 13)) } })); function handleGragHead2(x) { d3.select('.slider-circle-time-to') .attr('transform', 'translate(' + xScale(x) + ', 0)') } function handleGragHead1(x) { d3.select('.slider-circle-time-from') .attr('transform', 'translate(' + xScale(x) + ', 0)') } </script> </body>
https://d3js.org/d3.v4.min.js