function three_display(dataset, {goal, left, middle, right, extra, active_val = [], active_hash = [], matches = [], finished = [], hash = [], og_idx =[], immediate}) {
let height = height_slider
let buffer_1 = 0
let buffer_2 = 8
let buffer_h1 = 30
let arr_width = width*(dataset.length)/(dataset.length+2+matches.length) - buffer_1 - buffer_2
let xScale = d3.scaleBand()
.domain(d3.range(dataset.length))
.range([0, arr_width])
.padding(.25/Math.sqrt(dataset.length));
let yScale = d3.scaleLinear()
.domain([0, Math.max(d3.max(dataset), goal/2)])
.range([0, height/2-buffer_h1]);
let svg = d3.select(DOM.svg(width, height));
svg.append("rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "#dbefff");
svg.selectAll("bars")
.data(dataset)
.enter().append("rect")
.attr("x", (d, i) => xScale(i))
.attr("width", xScale.bandwidth())
.attr("y", d => height - yScale(d))
.attr("height", d => yScale(d))
.attr("fill", (d, i) => {
if (finished && finished.includes(i)) {return '#233b3b'} //
else if (i == left || i == right || i == middle || i == extra || i in active_val) {return 'lime'} //
else {return 'steelblue'} //
;})
.attr("stroke", "black")
.attr("stroke-width", "1");
// hash bars
svg.selectAll("hash")
.data(hash.keys())
.enter().append("rect")
.attr("x", (d, i) => xScale(i))
.attr("width", xScale.bandwidth())
.attr("y", d => 0)
.attr("height", d => yScale(d))
.attr("fill", (d, i) => { //
if (d in active_hash) {return 'lime'} //
// goal - d == dataset[left])
else {return 'wheat'} //
;})
.attr("stroke", "black")
.attr("stroke-width", "1");
// matches
svg.selectAll("matches_l")
.data(matches)
.enter().append("rect")
.attr("x", (d, i) => arr_width + buffer_2 + i*xScale.bandwidth())
.attr("width", xScale.bandwidth())
.attr("y", d => height - yScale(dataset[d.left]))
.attr("height", d => yScale(dataset[d.left]))
.attr("fill", '#710000')
.attr("stroke", "black")
.attr("stroke-width", "3");
svg.selectAll("matches_m")
.data(matches)
.enter().append("rect")
.attr("x", (d, i) => arr_width + buffer_2 + i*xScale.bandwidth())
.attr("width", xScale.bandwidth())
.attr("y", d => height - yScale(dataset[d.left]) - yScale(dataset[d.middle]))
.attr("height", d => yScale(dataset[d.middle]))
.attr("fill", 'orange');
// .attr("stroke", "black")
// .attr("stroke-width", "3");
svg.selectAll("matches_r")
.data(matches)
.enter().append("rect")
.attr("x", (d, i) => arr_width + buffer_2 + i*xScale.bandwidth())
.attr("width", xScale.bandwidth())
.attr("y", d => { //
if ("right" in d) { return height - yScale(dataset[d.left]) - yScale(dataset[d.middle]) - yScale(dataset[d.right])} //
else if ("hash_val" in d) { return height - yScale(dataset[d.left]) - yScale(d.hash_val)} //
}) //
.attr("height", d => { //
if ("right" in d) { return yScale(dataset[d.right])}
else if ("hash_val" in d) { return yScale(d.hash_val)}
}) //
.attr("fill", 'black')
.attr("stroke", "white")
.attr("stroke-width", 4.2 - dataset.length/100 - matches.length/200);
// .attr("stroke-width", (d) => {
// if (dataset.length < 100) {return '4'} //
// else if (dataset.length < 200) {return '3'}
// else if (dataset.length < 300) {return '2'}
// else if (dataset.length < 400) {return '2'}
// else {return '0'}
// });
// current combo
svg.append("rect")
// .attr("x", arr_width + buffer_2 + (1+matches.length) * xScale.bandwidth() + buffer_1)
.attr("x", arr_width + buffer_2 + matches.length * xScale.bandwidth() + buffer_1)
.attr("width", xScale.bandwidth())
.attr("y", height - yScale(dataset[left]))
.attr("height", yScale(dataset[left]))
.attr("fill", '#8f5825')
.attr("stroke", "black")
.attr("stroke-width", "3");
svg.append("rect")
// .attr("x", arr_width + buffer_2 + (1+matches.length) * xScale.bandwidth() + buffer_1)
.attr("x", arr_width + buffer_2 + matches.length * xScale.bandwidth() + buffer_1)
.attr("width", xScale.bandwidth())
.attr("y", height - yScale(dataset[left]) - yScale(dataset[middle]))
.attr("height", yScale(dataset[middle]))
.attr("fill", '#FF7F50')
.attr("stroke", "black")
.attr("stroke-width", "3");
svg.append("rect")
.attr("x", arr_width + buffer_2 + matches.length * xScale.bandwidth() + buffer_1)
.attr("width", xScale.bandwidth())
.attr("y", d => { if (right && middle) {return height - yScale(dataset[left]) - yScale(dataset[middle]) - yScale(dataset[right])}
else if (right) {return height - yScale(dataset[left]) - yScale(dataset[right])}
else {return height - yScale(dataset[left]) - yScale(goal-dataset[left])}
}) //
.attr("height", d => { //
if (right) { return yScale(dataset[right])}
else if (matches.length > 0) { return yScale(goal - dataset[left])}
}) //
.attr("fill", 'grey')
.attr("stroke", "black")
.attr("stroke-width", "3");
svg.append("rect")
// .attr("x", arr_width + buffer_2 + matches.length * xScale.bandwidth())
.attr("x", arr_width + buffer_2 + (1+matches.length) * xScale.bandwidth())
.attr("width", xScale.bandwidth())
.attr("y", height - yScale(goal))
.attr("height", yScale(goal))
// .attr("fill", 'wheat')
.attr("fill", '#2a0254')
.attr("stroke", "black")
.attr("stroke-width", "3");
if (labels.includes("Values") && dataset.length + matches.length < 125) {
svg.selectAll("bar_val_labels")
.data(dataset)
.enter().append("text")
.attr("fill", "red")
.attr("x", (d, i) => xScale(i) + xScale.bandwidth()/2)
.attr("y", d => Math.min(height - 10 - .4*xScale.bandwidth(), height - yScale(d)))
.attr("dy", -6 - 130/size)
.text(d => d)
.style("font-size", (d, i) => .75*xScale.bandwidth() + "px")
.attr("text-anchor", "middle")
.attr("dominant-baseline", "middle");
}
if (labels.includes("Original_Indeces") && dataset.length + matches.length < 125) {
svg.selectAll("bar_idx_labels")
.data(dataset)
.enter().append("text")
.attr("fill", "white")
.attr("x", (d, i) => xScale(i) + xScale.bandwidth()/2)
.attr("y", height-1)
.attr("dy", -6 - 130/size)
.text((d,i) =>
{
if (og_idx.length > 0) {return og_idx[i]}
else {return i}
})
.style("font-size", (d, i) => .75*xScale.bandwidth() + "px")
.attr("text-anchor", "middle")
.attr("dominant-baseline", "middle");
}
return immediate ? svg.node() : Promises.delay(speed, svg.node());
}