diff --git a/demos/xychart.html b/demos/xychart.html index 13d5dfde9..e737545db 100644 --- a/demos/xychart.html +++ b/demos/xychart.html @@ -18,8 +18,10 @@
     xychart-beta horizontal
     title Basic xychart
-    x-axis "this is x axis" [category1, "category 2", category3]
+    x-axis "this is x axis" [category1, "category 2", category3, category4]
     y-axis yaxisText 10 --> 150
+    line [23, 46, 75, 43]
+    bar "sample bat" [52, 96, 35, 10]
     

@@ -28,8 +30,10 @@
     xychart-beta
     title Basic xychart
-    x-axis "this is x axis" [category1, "category 2", category3]
+    x-axis "this is x axis" [category1, "category 2", category3, category4]
     y-axis yaxisText 10 --> 150
+    line [23, 46, 75, 43]
+    bar "sample bat" [52, 96, 35, 10]
     

diff --git a/packages/mermaid/src/diagrams/xychart/parser/xychart.jison b/packages/mermaid/src/diagrams/xychart/parser/xychart.jison index 7c17d1e57..1ecd6edf4 100644 --- a/packages/mermaid/src/diagrams/xychart/parser/xychart.jison +++ b/packages/mermaid/src/diagrams/xychart/parser/xychart.jison @@ -24,6 +24,8 @@ %x line_title %x line_data %x line_data_entries +%x line_data_without_label +%x bar_data_without_label %x bar %x bar_title %x bar_data @@ -77,18 +79,22 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multiline");} [^"]+ {return 'LINE_TITLE';} ["]" "* {this.popState(); this.begin("line_data");} "["" "* {this.begin('line_data_entries');} -(?:[+-]?\d+(?:\.\d+)?)+(?:" "*[,]" "*(?:[+-]?\d+(?:\.\d+)?)+)*" "* {return 'LINE_DATA'} +(?:[+-]?\d+(?:\.\d+)?)+(?:" "*[,]" "*(?:[+-]?\d+(?:\.\d+)?)+)*" "* {return 'LINE_DATA'} "]"" "* {this.popState(); this.popState(); this.popState()} -[^\s]+" "* {this.begin("line_data"); return 'LINE_TITLE';} +"]"" "* {this.popState(); this.popState()} +[^\s\[]+" "* {this.begin("line_data"); return 'LINE_TITLE';} +"["" "* {this.begin('line_data_without_label');} "bar"" "* {this.begin("bar"); return 'BAR';} ["] {this.begin("bar_title");} [^"]+ {return 'BAR_TITLE';} ["]" "* {this.popState(); this.begin("bar_data");} "["" "* {this.begin('bar_data_entries');} -(?:[+-]?\d+(?:\.\d+)?)+(?:" "*[,]" "*(?:[+-]?\d+(?:\.\d+)?)+)*" "* {return 'BAR_DATA'} +(?:[+-]?\d+(?:\.\d+)?)+(?:" "*[,]" "*(?:[+-]?\d+(?:\.\d+)?)+)*" "* {return 'BAR_DATA'} "]"" "* {this.popState(); this.popState(); this.popState()} -[^\s]+" "* {this.begin("bar_data"); return 'BAR_TITLE';} +"]"" "* {this.popState(); this.popState()} +[^\s\[]+" "* {this.begin("bar_data"); return 'BAR_TITLE';} +"["" "* {this.begin('bar_data_without_label');} @@ -157,11 +163,13 @@ statement ; parseLine - : LINE LINE_TITLE LINE_DATA {yy.setLineData($2.trim(), $3.split(',').map(d => Number(d.trim())));} + : LINE LINE_DATA {yy.setLineData('', $2.split(',').map(d => Number(d.trim())));} + | LINE LINE_TITLE LINE_DATA {yy.setLineData($2.trim(), $3.split(',').map(d => Number(d.trim())));} ; parseBar - : BAR BAR_TITLE BAR_DATA {yy.setBarData($2.trim(), $3.split(',').map(d => Number(d.trim())));} + : BAR BAR_DATA {yy.setBarData('', $2.split(',').map(d => Number(d.trim())));} + | BAR BAR_TITLE BAR_DATA {yy.setBarData($2.trim(), $3.split(',').map(d => Number(d.trim())));} ; parseXAxis diff --git a/packages/mermaid/src/diagrams/xychart/parser/xychart.jison.spec.ts b/packages/mermaid/src/diagrams/xychart/parser/xychart.jison.spec.ts index 41d4f36db..2b96a63f7 100644 --- a/packages/mermaid/src/diagrams/xychart/parser/xychart.jison.spec.ts +++ b/packages/mermaid/src/diagrams/xychart/parser/xychart.jison.spec.ts @@ -175,6 +175,14 @@ describe('Testing xychart jison file', () => { expect(mockDB.setXAxisTitle).toHaveBeenCalledWith('xAxisName'); expect(mockDB.setLineData).toHaveBeenCalledWith('lineTitle with space', [23, -45, 56.6]); + // set line data without title + str = + 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line [ +23 , -45 , 56.6 ] '; + expect(parserFnConstructor(str)).not.toThrow(); + expect(mockDB.setYAxisTitle).toHaveBeenCalledWith('yAxisName'); + expect(mockDB.setXAxisTitle).toHaveBeenCalledWith('xAxisName'); + expect(mockDB.setLineData).toHaveBeenCalledWith('', [23, -45, 56.6]); + clearMocks(); str = 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -4aa5 , 56.6 ] '; @@ -197,6 +205,15 @@ describe('Testing xychart jison file', () => { expect(mockDB.setBarData).toHaveBeenCalledWith('barTitle with space', [23, -45, 56.6]); clearMocks(); + // set bar data without title + str = + 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar [ +23 , -45 , 56.6 ] '; + expect(parserFnConstructor(str)).not.toThrow(); + expect(mockDB.setYAxisTitle).toHaveBeenCalledWith('yAxisName'); + expect(mockDB.setXAxisTitle).toHaveBeenCalledWith('xAxisName'); + expect(mockDB.setBarData).toHaveBeenCalledWith('', [23, -45, 56.6]); + clearMocks(); + str = 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -4aa5 , 56.6 ] '; expect(parserFnConstructor(str)).toThrow(); diff --git a/packages/mermaid/src/diagrams/xychart/xychartDb.ts b/packages/mermaid/src/diagrams/xychart/xychartDb.ts index cc002405e..19622c4a6 100644 --- a/packages/mermaid/src/diagrams/xychart/xychartDb.ts +++ b/packages/mermaid/src/diagrams/xychart/xychartDb.ts @@ -12,7 +12,12 @@ import { clear as commonClear, } from '../../commonDb.js'; import { XYChartBuilder } from './chartBuilder/index.js'; -import { ChartPlotEnum, DrawableElem, XYChartData, isBandAxisData } from './chartBuilder/Interfaces.js'; +import { + ChartPlotEnum, + DrawableElem, + XYChartData, + isBandAxisData, +} from './chartBuilder/Interfaces.js'; import { XYChartConfig } from '../../config.type.js'; const config = configApi.getConfig(); @@ -76,27 +81,7 @@ function getChartDefalutData(): XYChartData { categories: [], }, title: '', - plots: [ - { - type: ChartPlotEnum.BAR, - fill: '#0000bb', - data: [ - ['category1', 23], - ['category 2', 56], - ['category3', 34], - ], - }, - { - type: ChartPlotEnum.LINE, - strokeFill: '#bb0000', - strokeWidth: 2, - data: [ - ['category1', 33], - ['category 2', 45], - ['category3', 65], - ], - }, - ], + plots: [], }; } @@ -112,7 +97,6 @@ function parseDirective(statement: string, context: string, type: string) { mermaidAPI.parseDirective(this, statement, context, type); } - function setOrientation(oriantation: string) { if (oriantation === 'horizontal') { xyChartConfig.chartOrientation = 'horizontal'; @@ -124,19 +108,39 @@ function setXAxisTitle(title: string) { xyChartData.xAxis.title = textSanitizer(title); } function setXAxisRangeData(min: number, max: number) { - xyChartData.xAxis = {title: xyChartData.xAxis.title, min, max}; + xyChartData.xAxis = { title: xyChartData.xAxis.title, min, max }; } function setXAxisBand(categories: string[]) { - xyChartData.xAxis = {title: xyChartData.xAxis.title, categories: categories.map(c => textSanitizer(c))}; + xyChartData.xAxis = { + title: xyChartData.xAxis.title, + categories: categories.map((c) => textSanitizer(c)), + }; } function setYAxisTitle(title: string) { xyChartData.yAxis.title = textSanitizer(title); } function setYAxisRangeData(min: number, max: number) { - xyChartData.yAxis = {title: xyChartData.yAxis.title, min, max}; + xyChartData.yAxis = { title: xyChartData.yAxis.title, min, max }; +} +function setLineData(title: string, data: number[]) { + if (isBandAxisData(xyChartData.xAxis)) { + xyChartData.plots.push({ + type: ChartPlotEnum.BAR, + fill: '#0000bb', + data: xyChartData.xAxis.categories.map((c, i) => [c, data[i]]), + }); + } +} +function setBarData(title: string, data: number[]) { + if (isBandAxisData(xyChartData.xAxis)) { + xyChartData.plots.push({ + type: ChartPlotEnum.LINE, + strokeFill: '#00ff00', + strokeWidth: 2, + data: xyChartData.xAxis.categories.map((c, i) => [c, data[i]]), + }); + } } -function setLineData(title: string, data: number[]) {} -function setBarData(title: string, data: number[]) {} function getDrawableElem(): DrawableElem[] { xyChartData.title = getDiagramTitle();