generate_radar_chart
Visualize multidimensional data in a radar chart to compare multiple entities across four or more dimensions, such as product features or performance metrics, using customizable themes and output formats.
Instructions
Generate a radar chart to display multidimensional data (four dimensions or more), such as, evaluate Huawei and Apple phones in terms of five dimensions: ease of use, functionality, camera, benchmark scores, and battery life.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| data | Yes | Data for radar chart, such as, [{ name: 'Design', value: 70 }, { name: 'Performance', value: 85 }] or [{ name: 'Design', value: 70, group: 'iPhone' }]. | |
| height | No | Set the height of the chart, default is 600px. | |
| outputType | No | The output type of the diagram. Can be 'png', 'svg' or 'option'. Default is 'png', 'png' will return the rendered PNG image, 'svg' will return the rendered SVG string, and 'option' will return the valid ECharts option. | png |
| theme | No | Set the theme for the chart, optional, default is 'default'. | default |
| title | No | Set the title of the chart. | |
| width | No | Set the width of the chart, default is 800px. |
Implementation Reference
- src/tools/radar.ts:41-176 (handler)The 'run' function executes the tool logic: processes input data into radar dimensions and series (handling single or multi-group data), configures ECharts radar chart options with unified max values and styling, then generates the image using shared utility.run: async (params: { data: Array<{ name: string; value: number; group?: string }>; height: number; theme?: "default" | "dark"; title?: string; width: number; outputType?: "png" | "svg" | "option"; }) => { const { data, height, theme, title, width, outputType } = params; // Check if data has group field for multiple series const hasGroups = data.some((item) => item.group); // Collect all unique dimensions const dimensionSet = new Set<string>(); for (const item of data) { dimensionSet.add(item.name); } const dimensions = Array.from(dimensionSet).sort(); // Create radar indicator configuration // Calculate the maximum value for all dimensions, then use the same max value to avoid alignTicks warning const allValues = data.map((item) => item.value); const globalMaxValue = Math.max(...allValues); const unifiedMax = Math.ceil((globalMaxValue * 1.2) / 10) * 10; const indicator = dimensions.map((name) => ({ name, max: unifiedMax, })); let series: Array<SeriesOption> = []; if (hasGroups) { // Handle multiple series data (grouped) const groupMap = new Map< string, Array<{ name: string; value: number }> >(); // Group data by group field for (const item of data) { const groupName = item.group || "Default"; if (!groupMap.has(groupName)) { groupMap.set(groupName, []); } const groupData = groupMap.get(groupName); if (groupData) { groupData.push({ name: item.name, value: item.value }); } } // Create series data for each group const seriesData = Array.from(groupMap.entries()).map( ([groupName, groupData]) => { // Create a map for quick lookup const dataMap = new Map(groupData.map((d) => [d.name, d.value])); // Fill values for all dimensions (0 for missing data) const values = dimensions.map( (dimension) => dataMap.get(dimension) ?? 0, ); return { name: groupName, value: values, }; }, ); series = [ { data: seriesData, type: "radar", }, ]; } else { // Handle single series data const dataMap = new Map(data.map((d) => [d.name, d.value])); const values = dimensions.map((dimension) => dataMap.get(dimension) ?? 0); series = [ { data: [ { value: values, name: title || "Data", }, ], type: "radar", }, ]; } const echartsOption: EChartsOption = { legend: hasGroups ? { left: "center", orient: "horizontal", bottom: "5%", } : undefined, radar: { indicator, radius: "60%", splitNumber: 4, axisName: { formatter: "{value}", color: "#666", }, splitArea: { areaStyle: { color: ["rgba(250, 250, 250, 0.3)", "rgba(200, 200, 200, 0.3)"], }, }, }, series, title: { left: "center", text: title, top: "5%", }, tooltip: { trigger: "item", }, }; return await generateChartImage( echartsOption, width, height, theme, outputType, "generate_radar_chart", ); },
- src/tools/radar.ts:28-40 (schema)Zod schema for tool inputs, including radar data array, dimensions (height, width), theme, title, and output type.inputSchema: z.object({ data: z .array(data) .describe( "Data for radar chart, such as, [{ name: 'Design', value: 70 }, { name: 'Performance', value: 85 }] or [{ name: 'Design', value: 70, group: 'iPhone' }].", ) .nonempty({ message: "Radar chart data cannot be empty." }), height: HeightSchema, theme: ThemeSchema, title: TitleSchema, width: WidthSchema, outputType: OutputTypeSchema, }),
- src/tools/radar.ts:13-22 (schema)Zod schema for individual data points in the radar chart (dimension name, value, optional group for multi-series).const data = z.object({ name: z.string().describe("Dimension name, such as 'Design'."), value: z.number().describe("Value of the dimension, such as 70."), group: z .string() .optional() .describe( "Group name for multiple series, used for comparing different entities", ), });
- src/tools/index.ts:19-37 (registration)The generateRadarChartTool is registered by including it in the exported 'tools' array alongside other chart tools.export const tools = [ generateEChartsTool, generateLineChartTool, generateBarChartTool, generatePieChartTool, generateRadarChartTool, generateScatterChartTool, generateSankeyChartTool, generateFunnelChartTool, generateGaugeChartTool, generateTreemapChartTool, generateSunburstChartTool, generateHeatmapChartTool, generateCandlestickChartTool, generateBoxplotChartTool, generateGraphChartTool, generateParallelChartTool, generateTreeChartTool, ];