MCPcopy
hub / github.com/chartjs/Chart.js / pathArc

Function pathArc

src/elements/element.arc.ts:116–216  ·  view source on GitHub ↗

* Path the arc, respecting border radius by separating into left and right halves. * * Start End * * 1--->a--->2 Outer * / \ * 8 3 * | | * | | * 7 4 * \ / * 6<---b<---5 Inner

(
  ctx: CanvasRenderingContext2D,
  element: ArcElement,
  offset: number,
  spacing: number,
  end: number,
  circular: boolean,
)

Source from the content-addressed store, hash-verified

114 * 6<---b<---5 Inner
115 */
116function pathArc(
117 ctx: CanvasRenderingContext2D,
118 element: ArcElement,
119 offset: number,
120 spacing: number,
121 end: number,
122 circular: boolean,
123) {
124 const {x, y, startAngle: start, pixelMargin, innerRadius: innerR} = element;
125
126 const outerRadius = Math.max(element.outerRadius + spacing + offset - pixelMargin, 0);
127 const innerRadius = innerR > 0 ? innerR + spacing + offset + pixelMargin : 0;
128
129 let spacingOffset = 0;
130 const alpha = end - start;
131
132 if (spacing) {
133 // When spacing is present, it is the same for all items
134 // So we adjust the start and end angle of the arc such that
135 // the distance is the same as it would be without the spacing
136 const noSpacingInnerRadius = innerR > 0 ? innerR - spacing : 0;
137 const noSpacingOuterRadius = outerRadius > 0 ? outerRadius - spacing : 0;
138 const avNogSpacingRadius = (noSpacingInnerRadius + noSpacingOuterRadius) / 2;
139 const adjustedAngle = avNogSpacingRadius !== 0 ? (alpha * avNogSpacingRadius) / (avNogSpacingRadius + spacing) : alpha;
140 spacingOffset = (alpha - adjustedAngle) / 2;
141 }
142
143 const beta = Math.max(0.001, alpha * outerRadius - offset / PI) / outerRadius;
144 const angleOffset = (alpha - beta) / 2;
145 const startAngle = start + angleOffset + spacingOffset;
146 const endAngle = end - angleOffset - spacingOffset;
147 const {outerStart, outerEnd, innerStart, innerEnd} = parseBorderRadius(element, innerRadius, outerRadius, endAngle - startAngle);
148
149 const outerStartAdjustedRadius = outerRadius - outerStart;
150 const outerEndAdjustedRadius = outerRadius - outerEnd;
151 const outerStartAdjustedAngle = startAngle + outerStart / outerStartAdjustedRadius;
152 const outerEndAdjustedAngle = endAngle - outerEnd / outerEndAdjustedRadius;
153
154 const innerStartAdjustedRadius = innerRadius + innerStart;
155 const innerEndAdjustedRadius = innerRadius + innerEnd;
156 const innerStartAdjustedAngle = startAngle + innerStart / innerStartAdjustedRadius;
157 const innerEndAdjustedAngle = endAngle - innerEnd / innerEndAdjustedRadius;
158
159 ctx.beginPath();
160
161 if (circular) {
162 // The first arc segments from point 1 to point a to point 2
163 const outerMidAdjustedAngle = (outerStartAdjustedAngle + outerEndAdjustedAngle) / 2;
164 ctx.arc(x, y, outerRadius, outerStartAdjustedAngle, outerMidAdjustedAngle);
165 ctx.arc(x, y, outerRadius, outerMidAdjustedAngle, outerEndAdjustedAngle);
166
167 // The corner segment from point 2 to point 3
168 if (outerEnd > 0) {
169 const pCenter = rThetaToXY(outerEndAdjustedRadius, outerEndAdjustedAngle, x, y);
170 ctx.arc(pCenter.x, pCenter.y, outerEnd, outerEndAdjustedAngle, endAngle + HALF_PI);
171 }
172
173 // The line from point 3 to point 4

Callers 2

drawArcFunction · 0.85
drawBorderFunction · 0.85

Calls 2

rThetaToXYFunction · 0.85
parseBorderRadiusFunction · 0.70

Tested by

no test coverage detected