Skip to content

Commit

Permalink
feat(view): add syncViewPadding support callback (#2995)
Browse files Browse the repository at this point in the history
* feat(view): add syncViewPadding support callback

* chore: rename new to instance
  • Loading branch information
hustcc committed Nov 10, 2020
1 parent d20edcf commit c8355f2
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 14 deletions.
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "@antv/g2",
"version": "4.1.0-beta.17",
"version": "4.1.0-beta.18",
"description": "the Grammar of Graphics in Javascript",
"main": "lib/index.js",
"module": "esm/index.js",
Expand Down
22 changes: 22 additions & 0 deletions src/chart/layout/padding-cal.ts
Expand Up @@ -2,13 +2,28 @@ import { DIRECTION } from '../../constant';
import { BBox } from '../../dependents';
import { Padding } from '../../interface';

export type PaddingCalCtor = {
readonly instance: (top?: number, right?: number, bottom?: number, left?: number) => PaddingCal;
};

/** @ignore */
export class PaddingCal {
private top: number;
private right: number;
private bottom: number;
private left: number;

/**
* 使用静态方法创建一个
* @param top
* @param right
* @param bottom
* @param left
*/
public static instance(top: number = 0, right: number = 0, bottom: number = 0, left: number = 0) {
return new PaddingCal(top, right, bottom, left);
}

/**
* 初始的 padding 数据
* @param top
Expand Down Expand Up @@ -98,4 +113,11 @@ export class PaddingCal {
public getPadding(): Padding {
return [this.top, this.right, this.bottom, this.left];
}

/**
* clone 一个 padding cal
*/
public clone(): PaddingCal {
return new PaddingCal(...this.getPadding());
}
}
17 changes: 17 additions & 0 deletions src/chart/util/sync-view-padding.ts
@@ -0,0 +1,17 @@
import { PaddingCalCtor } from '../layout/padding-cal';
import{ View } from '../view';

/**
* 默认的 syncViewPadding 逻辑
* @param chart
* @param views
* @param PC: PaddingCalCtor
*/
export function defaultSyncViewPadding(chart: View, views: View[], PC: PaddingCalCtor) {
const syncPadding = PC.instance();

// 所有的 view 的 autoPadding 指向同一个引用
views.forEach((v: View) => {
v.autoPadding = syncPadding.max(v.autoPadding.getPadding());
});
}
15 changes: 7 additions & 8 deletions src/chart/view.ts
Expand Up @@ -63,6 +63,7 @@ import defaultLayout, { Layout } from './layout';
import { ScalePool } from './util/scale-pool';
import { PaddingCal } from './layout/padding-cal';
import { calculatePadding } from './layout/auto';
import { defaultSyncViewPadding } from './util/sync-view-padding';

/**
* G2 视图 View 类
Expand Down Expand Up @@ -1348,15 +1349,13 @@ export class View extends Base {
*/
protected renderLayoutRecursive(isUpdate: boolean) {
// 1. 同步子 view padding
if (this.syncViewPadding) {
const syncPadding = new PaddingCal();
// 根据配置获取 padding
const syncViewPaddingFn = this.syncViewPadding === true ? defaultSyncViewPadding :
isFunction(this.syncViewPadding) ? this.syncViewPadding : undefined;

// 所有的 view 的 autoPadding 指向同一个引用
this.views.forEach((v: View) => {
v.autoPadding = syncPadding.max(v.autoPadding.getPadding());
});

// 更新 coordinate
if (syncViewPaddingFn) {
syncViewPaddingFn(this, this.views, PaddingCal);
// 同步 padding 之后,更新 coordinate
this.views.forEach((v: View) => {
v.coordinateBBox = v.viewBBox.shrink(v.autoPadding.getPadding());
v.adjustCoordinate();
Expand Down
2 changes: 1 addition & 1 deletion src/core.ts
@@ -1,6 +1,6 @@
/* G2 的一个壳子,不包含 Geometry,由开发者自己定义和引入 */

export const VERSION = '4.1.0-beta.17';
export const VERSION = '4.1.0-beta.18';

// 核心基类导出
export { Chart, View, Event } from './chart'; // Chart, View 类
Expand Down
11 changes: 8 additions & 3 deletions src/interface.ts
Expand Up @@ -36,6 +36,7 @@ import {
import { View } from './chart';
import { Facet } from './facet';
import Element from './geometry/element';
import { PaddingCalCtor } from './chart/layout/padding-cal';

// ============================ 基础类型 ============================
/** 通用对象 */
Expand Down Expand Up @@ -797,6 +798,8 @@ export interface ChartCfg
readonly defaultInteractions?: string[];
}

export type SyncViewPaddingFn = (chart: View, views: View[], PC: PaddingCalCtor) => void;

/** View 构造参数 */
export interface ViewCfg {
/** View id,可以由外部传入 */
Expand Down Expand Up @@ -833,13 +836,15 @@ export interface ViewCfg {
*/
readonly appendPadding?: ViewAppendPadding;
/**
* 是否同步子 view 的 padding
* 是否同步子 view 的 padding,可以是 boolean / SyncViewPaddingFn
* 比如:
* view1 的 padding 10
* view2 的 padding 20
* 那么两个子 view 的 padding 统一变成最大的 20(后面可以传入 function 自己写策略)
* 那么两个子 view 的 padding 统一变成最大的 20.
*
* 如果是 Funcion,则使用自定义的方式去计算子 view 的 padding,这个函数中去修改所有的 views autoPadding 值
*/
readonly syncViewPadding?: boolean;
readonly syncViewPadding?: boolean | SyncViewPaddingFn;
/** 设置 view 实例主题。 */
readonly theme?: LooseObject | string;
/**
Expand Down
47 changes: 46 additions & 1 deletion tests/bugs/2849-spec.ts
@@ -1,8 +1,9 @@
import { Chart } from '../../src';
import { PaddingCal, PaddingCalCtor } from '../../src/chart/layout/padding-cal';
import { createDiv } from '../util/dom';

describe('2849', () => {
it('2849', () => {
it('boolean', () => {
const chart = new Chart({
container: createDiv(),
autoFit: false,
Expand Down Expand Up @@ -37,5 +38,49 @@ describe('2849', () => {

// 不会创建多份 controller
expect(chart.views[0].controllers.length).toBe(6);
});

it('function', () => {
// 均分画布
const fn = jest.fn((c, views, PC: PaddingCalCtor) => {
const [v1, v2] = views;
v1.autoPadding = PC.instance(40, 200, 40, 40);
v2.autoPadding = PC.instance(40, 40, 40, 200);
});

const chart = new Chart({
container: createDiv(),
autoFit: false,
width: 400,
height: 400,
syncViewPadding: fn,
options: {
views: [
{
options: {
data: [{ x: 'A', y: 10 }, { x: 'B', y: 15 }, { x: 'C', 'y': 40 }],
scales: { y: { nice: true } },
geometries: [
{ type: 'interval', position: { fields: ['x', 'y'] } }
]
}
},
{
options: {
data: [{ x: 'A', y1: 23 }, { x: 'B', y1: 40 }, { x: 'C', y1: 100 }],
geometries: [
{ type: 'line', position: { fields: ['x', 'y1'] }, size: { values: [2] } }
],
axes: { x: false, y1: { position: 'right' } }
}
}
],
}
});

chart.render();

expect(fn).toBeCalledTimes(1);
expect(fn).toBeCalledWith(chart, chart.views, PaddingCal);
})
});
11 changes: 11 additions & 0 deletions tests/unit/chart/layout/padding-cal-spec.ts
Expand Up @@ -34,4 +34,15 @@ describe('padding-cal', () => {

expect(pc.getPadding()).toEqual([16, 8, 16, 8]);
});

it('get', () => {
expect(PaddingCal.instance().getPadding()).toEqual([0, 0, 0, 0]);
expect(PaddingCal.instance(1, 2, 3, 4).getPadding()).toEqual([1, 2, 3, 4]);
});

it('clone', () => {
const pc = PaddingCal.instance(1, 2, 3, 4);
expect(pc.clone().getPadding()).toEqual([1, 2, 3, 4]);
expect(pc.clone()).not.toBe(pc);
});
});

0 comments on commit c8355f2

Please sign in to comment.