Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
49 changes: 49 additions & 0 deletions src/tools/area.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
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;
showArea?: boolean;
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