in src/visual.ts [1885:2155]
private render(suppressAnimations: boolean = true): void {
this.setVisibility(true);
this.legendMargins = this.legendMargins || this.legend.getMargins();
if (this.legend.isVisible()) {
this.legendMargins = this.legend.getMargins();
}
const viewport: IViewport = {
height: this.currentViewport.height - this.legendMargins.height,
width: this.currentViewport.width - this.legendMargins.width
};
const maxMarginFactor: number = this.getMaxMarginFactor(),
leftRightMarginLimit: number
= this.leftRightMarginLimit
= viewport.width * maxMarginFactor;
this.bottomMarginLimit = Math.max(
MekkoChart.MinBottomMargin,
Math.ceil(viewport.height * maxMarginFactor));
const xAxisTextProperties: TextProperties = MekkoChart.getTextProperties(this.categoryAxisProperties
&& PixelConverter.fromPointToPixel(
parseFloat(<any>this.categoryAxisProperties["fontSize"])) || undefined);
const y1AxisTextProperties: TextProperties = MekkoChart.getTextProperties(this.valueAxisProperties
&& PixelConverter.fromPointToPixel(
parseFloat(<any>this.valueAxisProperties["fontSize"])) || undefined);
const margin: IMargin = this.margin;
// reset defaults
margin.top = parseFloat(y1AxisTextProperties.fontSize) / MekkoChart.MarginTopFactor;
margin.bottom = MekkoChart.MinBottomMargin;
margin.right = 0;
let axes: MekkoChartAxisProperties = this.axes = axisUtils.calculateAxes(
this.layers,
viewport,
margin,
this.categoryAxisProperties,
this.valueAxisProperties,
this.isXScrollBarVisible || this.isYScrollBarVisible,
null);
this.yAxisIsCategorical = axes.y1.isCategoryAxis;
this.hasCategoryAxis = this.yAxisIsCategorical
? axes.y1 && axes.y1.values.length > 0
: axes.x && axes.x.values.length > 0;
const renderXAxis: boolean = this.shouldRenderAxis(axes.x),
renderY1Axis: boolean = this.shouldRenderAxis(axes.y1),
renderY2Axis: boolean = this.shouldRenderSecondaryAxis(axes.y2);
let width: number = viewport.width - (margin.left + margin.right),
isScalar: boolean = false,
mainAxisScale,
preferredViewport: IViewport;
this.isXScrollBarVisible = false;
this.isYScrollBarVisible = false;
const yAxisOrientation: string = this.yAxisOrientation,
showY1OnRight: boolean = yAxisOrientation === axisPosition.right;
if (this.layers) {
if (this.layers[0].getVisualCategoryAxisIsScalar) {
isScalar = this.layers[0].getVisualCategoryAxisIsScalar();
}
if (!isScalar && this.isScrollable && this.layers[0].getPreferredPlotArea) {
const categoryThickness: number = this.scrollX
? axes.x.categoryThickness
: axes.y1.categoryThickness;
const categoryCount: number = this.scrollX
? axes.x.values.length
: axes.y1.values.length;
preferredViewport = this.layers[0].getPreferredPlotArea(
isScalar,
categoryCount,
categoryThickness);
if (this.scrollX
&& preferredViewport
&& preferredViewport.width > viewport.width) {
this.isXScrollBarVisible = true;
viewport.height -= MekkoChart.ScrollBarWidth;
}
if (this.scrollY
&& preferredViewport
&& preferredViewport.height > viewport.height) {
this.isYScrollBarVisible = true;
viewport.width -= MekkoChart.ScrollBarWidth;
width = viewport.width - (margin.left + margin.right);
}
}
}
// Only create the g tag where there is a scrollbar
if (this.isXScrollBarVisible || this.isYScrollBarVisible) {
if (!this.brushGraphicsContext) {
this.brushGraphicsContext = this.svg.append("g")
.classed(MekkoChart.XBrushSelector.className, true);
}
}
else {
// clear any existing brush if no scrollbar is shown
this.svg
.selectAll(MekkoChart.BrushSelector.selectorName)
.remove();
this.brushGraphicsContext = undefined;
}
// Recalculate axes now that scrollbar visible variables have been set
axes = axisUtils.calculateAxes(
this.layers,
viewport,
margin,
this.categoryAxisProperties,
this.valueAxisProperties,
this.isXScrollBarVisible || this.isYScrollBarVisible,
null);
// we need to make two passes because the margin changes affect the chosen tick values, which then affect the margins again.
// after the second pass the margins are correct.
let doneWithMargins: boolean = false,
maxIterations: number = 2,
numIterations: number = 0,
tickLabelMargins: TickLabelMargins = undefined,
chartHasAxisLabels: boolean = undefined,
axisLabels: MekkoChartAxesLabels = undefined;
while (!doneWithMargins && numIterations < maxIterations) {
numIterations++;
tickLabelMargins = labelUtils.getTickLabelMargins(
{ width, height: viewport.height },
leftRightMarginLimit,
textMeasurementService.measureSvgTextWidth,
textMeasurementService.estimateSvgTextHeight,
axes,
this.bottomMarginLimit,
xAxisTextProperties,
y1AxisTextProperties,
null,
false,
this.isXScrollBarVisible || this.isYScrollBarVisible,
showY1OnRight,
renderXAxis,
renderY1Axis,
renderY2Axis);
// We look at the y axes as main and second sides, if the y axis orientation is right so the main side represents the right side
let maxMainYaxisSide: number = showY1OnRight
? tickLabelMargins.yRight
: tickLabelMargins.yLeft;
let maxSecondYaxisSide: number = showY1OnRight
? tickLabelMargins.yLeft
: tickLabelMargins.yRight;
let xMax: number = renderXAxis
? (tickLabelMargins.xMax / MekkoChart.TickLabelMarginsXMaxFactor)
: 0;
maxMainYaxisSide += MekkoChart.LeftPadding;
maxSecondYaxisSide += MekkoChart.RightPadding;
xMax += MekkoChart.BottomPadding;
const rotataionEnabled = (<BaseColumnChart>this.layers[0]).getXAxisLabelsSettings().enableRotataion;
if (rotataionEnabled) {
let axes: MekkoChartAxisProperties = this.axes = axisUtils.calculateAxes(
this.layers,
this.currentViewport,
this.margin,
this.categoryAxisProperties,
this.valueAxisProperties,
this.isXScrollBarVisible || this.isYScrollBarVisible,
null);
xMax += this.calculateXAxisAdditionalHeight(axes.x.values);
}
if (this.hideAxisLabels(this.legendMargins)) {
axes.x.axisLabel = null;
axes.y1.axisLabel = null;
if (axes.y2) {
axes.y2.axisLabel = null;
}
}
this.addUnitTypeToAxisLabel(axes);
axisLabels = {
x: axes.x.axisLabel,
y: axes.y1.axisLabel,
y2: axes.y2
? axes.y2.axisLabel
: null
};
chartHasAxisLabels = (axisLabels.x != null)
|| (axisLabels.y != null || axisLabels.y2 != null);
if (axisLabels.x != null) {
xMax += MekkoChart.XAxisLabelPadding;
}
if (axisLabels.y != null) {
maxMainYaxisSide += MekkoChart.YAxisLabelPadding;
}
if (axisLabels.y2 != null) {
maxSecondYaxisSide += MekkoChart.YAxisLabelPadding;
}
margin.left = showY1OnRight
? maxSecondYaxisSide
: maxMainYaxisSide;
margin.right = showY1OnRight
? maxMainYaxisSide
: maxSecondYaxisSide;
margin.bottom = xMax;
this.margin = margin;
width = viewport.width - (margin.left + margin.right);
// re-calculate the axes with the new margins
const previousTickCountY1: number = axes.y1.values.length,
previousTickCountY2: number = axes.y2 && axes.y2.values.length;
axes = axisUtils.calculateAxes(
this.layers,
viewport,
margin,
this.categoryAxisProperties,
this.valueAxisProperties,
this.isXScrollBarVisible || this.isYScrollBarVisible,
axes);
if (axes.y1.values.length === previousTickCountY1
&& (!axes.y2 || axes.y2.values.length === previousTickCountY2)) {
doneWithMargins = true;
}
}
this.renderChart(
mainAxisScale,
axes,
width,
tickLabelMargins,
chartHasAxisLabels,
axisLabels,
viewport,
suppressAnimations);
}