Added align options, defualting to true, to align up each row of legend. WARNING may make legen take up MORE ROWS.

master-patched
Bob Monteverde 12 years ago
parent 6bbe097e04
commit f24490f1e3

@ -2079,12 +2079,14 @@ nv.models.legend = function() {
var margin = {top: 5, right: 0, bottom: 5, left: 10},
width = 400,
height = 20,
color = d3.scale.category20().range();
color = d3.scale.category20().range(),
align = true;
var dispatch = d3.dispatch('legendClick', 'legendMouseover', 'legendMouseout');
function chart(selection) {
selection.each(function(data) {
var availableWidth = width - margin.left - margin.right;
var wrap = d3.select(this).selectAll('g.legend').data([data]);
var gEnter = wrap.enter().append('g').attr('class', 'nvd3 legend').append('g');
@ -2120,34 +2122,87 @@ nv.models.legend = function() {
series.exit().remove();
var ypos = 5,
newxpos = 5,
maxwidth = 0,
xpos;
series
.attr('transform', function(d, i) {
var length = d3.select(this).select('text').node().getComputedTextLength() + 28;
xpos = newxpos;
if (width < margin.left + margin.right + xpos + length) {
newxpos = xpos = 5;
ypos += 20;
}
newxpos += length;
if (newxpos > maxwidth) maxwidth = newxpos;
// NEW ALIGNING CODE, TODO: drastically clean up ... just initial code to make sure the math is right
if (align) {
var seriesWidths = [];
series.each(function(d,i) {
seriesWidths.push(d3.select(this).select('text').node().getComputedTextLength() + 28); // 28 is ~ the width of the circle plus some padding
});
//console.log('Series Widths: ', JSON.stringify(seriesWidths));
return 'translate(' + xpos + ',' + ypos + ')';
});
var seriesPerRow = 0;
var legendWidth = 0;
var columnWidths = [];
while ( legendWidth < availableWidth && seriesPerRow < seriesWidths.length) {
columnWidths[seriesPerRow] = seriesWidths[seriesPerRow];
legendWidth += seriesWidths[seriesPerRow++];
}
while ( legendWidth > availableWidth && seriesPerRow > 1 ) {
columnWidths = [];
seriesPerRow--;
for (k = 0; k < seriesWidths.length; k++) {
if (seriesWidths[k] > (columnWidths[k % seriesPerRow] || 0) )
columnWidths[k % seriesPerRow] = seriesWidths[k];
}
legendWidth = columnWidths.reduce(function(prev, cur, index, array) {
return prev + cur;
});
}
//console.log(columnWidths, legendWidth, seriesPerRow);
var xPositions = [];
for (var i = 0, curX = 0; i < seriesPerRow; i++) {
xPositions[i] = curX;
curX += columnWidths[i];
}
series
.attr('transform', function(d, i) {
return 'translate(' + xPositions[i % seriesPerRow] + ',' + (5 + Math.floor(i / seriesPerRow) * 20) + ')';
});
//position legend as far right as possible within the total width
g.attr('transform', 'translate(' + (width - margin.right - legendWidth) + ',' + margin.top + ')');
height = margin.top + margin.bottom + (5 + Math.ceil(seriesWidths.length / seriesPerRow) * 20) + 15;
} else {
var ypos = 5,
newxpos = 5,
maxwidth = 0,
xpos;
series
.attr('transform', function(d, i) {
var length = d3.select(this).select('text').node().getComputedTextLength() + 28;
xpos = newxpos;
if (width < margin.left + margin.right + xpos + length) {
newxpos = xpos = 5;
ypos += 20;
}
newxpos += length;
if (newxpos > maxwidth) maxwidth = newxpos;
return 'translate(' + xpos + ',' + ypos + ')';
});
//position legend as far right as possible within the total width
g.attr('transform', 'translate(' + (width - margin.right - maxwidth) + ',' + margin.top + ')');
//position legend as far right as possible within the total width
g.attr('transform', 'translate(' + (width - margin.right - maxwidth) + ',' + margin.top + ')');
//update height value if calculated larger than current
//Asuming legend is always horizontal for now, removing if clause because this does not let legend shrink after expanding
//TODO: allow legend to be horizontal or vertical, instead of definign height/width define one, and maybe call it maxHeight/maxWidth
//if (height < margin.top + margin.bottom + ypos + 15)
height = margin.top + margin.bottom + ypos + 15;
}
});
@ -2181,6 +2236,12 @@ nv.models.legend = function() {
return chart;
};
chart.align = function(_) {
if (!arguments.length) return align;
align = _;
return chart;
};
return chart;
}

6
nv.d3.min.js vendored

File diff suppressed because one or more lines are too long

@ -3,12 +3,14 @@ nv.models.legend = function() {
var margin = {top: 5, right: 0, bottom: 5, left: 10},
width = 400,
height = 20,
color = d3.scale.category20().range();
color = d3.scale.category20().range(),
align = true;
var dispatch = d3.dispatch('legendClick', 'legendMouseover', 'legendMouseout');
function chart(selection) {
selection.each(function(data) {
var availableWidth = width - margin.left - margin.right;
var wrap = d3.select(this).selectAll('g.legend').data([data]);
var gEnter = wrap.enter().append('g').attr('class', 'nvd3 legend').append('g');
@ -44,34 +46,87 @@ nv.models.legend = function() {
series.exit().remove();
var ypos = 5,
newxpos = 5,
maxwidth = 0,
xpos;
series
.attr('transform', function(d, i) {
var length = d3.select(this).select('text').node().getComputedTextLength() + 28;
xpos = newxpos;
if (width < margin.left + margin.right + xpos + length) {
newxpos = xpos = 5;
ypos += 20;
}
newxpos += length;
if (newxpos > maxwidth) maxwidth = newxpos;
// NEW ALIGNING CODE, TODO: drastically clean up ... just initial code to make sure the math is right
if (align) {
var seriesWidths = [];
series.each(function(d,i) {
seriesWidths.push(d3.select(this).select('text').node().getComputedTextLength() + 28); // 28 is ~ the width of the circle plus some padding
});
return 'translate(' + xpos + ',' + ypos + ')';
});
//console.log('Series Widths: ', JSON.stringify(seriesWidths));
var seriesPerRow = 0;
var legendWidth = 0;
var columnWidths = [];
while ( legendWidth < availableWidth && seriesPerRow < seriesWidths.length) {
columnWidths[seriesPerRow] = seriesWidths[seriesPerRow];
legendWidth += seriesWidths[seriesPerRow++];
}
while ( legendWidth > availableWidth && seriesPerRow > 1 ) {
columnWidths = [];
seriesPerRow--;
for (k = 0; k < seriesWidths.length; k++) {
if (seriesWidths[k] > (columnWidths[k % seriesPerRow] || 0) )
columnWidths[k % seriesPerRow] = seriesWidths[k];
}
legendWidth = columnWidths.reduce(function(prev, cur, index, array) {
return prev + cur;
});
}
//console.log(columnWidths, legendWidth, seriesPerRow);
var xPositions = [];
for (var i = 0, curX = 0; i < seriesPerRow; i++) {
xPositions[i] = curX;
curX += columnWidths[i];
}
series
.attr('transform', function(d, i) {
return 'translate(' + xPositions[i % seriesPerRow] + ',' + (5 + Math.floor(i / seriesPerRow) * 20) + ')';
});
//position legend as far right as possible within the total width
g.attr('transform', 'translate(' + (width - margin.right - legendWidth) + ',' + margin.top + ')');
height = margin.top + margin.bottom + (5 + Math.ceil(seriesWidths.length / seriesPerRow) * 20) + 15;
} else {
//position legend as far right as possible within the total width
g.attr('transform', 'translate(' + (width - margin.right - maxwidth) + ',' + margin.top + ')');
var ypos = 5,
newxpos = 5,
maxwidth = 0,
xpos;
series
.attr('transform', function(d, i) {
var length = d3.select(this).select('text').node().getComputedTextLength() + 28;
xpos = newxpos;
if (width < margin.left + margin.right + xpos + length) {
newxpos = xpos = 5;
ypos += 20;
}
newxpos += length;
if (newxpos > maxwidth) maxwidth = newxpos;
return 'translate(' + xpos + ',' + ypos + ')';
});
//position legend as far right as possible within the total width
g.attr('transform', 'translate(' + (width - margin.right - maxwidth) + ',' + margin.top + ')');
//update height value if calculated larger than current
//Asuming legend is always horizontal for now, removing if clause because this does not let legend shrink after expanding
//TODO: allow legend to be horizontal or vertical, instead of definign height/width define one, and maybe call it maxHeight/maxWidth
//if (height < margin.top + margin.bottom + ypos + 15)
height = margin.top + margin.bottom + ypos + 15;
}
});
@ -105,5 +160,11 @@ nv.models.legend = function() {
return chart;
};
chart.align = function(_) {
if (!arguments.length) return align;
align = _;
return chart;
};
return chart;
}

Loading…
Cancel
Save