Published
Edited
Aug 31, 2020
13 stars
Insert cell
Insert cell
Insert cell
eq = {
var data = tracks;
var margin = {top:140,left:45,bottom:30,right:45},
width = 960 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
var svg = d3.select(DOM.svg(width + margin.left + margin.right, height + margin.top + margin.bottom))
.style('background-color','#232b2b')
.append('g')
.attr('transform','translate(' + margin.left + ',' + margin.top + ')');
svg.append('text')
.attr('transform','translate(' + (width + margin.right -10) + ',' + (height + margin.bottom-5) + ')')
.style('text-anchor','end')
.style('font-size','10px')
.style('font-style','italic')
.text('...Double-click a knob to reset it.')
svg.append('text')
.attr('transform','translate(' + (-margin.left + 10) + ',' + (height + margin.bottom-5) + ')')
.style('text-anchor','start')
.style('font-size','10px')
.style('font-style','italic')
.text('Click and drag a knob to set it...')
var xTrack = d3.scaleBand()
.domain(data.map(function(d) { return d.name }))
.range([0,width])
.padding(.35);
var xLevel = d3.scaleBand()
.domain(['Low','High'])
.range([0,xTrack.bandwidth()])
.paddingOuter(.1);
var knob = {r:xLevel.bandwidth()/3};
var gTracks = svg.selectAll(null)
.data(data)
.enter()
.append('g')
.classed('track',true)
.attr('transform', function(d) { return 'translate(' + (xTrack(d.name)) + ',0)' })

gTracks.append('text')
.attr('transform','translate(-2,-12)rotate(-45)')
.text(function(d) { return d.name })
.style('font-size','14px')
.style('text-decoration','underline');
gTracks.each(appendLevels);
function appendLevels(d,i) {
var format = d.format;
var gTrack = d3.select(this);
var y = d3.scaleLinear()
.domain(d.domain)
.range([height,0]);
var gLevels = gTrack.selectAll(null)
.data(xLevel.domain())
.enter()
.append('g')
.classed('level',true)
.attr('transform', function(d) { return 'translate(' + (xLevel(d) + xLevel.bandwidth()/2) + ',0)' });
gLevels.append('text')
.attr('transform','translate(0,-10)rotate(-45)')
.text(function(d) { return d })
.style('font-size','9px')

gLevels.append('line')
.attr('x1',0)
.attr('x2', 0)
.attr('y1', 0)
.attr('y2',height)
.attr('stroke-linecap','round')
.style('stroke','#4e5555')
.style('stroke-width', 3);
gLevels.append('circle')
.attr('cx',0)
.attr('cy', height/2)
.attr('r',knob.r)
.style('fill','#4e5555')
.style('stroke','#d1d1d1')
.style('stroke-width', 2)
.call(d3.drag().on("drag", dragged))
.on('dblclick', rest)
function rest(d) {
d3.select(this.parentNode)
.classed('on',false)
.select('text')
.text(d);
d3.select(this)
.attr('cy', height/2)
.style('fill','#4e5555');
}
function dragged(d,i) {
d3.select(this.parentNode).classed('on',true);
var level = d,
track = d3.select(this.parentNode.parentNode),
cy = +d3.event.y < 0 ? 0 : (d3.event.y > height? height : d3.event.y);
track.selectAll('g.on circle')
.attr('cy', function(d) {
var cy0 = d3.select(this).attr('cy');
if(d == level || (cy0 >= cy && level=='Low') || (cy0 <= cy && level=='High')) {
return cy
} else { return cy0;}
})
.style('fill', function(d) { return d3.interpolateRdYlGn(1-(+d3.select(this).attr('cy'))/height) })
track.selectAll('g.level.on text')
.text(function(d) {
var prefix = d == 'High' ? 'Below ' : 'Above ';
return prefix + format(y.invert(+d3.select(this.parentNode).select('circle').attr('cy')))
})
}
}
return svg.node().parentNode;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more