Skip to content
Open
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 __tests__/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ describe("integration tests", () => {

it("should have all tools properly exported", () => {
// Verify that the total number of tools is correct
expect(tools).toHaveLength(17);
expect(tools).toHaveLength(18);

// Define the expected list of tool names
const expectedToolNames = [
Expand All @@ -312,6 +312,7 @@ describe("integration tests", () => {
"generate_graph_chart",
"generate_parallel_chart",
"generate_tree_chart",
"generate_area_chart",
];

// Verify that the actual exported tool names match expectations
Expand Down
Binary file added __tests__/snapshots/area-basic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added __tests__/snapshots/area-custom.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added __tests__/snapshots/area-smooth.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added __tests__/snapshots/area-stacked.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
82 changes: 82 additions & 0 deletions __tests__/tools/area.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { describe, expect, it } from "vitest";
import { generateAreaChartTool } from "../../src/tools/area";
import "../utils/matcher";

describe("Area Chart Tool", () => {
it("should generate a basic area chart", async () => {
const result = await generateAreaChartTool.run({
data: [
{ time: "2015", value: 23 },
{ time: "2016", value: 32 },
{ time: "2017", value: 28 },
{ time: "2018", value: 45 },
{ time: "2019", value: 38 },
{ time: "2020", value: 52 },
],
title: "Basic Area Chart",
width: 600,
height: 400,
});

await expect(result).toImageEqual("area-basic");
});

it("should generate a stacked area chart", async () => {
const result = await generateAreaChartTool.run({
data: [
{ group: "Series A", time: "2015", value: 23 },
{ group: "Series A", time: "2016", value: 32 },
{ group: "Series A", time: "2017", value: 28 },
{ group: "Series B", time: "2015", value: 18 },
{ group: "Series B", time: "2016", value: 25 },
{ group: "Series B", time: "2017", value: 22 },
],
title: "Stacked Area Chart",
stack: true,
width: 600,
height: 400,
});

await expect(result).toImageEqual("area-stacked");
});

it("should generate an area chart with custom styling", async () => {
const result = await generateAreaChartTool.run({
data: [
{ time: "Q1", value: 100 },
{ time: "Q2", value: 150 },
{ time: "Q3", value: 120 },
{ time: "Q4", value: 180 },
],
title: "Custom Styled Area Chart",
width: 800,
height: 500,
theme: "dark",
style: {
backgroundColor: "#1a1a1a",
palette: ["#ff6b6b", "#4ecdc4", "#45b7d1"],
},
});

await expect(result).toImageEqual("area-custom");
});

it("should generate area chart with smooth curves", async () => {
const result = await generateAreaChartTool.run({
data: [
{ time: "Jan", value: 10 },
{ time: "Feb", value: 25 },
{ time: "Mar", value: 15 },
{ time: "Apr", value: 35 },
{ time: "May", value: 20 },
{ time: "Jun", value: 40 },
],
title: "Smooth Area Chart",
smooth: true,
width: 600,
height: 400,
});

await expect(result).toImageEqual("area-smooth");
});
});
5 changes: 3 additions & 2 deletions __tests__/tools/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ describe("tools index", () => {
* Tool count validation
* Validates that the total number of exported tools meets expectations (17 chart tools)
*/
it("should export all 17 chart tools", () => {
it("should export all 18 chart tools", () => {
// Validate that the tools array contains 17 chart tools
expect(tools).toHaveLength(17);
expect(tools).toHaveLength(18);
});

/**
Expand Down Expand Up @@ -74,6 +74,7 @@ describe("tools index", () => {
"generate_graph_chart", // Graph chart
"generate_parallel_chart", // Parallel coordinates chart
"generate_tree_chart", // Tree chart
"generate_area_chart", // Area chart
];

// Get actual tool names and sort them
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "mcp-echarts",
"description": "❤️ Generate visual charts using Apache ECharts with AI MCP dynamically.",
"version": "0.6.1",
"version": "0.7.0",
"main": "build/index.js",
"scripts": {
"test": "vitest",
Expand Down
48 changes: 48 additions & 0 deletions src/tools/area.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { z } from "zod";
import { generateLineChartTool } from "./line";

// Extends generateLineChartTool implementation since area charts are line charts with area fill enabled
export const generateAreaChartTool = {
...generateLineChartTool,
name: "generate_area_chart",
description:
"Generate an area chart to show data trends under continuous independent variables and observe the overall data trend, such as, displacement = velocity (average or instantaneous) × time: s = v × t. If the x-axis is time (t) and the y-axis is velocity (v) at each moment, an area chart allows you to observe the trend of velocity over time and infer the distance traveled by the area's size.",
inputSchema: generateLineChartTool.inputSchema.extend({
data: z
.array(
z.object({
group: z
.string()
.optional()
.describe(
"Group name for multiple series, required when stack is enabled",
),
time: z.string(),
value: z.number(),
}),
)
.describe(
"Data for area chart, such as, [{ time: '2015', value: 23 }, { time: '2016', value: 32 }]. For multiple series: [{ group: 'Series A', time: '2015', value: 23 }, { group: 'Series B', time: '2015', value: 18 }].",
)
.nonempty({ message: "Area chart data cannot be empty." }),
}),
run: (params: {
axisXTitle?: string;
axisYTitle?: string;
data: Array<{ time: string; value: number; group?: string }>;
height: number;
showSymbol?: boolean;
smooth?: boolean;
stack?: boolean;
theme?: "default" | "dark";
title?: string;
width: number;
outputType?: "png" | "svg" | "option";
}) => {
// Force showArea to true for area chart
return generateLineChartTool.run({
...params,
showArea: true,
});
},
};
3 changes: 3 additions & 0 deletions src/tools/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { generateAreaChartTool } from "./area";
import { generateBarChartTool } from "./bar";
import { generateBoxplotChartTool } from "./boxplot";
import { generateCandlestickChartTool } from "./candlestick";
Expand All @@ -18,6 +19,7 @@ import { generateTreemapChartTool } from "./treemap";

export const tools = [
generateEChartsTool,
generateAreaChartTool,
generateLineChartTool,
generateBarChartTool,
generatePieChartTool,
Expand All @@ -39,6 +41,7 @@ export const tools = [
// Re-export individual tools for convenient use in tests and other places
export {
generateEChartsTool,
generateAreaChartTool,
generateLineChartTool,
generateBarChartTool,
generatePieChartTool,
Expand Down