PR modifications
This commit is contained in:
Родитель
e29c668898
Коммит
4771f5bc55
|
@ -185,7 +185,15 @@ export abstract class Chart {
|
|||
}
|
||||
}
|
||||
|
||||
public /*virtual*/ getDataPoint(chartOptions: IChartOptions, point: Highcharts.Point): IDataPoint {
|
||||
public /*virtual*/ verifyInput(options: IVisualizerOptions): void {
|
||||
const columnSelection = options.chartOptions.columnsSelection;
|
||||
|
||||
if(columnSelection.splitBy && columnSelection.splitBy.length > 1) {
|
||||
throw new InvalidInputError(`Multiple split-by columns selection isn't allowed for ${options.chartOptions.chartType}`, ErrorCode.InvalidColumnsSelection);
|
||||
}
|
||||
}
|
||||
|
||||
protected /*virtual*/ getDataPoint(chartOptions: IChartOptions, point: Highcharts.Point): IDataPoint {
|
||||
// Y axis
|
||||
const yAxes = chartOptions.columnsSelection.yAxes;
|
||||
let yAxisColumn;
|
||||
|
@ -224,14 +232,6 @@ export abstract class Chart {
|
|||
return dataPointInfo;
|
||||
}
|
||||
|
||||
public /*virtual*/ verifyInput(options: IVisualizerOptions): void {
|
||||
const columnSelection = options.chartOptions.columnsSelection;
|
||||
|
||||
if(columnSelection.splitBy && columnSelection.splitBy.length > 1) {
|
||||
throw new InvalidInputError(`Multiple split-by columns selection isn't allowed for ${options.chartOptions.chartType}`, ErrorCode.InvalidColumnsSelection);
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion Virtual methods
|
||||
|
||||
//#region Abstract methods
|
||||
|
|
|
@ -24,29 +24,6 @@ interface IPieSeries {
|
|||
export class Pie extends Chart {
|
||||
//#region Methods override
|
||||
|
||||
protected /*override*/ getChartType(): string {
|
||||
return 'pie';
|
||||
};
|
||||
|
||||
protected /*override*/ plotOptions(): Highcharts.PlotOptions {
|
||||
const self = this;
|
||||
|
||||
return {
|
||||
pie: {
|
||||
innerSize: this.getInnerSize(),
|
||||
showInLegend: true,
|
||||
dataLabels: {
|
||||
formatter: function() {
|
||||
return `<b>${this.point.name}</b>${self.getPercentageSuffix(this)}`;
|
||||
},
|
||||
style: {
|
||||
textOverflow: 'ellipsis'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public /*override*/ getStandardCategoriesAndSeries(options: IVisualizerOptions): ICategoriesAndSeries {
|
||||
const xColumn: IColumn = options.chartOptions.columnsSelection.xAxis;
|
||||
const xAxisColumnIndex: number = Utilities.getColumnIndex(options.queryResultData, xColumn);
|
||||
|
@ -154,7 +131,38 @@ export class Pie extends Chart {
|
|||
}
|
||||
}
|
||||
|
||||
public /*virtual*/ getDataPoint(chartOptions: IChartOptions, point: Highcharts.Point): IDataPoint {
|
||||
public /*override*/ verifyInput(options: IVisualizerOptions): void {
|
||||
const columnSelection = options.chartOptions.columnsSelection;
|
||||
|
||||
if(columnSelection.yAxes.length > 1) {
|
||||
throw new InvalidInputError(`Multiple y-axis columns selection isn't allowed for ${options.chartOptions.chartType}`, ErrorCode.InvalidColumnsSelection);
|
||||
}
|
||||
}
|
||||
|
||||
protected /*override*/ getChartType(): string {
|
||||
return 'pie';
|
||||
};
|
||||
|
||||
protected /*override*/ plotOptions(): Highcharts.PlotOptions {
|
||||
const self = this;
|
||||
|
||||
return {
|
||||
pie: {
|
||||
innerSize: this.getInnerSize(),
|
||||
showInLegend: true,
|
||||
dataLabels: {
|
||||
formatter: function() {
|
||||
return `<b>${this.point.name}</b>${self.getPercentageSuffix(this)}`;
|
||||
},
|
||||
style: {
|
||||
textOverflow: 'ellipsis'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected /*override*/ getDataPoint(chartOptions: IChartOptions, point: Highcharts.Point): IDataPoint {
|
||||
const seriesColumnName: string = point.series.name;
|
||||
const xColumn: IColumn = chartOptions.columnsSelection.xAxis;
|
||||
const splitBy = chartOptions.columnsSelection.splitBy;
|
||||
|
@ -189,14 +197,6 @@ export class Pie extends Chart {
|
|||
return dataPointInfo;
|
||||
}
|
||||
|
||||
public /*override*/ verifyInput(options: IVisualizerOptions): void {
|
||||
const columnSelection = options.chartOptions.columnsSelection;
|
||||
|
||||
if(columnSelection.yAxes.length > 1) {
|
||||
throw new InvalidInputError(`Multiple y-axis columns selection isn't allowed for ${options.chartOptions.chartType}`, ErrorCode.InvalidColumnsSelection);
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion Methods override
|
||||
|
||||
protected getInnerSize(): string {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import * as _ from 'lodash';
|
||||
import { DraftColumnType, IColumn, ChartType, ColumnsSelection } from '../../src/common/chartModels';
|
||||
import { DraftColumnType, IColumn, ChartType, ColumnsSelection, IDataPoint } from '../../src/common/chartModels';
|
||||
import { ChartFactory } from '../../src/visualizers/highcharts/charts/chartFactory';
|
||||
import { ICategoriesAndSeries } from '../../src/visualizers/highcharts/charts/chart';
|
||||
import { Utilities } from '../../src/common/utilities';
|
||||
|
@ -1220,5 +1220,319 @@ describe('Unit tests for Chart methods', () => {
|
|||
//#endregion Pie chart
|
||||
});
|
||||
|
||||
describe('Validate getDataPoint method', () => {
|
||||
//#region Line chart getDataPoint
|
||||
|
||||
it('Validate getDataPoint for Line chart with 1 y-axis', () => {
|
||||
// Input
|
||||
options.queryResultData.rows = [
|
||||
['Israel', 'Herzliya', 30, 300],
|
||||
['United States', 'New York', 100, 1000],
|
||||
['Japan', 'Tokyo', 20, 2000],
|
||||
['Russia', 'Moscow', 25, 2250000],
|
||||
];
|
||||
|
||||
const columns: IColumn[] = [
|
||||
{ name: 'country', type: DraftColumnType.String },
|
||||
{ name: 'city', type: DraftColumnType.String },
|
||||
{ name: 'request_count', type: DraftColumnType.Int },
|
||||
{ name: 'second_count', type: DraftColumnType.Int },
|
||||
];
|
||||
|
||||
columnsSelection.xAxis = columns[0]; // country
|
||||
columnsSelection.yAxes = [columns[2]]; // request_count
|
||||
options.queryResultData.columns = columns;
|
||||
|
||||
// Act
|
||||
const chart = ChartFactory.create(ChartType.Line, options);
|
||||
const point = {
|
||||
category: 'Israel',
|
||||
name: undefined,
|
||||
y: 30,
|
||||
series: {
|
||||
name: 'request_count'
|
||||
}
|
||||
};
|
||||
|
||||
const result: IDataPoint = chart['getDataPoint'](options.chartOptions, <Highcharts.Point>point);
|
||||
const expected: IDataPoint = {
|
||||
x: {
|
||||
column: columnsSelection.xAxis,
|
||||
value: 'Israel'
|
||||
},
|
||||
y: {
|
||||
column: columnsSelection.yAxes[0],
|
||||
value: 30
|
||||
},
|
||||
splitBy: undefined
|
||||
};
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Validate getDataPoint for Line chart with 2 y-axes', () => {
|
||||
// Input
|
||||
options.queryResultData.rows = [
|
||||
['Israel', 'Herzliya', 30, 300],
|
||||
['United States', 'New York', 100, 1000],
|
||||
['Japan', 'Tokyo', 20, 2000],
|
||||
['Russia', 'Moscow', 25, 2250000],
|
||||
];
|
||||
|
||||
const columns: IColumn[] = [
|
||||
{ name: 'country', type: DraftColumnType.String },
|
||||
{ name: 'city', type: DraftColumnType.String },
|
||||
{ name: 'request_count', type: DraftColumnType.Int },
|
||||
{ name: 'second_count', type: DraftColumnType.Int },
|
||||
];
|
||||
|
||||
columnsSelection.xAxis = columns[1]; // city
|
||||
columnsSelection.yAxes = [columns[2], columns[3]]; // request_count, second_count
|
||||
options.queryResultData.columns = columns;
|
||||
|
||||
// Act
|
||||
const chart = ChartFactory.create(ChartType.Line, options);
|
||||
|
||||
// Select first y-axis point
|
||||
let point = {
|
||||
category: 'Moscow',
|
||||
name: undefined,
|
||||
y: 25,
|
||||
series: {
|
||||
name: 'request_count'
|
||||
}
|
||||
};
|
||||
|
||||
let result: IDataPoint = chart['getDataPoint'](options.chartOptions, <Highcharts.Point>point);
|
||||
let expected: IDataPoint = {
|
||||
x: {
|
||||
column: columnsSelection.xAxis,
|
||||
value: 'Moscow'
|
||||
},
|
||||
y: {
|
||||
column: columnsSelection.yAxes[0],
|
||||
value: 25
|
||||
},
|
||||
splitBy: undefined
|
||||
};
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual(expected);
|
||||
|
||||
// Select second y-axis point
|
||||
point = {
|
||||
category: 'Moscow',
|
||||
name: undefined,
|
||||
y: 2250000,
|
||||
series: {
|
||||
name: 'second_count'
|
||||
}
|
||||
};
|
||||
|
||||
result = chart['getDataPoint'](options.chartOptions, <Highcharts.Point>point);
|
||||
expected = {
|
||||
x: {
|
||||
column: columnsSelection.xAxis,
|
||||
value: 'Moscow'
|
||||
},
|
||||
y: {
|
||||
column: columnsSelection.yAxes[1],
|
||||
value: 2250000
|
||||
},
|
||||
splitBy: undefined
|
||||
};
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Validate getDataPoint for Line chart with split-by', () => {
|
||||
// Input
|
||||
options.queryResultData.rows = [
|
||||
['Israel', 'Herzliya', 30, 300],
|
||||
['Israel', 'Holon', 12, 120],
|
||||
['United States', 'New York', 100, 1000],
|
||||
['Japan', 'Tokyo', 20, 2000],
|
||||
['Russia', 'Moscow', 25, 2250000],
|
||||
];
|
||||
|
||||
const columns: IColumn[] = [
|
||||
{ name: 'country', type: DraftColumnType.String },
|
||||
{ name: 'city', type: DraftColumnType.String },
|
||||
{ name: 'request_count', type: DraftColumnType.Int },
|
||||
{ name: 'second_count', type: DraftColumnType.Int },
|
||||
];
|
||||
|
||||
columnsSelection.xAxis = columns[0]; // country
|
||||
columnsSelection.yAxes = [columns[2]]; // request_count
|
||||
columnsSelection.splitBy = [columns[1]] // city
|
||||
options.queryResultData.columns = columns;
|
||||
|
||||
// Act
|
||||
const chart = ChartFactory.create(ChartType.Line, options);
|
||||
const point = {
|
||||
category: 'Israel',
|
||||
name: undefined,
|
||||
y: 12,
|
||||
series: {
|
||||
name: 'Holon'
|
||||
}
|
||||
};
|
||||
|
||||
const result: IDataPoint = chart['getDataPoint'](options.chartOptions, <Highcharts.Point>point);
|
||||
const expected: IDataPoint = {
|
||||
x: {
|
||||
column: columnsSelection.xAxis,
|
||||
value: 'Israel'
|
||||
},
|
||||
y: {
|
||||
column: columnsSelection.yAxes[0],
|
||||
value: 12
|
||||
},
|
||||
splitBy: {
|
||||
column: columnsSelection.splitBy[0],
|
||||
value: 'Holon'
|
||||
},
|
||||
};
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
//#endregion Line chart getDataPoint
|
||||
|
||||
//#region Pie chart getDataPoint
|
||||
|
||||
it('Validate getDataPoint for Pie chart without split-by', () => {
|
||||
// Input
|
||||
options.queryResultData.rows = [
|
||||
['Israel', 'Tel Aviv', 10],
|
||||
['United States', 'Redmond', 5],
|
||||
['United States', 'New York', 2],
|
||||
['United States', 'Miami', 3],
|
||||
['Israel', 'Herzliya', 30],
|
||||
['Israel', 'Jaffa', 50],
|
||||
['United States', 'Boston', 1],
|
||||
];
|
||||
|
||||
const columns: IColumn[] = [
|
||||
{ name: 'country', type: DraftColumnType.String },
|
||||
{ name: 'city', type: DraftColumnType.String },
|
||||
{ name: 'request_count', type: DraftColumnType.Int },
|
||||
];
|
||||
|
||||
columnsSelection.xAxis = columns[1]; // city
|
||||
columnsSelection.yAxes = [columns[2]]; // request_count
|
||||
options.queryResultData.columns = columns;
|
||||
|
||||
// Act
|
||||
const chart = ChartFactory.create(ChartType.Pie, options);
|
||||
const point = {
|
||||
category: undefined,
|
||||
name: 'New York',
|
||||
y: 2,
|
||||
series: {
|
||||
name: 'request_count'
|
||||
}
|
||||
};
|
||||
|
||||
const result: IDataPoint = chart['getDataPoint'](options.chartOptions, <Highcharts.Point>point);
|
||||
const expected: IDataPoint = {
|
||||
x: {
|
||||
column: columnsSelection.xAxis,
|
||||
value: 'New York'
|
||||
},
|
||||
y: {
|
||||
column: columnsSelection.yAxes[0],
|
||||
value: 2
|
||||
},
|
||||
splitBy: undefined
|
||||
};
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Validate getDataPoint for Pie chart with split-by', () => {
|
||||
// Input
|
||||
options.queryResultData.rows = [
|
||||
['Israel', 'Tel Aviv', 10],
|
||||
['United States', 'Redmond', 5],
|
||||
['United States', 'New York', 2],
|
||||
['United States', 'Miami', 3],
|
||||
['Israel', 'Herzliya', 30],
|
||||
['Israel', 'Jaffa', 50],
|
||||
['United States', 'Boston', 1],
|
||||
];
|
||||
|
||||
const columns: IColumn[] = [
|
||||
{ name: 'country', type: DraftColumnType.String },
|
||||
{ name: 'city', type: DraftColumnType.String },
|
||||
{ name: 'request_count', type: DraftColumnType.Int },
|
||||
];
|
||||
|
||||
columnsSelection.xAxis = columns[0]; // country
|
||||
columnsSelection.yAxes = [columns[2]]; // request_count
|
||||
columnsSelection.splitBy = [columns[1]] // city
|
||||
options.queryResultData.columns = columns;
|
||||
|
||||
// Act
|
||||
const chart = ChartFactory.create(ChartType.Pie, options);
|
||||
|
||||
// Point in the first pie level
|
||||
let point = {
|
||||
category: undefined,
|
||||
name: 'United States',
|
||||
y: 11,
|
||||
series: {
|
||||
name: 'country'
|
||||
}
|
||||
};
|
||||
|
||||
let result: IDataPoint = chart['getDataPoint'](options.chartOptions, <Highcharts.Point>point);
|
||||
let expected: IDataPoint = {
|
||||
x: {
|
||||
column: columnsSelection.xAxis,
|
||||
value: 'United States'
|
||||
},
|
||||
y: {
|
||||
column: columnsSelection.yAxes[0],
|
||||
value: 11
|
||||
}
|
||||
};
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual(expected);
|
||||
|
||||
// Point in the second pie level
|
||||
point = {
|
||||
category: undefined,
|
||||
name: 'Herzliya',
|
||||
y: 30,
|
||||
series: {
|
||||
name: 'city'
|
||||
}
|
||||
};
|
||||
|
||||
result = chart['getDataPoint'](options.chartOptions, <Highcharts.Point>point);
|
||||
expected = {
|
||||
x: {
|
||||
column: columnsSelection.splitBy[0],
|
||||
value: 'Herzliya'
|
||||
},
|
||||
y: {
|
||||
column: columnsSelection.yAxes[0],
|
||||
value: 30
|
||||
}
|
||||
};
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
//#endregion Pie chart getDataPoint
|
||||
});
|
||||
|
||||
//#endregion Tests
|
||||
});
|
Загрузка…
Ссылка в новой задаче