Skip to main content
Glama
VisActor
by VisActor

generate_progress_chart

Create progress charts to visualize completion rates, proportional metrics, and normalized quantitative values between 0 and 1 using gauge, liquid, linear, or circular formats.

Instructions

Generates a progress chart for visualizing quantitative values normalized between 0 and 1. Ideal for representing progress, completion rates, or proportional metrics. The gauge chart and liquid chart currently only supports displaying data for a single dimension.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
outputNoChart output type. Defaults to 'image'.image
widthNoChart width. Optional, defaults to 500.
heightNoChart height. Optional, defaults to 500.
dataTableYesData for the progress chart, e.g., [{ category: 'category 01', value: 0.5 }].
chartTypeYes
colorFieldNoDimension field, Must exist in the data, required in linear_progress, circular_progress and gauge
valueFieldYesMeasure field with values in [0, 1]. Must exist in the data.
chartThemeNoChart theme. Optional, defaults to 'light'.
titleNoChart title text.
subTitleNoChart subtitle text.
titleOrientNoTitle position in the chart.
backgroundNoChart background color (hex). Optional, defaults to white.
colorsNoColor palette for chart elements.

Implementation Reference

  • The MCP CallToolRequest handler that executes 'generate_progress_chart' by identifying the 'progress' chart type from the tool name, validating arguments with the progress schema, invoking generateChartByType('progress', args), and formatting the response as text content (spec, image URL, or HTML URL).
    server.setRequestHandler(CallToolRequestSchema, async request => { const toolName = request.params.name; const chartType = Object.keys(Charts).find( key => (Charts as any)[key].tool.name === toolName ); if (!chartType) { throw new McpError( ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}.` ); } try { // Validate input using Zod before generating chart const args = request.params.arguments || {}; // Select the appropriate schema based on the chart type const schema = Charts[chartType as keyof typeof Charts].schema; if (schema) { const result = schema.safeParse(args); if (!result.success) { throw new McpError( ErrorCode.InvalidParams, `Invalid parameters: ${result.error.message}` ); } } const res = await generateChartByType(chartType, args); if (res && (res as any).spec) { return { content: [ { type: 'text', text: JSON.stringify((res as any).spec, null, 2), }, ], }; } if (res && (res as any).image) { return { content: [ { type: 'text', text: (res as any).image, }, ], }; } if (res && (res as any).html) { return { content: [ { type: 'text', text: (res as any).html, }, ], }; } return { content: [ { type: 'text', text: 'Failed to generate chart', }, ], }; } catch (error: any) { if (error instanceof McpError) { throw error; } throw new McpError( ErrorCode.InternalError, `Failed to generate chart: ${error?.message || 'Unknown error.'}` ); } });
  • Zod schema defining the input parameters for generate_progress_chart, including output format, dimensions, dataTable, chartType (linear_progress, circular_progress, gauge, liquid), valueField, styling options like theme, title, background, and colors.
    const schema = z.object({ output: ChartOutputSchema, width: WidthSchema, height: HeightSchema, dataTable: z .array(z.any()) .describe( "Data for the progress chart, e.g., [{ category: 'category 01', value: 0.5 }]." ) .nonempty({ message: "Data for the progress chart must not be empty.", }), chartType: z.enum([ "linear_progress", "circular_progress", "gauge", "liquid", ]), colorField: z .string() .optional() .describe( "Dimension field, Must exist in the data, required in linear_progress, circular_progress and gauge" ), valueField: ProgressFieldSchema, chartTheme: ThemeSchema, title: TitleTextSchema, subTitle: TitleSubTextSchema, titleOrient: TitleOrientSchema, background: BackgroundSchema, colors: ColorsSchema, });
  • Defines and exports the tool metadata for 'generate_progress_chart', including name, description, and JSON schema derived from Zod for MCP tool registration.
    const tool = { name: "generate_progress_chart", description: "Generates a progress chart for visualizing quantitative values normalized between 0 and 1. Ideal for representing progress, completion rates, or proportional metrics. The gauge chart and liquid chart currently only supports displaying data for a single dimension.", inputSchema: convertZodToJsonSchema(schema), }; export const progress = { schema, tool, };
  • src/server.ts:34-38 (registration)
    MCP ListToolsRequest handler that dynamically registers all chart tools, including generate_progress_chart, by collecting .tool objects from imported charts modules.
    server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: Object.values(Charts).map(chart => (chart as any).tool), }; });
  • Primary helper function invoked by the handler for 'progress' chartType; normalizes options, extracts fields/axes/title, generates VChart spec using generateChart from @visactor/generate-vchart (with sub chartType), and renders to image URL, HTML URL, or spec via external service.
    export async function generateChartByType(chartType: string, options: any) { const { title, subTitle, titleOrient, xAxisType, xAxisOrient, xAxisTitle, xAxisHasGrid, xAxisHasLabel, xAxisHasTick, yAxisType, yAxisOrient, yAxisTitle, yAxisHasGrid, yAxisHasLabel, yAxisHasTick, leftYAxisTitle, leftYAxisHasGrid, leftYAxisHasLabel, leftYAxisHasTick, rightYAxisTitle, rightYAxisHasGrid, rightYAxisHasLabel, rightYAxisHasTick, angleAxisTitle, angleAxisHasGrid, angleAxisHasLabel, angleAxisHasTick, angleAxisType, radiusAxisHasGrid, radiusAxisHasLabel, radiusAxisHasTick, radiusAxisType, radiusAxisTitle, output, width, height, ...res } = options; const opts = { ...res }; const titleObj = filterValidAttributes({ text: title, subText: subTitle, orient: titleOrient, }); const xAxisObj = filterValidAttributes({ type: xAxisType, orient: xAxisOrient, title: xAxisTitle, hasGrid: xAxisHasGrid, hasLabel: xAxisHasLabel, hasTick: xAxisHasTick, }); const yAxisObj = filterValidAttributes({ type: yAxisType, orient: yAxisOrient, title: yAxisTitle, hasGrid: yAxisHasGrid, hasLabel: yAxisHasLabel, hasTick: yAxisHasTick, }); const leftYAxisObj = filterValidAttributes({ title: leftYAxisTitle, hasGrid: leftYAxisHasGrid, hasLabel: leftYAxisHasLabel, hasTick: leftYAxisHasTick, }); const rightYAxisObj = filterValidAttributes({ title: rightYAxisTitle, hasGrid: rightYAxisHasGrid, hasLabel: rightYAxisHasLabel, hasTick: rightYAxisHasTick, }); const angleAxisObj = filterValidAttributes({ title: angleAxisTitle, hasGrid: angleAxisHasGrid, hasLabel: angleAxisHasLabel, hasTick: angleAxisHasTick, type: angleAxisType, }); const radiusAxisObj = filterValidAttributes({ hasGrid: radiusAxisHasGrid, hasLabel: radiusAxisHasLabel, hasTick: radiusAxisHasTick, type: radiusAxisType, title: radiusAxisTitle, }); const cell: Record<string, string> = {}; [ "xField", "yField", "colorField", "categoryField", "valueField", "wordField", "sizeField", "timeField", "sourceField", "targetField", "setsField", "radiusField", ].forEach((fieldName) => { if (isValid(options[fieldName])) { cell[fieldName.replace("Field", "")] = options[fieldName]; delete opts[fieldName]; } }); opts.cell = cell; if (!isEmpty(titleObj)) { opts.title = titleObj; } const axes = [ xAxisObj, yAxisObj, leftYAxisObj, rightYAxisObj, angleAxisObj, radiusAxisObj, ]; if (axes.some((axis) => !isEmpty(axis))) { opts.axes = axes.filter((axis) => !isEmpty(axis)); } const { spec } = generateChart(options.chartType ?? chartType, opts); if (!spec) { return null; } if (output === "spec") { if (isValid(width)) { spec.width = width; } if (isValid(height)) { spec.height = height; } return { spec: spec, }; } return gentrateChartImageOrHtml(output, spec, { width: `${width ?? 500}px`, height: `${height ?? 500}px`, }); }

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/VisActor/vchart-mcp-server'

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