Browse Source

Show legend as new line when overflow - #15 #64

pull/80/head
Masayuki Tanaka 11 years ago
parent
commit
45ba2dbefe
  1. 180
      c3.js
  2. 4
      c3.min.js

180
c3.js

@ -68,7 +68,6 @@
__data_selection_isselectable = getConfig(['data', 'selection', 'isselectable'], function () { return true; }), __data_selection_isselectable = getConfig(['data', 'selection', 'isselectable'], function () { return true; }),
__data_selection_multiple = getConfig(['data', 'selection', 'multiple'], true); __data_selection_multiple = getConfig(['data', 'selection', 'multiple'], true);
// subchart // subchart
var __subchart_show = getConfig(['subchart', 'show'], false), var __subchart_show = getConfig(['subchart', 'show'], false),
__subchart_size_height = __subchart_show ? getConfig(['subchart', 'size', 'height'], 60) : 0; __subchart_size_height = __subchart_show ? getConfig(['subchart', 'size', 'height'], 60) : 0;
@ -221,6 +220,7 @@
}; };
var isLegendRight = __legend_position === 'right'; var isLegendRight = __legend_position === 'right';
var legendStep = 0, legendItemWidth = 0, legendItemHeight = 0;
/*-- Define Functions --*/ /*-- Define Functions --*/
@ -365,12 +365,20 @@
maxDataCount = getMaxDataCount(); maxDataCount = getMaxDataCount();
return maxDataCount > 1 ? (base * ratio) / (maxDataCount - 1) : base; return maxDataCount > 1 ? (base * ratio) / (maxDataCount - 1) : base;
} }
function updateLegndStep(step) {
legendStep = step;
}
function updateLegendItemWidth(w) {
legendItemWidth = w;
}
function updateLegendItemHeight(h) {
legendItemHeight = h;
}
function getLegendWidth() { function getLegendWidth() {
// TODO: legend width should be an option return __legend_show ? isLegendRight ? legendItemWidth * (legendStep + 1) : currentWidth : 0;
return __legend_show ? isLegendRight ? 150 : currentWidth : 0;
} }
function getLegendHeight() { function getLegendHeight() {
return __legend_show ? isLegendRight ? currentHeight : 40 : 0; return __legend_show ? isLegendRight ? currentHeight : legendItemHeight * (legendStep + 1) : 0;
} }
function getLegendPaddingTop() { function getLegendPaddingTop() {
var xAxisLabelPositon = getXAxisLabelPosition(); var xAxisLabelPositon = getXAxisLabelPosition();
@ -1963,17 +1971,11 @@
.attr("clip-path", __axis_rotated ? getClipPath("yaxis-clip") : ""); .attr("clip-path", __axis_rotated ? getClipPath("yaxis-clip") : "");
} }
/*-- Legend Region --*/
if (__legend_show) {
updateLegend(c3.data.targets);
}
// Set targets // Set targets
updateTargets(c3.data.targets); updateTargets(c3.data.targets);
// Draw with targets // Draw with targets
redraw({withTransform: true, withUpdateXDomain: true}); redraw({withTransform: true, withUpdateXDomain: true, withLegend: true});
// Show tooltip if needed // Show tooltip if needed
if (__tooltip_init_show) { if (__tooltip_init_show) {
@ -1997,7 +1999,9 @@
window.onresize = generateResize(); window.onresize = generateResize();
} }
if (window.onresize.add) { if (window.onresize.add) {
window.onresize.add(updateAndRedraw); window.onresize.add(function () {
updateAndRedraw({withTransition: false, withLegend: true});
});
} }
} }
@ -2271,7 +2275,7 @@
var mainCircle, mainBar, mainRegion, mainText, contextBar, eventRectUpdate; var mainCircle, mainBar, mainRegion, mainText, contextBar, eventRectUpdate;
var barIndices = getBarIndices(), maxDataCountTarget; var barIndices = getBarIndices(), maxDataCountTarget;
var rectX, rectW; var rectX, rectW;
var withY, withSubchart, withTransition, withTransform, withUpdateXDomain, withUpdateOrgXDomain; var withY, withSubchart, withTransition, withTransform, withUpdateXDomain, withUpdateOrgXDomain, withLegend;
var hideAxis = hasArcType(c3.data.targets); var hideAxis = hasArcType(c3.data.targets);
var drawBar, drawBarOnSub, xForText, yForText; var drawBar, drawBarOnSub, xForText, yForText;
var duration, durationForExit; var duration, durationForExit;
@ -2283,10 +2287,17 @@
withTransform = isDefined(options.withTransform) ? options.withTransform : false; withTransform = isDefined(options.withTransform) ? options.withTransform : false;
withUpdateXDomain = isDefined(options.withUpdateXDomain) ? options.withUpdateXDomain : false; withUpdateXDomain = isDefined(options.withUpdateXDomain) ? options.withUpdateXDomain : false;
withUpdateOrgXDomain = isDefined(options.withUpdateOrgXDomain) ? options.withUpdateOrgXDomain : false; withUpdateOrgXDomain = isDefined(options.withUpdateOrgXDomain) ? options.withUpdateOrgXDomain : false;
withLegend = isDefined(options.withLegend) ? options.withLegend : false;
duration = withTransition ? __transition_duration : 0; duration = withTransition ? __transition_duration : 0;
durationForExit = isDefined(options.durationForExit) ? options.durationForExit : duration; durationForExit = isDefined(options.durationForExit) ? options.durationForExit : duration;
// update legend
if (withLegend && __legend_show) {
updateLegend(c3.data.targets, options);
return; // call in updateLegend again with same options
}
if (withUpdateOrgXDomain) { if (withUpdateOrgXDomain) {
x.domain(d3.extent(getXDomain(c3.data.targets))); x.domain(d3.extent(getXDomain(c3.data.targets)));
orgXDomain = x.domain(); orgXDomain = x.domain();
@ -2640,11 +2651,6 @@
.style("fill-opacity", 0) .style("fill-opacity", 0)
.remove(); .remove();
// update legend
if (__legend_show) {
updateLegend(c3.data.targets, {withTransition: withTransition});
}
// update fadein condition // update fadein condition
getTargetIds().forEach(function (id) { getTargetIds().forEach(function (id) {
withoutFadeIn[id] = true; withoutFadeIn[id] = true;
@ -2690,10 +2696,11 @@
return callResizeFunctions; return callResizeFunctions;
} }
function updateAndRedraw(options) { function updateAndRedraw(options) {
var withTransition, withTransform; var withTransition, withTransform, withLegend;
options = isDefined(options) ? options : {}; options = isDefined(options) ? options : {};
withTransition = isDefined(options.withTransition) ? options.withTransition : false; withTransition = isDefined(options.withTransition) ? options.withTransition : true;
withTransform = isDefined(options.withTransform) ? options.withTransform : false; withTransform = isDefined(options.withTransform) ? options.withTransform : false;
withLegend = isDefined(options.withLegend) ? options.withLegend : false;
// Update sizes and scales // Update sizes and scales
updateSizes(); updateSizes();
updateScales(); updateScales();
@ -2713,7 +2720,8 @@
withTransition: withTransition, withTransition: withTransition,
withUpdateXDomain: true, withUpdateXDomain: true,
withTransform: withTransform, withTransform: withTransform,
durationForExit: 0 durationForExit: 0,
withLegend: withLegend
}); });
} }
@ -2846,12 +2854,6 @@
.style("stroke", function (d) { return color(d.id); }); .style("stroke", function (d) { return color(d.id); });
} }
/*-- Legend --*/
if (__legend_show) {
updateLegend(targets);
}
/*-- Show --*/ /*-- Show --*/
// Fade-in each chart // Fade-in each chart
@ -2877,7 +2879,7 @@
updateTargets(c3.data.targets); updateTargets(c3.data.targets);
// Redraw with new targets // Redraw with new targets
redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true}); redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true});
done(); done();
} }
@ -2907,58 +2909,74 @@
function updateLegend(targets, options) { function updateLegend(targets, options) {
var ids = getTargetIds(targets), l; var ids = getTargetIds(targets), l;
var xForLegend, xForLegendText, xForLegendRect, yForLegend, yForLegendText, yForLegendRect; var xForLegend, xForLegendText, xForLegendRect, yForLegend, yForLegendText, yForLegendRect;
var paddingTop = 4, paddingRight = 30, margin; var paddingTop = 4, paddingRight = 26, maxWidth, maxHeight, posMin = 10;
var totalLength = 0, offsets = {}, widths = {}, heights = {}; var totalLength = 0, offsets = {}, widths = {}, heights = {}, margins = {}, steps = {}, step = 0;
var withTransition; var withTransition;
options = isUndefined(options) ? {} : options; options = isUndefined(options) ? {} : options;
withTransition = isDefined(options.withTransition) ? options.withTransition : true; withTransition = isDefined(options.withTransition) ? options.withTransition : true;
function getXOffset(id, i) { function updatePositions(textElement, id, reset) {
return __legend_equally ? widths[id] * i : offsets[id];
}
function getYOffset(id, i) {
return __legend_equally ? heights[id] * i : offsets[id];
}
function updatePositions(textElement, id) {
var box = textElement.getBBox(), var box = textElement.getBBox(),
width = Math.ceil((box.width + paddingRight) / 10) * 10, itemWidth = Math.ceil((box.width + paddingRight) / 10) * 10,
height = Math.ceil((box.height + paddingTop) / 10) * 10, itemHeight = Math.ceil((box.height + paddingTop) / 10) * 10,
length = isLegendRight ? height : width, itemLength = isLegendRight ? itemHeight : itemWidth,
areaLength = isLegendRight ? legendHeight : legendWidth, areaLength = isLegendRight ? legendHeight : legendWidth,
maxWidth, maxHeight; margin, maxLength;
widths[id] = width; // MEMO: care about condifion of step, totalLength
heights[id] = height; function updateValues(id, withoutStep) {
if (!withoutStep) {
if (__legend_equally) { margin = (areaLength - totalLength - itemLength) / 2;
maxWidth = d3.max(Object.keys(widths).map(function (key) { return widths[key]; })); if (margin < posMin) {
maxHeight = d3.max(Object.keys(heights).map(function (key) { return heights[key]; })); margin = (areaLength - itemLength) / 2;
if (width >= maxWidth) { totalLength = 0;
Object.keys(widths).forEach(function (key) { widths[key] = width; }); step++;
if (! isLegendRight) {
margin = (legendWidth - width * Object.keys(targets).length) / 2;
} }
} }
if (height >= maxHeight) { steps[id] = step;
Object.keys(heights).forEach(function (key) { heights[key] = height; }); margins[step] = margin;
if (isLegendRight) { offsets[id] = totalLength;
margin = (legendHeight - height * Object.keys(targets).length) / 2; totalLength += itemLength;
}
if (reset) {
totalLength = 0;
step = 0;
maxWidth = 0;
maxHeight = 0;
}
widths[id] = itemWidth;
heights[id] = itemHeight;
if (!maxWidth || itemWidth >= maxWidth) { maxWidth = itemWidth; }
if (!maxHeight || itemHeight >= maxHeight) { maxHeight = itemHeight; }
maxLength = isLegendRight ? maxHeight : maxWidth;
if (__legend_equally) {
Object.keys(widths).forEach(function (id) { widths[id] = maxWidth; });
Object.keys(heights).forEach(function (id) { heights[id] = maxHeight; });
margin = (areaLength - maxLength * ids.length) / 2;
if (margin < posMin) {
totalLength = 0;
step = 0;
ids.forEach(function (id) { updateValues(id); });
} }
else {
updateValues(id, true);
} }
} else { } else {
offsets[id] = totalLength; updateValues(id);
totalLength += length;
margin = (areaLength - totalLength) / 2;
} }
} }
if (isLegendRight) { if (isLegendRight) {
xForLegend = function () { return legendWidth * 0.2; }; xForLegend = function (id) { return maxWidth * (0.2 + steps[id]); };
yForLegend = function (id, i) { return margin + getYOffset(id, i); }; yForLegend = function (id) { return margins[steps[id]] + offsets[id]; };
} else { } else {
xForLegend = function (id, i) { return margin + getXOffset(id, i); }; xForLegend = function (id) { return margins[steps[id]] + offsets[id]; };
yForLegend = function () { return legendHeight * 0.2; }; yForLegend = function (id) { return maxHeight * (0.2 + steps[id]); };
} }
xForLegendText = function (id, i) { return xForLegend(id, i) + 14; }; xForLegendText = function (id, i) { return xForLegend(id, i) + 14; };
yForLegendText = function (id, i) { return yForLegend(id, i) + 9; }; yForLegendText = function (id, i) { return yForLegend(id, i) + 9; };
@ -2984,10 +3002,10 @@
}); });
l.append('text') l.append('text')
.text(function (id) { return isDefined(__data_names[id]) ? __data_names[id] : id; }) .text(function (id) { return isDefined(__data_names[id]) ? __data_names[id] : id; })
.each(function (id) { updatePositions(this, id); }) .each(function (id, i) { updatePositions(this, id, i === 0); })
.style("pointer-events", "none") .style("pointer-events", "none")
.attr('x', isLegendRight ? xForLegendText : -200) .attr('x', isLegendRight ? xForLegendText : -200)
.attr('y', isLegendRight ? -200 : yForLegend); .attr('y', isLegendRight ? -200 : yForLegendText);
l.append('rect') l.append('rect')
.attr("class", "legend-item-event") .attr("class", "legend-item-event")
.style('fill-opacity', 0) .style('fill-opacity', 0)
@ -3000,13 +3018,13 @@
.style("pointer-events", "none") .style("pointer-events", "none")
.style('fill', function (id) { return color(id); }) .style('fill', function (id) { return color(id); })
.attr('x', isLegendRight ? xForLegendText : -200) .attr('x', isLegendRight ? xForLegendText : -200)
.attr('y', isLegendRight ? -200 : yForLegendText) .attr('y', isLegendRight ? -200 : yForLegend)
.attr('width', 10) .attr('width', 10)
.attr('height', 10); .attr('height', 10);
legend.selectAll('text') legend.selectAll('text')
.data(ids) .data(ids)
.each(function (id) { updatePositions(this, id); }) .each(function (id, i) { updatePositions(this, id, i === 0); })
.transition().duration(withTransition ? 250 : 0) .transition().duration(withTransition ? 250 : 0)
.attr('x', xForLegendText) .attr('x', xForLegendText)
.attr('y', yForLegendText); .attr('y', yForLegendText);
@ -3023,6 +3041,15 @@
.attr('x', xForLegend) .attr('x', xForLegend)
.attr('y', yForLegend); .attr('y', yForLegend);
// Update all to reflect change of legend
updateLegendItemWidth(maxWidth);
updateLegendItemHeight(maxHeight);
updateLegndStep(step);
updateSizes();
updateScales();
transformAll(false);
options.withLegend = false;
redraw(options);
} }
/*-- Event Handling --*/ /*-- Event Handling --*/
@ -3160,11 +3187,10 @@
if (__legend_show) { if (__legend_show) {
svg.selectAll('.legend-item' + getTargetSelectorSuffix(targetId)).remove(); svg.selectAll('.legend-item' + getTargetSelectorSuffix(targetId)).remove();
updateLegend(c3.data.targets);
} }
if (c3.data.targets.length > 0) { if (c3.data.targets.length > 0) {
redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true}); redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true});
} }
}; };
@ -3210,42 +3236,42 @@
c3.toLine = function (targets) { c3.toLine = function (targets) {
setTargetType(targets, 'line'); setTargetType(targets, 'line');
updateAndRedraw({withTransition: true}); updateAndRedraw();
}; };
c3.toSpline = function (targets) { c3.toSpline = function (targets) {
setTargetType(targets, 'spline'); setTargetType(targets, 'spline');
updateAndRedraw({withTransition: true}); updateAndRedraw();
}; };
c3.toBar = function (targets) { c3.toBar = function (targets) {
setTargetType(targets, 'bar'); setTargetType(targets, 'bar');
updateAndRedraw({withTransition: true}); updateAndRedraw();
}; };
c3.toScatter = function (targets) { c3.toScatter = function (targets) {
setTargetType(targets, 'scatter'); setTargetType(targets, 'scatter');
updateAndRedraw({withTransition: true}); updateAndRedraw();
}; };
c3.toArea = function (targets) { c3.toArea = function (targets) {
setTargetType(targets, 'area'); setTargetType(targets, 'area');
updateAndRedraw({withTransition: true}); updateAndRedraw();
}; };
c3.toAreaSpline = function (targets) { c3.toAreaSpline = function (targets) {
setTargetType(targets, 'area-spline'); setTargetType(targets, 'area-spline');
updateAndRedraw({withTransition: true}); updateAndRedraw();
}; };
c3.toPie = function (targets) { c3.toPie = function (targets) {
setTargetType(targets, 'pie'); setTargetType(targets, 'pie');
updateAndRedraw({withTransition: true, withTransform: true}); updateAndRedraw({withTransform: true});
}; };
c3.toDonut = function (targets) { c3.toDonut = function (targets) {
setTargetType(targets, 'donut'); setTargetType(targets, 'donut');
updateAndRedraw({withTransition: true, withTransform: true}); updateAndRedraw({withTransform: true});
}; };
c3.groups = function (groups) { c3.groups = function (groups) {
@ -3325,7 +3351,7 @@
c3.resize = function (size) { c3.resize = function (size) {
__size_width = size ? size.width : null; __size_width = size ? size.width : null;
__size_height = size ? size.height : null; __size_height = size ? size.height : null;
updateAndRedraw(); updateAndRedraw({withLegend: true, withTransition: false});
}; };
c3.destroy = function () { c3.destroy = function () {

4
c3.min.js vendored

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save