@mozaic-ds/chart
Version:
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
92 lines (78 loc) • 2.42 kB
text/typescript
import type { Chart, RadialLinearScale } from 'chart.js';
export function drawLabels(chart: Chart, props: any) {
const ctx = chart.ctx;
const scale = chart.scales.r as RadialLinearScale;
const labels = chart.data.labels as string[][];
if (!ctx || !scale || !labels) {
return;
}
ctx.save();
labels.forEach((label: string[], index: number) => {
const angle = (scale.getIndexAngle(index) - Math.PI / 2) % (2 * Math.PI);
const position = scale.getPointPositionForValue(index, scale.max);
ctx.textAlign =
angle <= Math.PI / 2 || angle > (3 * Math.PI) / 2 ? 'left' : 'right';
let xOffset = angle <= Math.PI / 2 || angle > (3 * Math.PI) / 2 ? 15 : -15;
let yOffset;
//top or bottom labels
if (angle < 0 || angle > Math.PI) {
yOffset = -15;
} else {
yOffset = 15;
}
//bottom labels
if (angle > Math.PI / 4 && angle < (3 * Math.PI) / 4) {
yOffset *= 3;
}
//top labels left and right
if (angle < -Math.PI / 4 || angle > (5 * Math.PI) / 4) {
yOffset *= 3;
xOffset = 0;
}
// full top label
if (angle > (11 * Math.PI) / 8 || angle < (-3 * Math.PI) / 8) {
ctx.textAlign = 'center';
}
const yPos = position.y + (yOffset * (label.length - 1)) / 2;
ctx.font = '12px Arial';
label.forEach((text, i) => {
const color =
i === label.length - 1 ? buildColorArray(props)[index] : '#000000';
ctx.fillStyle = color;
const x = position.x + xOffset;
const y = yPos + 15 * i;
ctx.fillText(text, x, y);
});
});
ctx.restore();
}
const buildColorArray = (props: any): string[] => {
return props.datasets[0].areaData.map((x: { color: string }) => {
switch (x.color) {
case 'red':
return '#C61112';
case 'green':
return '#46A610';
default:
return '#000000';
}
});
};
export function splitLabelIfTooLong(axisLabel: string, buildValue: string) {
const radarLimitLabelLength = 7;
if (
axisLabel.length > radarLimitLabelLength &&
axisLabel.includes(' ', radarLimitLabelLength)
) {
const indexOfFirstSpaceAfterLimit: number = axisLabel.indexOf(
' ',
radarLimitLabelLength
);
return [
axisLabel.substring(0, indexOfFirstSpaceAfterLimit),
axisLabel.substring(indexOfFirstSpaceAfterLimit),
buildValue
];
}
return [axisLabel, buildValue];
}