Here is my code for WordCloud Chart and i need to give a background based on frequency check with threshold. Same as text fill color i want to give a background dynamically but not able to get the dataItem as always get the undefined in dataItem so comparison is not applying.
import React, { useEffect, useRef } from "react";
import * as am5 from "@amcharts/amcharts5";
import * as am5wc from "@amcharts/amcharts5/wc";
import am5themes_Animated from "@amcharts/amcharts5/themes/Animated";
interface DataPoint {
name: string;
frequency: number;
}
interface WordChartProps {
data: DataPoint[];
}
const WordChart: React.FC<WordChartProps> = ({ data = [] }) => {
const chartRef = useRef<HTMLDivElement>(null);
const dataSet = [
{ name: "Pricing", frequency: 100 },
{ name: "Availability", frequency: 50 },
{ name: "Online", frequency: 20 },
{ name: "Process", frequency: 10 },
{ name: "Work", frequency: 30 },
{ name: "Pricing", frequency: 100 },
{ name: "Availability", frequency: 50 },
{ name: "Online", frequency: 20 },
{ name: "Process", frequency: 10 },
{ name: "Work", frequency: 30 },
{ name: "Pricing", frequency: 100 },
{ name: "Availability", frequency: 50 },
{ name: "Online", frequency: 20 },
{ name: "Process", frequency: 10 },
{ name: "Work", frequency: 30 },
{ name: "Pricing", frequency: 100 },
{ name: "Availability", frequency: 50 },
{ name: "Online", frequency: 20 },
{ name: "Process", frequency: 10 },
{ name: "Work", frequency: 30 },
]
dataSet.sort((a, b) => b.frequency - a.frequency);
const groupSize = Math.ceil(dataSet.length / 3);
const highThreshold = dataSet[groupSize - 1]?.frequency || 0; // Lowest frequency in "high"
const mediumThreshold = dataSet[groupSize * 2 - 1]?.frequency || 0; // Lowest frequency in "medium"
useEffect(() => {
if (!chartRef.current) return;
const root = am5.Root.new(chartRef.current);
root.setThemes([am5themes_Animated.new(root)]);
const series = root.container.children.push(
am5wc.WordCloud.new(root, {
maxFontSize: am5.percent(12),
minFontSize: am5.percent(5),
categoryField: "name",
valueField: "frequency",
rotation: 0,
centerX: am5.percent(0),
centerY: am5.percent(0),
angles: [0],
})
);
series.labels.template.setAll({
paddingTop: 10,
paddingBottom: 10,
paddingLeft: 10,
paddingRight: 10,
fontFamily: "Roboto",
fontSize: "14px",
fontStyle: "normal",
fontWeight: "400",
textAlign: "center",
tooltipText: "{category}: {value}"
});
// Dynamically setting the `fill` color for each label
series.labels.template.adapters.add("fill", (fill, target) => {
const dataItem = target.dataItem; // Access the associated data item
const frequency: any = dataItem?.get("value"); // Retrieve the frequency field from data
if (frequency >= highThreshold) {
return am5.color(0x52a3ff);
} else if (frequency >= mediumThreshold) {
return am5.color(0x7fb5f2);
} else {
return am5.color(0x5e93c2);
}
});
series.labels.template.setup = function (label) {
let backgroundColor;
let borderColor;
const dataItem = label.dataItem;
console.log("dataItem Background", dataItem);
const frequency = dataItem?.get("frequency");
console.log("background frequency", frequency)
if (frequency >= highThreshold) {
backgroundColor = am5.color(0X52A3FF);
} else if (frequency >= mediumThreshold) {
backgroundColor = am5.color(0xF4F5F8);
} else {
// backgroundColor = am5.color(0xffffff);
backgroundColor = am5.color(0X52A3FF);
}
backgroundColor = am5.color(0xffffff);
borderColor = am5.color(0x52a3ff);
label.set(
"background",
am5.RoundedRectangle.new(root, {
cornerRadiusBL: 10,
cornerRadiusBR: 10,
cornerRadiusTL: 10,
cornerRadiusTR: 10,
fill: backgroundColor,
fillOpacity: 1,
stroke: borderColor,
strokeWidth: 1,
marginTop: 15,
marginBottom: 15,
marginLeft: 15,
marginRight: 15,
})
);
};
series.data.setAll(dataSet);
return () => {
root.dispose();
};
}, []);
return <div ref={chartRef} style={{ width: "100%", height: "300px" }} />;
};
export default WordChart;
Here i'm not getting the dataItem:
series.labels.template.setup = function (label) {
let backgroundColor;
let borderColor;
const dataItem = label.dataItem;
console.log("dataItem Background", dataItem);
const frequency = dataItem?.get("frequency");
console.log("background frequency", frequency)
Thank you in advance for the help!
Now i'm able to change the backgroundcolor and borderColor accroding to dataItem based on threshold. Here is the code fo
series.labels.template.setup = function (label) {
let backgroundColor = am5.color(0xffffff);
let borderColor = am5.color(0x52a3ff);
label.set(
"background",
am5.RoundedRectangle.new(root, {
cornerRadiusBL: 20,
cornerRadiusBR: 20,
cornerRadiusTL: 20,
cornerRadiusTR: 20,
marginTop: 15,
marginBottom: 15,
marginLeft: 15,
marginRight: 15,
})
);
label.events.on("dataitemchanged", function (ev) {
var label = ev.target;
const frequency = label.dataItem?.dataContext?.frequency; // Retrieve the frequency field from data
if (frequency >= highThreshold) {
backgroundColor = am5.color(0x52A3FF);
borderColor = am5.color(0xFFFFFF)
} else if (frequency >= mediumThreshold) {
backgroundColor = am5.color(0xDBECFF);
borderColor = am5.color(0xFFFFFF)
} else {
backgroundColor = am5.color(0xFFFFFF);
borderColor = am5.color(0x7FB5F2)
}
label.set(
"background",
am5.RoundedRectangle.new(root, {
fill: backgroundColor,
fillOpacity: 1,
stroke: borderColor,
strokeWidth: 1,
})
);
});
};