Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(api): use api and spec together #5074

Merged
merged 2 commits into from
May 23, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
187 changes: 185 additions & 2 deletions __tests__/unit/api/options.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Chart } from '../../../src';
import { Point } from '../../../src/api/mark/mark';

describe('API and Options', () => {
it('', () => {
describe('chart api and options', () => {
it('chart.options({...}) should create node instance from spec.', () => {
const chart = new Chart({});

chart.options({
Expand All @@ -18,5 +19,187 @@ describe('API and Options', () => {
y: 'sold',
},
});

expect(chart.getNodeByType('view')).toBeDefined();
expect(chart.getNodeByType('interval')).toBeDefined();
});

it('chart.options({...}) should bubble view options', () => {
const chart = new Chart({});

chart.options({
type: 'interval',
width: 100,
height: 100,
padding: 10,
paddingLeft: 10,
paddingRight: 10,
paddingBottom: 10,
paddingTop: 10,
inset: 10,
insetLeft: 10,
insetRight: 10,
insetTop: 10,
insetBottom: 10,
margin: 10,
marginLeft: 10,
marginRight: 10,
marginTop: 10,
marginBottom: 10,
autoFit: 10,
theme: 10,
});

expect(chart.options()).toEqual({
type: 'view',
width: 100,
height: 100,
padding: 10,
paddingLeft: 10,
paddingRight: 10,
paddingBottom: 10,
paddingTop: 10,
inset: 10,
insetLeft: 10,
insetRight: 10,
insetTop: 10,
insetBottom: 10,
margin: 10,
marginLeft: 10,
marginRight: 10,
marginTop: 10,
marginBottom: 10,
autoFit: 10,
theme: 10,
children: [{ type: 'interval' }],
});
});

it('chart.options({...}) should create nested node tree from spec.', () => {
const chart = new Chart({});
const options = {
type: 'spaceFlex',
flex: [1, 2],
children: [
{
type: 'spaceLayer',
children: [
{
type: 'view',
children: [
{ type: 'interval', data: [2, 3, 4] },
{ type: 'point' },
],
},
],
},
{ type: 'interval', data: [1, 2, 3] },
],
};

chart.options(options);

expect(chart.options()).toEqual(options);
expect(chart.getNodeByType('point')).toBeInstanceOf(Point);
});

it('chart.options({...}) should update node with same height and index.', () => {
const chart = new Chart({});

chart.options({
type: 'view',
children: [{ type: 'interval' }],
});

chart.options({
children: [{ data: [1, 2, 3] }],
});

expect(chart.getNodeByType('interval').value.data).toEqual([1, 2, 3]);
});

it('chart.options({...}) should update nested node tree.', () => {
const chart = new Chart({});

chart.options({
type: 'spaceFlex',
flex: [1, 2],
children: [
{
type: 'spaceLayer',
children: [
{
type: 'view',
children: [
{ type: 'interval', data: [2, 3, 4] },
{ type: 'point' },
],
},
],
},
{ type: 'interval', data: [1, 2, 3] },
],
});

chart.options({
flex: [2, 3, 4],
children: [
{ children: [{ children: [{}, { data: [1, 2, 3] }] }] },
{ data: [2, 3, 4], scale: { x: { nice: true } } },
],
});

expect(chart.options()).toEqual({
type: 'spaceFlex',
flex: [2, 3, 4],
children: [
{
type: 'spaceLayer',
children: [
{
type: 'view',
children: [
{ type: 'interval', data: [2, 3, 4] },
{ type: 'point', data: [1, 2, 3] },
],
},
],
},
{ type: 'interval', data: [2, 3, 4], scale: { x: { nice: true } } },
],
});
});

it('chart.options({...}) should transform node.', () => {
const chart = new Chart({});

chart.options({
type: 'view',
children: [
{ type: 'interval', scale: { x: { nice: true } }, data: [1, 2, 3] },
],
});

chart.options({
type: 'view',
children: [{ type: 'line', data: [4, 5, 6] }],
});

const line = chart.getNodeByType('line');
expect(line.type).toBe('line');
expect(line.value).toEqual({ data: [4, 5, 6] });
});

it('chart.options({...}) should update node tree specified by API.', () => {
const chart = new Chart({});

const interval = chart.interval().data([1, 2, 3]);

chart.options({
type: 'view',
children: [{ data: [2, 3, 4] }],
});

expect(interval.data()).toEqual([2, 3, 4]);
});
});
28 changes: 13 additions & 15 deletions src/api/chart.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IRenderer, RendererPlugin, Canvas as GCanvas } from '@antv/g';
import { Renderer as CanvasRenderer } from '@antv/g-canvas';
import { Plugin as DragAndDropPlugin } from '@antv/g-plugin-dragndrop';
import { debounce, deepMix } from '@antv/util';
import { debounce } from '@antv/util';
import EventEmitter from '@antv/event-emitter';
import { G2Context, render, destroy } from '../runtime';
import { ViewComposition } from '../spec';
Expand All @@ -27,6 +27,8 @@ import {
removeContainer,
sizeOf,
optionsOf,
updateRoot,
VIEW_KEYS,
} from './utils';

export const G2_CHART_KEY = 'G2_CHART_KEY';
Expand Down Expand Up @@ -84,7 +86,6 @@ export class Chart extends View<ChartOptions> {
private _container: HTMLElement;
private _context: G2Context;
private _emitter: EventEmitter;
private _options: G2ViewTree;
private _width: number;
private _height: number;
private _renderer: IRenderer;
Expand Down Expand Up @@ -161,20 +162,11 @@ export class Chart extends View<ChartOptions> {
* @returns {Chart|G2ViewTree}
*/
options(options?: G2ViewTree): Chart | G2ViewTree {
if (arguments.length === 0) {
return this._options || optionsOf(this);
}
this._options = deepMix(this._options || optionsOf(this), options);
if (arguments.length === 0) return optionsOf(this);
updateRoot(this, options);
return this;
}

// @todo Remove it when implement updateRoot.
changeData(data: any): Promise<Chart> {
// Update options data.
this.options({ data });
return super.changeData(data);
}

getContainer(): HTMLElement {
return this._container;
}
Expand Down Expand Up @@ -206,7 +198,7 @@ export class Chart extends View<ChartOptions> {
clear() {
const options = this.options();
this.emit(ChartEvent.BEFORE_CLEAR);
this._options = {};
this._reset();
destroy(options, this._context, false);
this.emit(ChartEvent.AFTER_CLEAR);
}
Expand All @@ -215,7 +207,7 @@ export class Chart extends View<ChartOptions> {
const options = this.options();
this.emit(ChartEvent.BEFORE_DESTROY);
this._unbindAutoFit();
this._options = {};
this._reset();
destroy(options, this._context, true);
removeContainer(this._container);
this.emit(ChartEvent.AFTER_DESTROY);
Expand Down Expand Up @@ -252,6 +244,12 @@ export class Chart extends View<ChartOptions> {
return finished;
}

private _reset() {
this.type = 'view';
this.value = {};
this.children = [];
}

private _onResize = debounce(() => {
this.forceFit();
}, 300);
Expand Down
8 changes: 8 additions & 0 deletions src/api/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,14 @@ export class Node<
return nodes;
}

getNodeByType(type: string): Node {
let node;
bfs(this, (current: Node) => {
if (type === current.type) node = current;
});
return node;
}

pearmini marked this conversation as resolved.
Show resolved Hide resolved
/**
* Apply specified callback to the node value.
*/
Expand Down
Loading