Skip to content
Closed
Show file tree
Hide file tree
Changes from 5 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
6 changes: 3 additions & 3 deletions packages/ava/__tests__/unit/advisor/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const myRule: RuleModule = {
},
trigger: (args) => {
const { chartType } = args;
return ['pie_chart'].includes(chartType);
return ['pie_chart'].includes(chartType!);
},
validator: (args) => {
let result = 1;
Expand Down Expand Up @@ -61,8 +61,8 @@ describe('init Advisor', () => {

test('data to advices with ckb config custom chart', () => {
const splitAngleColor = (dataProps: BasicDataPropertyForAdvice[]) => {
const field4Color = dataProps.find((field) => hasSubset(field.levelOfMeasurements, ['Nominal']));
const field4Angle = dataProps.find((field) => hasSubset(field.levelOfMeasurements, ['Interval']));
const field4Color = dataProps.find((field) => hasSubset(field.levelOfMeasurements!, ['Nominal']));
const field4Angle = dataProps.find((field) => hasSubset(field.levelOfMeasurements!, ['Interval']));
return [field4Color, field4Angle];
};

Expand Down
5 changes: 3 additions & 2 deletions packages/ava/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@antv/ava",
"version": "3.4.1",
"version": "3.5.0-alpha.1",
"description": "A framework for automated visual analytics.",
"author": {
"name": "AntV",
Expand Down Expand Up @@ -55,14 +55,15 @@
},
"dependencies": {
"@antv/antv-spec": "^0.1.0-alpha.18",
"@antv/color-schema": "^0.2.3",
"@antv/g2": "^5.0.8",
"@antv/smart-color": "^0.2.1",
"@antv/color-schema": "^0.2.3",
"bayesian-changepoint": "^1.0.1",
"csstype": "^3.1.2",
"heap-js": "^2.1.6",
"lodash": "^4.17.21",
"regression": "^2.0.1",
"tapable": "^2.2.1",
"tslib": "^2.3.1"
},
"devDependencies": {
Expand Down
16 changes: 11 additions & 5 deletions packages/ava/src/advisor/advise-pipeline/data-to-advices.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { cloneDeep, deepMix } from '../utils';

import { getChartTypeSpec } from './spec-generator';
import { getChartTypeSpec } from './plugin/presets/spec-generator';
import { DEFAULT_COLOR } from './constants';
import { getChartTypeRecommendations } from './get-chart-Type';
import { applyTheme, applyDesignRules, applySmartColor } from './spec-processors';
import { getDataProps, getSelectedData } from './data-processors';
import { getChartTypeRecommendations } from './plugin/presets/chart-type-recommend/get-chart-Type';
import { applyTheme, applyDesignRules, applySmartColor } from './plugin/presets/spec-generator/spec-processors';
import { getDataProps, getSelectedData } from './plugin/presets/data-processors';

import type { ScoringResultForChartType, Advice, AdviseResult, ChartAdviseParams } from '../types';
import type { RuleModule } from '../ruler/types';
import type { ChartKnowledgeBase } from '../../ckb';

/**
* @deprecated 已改造为 plugin 插件形式,之前的硬编码形式函数后续清理掉
* recommending charts given data and dataProps, based on CKB and RuleBase
*
* @param params input params for charts recommending
Expand Down Expand Up @@ -46,7 +47,12 @@ export function dataToAdvices({
const list: Advice[] = chartTypeRecommendations.map((result) => {
// step 2: generate spec for each chart type
const { score, chartType } = result;
const chartTypeSpec = getChartTypeSpec(chartType, filteredData, dataProps, ckb[chartType]);
const chartTypeSpec = getChartTypeSpec({
chartType,
data: filteredData,
dataProps,
chartKnowledge: ckb[chartType],
});

// step 3: apply spec processors such as design rules, theme, color, to improve spec
if (chartTypeSpec && refine) {
Expand Down
4 changes: 2 additions & 2 deletions packages/ava/src/advisor/advise-pipeline/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export * from './data-to-advices';
export * from './spec-generator';
export * from './data-processors';
export * from './plugin/presets/spec-generator';
export * from './plugin/presets/data-processors';
1 change: 1 addition & 0 deletions packages/ava/src/advisor/advise-pipeline/plugin/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './presets';
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
import { compareAdvices, scoreRules } from './score-calculator';
import { compareAdvices, scoreRules } from '../../../score-calculator';

import type { ChartKnowledge } from '../../ckb';
import type { ScoringResultForChartType, BasicDataPropertyForAdvice, RuleModule, AdvisorOptions } from '../types';
import type { ChartKnowledge } from '../../../../../ckb';
import type {
ScoringResultForChartType,
BasicDataPropertyForAdvice,
RuleModule,
AdvisorOptions,
AdvisorPipelineContext,
} from '../../../../types';

export const getChartTypeRecommendations = ({
chartWIKI,
dataProps,
ruleBase,
options,
advisorContext,
}: {
dataProps: BasicDataPropertyForAdvice[];
chartWIKI: Record<string, ChartKnowledge>;
ruleBase: Record<string, RuleModule>;
options?: AdvisorOptions;
advisorContext?: Pick<AdvisorPipelineContext, 'extra'>;
}) => {
const chatTypes = Object.keys(chartWIKI);
const list: ScoringResultForChartType[] = chatTypes.map((chartType) => {
return scoreRules(chartType, chartWIKI, dataProps, ruleBase, options);
return scoreRules(chartType, chartWIKI, dataProps, ruleBase, options, advisorContext);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

看到了个之前遗留的不统一的点:chartWIKI 是不是要小驼峰?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

内部的函数我改了,但是之前有 validator 和 trigger 对外的 api 里有 chartWIKI,这个版本目前还不想产生不向下兼容的 break change... 所以对外接口里的还是先不改吧
Screenshot 2024-07-08 at 11 41 58

});

// filter and sorter
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './get-chart-Type';
export { chartTypeRecommendPlugin } from './plugin-config';
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { getChartTypeRecommendations } from './get-chart-Type';

import type {
AdvisorPipelineContext,
ChartTypeRecommendInput,
ChartTypeRecommendOutput,
AdvisorPluginType,
} from '../../../../types';

export const chartTypeRecommendPlugin: AdvisorPluginType<ChartTypeRecommendInput, ChartTypeRecommendOutput> = {
name: 'defaultChartTypeRecommend',
stage: ['chartTypeRecommend'],
execute(input: ChartTypeRecommendInput, context?: AdvisorPipelineContext): ChartTypeRecommendOutput {
const { dataProps } = input;
const { advisor, options, extra } = context || {};
const chartTypeRecommendations = getChartTypeRecommendations({
dataProps,
chartWIKI: advisor.ckb,
ruleBase: advisor.ruleBase,
options,
advisorContext: { extra },
});
return { chartTypeRecommendations };
},
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DataFrame } from '../../../data';
import { DataFrame } from '../../../../../data';

import type { Data } from '../../../common/types';
import type { BasicDataPropertyForAdvice } from '../../types';
import type { Data } from '../../../../../common/types';
import type { BasicDataPropertyForAdvice } from '../../../../types';

/**
* A utility function that assemble dataProps with user input and DataFrame
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Data } from '../../../common/types';
import { Data } from '../../../../../common/types';

/** filter out fields that are not included for advising */
export const getSelectedData = ({ data, fields }: { data: Data; fields?: string[] }) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './get-data-properties';
export * from './get-selected-data';
export { dataProcessorPlugin } from './plugin-config';
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { cloneDeep } from 'lodash';

import { getDataProps } from './get-data-properties';
import { getSelectedData } from './get-selected-data';

import type {
AdvisorPipelineContext,
DataProcessorInput,
DataProcessorOutput,
AdvisorPluginType,
} from '../../../../types';

export const dataProcessorPlugin: AdvisorPluginType<DataProcessorInput, DataProcessorOutput> = {
name: 'defaultDataProcessor',
stage: ['dataAnalyze'],
execute: (input: DataProcessorInput, context: AdvisorPipelineContext): DataProcessorOutput => {
const { data, customDataProps } = input;
const { fields } = context?.options || {};
const copyData = cloneDeep(data);
const dataProps = getDataProps(copyData, fields, customDataProps);
const filteredData = getSelectedData({ data: copyData, fields });
return {
data: filteredData,
dataProps,
};
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './chart-type-recommend';
export * from './data-processors';
export * from './spec-generator';
export * from './visual-encoder';
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { hasSubset, intersects } from '../../../utils';
import { splitAreaXYSeries } from '../splitFields';
import { hasSubset, intersects } from '../../../../../utils';
import { splitAreaXYSeries } from '../../visual-encoder/split-fields';
import { getLineSize } from '../../visual-encoder/utils';

import type { Data } from '../../../../common/types';
import type { Advice, BasicDataPropertyForAdvice } from '../../../types';
import type { Data, Datum } from '../../../../../../common/types';
import type { Advice, BasicDataPropertyForAdvice } from '../../../../../types';

export function areaChart(data: Data, dataProps: BasicDataPropertyForAdvice[]): Advice['spec'] {
const field4X = dataProps.find((field) => intersects(field.levelOfMeasurements, ['Time', 'Ordinal']));
Expand All @@ -16,6 +17,10 @@ export function areaChart(data: Data, dataProps: BasicDataPropertyForAdvice[]):
encode: {
x: field4X.name,
y: field4Y.name,
size: (datum: Datum) => getLineSize(datum, data, { field4X }),
},
legend: {
size: false,
},
};

Expand All @@ -33,6 +38,10 @@ export function stackedAreaChart(data: Data, dataProps: BasicDataPropertyForAdvi
x: field4X.name,
y: field4Y.name,
color: field4Series.name,
size: (datum: Datum) => getLineSize(datum, data, { field4Split: field4Series, field4X }),
},
legend: {
size: false,
},
transform: [{ type: 'stackY' }],
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { splitBarXYSeries } from '../splitFields';
import { splitBarXYSeries } from '../../visual-encoder/split-fields';

import type { Data } from '../../../../common/types';
import type { Advice, BasicDataPropertyForAdvice } from '../../../types';
import type { Data } from '../../../../../../common/types';
import type { Advice, BasicDataPropertyForAdvice } from '../../../../../types';

export function barChart(data: Data, dataProps: BasicDataPropertyForAdvice[]): Advice['spec'] {
const [field4X, field4Y, field4Color] = splitBarXYSeries(dataProps);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Data } from '../../../../common/types';
import { Advice, BasicDataPropertyForAdvice } from '../../../types';
import { compare, hasSubset } from '../../../utils';
import { splitColumnXYSeries } from '../splitFields';
import { Data } from '../../../../../../common/types';
import { Advice, BasicDataPropertyForAdvice } from '../../../../../types';
import { compare, hasSubset } from '../../../../../utils';
import { splitColumnXYSeries } from '../../visual-encoder/split-fields';

export function columnChart(data: Data, dataProps: BasicDataPropertyForAdvice[]): Advice['spec'] {
const nominalFields = dataProps.filter((field) => hasSubset(field.levelOfMeasurements, ['Nominal']));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { intersects, compare, hasSubset } from '../../../utils';
import { intersects, compare, hasSubset } from '../../../../../utils';

import type { Data } from '../../../../common/types';
import type { BasicDataPropertyForAdvice, Advice } from '../../../types';
import type { Data } from '../../../../../../common/types';
import type { BasicDataPropertyForAdvice, Advice } from '../../../../../types';

export function heatmap(data: Data, dataProps: BasicDataPropertyForAdvice[]): Advice['spec'] {
const axisFields = dataProps.filter((field) => intersects(field.levelOfMeasurements, ['Nominal', 'Ordinal']));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { hasSubset } from '../../../utils';
import { hasSubset } from '../../../../../utils';

import type { Data } from '../../../../common/types';
import type { BasicDataPropertyForAdvice, Advice } from '../../../types';
import type { Data } from '../../../../../../common/types';
import type { BasicDataPropertyForAdvice, Advice } from '../../../../../types';

export function histogram(data: Data, dataProps: BasicDataPropertyForAdvice[]): Advice['spec'] {
const field = dataProps.find((field) => hasSubset(field.levelOfMeasurements, ['Interval']));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { splitLineXY } from '../splitFields';
import { splitLineXY } from '../../visual-encoder/split-fields';
import { getLineSize } from '../../visual-encoder/utils';

import type { Data } from '../../../../common/types';
import type { Advice, BasicDataPropertyForAdvice } from '../../../types';
import type { Data, Datum } from '../../../../../../common/types';
import type { Advice, BasicDataPropertyForAdvice } from '../../../../../types';

export function lineChart(data: Data, dataProps: BasicDataPropertyForAdvice[]): Advice['spec'] {
const [field4X, field4Y, field4Color] = splitLineXY(dataProps);
Expand All @@ -13,6 +14,10 @@ export function lineChart(data: Data, dataProps: BasicDataPropertyForAdvice[]):
encode: {
x: field4X.name,
y: field4Y.name,
size: (datum: Datum) => getLineSize(datum, data, { field4X }),
},
legend: {
size: false,
},
};

Expand All @@ -34,6 +39,10 @@ export function stepLineChart(data: Data, dataProps: BasicDataPropertyForAdvice[
x: field4X.name,
y: field4Y.name,
shape: 'hvh',
size: (datum: Datum) => getLineSize(datum, data, { field4X }),
},
legend: {
size: false,
},
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { splitAngleColor } from '../splitFields';
import { splitAngleColor } from '../../visual-encoder/split-fields';

import type { Data } from '../../../../common/types';
import type { Advice, BasicDataPropertyForAdvice } from '../../../types';
import type { Data } from '../../../../../../common/types';
import type { Advice, BasicDataPropertyForAdvice } from '../../../../../types';

export function pieChart(data: Data, dataProps: BasicDataPropertyForAdvice[]): Advice['spec'] {
const [field4Color, field4Angle] = splitAngleColor(dataProps);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { pearson } from '../../../../data';
import { hasSubset, compare, intersects } from '../../../utils';
import { pearson } from '../../../../../../data';
import { hasSubset, compare, intersects } from '../../../../../utils';

import type { BasicDataPropertyForAdvice, Advice } from '../../../types';
import type { Data } from '../../../../common/types';
import type { BasicDataPropertyForAdvice, Advice } from '../../../../../types';
import type { Data } from '../../../../../../common/types';

export function scatterPlot(data: Data, dataProps: BasicDataPropertyForAdvice[]): Advice['spec'] {
const intervalFields = dataProps.filter((field) => hasSubset(field.levelOfMeasurements, ['Interval']));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CHART_IDS } from '../../../ckb';
import { CHART_IDS } from '../../../../../ckb';

import {
pieChart,
Expand All @@ -22,9 +22,10 @@ import {
histogram,
} from './charts';

import type { Data } from '../../../common/types';
import type { ChartId, ChartKnowledge } from '../../../ckb';
import type { BasicDataPropertyForAdvice } from '../../ruler';
import type { Data } from '../../../../../common/types';
import type { ChartId, ChartKnowledge } from '../../../../../ckb';
import type { BasicDataPropertyForAdvice } from '../../../../ruler';
import type { Advice } from '../../../../types';

/**
* Convert chartType + data to antv-spec
Expand All @@ -36,12 +37,17 @@ import type { BasicDataPropertyForAdvice } from '../../ruler';
* @param chartKnowledge chart knowledge of a singble chart
* @returns spec or null
*/
export function getChartTypeSpec(
chartType: string,
data: Data,
dataProps: BasicDataPropertyForAdvice[],
chartKnowledge?: ChartKnowledge
) {
export function getChartTypeSpec({
chartType,
data,
dataProps,
chartKnowledge,
}: {
chartType: string;
data: Data;
dataProps: BasicDataPropertyForAdvice[];
chartKnowledge?: ChartKnowledge;
}): Advice['spec'] {
// step 0: check whether the chartType is default in `ChartId`
// if not, use customized `toSpec` function
if (!CHART_IDS.includes(chartType as ChartId) && chartKnowledge) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { getChartTypeSpec } from './get-chart-spec';
export { specGeneratorPlugin } from './plugin-config';
Loading