in src/visualComponent/axes/helpers/axisHelper.ts [107:228]
export function createAxis(options: ICreateAxisOptions): axisInterfaces.IAxisProperties {
const pixelSpan: number = options.pixelSpan;
const dataDomain: number[] = options.dataDomain;
const metaDataColumn: powerbi.DataViewMetadataColumn = options.metaDataColumn as powerbi.DataViewMetadataColumn;
const formatString: string = options.formatString;
const outerPadding: number = options.outerPadding || DefaultOuterPadding;
const isCategoryAxis: boolean = !!options.isCategoryAxis;
const isScalar: boolean = !!options.isScalar;
const isVertical: boolean = !!options.isVertical;
const useTickIntervalForDisplayUnits: boolean = !!options.useTickIntervalForDisplayUnits;
const getValueFn: (index: number, type: powerbi.ValueTypeDescriptor) => any = options.getValueFn;
let categoryThickness: number = options.categoryThickness;
const axisDisplayUnits: number = options.axisDisplayUnits;
const axisPrecision: number = options.axisPrecision;
const is100Pct: boolean = !!options.is100Pct;
const tickLabelPadding: number = options.tickLabelPadding || TickLabelPadding;
const dataType: powerbi.ValueTypeDescriptor = getCategoryValueType(metaDataColumn, isScalar);
// Create the Scale
const scaleResult: ICreateScaleResult = createScale(options);
const scale: ScaleLinear<any, any> = scaleResult.scale;
const bestTickCount: number = scaleResult.bestTickCount;
const scaleDomain: number[] = scale.domain();
const isLogScaleAllowed: boolean = isLogScalePossible(dataDomain, dataType);
// fix categoryThickness if scalar and the domain was adjusted when making the scale "nice"
if (categoryThickness && isScalar && dataDomain && dataDomain.length === 2) {
const oldSpan: number = dataDomain[1] - dataDomain[0];
const newSpan: number = scaleDomain[1] - scaleDomain[0];
if (oldSpan > 0 && newSpan > 0) {
categoryThickness = categoryThickness * oldSpan / newSpan;
}
}
const minTickInterval: number = isScalar
? getMinTickValueInterval(formatString, dataType, is100Pct)
: undefined;
let tickValues: any[] = getRecommendedTickValues(
bestTickCount,
scale,
dataType,
isScalar,
minTickInterval,
options.shouldTheMinValueBeIncluded);
if (isScalar
&& bestTickCount === 1
&& tickValues
&& tickValues.length > 1
) {
tickValues = [tickValues[0]];
}
if (options.scaleType && options.scaleType === axisScale.log && isLogScaleAllowed) {
tickValues = tickValues.filter((d: any) => {
return powerOfTen(d);
});
}
const formatter: valueFormatter.IValueFormatter = createFormatter(
scaleDomain,
dataDomain,
dataType,
isScalar,
formatString,
bestTickCount,
tickValues,
getValueFn,
useTickIntervalForDisplayUnits,
axisDisplayUnits,
axisPrecision);
const axisInstance = isVertical
? axisLeft(scale)
: axisBottom(scale);
const axis = axisInstance
.tickSizeInner(DefaultInnerTickSize)
.tickSizeOuter(DefaultOuterTickSize)
.ticks(bestTickCount)
.tickValues(tickValues);
let formattedTickValues: any[] = [];
if (metaDataColumn) {
formattedTickValues = formatAxisTickValues(axis, tickValues, formatter, dataType, getValueFn);
}
let xLabelMaxWidth: number;
// Use category layout of labels if specified, otherwise use scalar layout of labels
if (!isScalar && categoryThickness) {
xLabelMaxWidth = Math.max(
DefaultXLabelMaxWidth,
categoryThickness - tickLabelPadding * DefaultXLabelFactor);
}
else {
// When there are 0 or 1 ticks, then xLabelMaxWidth = pixelSpan
xLabelMaxWidth = tickValues.length > DefaultXLabelMaxWidth
? getScalarLabelMaxWidth(scale, tickValues)
: pixelSpan;
xLabelMaxWidth = xLabelMaxWidth - ScalarTickLabelPadding * DefaultXLabelFactor;
}
return {
axis,
axisLabel: null,
axisType: dataType as unknown as valueType.ValueType,
categoryThickness,
dataDomain,
formatter,
isCategoryAxis,
isLogScaleAllowed,
outerPadding,
scale,
usingDefaultDomain: scaleResult.usingDefaultDomain,
values: formattedTickValues,
xLabelMaxWidth,
};
}