diff --git a/src/axis.js b/src/axis.js index 32caec380..669ba9aa1 100644 --- a/src/axis.js +++ b/src/axis.js @@ -309,40 +309,51 @@ Axis.prototype.textAnchorForY2AxisLabel = function textAnchorForY2AxisLabel() { var $$ = this.owner; return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getY2AxisLabelPosition()); }; -Axis.prototype.getMaxTickWidth = function getMaxTickWidth(id, withoutRecompute) { +Axis.prototype.getMaxTickWidth = function getMaxTickWidth(id) { var $$ = this.owner, maxWidth = 0, targetsToShow, scale, axis, dummy, svg; - if (withoutRecompute && $$.currentMaxTickWidths[id]) { - return $$.currentMaxTickWidths[id]; + + const cacheKey = `MaxTickWidth(${id})`; + + // return cached value if any + const cachedMaxTickWidth = $$.getFromCache(cacheKey); + if (cachedMaxTickWidth !== undefined) { + return cachedMaxTickWidth; } - if ($$.svg) { - targetsToShow = $$.filterTargetsToShow($$.data.targets); - if (id === 'y') { - scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y')); - axis = this.getYAxis(id, scale, $$.yOrient, $$.yAxisTickValues, false, true, true); - } else if (id === 'y2') { - scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2')); - axis = this.getYAxis(id, scale, $$.y2Orient, $$.y2AxisTickValues, false, true, true); - } else { - scale = $$.x.copy().domain($$.getXDomain(targetsToShow)); - axis = this.getXAxis(scale, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, false, true, true); - this.updateXAxisTickValues(targetsToShow, axis); - } - dummy = $$.d3.select('body').append('div').classed('c3', true); - svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), - svg.append('g').call(axis).each(function () { - $$.d3.select(this).selectAll('text').each(function () { - var box = this.getBBox(); - if (maxWidth < box.width) { - maxWidth = box.width; - } - }); - dummy.remove(); - }); + + // bypass if SVG not rendered yet + if (!$$.svg) { + return 0; + } + + targetsToShow = $$.filterTargetsToShow($$.data.targets); + if (id === 'y') { + scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y')); + axis = this.getYAxis(id, scale, $$.yOrient, $$.yAxisTickValues, false, true, true); + } else if (id === 'y2') { + scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2')); + axis = this.getYAxis(id, scale, $$.y2Orient, $$.y2AxisTickValues, false, true, true); + } else { + scale = $$.x.copy().domain($$.getXDomain(targetsToShow)); + axis = this.getXAxis(scale, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, false, true, true); + this.updateXAxisTickValues(targetsToShow, axis); } - $$.currentMaxTickWidths[id] = maxWidth <= 0 ? $$.currentMaxTickWidths[id] : maxWidth; - return $$.currentMaxTickWidths[id]; + dummy = $$.d3.select('body').append('div').classed('c3', true); + svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), + svg.append('g').call(axis).each(function () { + $$.d3.select(this).selectAll('text').each(function () { + var box = this.getBBox(); + if (maxWidth < box.width) { + maxWidth = box.width; + } + }); + dummy.remove(); + }); + + $$.addToCache(cacheKey, maxWidth); + + return maxWidth; }; Axis.prototype.updateLabels = function updateLabels(withTransition) { diff --git a/src/core.js b/src/core.js index c3f822723..991fff409 100644 --- a/src/core.js +++ b/src/core.js @@ -138,12 +138,6 @@ ChartInternal.prototype.initParams = function() { $$.legendItemWidth = 0; $$.legendItemHeight = 0; - $$.currentMaxTickWidths = { - x: 0, - y: 0, - y2: 0 - }; - $$.rotated_padding_left = 30; $$.rotated_padding_right = config.axis_rotated && !config.axis_x_show ? 0 : 30; $$.rotated_padding_top = 5; @@ -533,6 +527,9 @@ ChartInternal.prototype.redraw = function(options, transitions) { durationForExit = withTransitionForExit ? duration : 0; durationForAxis = withTransitionForAxis ? duration : 0; + // reset caches when we are re-drawing the chart + $$.resetCache(); + transitions = transitions || $$.axis.generateTransitions(durationForAxis); // update legend and transform each g @@ -762,6 +759,8 @@ ChartInternal.prototype.updateAndRedraw = function(options) { options.withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", true); options.withTransitionForExit = false; options.withTransitionForTransform = getOption(options, "withTransitionForTransform", options.withTransition); + // clear any cache before we update sizes + $$.resetCache(); // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called) $$.updateSizes(); // MEMO: called in updateLegend in redraw if withLegend @@ -1148,7 +1147,7 @@ ChartInternal.prototype.generateWait = function() { if (!$$.isTabVisible()) { return; } - + var done = 0; transitionsToWait.forEach(function(t) { if (t.empty()) { diff --git a/src/size.js b/src/size.js index 759f9a0c5..eed20e523 100644 --- a/src/size.js +++ b/src/size.js @@ -24,16 +24,16 @@ ChartInternal.prototype.getCurrentPaddingBottom = function () { var config = this.config; return isValue(config.padding_bottom) ? config.padding_bottom : 0; }; -ChartInternal.prototype.getCurrentPaddingLeft = function (withoutRecompute) { +ChartInternal.prototype.getCurrentPaddingLeft = function () { var $$ = this, config = $$.config; if (isValue(config.padding_left)) { return config.padding_left; } else if (config.axis_rotated) { - return (!config.axis_x_show || config.axis_x_inner) ? 1 : Math.max(ceil10($$.getAxisWidthByAxisId('x', withoutRecompute)), 40); + return (!config.axis_x_show || config.axis_x_inner) ? 1 : Math.max(ceil10($$.getAxisWidthByAxisId('x')), 40); } else if (!config.axis_y_show || config.axis_y_inner) { // && !config.axis_rotated return $$.axis.getYAxisLabelPosition().isOuter ? 30 : 1; } else { - return ceil10($$.getAxisWidthByAxisId('y', withoutRecompute)); + return ceil10($$.getAxisWidthByAxisId('y')); } }; ChartInternal.prototype.getCurrentPaddingRight = function () { @@ -85,7 +85,7 @@ ChartInternal.prototype.getParentHeight = function () { }; -ChartInternal.prototype.getSvgLeft = function (withoutRecompute) { +ChartInternal.prototype.getSvgLeft = function () { var $$ = this, config = $$.config, hasLeftAxisRect = config.axis_rotated || (!config.axis_rotated && !config.axis_y_inner), leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY, @@ -93,14 +93,14 @@ ChartInternal.prototype.getSvgLeft = function (withoutRecompute) { svgRect = leftAxis && hasLeftAxisRect ? leftAxis.getBoundingClientRect() : {right: 0}, chartRect = $$.selectChart.node().getBoundingClientRect(), hasArc = $$.hasArcType(), - svgLeft = svgRect.right - chartRect.left - (hasArc ? 0 : $$.getCurrentPaddingLeft(withoutRecompute)); + svgLeft = svgRect.right - chartRect.left - (hasArc ? 0 : $$.getCurrentPaddingLeft()); return svgLeft > 0 ? svgLeft : 0; }; -ChartInternal.prototype.getAxisWidthByAxisId = function (id, withoutRecompute) { +ChartInternal.prototype.getAxisWidthByAxisId = function (id) { var $$ = this, position = $$.axis.getLabelPositionById(id); - return $$.axis.getMaxTickWidth(id, withoutRecompute) + (position.isInner ? 20 : 40); + return $$.axis.getMaxTickWidth(id) + (position.isInner ? 20 : 40); }; ChartInternal.prototype.getHorizontalAxisHeight = function (axisId) { var $$ = this, config = $$.config, h = 30;