Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .skills/chart-visualization/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: chart-visualization
description: This skill should be used when the user wants to visualize data. It intelligently selects the most suitable chart type from 25 available options, extracts parameters based on detailed specifications, and generates a chart image using a Python script.
description: This skill should be used when the user wants to visualize data. It intelligently selects the most suitable chart type from 26 available options, extracts parameters based on detailed specifications, and generates a chart image using a Python script.
---

# Chart Visualization Skill
Expand Down Expand Up @@ -29,6 +29,7 @@ Analyze the user's data features to determine the most appropriate chart type. U
- `generate_network_graph`: Complex node-edge relationships.
- `generate_fishbone_diagram`: Cause-effect analysis.
- `generate_flow_diagram`: Process flow.
- `generate_spreadsheet`: Tabular data or pivot tables for structured data display and cross-tabulation.

### 2. Parameter Extraction
Once a chart type is selected, read the corresponding file in the `references/` directory (e.g., `references/generate_line_chart.md`) to identify the required and optional fields.
Expand Down
24 changes: 24 additions & 0 deletions .skills/chart-visualization/references/generate_spreadsheet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# generate_spreadsheet — 电子表格/数据透视表

## 功能概述
生成电子表格或数据透视表,用于展示结构化的表格数据。当提供 `rows` 或 `values` 字段时,渲染为数据透视表(交叉表);否则渲染为常规表格。适合展示结构化数据、跨类别比较值以及创建数据汇总。

## 输入字段
### 必填
- `data`: array<object>,表格数据数组,每个对象代表一行。键是列名,值可以是字符串、数字、null 或 undefined。例如:`[{ name: 'John', age: 30 }, { name: 'Jane', age: 25 }]`。

### 可选
- `rows`: array<string>,数据透视表的行标题字段。当提供 `rows` 或 `values` 时,电子表格将渲染为数据透视表。
- `columns`: array<string>,列标题字段,用于指定列的顺序。对于常规表格,这决定列的顺序;对于数据透视表,用于列分组。
- `values`: array<string>,数据透视表的值字段。当提供 `rows` 或 `values` 时,电子表格将渲染为数据透视表。
- `theme`: string,默认 `default`,可选 `default`/`dark`。
- `width`: number,默认 `600`。
- `height`: number,默认 `400`。

## 使用建议
- 对于常规表格,只需提供 `data` 和可选的 `columns` 来控制列的顺序。
- 对于数据透视表(交叉表),提供 `rows` 用于行分组,`columns` 用于列分组,`values` 用于聚合的值字段。
- 确保数据中的字段名与 `rows`、`columns`、`values` 中指定的字段名一致。

## 返回结果
- 返回电子表格/数据透视表图片 URL,并附 `_meta.spec` 供后续编辑。
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ This is a TypeScript-based MCP server that provides chart generation capabilitie

## ✨ Features

Now 25+ charts supported.
Now 26+ charts supported.

<img width="768" alt="mcp-server-chart preview" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*IyIRQIQHyKYAAAAAgCAAAAgAemJ7AQ/fmt.avif" />

Expand Down Expand Up @@ -54,6 +54,7 @@ Now 25+ charts supported.
1. `generate_venn_chart`: Generate a `venn` diagram, used to display relationships between sets, including intersections, unions, and differences.
1. `generate_violin_chart`: Generate a `violin` plot, used to display the distribution of data, combining features of boxplots and density plots to provide a more detailed view of the data distribution.
1. `generate_word_cloud_chart`: Generate a `word-cloud`, used to display the frequency of words in textual data, with font sizes indicating the frequency of each word.
1. `generate_spreadsheet`: Generate a `spreadsheet` or pivot table for displaying tabular data. When 'rows' or 'values' fields are provided, it renders as a pivot table (cross-tabulation); otherwise, it renders as a regular table.

> [!NOTE]
> The above geographic visualization chart generation tool uses [AMap service](https://lbs.amap.com/) and currently only supports map generation within China.
Expand Down
1 change: 1 addition & 0 deletions __tests__/api.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ describe("sdk API", () => {
"violin",
"waterfall",
"word-cloud",
"spreadsheet",
]);
});

Expand Down
1 change: 1 addition & 0 deletions __tests__/charts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ export { default as venn } from "./venn.json";
export { default as violin } from "./violin.json";
export { default as waterfall } from "./waterfall.json";
export { default as "word-cloud" } from "./word-cloud.json";
export { default as spreadsheet } from "./spreadsheet.json";
76 changes: 76 additions & 0 deletions __tests__/charts/spreadsheet.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{
"name": "generate_spreadsheet",
"description": "Generate a spreadsheet or pivot table for displaying tabular data. When 'rows' or 'values' fields are provided, it renders as a pivot table (cross-tabulation); otherwise, it renders as a regular table. Useful for displaying structured data, comparing values across categories, and creating data summaries.",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
},
{
"type": "null"
},
{
"not": {}
}
]
}
},
"minItems": 1,
"description": "Data for spreadsheet, an array of objects where each object represents a row. Keys are column names and values can be string, number, null, or undefined. Such as, [{ name: 'John', age: 30 }, { name: 'Jane', age: 25 }]."
},
"rows": {
"type": "array",
"items": {
"type": "string"
},
"description": "Row header fields for pivot table. When 'rows' or 'values' is provided, the spreadsheet will be rendered as a pivot table."
},
"columns": {
"type": "array",
"items": {
"type": "string"
},
"description": "Column header fields, used to specify the order of columns. For regular tables, this determines column order; for pivot tables, this is used for column grouping."
},
"values": {
"type": "array",
"items": {
"type": "string"
},
"description": "Value fields for pivot table. When 'rows' or 'values' is provided, the spreadsheet will be rendered as a pivot table."
},
"theme": {
"type": "string",
"enum": ["default", "dark"],
"default": "default",
"description": "Set the theme for the spreadsheet, optional, default is 'default'."
},
"width": {
"type": "number",
"default": 600,
"description": "Set the width of chart, default is 600."
},
"height": {
"type": "number",
"default": 400,
"description": "Set the height of chart, default is 400."
}
},
"required": ["data"]
},
"annotations": {
"title": "Generate Spreadsheet",
"readOnlyHint": true
}
}
6 changes: 3 additions & 3 deletions __tests__/server.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe("MCP Server", () => {
await client.connect(transport);
const listTools = await client.listTools();

expect(listTools.tools.length).toBe(26);
expect(listTools.tools.length).toBe(27);

const spec = {
type: "line",
Expand Down Expand Up @@ -82,7 +82,7 @@ describe("MCP Server", () => {
await client.connect(transport);
const listTools = await client.listTools();

expect(listTools.tools.length).toBe(26);
expect(listTools.tools.length).toBe(27);

const spec = {
type: "line",
Expand Down Expand Up @@ -129,7 +129,7 @@ describe("MCP Server", () => {
await client.connect(transport);
const listTools = await client.listTools();

expect(listTools.tools.length).toBe(26);
expect(listTools.tools.length).toBe(27);

const spec = {
type: "line",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"@vitest/coverage-v8": "3.2.4",
"husky": "^9.1.7",
"lint-staged": "^15.5.2",
"ts-node": "^10.9.2",
Comment thread
hustcc marked this conversation as resolved.
"tsc-alias": "^1.8.16",
"typescript": "^5.8.3",
"vitest": "^3.1.4"
Expand Down
1 change: 1 addition & 0 deletions src/charts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ export { venn } from "./venn";
export { violin } from "./violin";
export { waterfall } from "./waterfall";
export { wordCloud as "word-cloud" } from "./word-cloud";
export { spreadsheet } from "./spreadsheet";
66 changes: 66 additions & 0 deletions src/charts/spreadsheet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { z } from "zod";
import { zodToJsonSchema } from "../utils";
import { HeightSchema, WidthSchema } from "./base";

// Spreadsheet data schema - flexible record type
const data = z.record(
z.string(),
z.union([z.string(), z.number(), z.null(), z.undefined()]),
);
Comment thread
Alexzjt marked this conversation as resolved.

// Spreadsheet theme schema
const SpreadsheetThemeSchema = z
.enum(["default", "dark"])
.optional()
.default("default")
.describe(
"Set the theme for the spreadsheet, optional, default is 'default'.",
);

// Spreadsheet input schema
const schema = {
data: z
.array(data)
.describe(
"Data for spreadsheet, an array of objects where each object represents a row. Keys are column names and values can be string, number, null, or undefined. Such as, [{ name: 'John', age: 30 }, { name: 'Jane', age: 25 }].",
)
Comment thread
Alexzjt marked this conversation as resolved.
.nonempty({ message: "Spreadsheet data cannot be empty." }),
rows: z
.array(z.string())
.optional()
.describe(
"Row header fields for pivot table. When 'rows' or 'values' is provided, the spreadsheet will be rendered as a pivot table.",
),
columns: z
.array(z.string())
.optional()
.describe(
"Column header fields, used to specify the order of columns. For regular tables, this determines column order; for pivot tables, this is used for column grouping.",
),
values: z
.array(z.string())
.optional()
.describe(
"Value fields for pivot table. When 'rows' or 'values' is provided, the spreadsheet will be rendered as a pivot table.",
),
theme: SpreadsheetThemeSchema,
width: WidthSchema,
height: HeightSchema,
};

// Spreadsheet tool descriptor
const tool = {
name: "generate_spreadsheet",
description:
"Generate a spreadsheet or pivot table for displaying tabular data. When 'rows' or 'values' fields are provided, it renders as a pivot table (cross-tabulation); otherwise, it renders as a regular table. Useful for displaying structured data, comparing values across categories, and creating data summaries.",
inputSchema: zodToJsonSchema(schema),
annotations: {
title: "Generate Spreadsheet",
readOnlyHint: true,
},
};

export const spreadsheet = {
schema,
tool,
};
1 change: 1 addition & 0 deletions src/utils/callTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const CHART_TYPE_MAP = {
generate_violin_chart: "violin",
generate_waterfall_chart: "waterfall",
generate_word_cloud_chart: "word-cloud",
generate_spreadsheet: "spreadsheet",
} as const;

/**
Expand Down