Skip to content

Commit 70d7df3

Browse files
committed
feat: add liquid, funnel, organization-chart
1 parent d62244f commit 70d7df3

10 files changed

Lines changed: 307 additions & 24 deletions

File tree

__tests__/api.spec.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { afterEach, describe, expect, it } from "vitest";
1+
import { describe, expect, it } from "vitest";
22
import * as API from "../src/sdk";
33

44
describe("sdk API", () => {
@@ -12,18 +12,21 @@ describe("sdk API", () => {
1212
"area",
1313
"bar",
1414
"column",
15+
"dual-axes",
1516
"fishbone-diagram",
1617
"flow-diagram",
18+
"funnel",
1719
"histogram",
1820
"line",
21+
"liquid",
1922
"mind-map",
2023
"network-graph",
24+
"organization-chart",
2125
"pie",
2226
"radar",
2327
"scatter",
2428
"treemap",
2529
"word-cloud",
26-
"dual-axes",
2730
]);
2831
});
2932

__tests__/charts/charts.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ describe("charts schema check", () => {
99
// Create a separate test case for each chart
1010
for (const chartName of chartNames) {
1111
it(`should check schema for ${chartName} chart`, () => {
12-
const schema = actualCharts[chartName].tool.inputSchema;
12+
const schema = actualCharts[chartName].tool;
1313
const rightChart = expectedCharts[chartName];
1414

15-
expect(schema).toEqual(rightChart.inputSchema);
15+
expect(schema).toEqual(rightChart);
1616
});
1717
}
1818
});

__tests__/charts/funnel.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"name": "generate_funnel_chart",
3+
"description": "Generate a funnel chart to visualize the progressive reduction of data as it passes through stages, such as, the conversion rates of users from visiting a website to completing a purchase.",
4+
"inputSchema": {
5+
"$schema": "http://json-schema.org/draft-07/schema#",
6+
"properties": {
7+
"data": {
8+
"description": "Data for funnel chart, such as, [{ category: '浏览网站', value: 50000 }, { category: '放入购物车', value: 35000 }, { category: '生成订单', value: 25000 }, { category: '支付订单', value: 15000 }, { category: '完成交易', value: 8000 }].",
9+
"items": {
10+
"properties": {
11+
"category": {
12+
"type": "string"
13+
},
14+
"value": {
15+
"type": "number"
16+
}
17+
},
18+
"required": ["category", "value"],
19+
"type": "object"
20+
},
21+
"minItems": 1,
22+
"type": "array"
23+
},
24+
"height": {
25+
"default": 400,
26+
"description": "Set the height of chart, default is 400.",
27+
"type": "number"
28+
},
29+
"theme": {
30+
"default": "default",
31+
"description": "Set the theme for the chart, optional, default is 'default'.",
32+
"enum": ["default", "academy"],
33+
"type": "string"
34+
},
35+
"title": {
36+
"default": "",
37+
"description": "Set the title of chart.",
38+
"type": "string"
39+
},
40+
"width": {
41+
"default": 600,
42+
"description": "Set the width of chart, default is 600.",
43+
"type": "number"
44+
}
45+
},
46+
"required": ["data"],
47+
"type": "object"
48+
}
49+
}

__tests__/charts/index.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1-
export { default as line } from "./line.json";
2-
export { default as column } from "./column.json";
3-
export { default as pie } from "./pie.json";
41
export { default as area } from "./area.json";
52
export { default as bar } from "./bar.json";
6-
export { default as histogram } from "./histogram.json";
7-
export { default as scatter } from "./scatter.json";
8-
export { default as "word-cloud" } from "./word-cloud.json";
9-
export { default as radar } from "./radar.json";
10-
export { default as treemap } from "./treemap.json";
3+
export { default as column } from "./column.json";
114
export { default as "dual-axes" } from "./dual-axes.json";
5+
export { default as "fishbone-diagram" } from "./fishbone-diagram.json";
6+
export { default as "flow-diagram" } from "./flow-diagram.json";
7+
export { default as funnel } from "./funnel.json";
8+
export { default as histogram } from "./histogram.json";
9+
export { default as line } from "./line.json";
10+
export { default as liquid } from "./liquid.json";
1211
export { default as "mind-map" } from "./mind-map.json";
1312
export { default as "network-graph" } from "./network-graph.json";
14-
export { default as "flow-diagram" } from "./flow-diagram.json";
15-
export { default as "fishbone-diagram" } from "./fishbone-diagram.json";
13+
export { default as "organization-chart" } from "./organization-chart.json";
14+
export { default as pie } from "./pie.json";
15+
export { default as radar } from "./radar.json";
16+
export { default as scatter } from "./scatter.json";
17+
export { default as treemap } from "./treemap.json";
18+
export { default as "word-cloud" } from "./word-cloud.json";

__tests__/charts/liquid.json

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "generate_liquid_chart",
3+
"description": "Generate a liquid chart to visualize a single value as a percentage, such as, the current occupancy rate of a reservoir or the completion percentage of a project.",
4+
"inputSchema": {
5+
"type": "object",
6+
"properties": {
7+
"data": {
8+
"type": "number",
9+
"minimum": 0,
10+
"maximum": 1,
11+
"description": "The percentage value to display in the liquid chart, should be a number between 0 and 1, where 1 represents 100%. For example, 0.75 represents 75%."
12+
},
13+
"shape": {
14+
"type": "string",
15+
"enum": ["circle", "rect", "pin", "triangle"],
16+
"default": "circle",
17+
"description": "The shape of the liquid chart, can be 'circle', 'rect', 'pin', or 'triangle'. Default is 'circle'."
18+
},
19+
"theme": {
20+
"type": "string",
21+
"enum": ["default", "academy"],
22+
"default": "default",
23+
"description": "Set the theme for the chart, optional, default is 'default'."
24+
},
25+
"width": {
26+
"type": "number",
27+
"default": 600,
28+
"description": "Set the width of chart, default is 600."
29+
},
30+
"height": {
31+
"type": "number",
32+
"default": 400,
33+
"description": "Set the height of chart, default is 400."
34+
},
35+
"title": {
36+
"type": "string",
37+
"default": "",
38+
"description": "Set the title of chart."
39+
}
40+
},
41+
"required": ["data"],
42+
"$schema": "http://json-schema.org/draft-07/schema#"
43+
}
44+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
{
2+
"name": "generate_organization_chart",
3+
"description": "Generate an organization chart to visualize the hierarchical structure of an organization, such as, a diagram showing the relationship between a CEO and their direct reports.",
4+
"inputSchema": {
5+
"type": "object",
6+
"properties": {
7+
"data": {
8+
"type": "object",
9+
"properties": {
10+
"name": {
11+
"type": "string"
12+
},
13+
"description": {
14+
"type": "string"
15+
},
16+
"children": {
17+
"type": "array",
18+
"items": {
19+
"type": "object",
20+
"properties": {
21+
"name": {
22+
"type": "string"
23+
},
24+
"description": {
25+
"type": "string"
26+
},
27+
"children": {
28+
"type": "array",
29+
"items": {
30+
"$ref": "#/properties/data/properties/children/items"
31+
}
32+
}
33+
},
34+
"required": ["name"]
35+
}
36+
}
37+
},
38+
"required": ["name"],
39+
"description": "Data for organization chart, such as, { name: 'CEO', description: 'Chief Executive Officer', children: [{ name: 'CTO', description: 'Chief Technology Officer', children: [{ name: 'Dev Manager', description: 'Development Manager' }] }] }."
40+
},
41+
"orient": {
42+
"type": "string",
43+
"enum": ["horizontal", "vertical"],
44+
"default": "vertical",
45+
"description": "Orientation of the organization chart, either horizontal or vertical, default is vertical."
46+
},
47+
"theme": {
48+
"type": "string",
49+
"enum": ["default", "academy"],
50+
"default": "default",
51+
"description": "Set the theme for the chart, optional, default is 'default'."
52+
},
53+
"width": {
54+
"type": "number",
55+
"default": 600,
56+
"description": "Set the width of chart, default is 600."
57+
},
58+
"height": {
59+
"type": "number",
60+
"default": 400,
61+
"description": "Set the height of chart, default is 400."
62+
}
63+
},
64+
"required": ["data"],
65+
"$schema": "http://json-schema.org/draft-07/schema#"
66+
}
67+
}

src/charts/funnel.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { z } from "zod";
2+
import { zodToJsonSchema } from "../utils";
3+
import { HeightSchema, ThemeSchema, TitleSchema, WidthSchema } from "./base";
4+
5+
const data = z.object({
6+
category: z.string(),
7+
value: z.number(),
8+
});
9+
10+
const schema = {
11+
data: z
12+
.array(data)
13+
.describe(
14+
"Data for funnel chart, such as, [{ category: '浏览网站', value: 50000 }, { category: '放入购物车', value: 35000 }, { category: '生成订单', value: 25000 }, { category: '支付订单', value: 15000 }, { category: '完成交易', value: 8000 }].",
15+
)
16+
.nonempty({ message: "Funnel chart data cannot be empty." }),
17+
theme: ThemeSchema,
18+
width: WidthSchema,
19+
height: HeightSchema,
20+
title: TitleSchema,
21+
};
22+
23+
const tool = {
24+
name: "generate_funnel_chart",
25+
description:
26+
"Generate a funnel chart to visualize the progressive reduction of data as it passes through stages, such as, the conversion rates of users from visiting a website to completing a purchase.",
27+
inputSchema: zodToJsonSchema(schema),
28+
};
29+
30+
export const funnel = {
31+
schema,
32+
tool,
33+
};

src/charts/index.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
/**
22
* export all charts as named exports to match the chart type
33
*/
4-
export { area as "area" } from "./area";
5-
export { bar as "bar" } from "./bar";
6-
export { column as "column" } from "./column";
4+
export { area } from "./area";
5+
export { bar } from "./bar";
6+
export { column } from "./column";
7+
export { dualAxes as "dual-axes" } from "./dual-axes";
78
export { fishboneDiagram as "fishbone-diagram" } from "./fishbone-diagram";
89
export { flowDiagram as "flow-diagram" } from "./flow-diagram";
9-
export { histogram as "histogram" } from "./histogram";
10-
export { line as "line" } from "./line";
10+
export { funnel } from "./funnel";
11+
export { histogram } from "./histogram";
12+
export { line } from "./line";
13+
export { liquid } from "./liquid";
1114
export { mindMap as "mind-map" } from "./mind-map";
1215
export { networkGraph as "network-graph" } from "./network-graph";
13-
export { pie as "pie" } from "./pie";
14-
export { radar as "radar" } from "./radar";
15-
export { scatter as "scatter" } from "./scatter";
16-
export { treemap as "treemap" } from "./treemap";
16+
export { organizationChart as "organization-chart" } from "./organization-chart";
17+
export { pie } from "./pie";
18+
export { radar } from "./radar";
19+
export { scatter } from "./scatter";
20+
export { treemap } from "./treemap";
1721
export { wordCloud as "word-cloud" } from "./word-cloud";
18-
export { dualAxes as "dual-axes" } from "./dual-axes";

src/charts/liquid.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { z } from "zod";
2+
import { zodToJsonSchema } from "../utils";
3+
import { HeightSchema, ThemeSchema, TitleSchema, WidthSchema } from "./base";
4+
5+
const schema = {
6+
data: z
7+
.number()
8+
.describe(
9+
"The percentage value to display in the liquid chart, should be a number between 0 and 1, where 1 represents 100%. For example, 0.75 represents 75%.",
10+
)
11+
.min(0, { message: "Value must be at least 0." })
12+
.max(1, { message: "Value must be at most 1." }),
13+
shape: z
14+
.enum(["circle", "rect", "pin", "triangle"])
15+
.optional()
16+
.default("circle")
17+
.describe(
18+
"The shape of the liquid chart, can be 'circle', 'rect', 'pin', or 'triangle'. Default is 'circle'.",
19+
),
20+
theme: ThemeSchema,
21+
width: WidthSchema,
22+
height: HeightSchema,
23+
title: TitleSchema,
24+
};
25+
26+
const tool = {
27+
name: "generate_liquid_chart",
28+
description:
29+
"Generate a liquid chart to visualize a single value as a percentage, such as, the current occupancy rate of a reservoir or the completion percentage of a project.",
30+
inputSchema: zodToJsonSchema(schema),
31+
};
32+
33+
export const liquid = {
34+
schema,
35+
tool,
36+
};

src/charts/organization-chart.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { z } from "zod";
2+
import { zodToJsonSchema } from "../utils";
3+
import { HeightSchema, ThemeSchema, WidthSchema } from "./base";
4+
5+
export type OrganizationChartDatumType = {
6+
name: string;
7+
description?: string;
8+
children?: OrganizationChartDatumType[];
9+
};
10+
11+
const OrganizationChartNodeSchema: z.ZodType<OrganizationChartDatumType> =
12+
z.lazy(() =>
13+
z.object({
14+
name: z.string(),
15+
description: z.string().optional(),
16+
children: z.array(OrganizationChartNodeSchema).optional(),
17+
}),
18+
);
19+
20+
const schema = {
21+
data: OrganizationChartNodeSchema.describe(
22+
"Data for organization chart, such as, { name: 'CEO', description: 'Chief Executive Officer', children: [{ name: 'CTO', description: 'Chief Technology Officer', children: [{ name: 'Dev Manager', description: 'Development Manager' }] }] }.",
23+
),
24+
orient: z
25+
.enum(["horizontal", "vertical"])
26+
.default("vertical")
27+
.describe(
28+
"Orientation of the organization chart, either horizontal or vertical, default is vertical.",
29+
),
30+
theme: ThemeSchema,
31+
width: WidthSchema,
32+
height: HeightSchema,
33+
};
34+
35+
const tool = {
36+
name: "generate_organization_chart",
37+
description:
38+
"Generate an organization chart to visualize the hierarchical structure of an organization, such as, a diagram showing the relationship between a CEO and their direct reports.",
39+
inputSchema: zodToJsonSchema(schema),
40+
};
41+
42+
export const organizationChart = {
43+
schema,
44+
tool,
45+
};

0 commit comments

Comments
 (0)