// d3.tsv('data.tsv', function(data){ // c = d3.conventions({parentSel: d3.select('#graph')}) // c.x.domain(d3.extent(data, ƒ('sepalWidth')) ).nice() // c.y.domain(d3.extent(data, ƒ('sepalLength'))).nice() // c.drawAxis() // c.svg.dataAppend(data, 'circle') // .attr('cx', ƒ('sepalWidth', c.x)) // .attr('cy', ƒ('sepalLength',c.y)) // .attr('fill', ƒ('species', c.color)) // .attr({r: 5, stroke: '#000'}) // .call(d3.attachTooltip) // var legend = c.svg.dataAppend(c.color.domain(), 'g.legend') // .translate(function(d, i){ return [0, i*20] }) // legend.append('rect') // .attr({x: c.width - 18, width: 18, height: 18}) // .style('fill', c.color) // legend.append('text') // .attr({x: c.width - 24, y: 9, dy: '.33em', 'text-anchor': 'end'}) // .text(ƒ()) // }) var height = 600, width = 300 var categories = generateCatories(100) categories.forEach(function(d){ d.subcategories = generateCatories(d.value) }) var y = categories.y var svg = d3.select('body') .append('svg') .attr({width: width, height: height}) svg.dataAppend(categories, 'rect.category') .attr('height', ƒ('value', y)) .attr('y', ƒ('prevValue', y)) .attr('width', 100) .on('click', expand) var topPath = svg.append('path.dash') var botPath = svg.append('path.dash') var sideBoxes = svg.append('g') function expand(d){ topPath .attr('d', ['M', [100, y(d.prevValue)], 'L', [100, y(d.prevValue)]].join('')) .transition().duration(700).ease('linear') .attr('d', ['M', [100, y(d.prevValue)], 'L', [200, 0]].join('')) botPath .attr('d', ['M', [100, y(d.prevValue + d.value)], 'L', [100, y(d.prevValue + d.value)]].join('')) .transition().duration(700).ease('linear') .attr('d', ['M', [100, y(d.prevValue + d.value)], 'L', [200, height]].join('')) //TODO - use a transition before removing sideBoxes.selectAll('*').remove() sideBoxes.dataAppend(d.subcategories, 'rect.subcategory') .attr('width', 100) .attr('x', 000) .attr('y', function(e){ return y(d.prevValue + e.prevValue) }) .attr('height', ƒ('value', y)) .transition().duration(700).ease('linear') .attr('x', 200) .attr('width', 100) .attr('y', ƒ('prevValue', d.subcategories.y)) .attr('height', ƒ('value', d.subcategories.y)) } function generateCatories(normalize){ var categories = d3.range(10).map(function(d){ return { name: 'cat ' + d, value: Math.random() } }) var totalValue = d3.sum(categories, ƒ('value')) categories.forEach(function(d){ d.value = d.value*normalize/totalValue }) categories = _.sortBy(categories, 'value') var curValue = 0 categories.forEach(function(d){ d.prevValue = curValue curValue += d.value }) var y = d3.scale.linear() .domain([0, normalize]) .range([0, height]) categories.y = y return categories }