parser fixed for > 2 datasets

some unit tests added
This commit is contained in:
Axel Müller
2024-01-07 15:56:46 +01:00
parent 39d175314c
commit e1d085925e
5 changed files with 447 additions and 401 deletions

View File

@@ -65,18 +65,18 @@
<pre class="mermaid"> <pre class="mermaid">
xychart-beta xychart-beta
title "Basic xychart with multiple datasets" title "Basic xychart with multiple datasets"
x-axis "Relevant categories" [category1, "category 2", category3, category4, category5, category6, category7] x-axis "Relevant categories" [category1, "category 2", category3, category4]
y-axis Animals 10 --> 200 y-axis Animals 0 --> 160
bar [["dogs" [52, 96, 35, 10, 87, 34, 67, 99]],["cats" [15, 7, 23, 55, 11, 41, 26, 3]]] bar [["dogs" [40, 20, 40, 30]],["cats" [20, 40, 50, 30]],["birds" [30, 60, 50, 30]]]
</pre> </pre>
<h1>XY Charts bar horizontal with multiple datasets</h1> <h1>XY Charts bar horizontal with multiple datasets</h1>
<pre class="mermaid"> <pre class="mermaid">
xychart-beta horizontal xychart-beta horizontal
title "Basic xychart with multiple datasets" title "Basic xychart with multiple datasets"
x-axis "Relevant categories" [category1, "category 2", category3, category4, category5, category6, category7] x-axis "Relevant categories" [category1, "category 2", category3, category4]
y-axis Animals 10 --> 200 y-axis Animals 0 --> 160
bar [["dogs" [52, 96, 35, 10, 87, 34, 67, 99]],["cats" [15, 7, 23, 55, 11, 41, 26, 3]]] bar [["dogs" [40, 20, 40, 30]],["cats" [20, 40, 50, 30]],["birds" [30, 60, 50, 30]]]
</pre> </pre>
<h1>XY Charts line single dataset</h1> <h1>XY Charts line single dataset</h1>

View File

@@ -32,7 +32,10 @@ export class BarPlot {
type: 'rect', type: 'rect',
data: finalData.map((data, index) => { data: finalData.map((data, index) => {
const x = offset[index] + this.boundingRect.x; const x = offset[index] + this.boundingRect.x;
const width = data[1] - this.boundingRect.x; const width =
data[1] -
this.boundingRect.x -
(dataIndex > 0 ? this.yAxis.getAxisOuterPadding() : 0);
offset[index] += width; offset[index] += width;
return { return {
x, x,
@@ -50,8 +53,10 @@ export class BarPlot {
groupTexts: ['plot', `bar-plot-${this.plotIndex}-${dataIndex}`], groupTexts: ['plot', `bar-plot-${this.plotIndex}-${dataIndex}`],
type: 'rect', type: 'rect',
data: finalData.map((data, index) => { data: finalData.map((data, index) => {
const y = data[1] - offset[index]; const adjustForAxisOuterPadding = dataIndex > 0 ? this.yAxis.getAxisOuterPadding() : 0;
const height = this.boundingRect.y + this.boundingRect.height - data[1]; const y = data[1] - offset[index] + adjustForAxisOuterPadding;
const height =
this.boundingRect.y + this.boundingRect.height - data[1] - adjustForAxisOuterPadding;
offset[index] += height; offset[index] += height;
return { return {
x: data[0] - barWidthHalf, x: data[0] - barWidthHalf,

View File

@@ -109,14 +109,14 @@ statement
; ;
datasets datasets
: SQUARE_BRACES_START datasetBraced COMMA datasets SQUARE_BRACES_END { $$ = [$datasetBraced, ...$datasets] } : SQUARE_BRACES_START datasetBraced SQUARE_BRACES_END { $$ = [$datasetBraced] }
| SQUARE_BRACES_START datasetBraced SQUARE_BRACES_END { $$ = [$datasetBraced] }
| datasetBraced { $$ = [$datasetBraced] } | datasetBraced { $$ = [$datasetBraced] }
| dataset { $$ = [$dataset] } | dataset { $$ = [$dataset] }
; ;
datasetBraced datasetBraced
: SQUARE_BRACES_START dataset SQUARE_BRACES_END { $$ = $dataset } : SQUARE_BRACES_START dataset SQUARE_BRACES_END COMMA datasetBraced { $$ = [$dataset, ...$datasetBraced] }
| SQUARE_BRACES_START dataset SQUARE_BRACES_END { $$ = [$dataset] }
; ;
dataset dataset

View File

@@ -33,380 +33,384 @@ describe('Testing xychart jison file', () => {
clearMocks(); clearMocks();
}); });
it('should throw error if xychart-beta text is not there', () => { describe('single dataset', () => {
const str = 'xychart-beta-1'; it('should throw error if xychart-beta text is not there', () => {
expect(parserFnConstructor(str)).toThrow(); const str = 'xychart-beta-1';
}); expect(parserFnConstructor(str)).toThrow();
it('should not throw error if only xychart is there', () => {
const str = 'xychart-beta';
expect(parserFnConstructor(str)).not.toThrow();
});
it('parse title of the chart within "', () => {
const str = 'xychart-beta \n title "This is a title"';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setDiagramTitle).toHaveBeenCalledWith('This is a title');
});
it('parse title of the chart without "', () => {
const str = 'xychart-beta \n title oneLinertitle';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setDiagramTitle).toHaveBeenCalledWith('oneLinertitle');
});
it('parse chart orientation', () => {
const str = 'xychart-beta vertical';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setOrientation).toHaveBeenCalledWith('vertical');
});
it('parse chart orientation with spaces', () => {
let str = 'xychart-beta horizontal ';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setOrientation).toHaveBeenCalledWith('horizontal');
str = 'xychart-beta abc';
expect(parserFnConstructor(str)).toThrow();
});
it('parse x-axis', () => {
const str = 'xychart-beta \nx-axis xAxisName\n';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
text: 'xAxisName',
type: 'text',
}); });
});
it('parse x-axis with axis name without "', () => { it('should not throw error if only xychart is there', () => {
const str = 'xychart-beta \nx-axis xAxisName \n'; const str = 'xychart-beta';
expect(parserFnConstructor(str)).not.toThrow(); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
text: 'xAxisName',
type: 'text',
}); });
});
it('parse x-axis with axis name with "', () => { it('parse title of the chart within "', () => {
const str = 'xychart-beta \n x-axis "xAxisName has space"\n'; const str = 'xychart-beta \n title "This is a title"';
expect(parserFnConstructor(str)).not.toThrow(); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ expect(mockDB.setDiagramTitle).toHaveBeenCalledWith('This is a title');
text: 'xAxisName has space', });
type: 'text', it('parse title of the chart without "', () => {
const str = 'xychart-beta \n title oneLinertitle';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setDiagramTitle).toHaveBeenCalledWith('oneLinertitle');
}); });
});
it('parse x-axis with axis name with " with spaces', () => { it('parse chart orientation', () => {
const str = 'xychart-beta \n x-axis " xAxisName has space " \n'; const str = 'xychart-beta vertical';
expect(parserFnConstructor(str)).not.toThrow(); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ expect(mockDB.setOrientation).toHaveBeenCalledWith('vertical');
text: ' xAxisName has space ',
type: 'text',
}); });
});
it('parse x-axis with axis name and range data', () => { it('parse chart orientation with spaces', () => {
const str = 'xychart-beta \nx-axis xAxisName 45.5 --> 33 \n'; let str = 'xychart-beta horizontal ';
expect(parserFnConstructor(str)).not.toThrow(); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ expect(mockDB.setOrientation).toHaveBeenCalledWith('horizontal');
text: 'xAxisName',
type: 'text',
});
expect(mockDB.setXAxisRangeData).toHaveBeenCalledWith(45.5, 33);
});
it('parse x-axis throw error for invalid range data', () => {
const str = 'xychart-beta \nx-axis xAxisName aaa --> 33 \n';
expect(parserFnConstructor(str)).toThrow();
});
it('parse x-axis with axis name and range data with only decimal part', () => {
const str = 'xychart-beta \nx-axis xAxisName 45.5 --> .34 \n';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
text: 'xAxisName',
type: 'text',
});
expect(mockDB.setXAxisRangeData).toHaveBeenCalledWith(45.5, 0.34);
});
it('parse x-axis without axisname and range data', () => { str = 'xychart-beta abc';
const str = 'xychart-beta \nx-axis 45.5 --> 1.34 \n'; expect(parserFnConstructor(str)).toThrow();
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
text: '',
type: 'text',
}); });
expect(mockDB.setXAxisRangeData).toHaveBeenCalledWith(45.5, 1.34);
});
it('parse x-axis with axis name and category data', () => { it('parse x-axis', () => {
const str = 'xychart-beta \nx-axis xAxisName [ "cat1" , cat2a ] \n '; const str = 'xychart-beta \nx-axis xAxisName\n';
expect(parserFnConstructor(str)).not.toThrow(); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
text: 'xAxisName', text: 'xAxisName',
type: 'text',
});
expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
{
text: 'cat1',
type: 'text', type: 'text',
}, });
{ text: 'cat2a', type: 'text' },
]);
});
it('parse x-axis without axisname and category data', () => {
const str = 'xychart-beta \nx-axis [ "cat1" , cat2a ] \n ';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
text: '',
type: 'text',
}); });
expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
{ it('parse x-axis with axis name without "', () => {
text: 'cat1', const str = 'xychart-beta \nx-axis xAxisName \n';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
text: 'xAxisName',
type: 'text', type: 'text',
}, });
{ text: 'cat2a', type: 'text' },
]);
});
it('parse x-axis throw error if unbalanced bracket', () => {
let str = 'xychart-beta \nx-axis xAxisName [ "cat1" [ cat2a ] \n ';
expect(parserFnConstructor(str)).toThrow();
str = 'xychart-beta \nx-axis xAxisName [ "cat1" , cat2a ] ] \n ';
expect(parserFnConstructor(str)).toThrow();
});
it('parse x-axis complete variant 1', () => {
const str = `xychart-beta \n x-axis "this is x axis" [category1, "category 2", category3]\n`;
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'this is x axis', type: 'text' });
expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
{ text: 'category1', type: 'text' },
{ text: 'category 2', type: 'text' },
{ text: 'category3', type: 'text' },
]);
});
it('parse x-axis complete variant 2', () => {
const str =
'xychart-beta \nx-axis xAxisName [ "cat1 with space" , cat2 , cat3] \n ';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
{ text: 'cat1 with space', type: 'text' },
{ text: 'cat2', type: 'text' },
{ text: 'cat3', type: 'text' },
]);
});
it('parse x-axis complete variant 3', () => {
const str =
'xychart-beta \nx-axis xAxisName [ "cat1 with space" , cat2 asdf , cat3] \n ';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
{ text: 'cat1 with space', type: 'text' },
{ text: 'cat2asdf', type: 'text' },
{ text: 'cat3', type: 'text' },
]);
});
it('parse y-axis with axis name', () => {
const str = 'xychart-beta \ny-axis yAxisName\n';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
});
it('parse y-axis with axis name with spaces', () => {
const str = 'xychart-beta \ny-axis yAxisName \n';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
});
it('parse y-axis with axis name with "', () => {
const str = 'xychart-beta \n y-axis "yAxisName has space"\n';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({
text: 'yAxisName has space',
type: 'text',
}); });
});
it('parse y-axis with axis name with " and spaces', () => { it('parse x-axis with axis name with "', () => {
const str = 'xychart-beta \n y-axis " yAxisName has space " \n'; const str = 'xychart-beta \n x-axis "xAxisName has space"\n';
expect(parserFnConstructor(str)).not.toThrow(); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
text: ' yAxisName has space ', text: 'xAxisName has space',
type: 'text', type: 'text',
});
}); });
});
it('parse y-axis with axis name with range data', () => { it('parse x-axis with axis name with " with spaces', () => {
const str = 'xychart-beta \ny-axis yAxisName 45.5 --> 33 \n'; const str = 'xychart-beta \n x-axis " xAxisName has space " \n';
expect(parserFnConstructor(str)).not.toThrow(); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 33); text: ' xAxisName has space ',
}); type: 'text',
it('parse y-axis without axisname with range data', () => { });
const str = 'xychart-beta \ny-axis 45.5 --> 33 \n'; });
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: '', type: 'text' }); it('parse x-axis with axis name and range data', () => {
expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 33); const str = 'xychart-beta \nx-axis xAxisName 45.5 --> 33 \n';
}); expect(parserFnConstructor(str)).not.toThrow();
it('parse y-axis with axis name with range data with only decimal part', () => { expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
const str = 'xychart-beta \ny-axis yAxisName 45.5 --> .33 \n'; text: 'xAxisName',
expect(parserFnConstructor(str)).not.toThrow(); type: 'text',
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); });
expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 0.33); expect(mockDB.setXAxisRangeData).toHaveBeenCalledWith(45.5, 33);
}); });
it('parse y-axis throw error for invalid number in range data', () => { it('parse x-axis throw error for invalid range data', () => {
const str = 'xychart-beta \ny-axis yAxisName 45.5 --> abc \n'; const str = 'xychart-beta \nx-axis xAxisName aaa --> 33 \n';
expect(parserFnConstructor(str)).toThrow(); expect(parserFnConstructor(str)).toThrow();
}); });
it('parse y-axis throws error if range data is passed', () => { it('parse x-axis with axis name and range data with only decimal part', () => {
const str = 'xychart-beta \ny-axis yAxisName [ 45.3, 33 ] \n'; const str = 'xychart-beta \nx-axis xAxisName 45.5 --> .34 \n';
expect(parserFnConstructor(str)).toThrow(); expect(parserFnConstructor(str)).not.toThrow();
}); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
it('parse both axis at once', () => { text: 'xAxisName',
const str = 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n'; type: 'text',
expect(parserFnConstructor(str)).not.toThrow(); });
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); expect(mockDB.setXAxisRangeData).toHaveBeenCalledWith(45.5, 0.34);
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); });
});
it('parse line Data', () => { it('parse x-axis without axisname and range data', () => {
const str = 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line lineTitle [23, 45, 56.6]'; const str = 'xychart-beta \nx-axis 45.5 --> 1.34 \n';
expect(parserFnConstructor(str)).not.toThrow(); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setLineData).toHaveBeenCalledWith( expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
{ text: 'lineTitle', type: 'text' }, text: '',
[23, 45, 56.6] type: 'text',
); });
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); expect(mockDB.setXAxisRangeData).toHaveBeenCalledWith(45.5, 1.34);
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); });
});
it('parse line Data with spaces and +,- symbols', () => { it('parse x-axis with axis name and category data', () => {
const str = const str = 'xychart-beta \nx-axis xAxisName [ "cat1" , cat2a ] \n ';
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -45 , 56.6 ] '; expect(parserFnConstructor(str)).not.toThrow();
expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); text: 'xAxisName',
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); type: 'text',
expect(mockDB.setLineData).toHaveBeenCalledWith( });
{ text: 'lineTitle with space', type: 'text' }, expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
[23, -45, 56.6] {
); text: 'cat1',
}); type: 'text',
it('parse line Data without title', () => { },
const str = { text: 'cat2a', type: 'text' },
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line [ +23 , -45 , 56.6 , .33] '; ]);
expect(parserFnConstructor(str)).not.toThrow(); });
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); it('parse x-axis without axisname and category data', () => {
expect(mockDB.setLineData).toHaveBeenCalledWith( const str = 'xychart-beta \nx-axis [ "cat1" , cat2a ] \n ';
{ text: '', type: 'text' }, expect(parserFnConstructor(str)).not.toThrow();
[23, -45, 56.6, 0.33] expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
); text: '',
}); type: 'text',
it('parse line Data throws error unbalanced brackets', () => { });
let str = expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 [ -45 , 56.6 ] '; {
expect(parserFnConstructor(str)).toThrow(); text: 'cat1',
str = type: 'text',
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -45 ] 56.6 ] '; },
expect(parserFnConstructor(str)).toThrow(); { text: 'cat2a', type: 'text' },
}); ]);
it('parse line Data throws error if data is not provided', () => { });
const str = 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" ';
expect(parserFnConstructor(str)).toThrow(); it('parse x-axis throw error if unbalanced bracket', () => {
}); let str = 'xychart-beta \nx-axis xAxisName [ "cat1" [ cat2a ] \n ';
it('parse line Data throws error if data is empty', () => { expect(parserFnConstructor(str)).toThrow();
const str = str = 'xychart-beta \nx-axis xAxisName [ "cat1" , cat2a ] ] \n ';
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ ] '; expect(parserFnConstructor(str)).toThrow();
expect(parserFnConstructor(str)).toThrow(); });
});
it('parse line Data throws error if , is not in proper', () => { it('parse x-axis complete variant 1', () => {
const str = const str = `xychart-beta \n x-axis "this is x axis" [category1, "category 2", category3]\n`;
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , , -45 , 56.6 ] '; expect(parserFnConstructor(str)).not.toThrow();
expect(parserFnConstructor(str)).toThrow(); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'this is x axis', type: 'text' });
}); expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
it('parse line Data throws error if not number', () => { { text: 'category1', type: 'text' },
const str = { text: 'category 2', type: 'text' },
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -4aa5 , 56.6 ] '; { text: 'category3', type: 'text' },
expect(parserFnConstructor(str)).toThrow(); ]);
}); });
it('parse bar Data', () => {
const str = it('parse x-axis complete variant 2', () => {
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar barTitle [23, 45, 56.6, .22]'; const str =
expect(parserFnConstructor(str)).not.toThrow(); 'xychart-beta \nx-axis xAxisName [ "cat1 with space" , cat2 , cat3] \n ';
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
expect(mockDB.setBarData).toHaveBeenCalledWith([ expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
[{ text: 'barTitle', type: 'text' }, [23, 45, 56.6, 0.22]], { text: 'cat1 with space', type: 'text' },
]); { text: 'cat2', type: 'text' },
}); { text: 'cat3', type: 'text' },
it('parse bar Data spaces and +,- symbol', () => { ]);
const str = });
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -45 , 56.6 ] ';
expect(parserFnConstructor(str)).not.toThrow(); it('parse x-axis complete variant 3', () => {
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); const str =
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); 'xychart-beta \nx-axis xAxisName [ "cat1 with space" , cat2 asdf , cat3] \n ';
expect(mockDB.setBarData).toHaveBeenCalledWith([ expect(parserFnConstructor(str)).not.toThrow();
[{ text: 'barTitle with space', type: 'text' }, [23, -45, 56.6]], expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
]); expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
}); { text: 'cat1 with space', type: 'text' },
it('parse bar Data without plot title', () => { { text: 'cat2asdf', type: 'text' },
const str = { text: 'cat3', type: 'text' },
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar [ +23 , -45 , 56.6 ] '; ]);
expect(parserFnConstructor(str)).not.toThrow(); });
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); it('parse y-axis with axis name', () => {
expect(mockDB.setBarData).toHaveBeenCalledWith([['', [23, -45, 56.6]]]); const str = 'xychart-beta \ny-axis yAxisName\n';
}); expect(parserFnConstructor(str)).not.toThrow();
it('parse bar should throw for unbalanced brackets', () => { expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
let str = });
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 [ -45 , 56.6 ] '; it('parse y-axis with axis name with spaces', () => {
expect(parserFnConstructor(str)).toThrow(); const str = 'xychart-beta \ny-axis yAxisName \n';
str = expect(parserFnConstructor(str)).not.toThrow();
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -45 ] 56.6 ] '; expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(parserFnConstructor(str)).toThrow(); });
}); it('parse y-axis with axis name with "', () => {
it('parse bar should throw error if data is not provided', () => { const str = 'xychart-beta \n y-axis "yAxisName has space"\n';
const str = 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" '; expect(parserFnConstructor(str)).not.toThrow();
expect(parserFnConstructor(str)).toThrow(); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({
}); text: 'yAxisName has space',
it('parse bar should throw error if data is empty', () => { type: 'text',
const str = });
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ ] '; });
expect(parserFnConstructor(str)).toThrow(); it('parse y-axis with axis name with " and spaces', () => {
}); const str = 'xychart-beta \n y-axis " yAxisName has space " \n';
it('parse bar should throw error if comma is not proper', () => { expect(parserFnConstructor(str)).not.toThrow();
const str = expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , , -45 , 56.6 ] '; text: ' yAxisName has space ',
expect(parserFnConstructor(str)).toThrow(); type: 'text',
}); });
it('parse bar should throw error if number is not passed', () => { });
const str = it('parse y-axis with axis name with range data', () => {
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -4aa5 , 56.6 ] '; const str = 'xychart-beta \ny-axis yAxisName 45.5 --> 33 \n';
expect(parserFnConstructor(str)).toThrow(); expect(parserFnConstructor(str)).not.toThrow();
}); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
it('parse multiple bar and line variant 1', () => { expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 33);
const str = });
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar barTitle1 [23, 45, 56.6] \n line lineTitle1 [11, 45.5, 67, 23] \n bar barTitle2 [13, 42, 56.89] \n line lineTitle2 [45, 99, 012]'; it('parse y-axis without axisname with range data', () => {
expect(parserFnConstructor(str)).not.toThrow(); const str = 'xychart-beta \ny-axis 45.5 --> 33 \n';
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: '', type: 'text' });
expect(mockDB.setBarData).toHaveBeenCalledWith([ expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 33);
[{ text: 'barTitle1', type: 'text' }, [23, 45, 56.6]], });
]); it('parse y-axis with axis name with range data with only decimal part', () => {
expect(mockDB.setBarData).toHaveBeenCalledWith([ const str = 'xychart-beta \ny-axis yAxisName 45.5 --> .33 \n';
[{ text: 'barTitle2', type: 'text' }, [13, 42, 56.89]], expect(parserFnConstructor(str)).not.toThrow();
]); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setLineData).toHaveBeenCalledWith( expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 0.33);
{ text: 'lineTitle1', type: 'text' }, });
[11, 45.5, 67, 23] it('parse y-axis throw error for invalid number in range data', () => {
); const str = 'xychart-beta \ny-axis yAxisName 45.5 --> abc \n';
expect(mockDB.setLineData).toHaveBeenCalledWith( expect(parserFnConstructor(str)).toThrow();
{ text: 'lineTitle2', type: 'text' }, });
[45, 99, 12] it('parse y-axis throws error if range data is passed', () => {
); const str = 'xychart-beta \ny-axis yAxisName [ 45.3, 33 ] \n';
}); expect(parserFnConstructor(str)).toThrow();
it('parse multiple bar and line variant 2', () => { });
const str = ` it('parse both axis at once', () => {
const str = 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
});
it('parse line Data', () => {
const str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line lineTitle [23, 45, 56.6]';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setLineData).toHaveBeenCalledWith(
{ text: 'lineTitle', type: 'text' },
[23, 45, 56.6]
);
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
});
it('parse line Data with spaces and +,- symbols', () => {
const str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -45 , 56.6 ] ';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
expect(mockDB.setLineData).toHaveBeenCalledWith(
{ text: 'lineTitle with space', type: 'text' },
[23, -45, 56.6]
);
});
it('parse line Data without title', () => {
const str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line [ +23 , -45 , 56.6 , .33] ';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
expect(mockDB.setLineData).toHaveBeenCalledWith(
{ text: '', type: 'text' },
[23, -45, 56.6, 0.33]
);
});
it('parse line Data throws error unbalanced brackets', () => {
let str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 [ -45 , 56.6 ] ';
expect(parserFnConstructor(str)).toThrow();
str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -45 ] 56.6 ] ';
expect(parserFnConstructor(str)).toThrow();
});
it('parse line Data throws error if data is not provided', () => {
const str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" ';
expect(parserFnConstructor(str)).toThrow();
});
it('parse line Data throws error if data is empty', () => {
const str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ ] ';
expect(parserFnConstructor(str)).toThrow();
});
it('parse line Data throws error if , is not in proper', () => {
const str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , , -45 , 56.6 ] ';
expect(parserFnConstructor(str)).toThrow();
});
it('parse line Data throws error if not number', () => {
const str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -4aa5 , 56.6 ] ';
expect(parserFnConstructor(str)).toThrow();
});
it('parse bar Data', () => {
const str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar barTitle [23, 45, 56.6, .22]';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
expect(mockDB.setBarData).toHaveBeenCalledWith([
[{ text: 'barTitle', type: 'text' }, [23, 45, 56.6, 0.22]],
]);
});
it('parse bar Data spaces and +,- symbol', () => {
const str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -45 , 56.6 ] ';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
expect(mockDB.setBarData).toHaveBeenCalledWith([
[{ text: 'barTitle with space', type: 'text' }, [23, -45, 56.6]],
]);
});
it('parse bar Data without plot title', () => {
const str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar [ +23 , -45 , 56.6 ] ';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
expect(mockDB.setBarData).toHaveBeenCalledWith([['', [23, -45, 56.6]]]);
});
it('parse bar should throw for unbalanced brackets', () => {
let str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 [ -45 , 56.6 ] ';
expect(parserFnConstructor(str)).toThrow();
str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -45 ] 56.6 ] ';
expect(parserFnConstructor(str)).toThrow();
});
it('parse bar should throw error if data is not provided', () => {
const str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" ';
expect(parserFnConstructor(str)).toThrow();
});
it('parse bar should throw error if data is empty', () => {
const str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ ] ';
expect(parserFnConstructor(str)).toThrow();
});
it('parse bar should throw error if comma is not proper', () => {
const str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , , -45 , 56.6 ] ';
expect(parserFnConstructor(str)).toThrow();
});
it('parse bar should throw error if number is not passed', () => {
const str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -4aa5 , 56.6 ] ';
expect(parserFnConstructor(str)).toThrow();
});
it('parse multiple bar and line variant 1', () => {
const str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar barTitle1 [23, 45, 56.6] \n line lineTitle1 [11, 45.5, 67, 23] \n bar barTitle2 [13, 42, 56.89] \n line lineTitle2 [45, 99, 012]';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
expect(mockDB.setBarData).toHaveBeenCalledWith([
[{ text: 'barTitle1', type: 'text' }, [23, 45, 56.6]],
]);
expect(mockDB.setBarData).toHaveBeenCalledWith([
[{ text: 'barTitle2', type: 'text' }, [13, 42, 56.89]],
]);
expect(mockDB.setLineData).toHaveBeenCalledWith(
{ text: 'lineTitle1', type: 'text' },
[11, 45.5, 67, 23]
);
expect(mockDB.setLineData).toHaveBeenCalledWith(
{ text: 'lineTitle2', type: 'text' },
[45, 99, 12]
);
});
it('parse multiple bar and line variant 2', () => {
const str = `
xychart-beta horizontal xychart-beta horizontal
title Basic xychart title Basic xychart
x-axis "this is x axis" [category1, "category 2", category3] x-axis "this is x axis" [category1, "category 2", category3]
@@ -415,28 +419,60 @@ describe('Testing xychart jison file', () => {
line lineTitle1 [11, 45.5, 67, 23] line lineTitle1 [11, 45.5, 67, 23]
bar barTitle2 [13, 42, 56.89] bar barTitle2 [13, 42, 56.89]
line lineTitle2 [45, 99, 012]`; line lineTitle2 [45, 99, 012]`;
expect(parserFnConstructor(str)).not.toThrow(); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yaxisText', type: 'text' }); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yaxisText', type: 'text' });
expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(10, 150); expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(10, 150);
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'this is x axis', type: 'text' }); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'this is x axis', type: 'text' });
expect(mockDB.setXAxisBand).toHaveBeenCalledWith([ expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
{ text: 'category1', type: 'text' }, { text: 'category1', type: 'text' },
{ text: 'category 2', type: 'text' }, { text: 'category 2', type: 'text' },
{ text: 'category3', type: 'text' }, { text: 'category3', type: 'text' },
]); ]);
expect(mockDB.setBarData).toHaveBeenCalledWith([ expect(mockDB.setBarData).toHaveBeenCalledWith([
[{ text: 'barTitle1', type: 'text' }, [23, 45, 56.6]], [{ text: 'barTitle1', type: 'text' }, [23, 45, 56.6]],
]); ]);
expect(mockDB.setBarData).toHaveBeenCalledWith([ expect(mockDB.setBarData).toHaveBeenCalledWith([
[{ text: 'barTitle2', type: 'text' }, [13, 42, 56.89]], [{ text: 'barTitle2', type: 'text' }, [13, 42, 56.89]],
]); ]);
expect(mockDB.setLineData).toHaveBeenCalledWith( expect(mockDB.setLineData).toHaveBeenCalledWith(
{ text: 'lineTitle1', type: 'text' }, { text: 'lineTitle1', type: 'text' },
[11, 45.5, 67, 23] [11, 45.5, 67, 23]
); );
expect(mockDB.setLineData).toHaveBeenCalledWith( expect(mockDB.setLineData).toHaveBeenCalledWith(
{ text: 'lineTitle2', type: 'text' }, { text: 'lineTitle2', type: 'text' },
[45, 99, 12] [45, 99, 12]
); );
});
});
describe('multiple datasets', () => {
it('parse 2 datasets', () => {
const str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\nbar [["barTitle1" [23, 45, 56.6]],["barTitle2" [13, 42, 56.89]]]';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
expect(mockDB.setBarData).toHaveBeenCalledWith([
[
[{ text: 'barTitle1', type: 'text' }, [23, 45, 56.6]],
[{ text: 'barTitle2', type: 'text' }, [13, 42, 56.89]],
],
]);
});
it('parse 3 datasets', () => {
const str =
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\nbar [["barTitle1" [23, 45, 56.6]],["barTitle2" [13, 42, 56.89]],["barTitle3" [18, 37, 56.1]]]';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
expect(mockDB.setBarData).toHaveBeenCalledWith([
[
[{ text: 'barTitle1', type: 'text' }, [23, 45, 56.6]],
[{ text: 'barTitle2', type: 'text' }, [13, 42, 56.89]],
[{ text: 'barTitle3', type: 'text' }, [18, 37, 56.1]],
],
]);
});
}); });
}); });

View File

@@ -172,15 +172,20 @@ function setLineData(title: NormalTextType, data: number[]) {
type NamedDataset = [title: NormalTextType, data: number[]]; type NamedDataset = [title: NormalTextType, data: number[]];
function setBarData(datasets: NamedDataset[]) { function setBarData(datasets: NamedDataset[]) {
datasets.forEach((dataset) => { datasets[0]
const plotData = transformDataWithoutCategory(dataset[1]); .filter((dataset) => Array.isArray(dataset))
xyChartData.plots.push({ .forEach((dataset) => {
type: 'bar', const data = dataset as any as NamedDataset;
fill: getPlotColorFromPalette(plotIndex), const plotData = transformDataWithoutCategory(
data: plotData, Array.isArray(data[1]) ? data[1] : (dataset as any as number[])
);
xyChartData.plots.push({
type: 'bar',
fill: getPlotColorFromPalette(plotIndex),
data: plotData,
});
plotIndex++;
}); });
plotIndex++;
});
} }
function getDrawableElem(): DrawableElem[] { function getDrawableElem(): DrawableElem[] {