This is an automated email from the ASF dual-hosted git repository.
ovilia pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/echarts-from-mermaid.git
The following commit(s) were added to refs/heads/main by this push:
new e55324e feat: add src
e55324e is described below
commit e55324eea843c1de2b091337c07b795b77d22144
Author: Ovilia <[email protected]>
AuthorDate: Thu Feb 6 17:40:59 2025 +0800
feat: add src
---
src/charts/base.ts | 22 +++++++++
src/charts/extended/README.md | 1 +
src/charts/mermaid/README.md | 1 +
src/charts/mermaid/xychart.ts | 107 ++++++++++++++++++++++++++++++++++++++++++
src/charts/types.ts | 1 +
src/index.ts | 34 ++++++++++++++
6 files changed, 166 insertions(+)
diff --git a/src/charts/base.ts b/src/charts/base.ts
new file mode 100644
index 0000000..5bfcfb2
--- /dev/null
+++ b/src/charts/base.ts
@@ -0,0 +1,22 @@
+import type { EChartsOption } from 'echarts';
+
+export abstract class BaseChart {
+ protected definition: string;
+
+ constructor(definition: string) {
+ this.definition = definition;
+ }
+
+ abstract parse(): any;
+ abstract getOption(): EChartsOption;
+
+ protected parseDirective(line: string): { type: string; args: string[] } {
+ const match = line.match(/^\s*%%\s*{?\s*(\w+)\s*}?\s*(.*)$/);
+ if (!match) return { type: '', args: [] };
+
+ return {
+ type: match[1],
+ args: match[2].split(/\s+/).filter(Boolean),
+ };
+ }
+}
diff --git a/src/charts/extended/README.md b/src/charts/extended/README.md
new file mode 100644
index 0000000..d4dba48
--- /dev/null
+++ b/src/charts/extended/README.md
@@ -0,0 +1 @@
+The types under this directory are the ones not supported by the Mermaid, but
we used Mermaid-like syntax to describe these types supported by Apache ECharts.
diff --git a/src/charts/mermaid/README.md b/src/charts/mermaid/README.md
new file mode 100644
index 0000000..7fc6c5b
--- /dev/null
+++ b/src/charts/mermaid/README.md
@@ -0,0 +1 @@
+The types under this directory are the ones supported by the Mermaid.
diff --git a/src/charts/mermaid/xychart.ts b/src/charts/mermaid/xychart.ts
new file mode 100644
index 0000000..60a77aa
--- /dev/null
+++ b/src/charts/mermaid/xychart.ts
@@ -0,0 +1,107 @@
+import { BaseChart } from '../base';
+import type {
+ EChartsOption,
+ XAXisComponentOption,
+ YAXisComponentOption,
+} from 'echarts';
+
+interface XYChartData {
+ type: string;
+ title?: string;
+ orientation?: string;
+ xAxis?: {
+ min?: number;
+ max?: number;
+ data?: string[];
+ };
+ yAxis?: {
+ min?: number;
+ max?: number;
+ };
+ series: Array<{
+ type: string;
+ data: number[];
+ }>;
+}
+
+export class XYChart extends BaseChart {
+ parse(): XYChartData {
+ const lines = this.definition.split('\n');
+ const result: XYChartData = {
+ type: 'xychart-beta',
+ series: [],
+ };
+
+ let currentSeries: { type: string; data: number[] } | null = null;
+
+ for (const line of lines) {
+ if (line.trim().startsWith('---')) continue;
+
+ // 处理指令
+ if (line.trim().startsWith('%%')) {
+ const { type, args } = this.parseDirective(line);
+ switch (type) {
+ case 'title':
+ result.title = args.join(' ');
+ break;
+ case 'orientation':
+ result.orientation = args[0];
+ break;
+ }
+ continue;
+ }
+
+ const dataMatch = line.match(/^\s*(\w+)\s+([0-9\s.]+)/);
+ if (dataMatch) {
+ currentSeries = {
+ type: dataMatch[1],
+ data: dataMatch[2].trim().split(/\s+/).map(Number),
+ };
+ result.series.push(currentSeries);
+ }
+ }
+
+ return result;
+ }
+
+ getOption(): EChartsOption {
+ const parsed = this.parse();
+ const option: EChartsOption = {};
+
+ if (parsed.title) {
+ option.title = { text: parsed.title };
+ }
+
+ if (parsed.orientation === 'horizontal') {
+ option.xAxis = { type: 'value' } as XAXisComponentOption;
+ option.yAxis = {
+ type: 'category',
+ data:
+ parsed.xAxis?.data ||
+ this.generateDefaultCategories(parsed.series[0]?.data.length),
+ } as YAXisComponentOption;
+ } else {
+ option.xAxis = {
+ type: parsed.xAxis?.min !== undefined ? 'value' : 'category',
+ ...parsed.xAxis,
+ } as XAXisComponentOption;
+ option.yAxis = {
+ type: 'value',
+ ...parsed.yAxis,
+ } as YAXisComponentOption;
+
+ if (!parsed.xAxis?.data && option.xAxis.type === 'category') {
+ (option.xAxis as any).data = this.generateDefaultCategories(
+ parsed.series[0]?.data.length
+ );
+ }
+ }
+
+ option.series = parsed.series as any;
+ return option;
+ }
+
+ private generateDefaultCategories(count: number): string[] {
+ return Array.from({ length: count }, (_, i) => (i + 1).toString());
+ }
+}
diff --git a/src/charts/types.ts b/src/charts/types.ts
new file mode 100644
index 0000000..a76f0c5
--- /dev/null
+++ b/src/charts/types.ts
@@ -0,0 +1 @@
+export type ChartType = 'xychart-beta' | 'pie';
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 0000000..acda26b
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,34 @@
+import { BaseChart } from './charts/base';
+import { XYChart } from './charts/mermaid/xychart';
+import type { EChartsOption } from 'echarts';
+
+export class EChartsMermaid {
+ /**
+ * Converts a Mermaid diagram definition to an ECharts option
+ * @param {string} mermaidDefinition The Mermaid diagram definition string
+ * @returns {EChartsOption} ECharts option object
+ */
+ static getOption(mermaidDefinition: string): EChartsOption {
+ const chartType = this.detectChartType(mermaidDefinition);
+ const chart = this.createChart(chartType, mermaidDefinition);
+ return chart.getOption();
+ }
+
+ private static detectChartType(definition: string): string {
+ if (definition.includes('xychart-beta')) {
+ return 'xychart-beta';
+ }
+ throw new Error('Unsupported chart type');
+ }
+
+ private static createChart(type: string, definition: string): BaseChart {
+ switch (type) {
+ case 'xychart-beta':
+ return new XYChart(definition);
+ default:
+ throw new Error('Unsupported chart type');
+ }
+ }
+}
+
+export default EChartsMermaid;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]