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(view): add syncViewPadding support callback #2995

Merged
merged 2 commits into from
Nov 10, 2020
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,28 @@ import { DIRECTION } from '../../constant';
import { BBox } from '../../dependents';
import { Padding } from '../../interface';

export type PaddingCalCtor = {
readonly new: (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 new(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
Original file line number Diff line number Diff line change
@@ -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.new();

// 所有的 view 的 autoPadding 指向同一个引用
views.forEach((v: View) => {
v.autoPadding = syncPadding.max(v.autoPadding.getPadding());
});
}
15 changes: 7 additions & 8 deletions src/chart/view.ts
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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.new(40, 200, 40, 40);
v2.autoPadding = PC.new(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
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,15 @@ describe('padding-cal', () => {

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

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

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