/** * */ var Itemgroup = { /** * */ items: function items(group, delay, n) { var g; var all = []; group.selectAll('g').remove(); // Items start with no background by default. for (var i = 0; i < n; i++) { g = group.append('g') .attr('class', `i${i}`) .attr('transform', function transform(d) { return `translate(${i * (Visualizer.itemW + Visualizer.spacerW) + Visualizer.padding}, ${Visualizer.padding})`; });; g.append('rect') .attr('class', 'item') .attr('height', Visualizer.itemH) .attr('width', Visualizer.itemW) .attr('fill', 'transparent'); // Item labels g.append('text') .attr('fill', '#aaa') .attr('font-size', 10) .attr('font-family', 'sans-serif') .attr('transform', function transform(d) { return `rotate(90 0,0), translate(5, -3)`; }); all.push(g); }; return all; }, /** * */ swap: function swap(group, delay, indexA, indexB) { var x, a, b; var len = group.selectAll('g')[0].length; // Animate a node swap which will be quietly undone after completion. group.selectAll('g').transition().duration(delay - 100) .attr('transform', function transform(d, i) { x = i * (Visualizer.itemW + Visualizer.spacerW) + Visualizer.padding; if (i === indexA) { x = indexB * (Visualizer.itemW + Visualizer.spacerW) + Visualizer.padding; a = d3.select(this).select('text').text(); if (indexA === indexB) { b = a; } } else if (i === indexB) { x = indexA * (Visualizer.itemW + Visualizer.spacerW) + Visualizer.padding; b = d3.select(this).select('text').text(); } return `translate(${x}, ${Visualizer.padding})`; }) .each('end', function(d, i) { if (i !== len - 1) { return; } // Undo the animation by restoring the original positions and swapping the values. group.selectAll('g') .attr('transform', function transform(d, i) { x = i * (Visualizer.itemW + Visualizer.spacerW) + Visualizer.padding; return `translate(${x}, ${Visualizer.padding})`; }) .each(function(d, i) { if (i === indexA) { d3.select(this).select('text').text(b); } else if (i === indexB) { d3.select(this).select('text').text(a); } }); }); }, /** * */ background: function background(group, delay, start, end, color) { group.selectAll('g').each(function(d, i) { if (i >= start && i <= end) { d3.select(this).select('rect').attr('fill', color); } }); }, /** * */ foreground: function foreground(group, delay, start, end, color) { group.selectAll('g').each(function(d, i) { if (i >= start && i <= end) { d3.select(this).select('text').attr('fill', color); } }); }, /** * */ text: function text(group, delay, which, text) { group.selectAll('g') .filter(function filter(d, i) { return i === which; }) .select('text').text(text); }, /** * */ opacity: function opacity(group, delay, start, end, opacity) { group.selectAll('g').each(function(d, i) { if (i >= start && i <= end) { d3.select(this).attr('opacity', opacity); } }); }, /** * Message updates. */ message: function message(group, delay, which, msg) { var msg = msg || ' '; this.parent.querySelector(`.message:nth-child(${which})`).innerHTML = msg; }, };