Skip to main content
Glama

generate_boxplot_chart

Create boxplot charts to visualize and compare data distributions across categories. Customize axis titles, themes, dimensions, and output formats (png, svg, option) for detailed statistical analysis.

Instructions

Generate a boxplot chart to show data for statistical summaries among different categories, such as, comparing the distribution of data points across categories.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
axisXTitleNoSet the x-axis title of chart.
axisYTitleNoSet the y-axis title of chart.
dataYesData for boxplot chart, such as, [{ category: 'Category A', value: 10 }, { category: 'Category B', value: 20, group: 'Group A' }].
heightNoSet the height of the chart, default is 600px.
outputTypeNoThe 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
themeNoSet the theme for the chart, optional, default is 'default'.default
titleNoSet the title of the chart.
widthNoSet the width of the chart, default is 800px.

Implementation Reference

  • The 'run' async function executes the tool logic: groups data by category/group, calculates boxplot statistics [min, Q1, median, Q3, max], builds ECharts configuration for boxplot series with axes and styling, and generates the output image or option using generateChartImage.
    run: async (params: { axisXTitle?: string; axisYTitle?: string; data: Array<{ category: string; value: number; group?: string }>; height: number; theme?: "default" | "dark"; title?: string; width: number; outputType?: "png" | "svg" | "option"; }) => { const { axisXTitle, axisYTitle, data, height, theme, title, width, outputType, } = params; // Group data by category and optional group const hasGroups = data.some((item) => item.group); let categories: string[] = []; const boxplotData: { name: string; value: number[] }[] = []; if (hasGroups) { // Group by category and group const groupMap = new Map< string, Array<{ category: string; value: number }> >(); const categorySet = new Set<string>(); for (const item of data) { const groupName = item.group || "Default"; const key = `${item.category}_${groupName}`; if (!groupMap.has(key)) { groupMap.set(key, []); } groupMap.get(key)?.push(item); categorySet.add(item.category); } categories = Array.from(categorySet).sort(); // Calculate boxplot statistics for each group groupMap.forEach((values, key) => { const [category, group] = key.split("_"); const sortedValues = values.map((v) => v.value).sort((a, b) => a - b); const boxplotStats = calculateBoxplotStats(sortedValues); boxplotData.push({ name: `${category}-${group}`, value: boxplotStats, }); }); } else { // Group by category only const categoryMap = new Map<string, number[]>(); for (const item of data) { if (!categoryMap.has(item.category)) { categoryMap.set(item.category, []); } categoryMap.get(item.category)?.push(item.value); } categories = Array.from(categoryMap.keys()).sort(); // Calculate boxplot statistics for each category for (const category of categories) { const values = categoryMap.get(category)?.sort((a, b) => a - b) || []; const boxplotStats = calculateBoxplotStats(values); boxplotData.push({ name: category, value: boxplotStats, }); } } const series: Array<SeriesOption> = [ { type: "boxplot", data: boxplotData, itemStyle: { borderWidth: 2, }, emphasis: { itemStyle: { borderWidth: 3, shadowBlur: 5, shadowColor: "rgba(0, 0, 0, 0.3)", }, }, }, ]; const echartsOption: EChartsOption = { series, title: { left: "center", text: title, }, tooltip: { trigger: "item", }, xAxis: { type: "category", data: categories, name: axisXTitle, boundaryGap: true, nameGap: 30, splitArea: { show: false, }, splitLine: { show: false, }, }, yAxis: { type: "value", name: axisYTitle, splitArea: { show: true, }, }, }; // Helper function to calculate boxplot statistics function calculateBoxplotStats(values: number[]): number[] { const len = values.length; const min = values[0]; const max = values[len - 1]; const median = len % 2 === 0 ? (values[len / 2 - 1] + values[len / 2]) / 2 : values[Math.floor(len / 2)]; const q1Index = Math.floor(len / 4); const q3Index = Math.floor((3 * len) / 4); const Q1 = values[q1Index]; const Q3 = values[q3Index]; return [min, Q1, median, Q3, max]; } return await generateChartImage( echartsOption, width, height, theme, outputType, "generate_boxplot_chart", ); },
  • Zod schema defining the input parameters for the tool, including axis titles, data array (with category, value, optional group), dimensions, theme, title, and output type.
    inputSchema: z.object({ axisXTitle: AxisXTitleSchema, axisYTitle: AxisYTitleSchema, data: z .array(data) .describe( "Data for boxplot chart, such as, [{ category: 'Category A', value: 10 }, { category: 'Category B', value: 20, group: 'Group A' }].", ) .nonempty({ message: "Boxplot chart data cannot be empty." }), height: HeightSchema, theme: ThemeSchema, title: TitleSchema, width: WidthSchema, outputType: OutputTypeSchema, }),
  • The 'tools' array collects all chart generation tools, including generateBoxplotChartTool, for export and use in the MCP server.
    export const tools = [ generateEChartsTool, generateLineChartTool, generateBarChartTool, generatePieChartTool, generateRadarChartTool, generateScatterChartTool, generateSankeyChartTool, generateFunnelChartTool, generateGaugeChartTool, generateTreemapChartTool, generateSunburstChartTool, generateHeatmapChartTool, generateCandlestickChartTool, generateBoxplotChartTool, generateGraphChartTool, generateParallelChartTool, generateTreeChartTool, ];
  • src/index.ts:28-32 (registration)
    Loop that registers each tool from the 'tools' array to the MCP server using server.tool(name, description, inputSchema.shape, run).
    for (const tool of tools) { const { name, description, inputSchema, run } = tool; // biome-ignore lint/suspicious/noExplicitAny: <explanation> server.tool(name, description, inputSchema.shape, run as any); }
  • Helper function inside the run handler that computes boxplot statistics from sorted values: min, Q1 (25th percentile), median, Q3 (75th percentile), max.
    function calculateBoxplotStats(values: number[]): number[] { const len = values.length; const min = values[0]; const max = values[len - 1]; const median = len % 2 === 0 ? (values[len / 2 - 1] + values[len / 2]) / 2 : values[Math.floor(len / 2)]; const q1Index = Math.floor(len / 4); const q3Index = Math.floor((3 * len) / 4); const Q1 = values[q1Index]; const Q3 = values[q3Index]; return [min, Q1, median, Q3, max]; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/hustcc/mcp-echarts'

If you have feedback or need assistance with the MCP directory API, please join our Discord server