diff --git a/src/services/dataRenderService.ts b/src/services/dataRenderService.ts index e1685aa..2dde1bb 100644 --- a/src/services/dataRenderService.ts +++ b/src/services/dataRenderService.ts @@ -840,34 +840,40 @@ export class DataRenderService { } }; } + + const labelLinePointsCache = new Map(); + const getCachedLinePoints = (d: d3PieArcDatum): [number, number] => { + if (!labelLinePointsCache.has(d)) { + const { lineEndPoint } = this.computeLabelLinePoints(d); + labelLinePointsCache.set(d, lineEndPoint); + } + return labelLinePointsCache.get(d)!; + }; - const isLabelsHasConflict = (d: d3PieArcDatum) => { - const pos = arc.centroid(d); + const isLabelsHasConflict = (d: d3PieArcDatum) => { const { labelWidth, labelHeight } = setTextAndGetLabelDimensions(d); - const horizontalSpaceAvailableForLabels = viewport.width / 2 - Math.abs(pos[0]); - const verticalSpaceAvailableForLabels = viewport.height / 2 - Math.abs(pos[1]); + const [ positionX, positionY ] = getCachedLinePoints(d); + const horizontalSpaceAvailableForLabels = Math.max(0, viewport.width / 2 - Math.abs(positionX) - DataRenderService.LabelLinePadding); + const verticalSpaceAvailableForLabels = Math.max(0, viewport.height / 2 - Math.abs(positionY) - DataRenderService.LabelLinePadding); d.data.isLabelHasConflict = labelWidth > horizontalSpaceAvailableForLabels || labelHeight > verticalSpaceAvailableForLabels; - return d.data.isLabelHasConflict; + return {spaceAvailableForLabels: horizontalSpaceAvailableForLabels}; }; return { labelText: (d: d3PieArcDatum) => { - textProperties.text = d.data.label; - const pos = arc.centroid(d); - const xPos = isLabelsHasConflict(d) ? pos[0] * DataRenderService.AsterConflictRatio : pos[0]; - const spaceAvailableForLabels = viewport.width / 2 - Math.abs(xPos); - return textMeasurementService.getTailoredTextOrDefault(textProperties, spaceAvailableForLabels); + textProperties.text = d.data.label; + const {spaceAvailableForLabels } = isLabelsHasConflict(d); + return textMeasurementService.getTailoredTextOrDefault(textProperties, spaceAvailableForLabels); }, labelLayout: { x: (d: d3PieArcDatum) => { - const pos = arc.centroid(d); - textProperties.text = d.data.label; - return d.data.isLabelHasConflict ? pos[0] * DataRenderService.AsterConflictRatio : pos[0]; - }, - y: (d: d3PieArcDatum) => { - const pos: [number, number] = arc.centroid(d); - return d.data.isLabelHasConflict ? pos[1] * DataRenderService.AsterConflictRatio : pos[1]; - }, + const [lineEndPointX] = getCachedLinePoints(d); + return d.data.isLabelHasConflict ? lineEndPointX * DataRenderService.AsterConflictRatio : lineEndPointX; + }, + y: (d: d3PieArcDatum) => { + const [,lineEndPointY] = getCachedLinePoints(d); + return d.data.isLabelHasConflict ? lineEndPointY * DataRenderService.AsterConflictRatio : lineEndPointY; + }, }, filter: (d: d3PieArcDatum) => (d != null && !isEmpty(d.data.label + "")), style: {