Skip to content

Commit

Permalink
test(pattern): 修复dot的stagger呈现问题,初步添加util中getCanvasPattern的单测 (#2786)
Browse files Browse the repository at this point in the history
* feat(square-pattern): 添加square样式贴图

* fix: 修复square形状stroke的rotate问题

* refactor(pattern): 对代码进行一点整理,含类型定义

* refactor(types): 重新定义下 pattern 的属性定义

* chore: 升级官网

* refactor(pattern): 内置 pattern 的属性设计 & 优化下创建逻辑 (#2785)

* feat(dot-pattern): 优化 dot pattern, 修复 stagger 展示

* feat(square-pattern): 优化 square pattern, 修复 stagger 展示

* refactor(pattern): 优化 line pattern & 删除无用代码

* refactor: 一些代码上的优化 & 删除无用的代码

* refactor(pattern): 初始化 canvas 的逻辑,抽取为一个 util 函数

* test: 修复dot的stagger呈现问题,初步添加util中getCanvasPattern的单测

* 修复:   [BUG] 双轴图图例legend使用symbol的时候,颜色不能自动调整 (#2776)

* fix: 修复 [BUG] 双轴图图例legend使用symbol的时候,颜色不能自动调整

* fix: 修复 [BUG] 双轴图图例legend使用symbol的时候,颜色不能自动调整  -2

Co-authored-by: ai-qing-hai <wb-xcf804241@antgroup.com>

* test: 修复dot的stagger呈现问题,初步添加util中getCanvasPattern的单测

* refactor: 修改pattern单测中的写法

Co-authored-by: 酥云 <lisuwen.lsw@antgroup.com>
Co-authored-by: visiky <736929286@qq.com>
Co-authored-by: ai-qing-hai <65594180+ai-qing-hai@users.noreply.github.com>
Co-authored-by: ai-qing-hai <wb-xcf804241@antgroup.com>
  • Loading branch information
5 people authored Aug 11, 2021
1 parent ebb9e58 commit 7397bad
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 36 deletions.
28 changes: 28 additions & 0 deletions __tests__/unit/plots/dual-axes/legend-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,34 @@ describe('Legend', () => {
});
});

it('Legend custom', () => {
const dualAxes = new DualAxes(createDiv('Legend custom '), {
width: 400,
height: 500,
data: [PV_DATA, UV_DATA],
xField: 'date',
yField: ['pv', 'uv'],
legend: {
marker: {
symbol: 'diamond',
},
},
});

dualAxes.render();

const legendController = dualAxes.chart.getController('legend');
const legendComponent = legendController.getComponents()[0];
const cfg = legendComponent.component.cfg;

expect(cfg.items[0].marker.symbol).toBe('diamond');
expect(cfg.items[1].marker.symbol).toBe('diamond');
expect(cfg.items[0].marker.style.fill).toBe('#5B8FF9');
expect(cfg.items[1].marker.style.fill).toBe('#5AD8A6');

dualAxes.destroy();
});

it('Legend custom', () => {
const dualAxes = new DualAxes(createDiv('Legend custom '), {
width: 400,
Expand Down
69 changes: 69 additions & 0 deletions __tests__/unit/utils/pattern/index-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { getCanvasPattern, PatternOption } from '../../../../src/utils/pattern';

describe('getCanvasPattern', () => {
it('dot-pattern without cfg', () => {
const pattern = getCanvasPattern({ type: 'dot' });
expect(pattern.toString()).toEqual('[object CanvasPattern]');
});

it('dot-pattern with cfg', () => {
const patternOption = {
type: 'dot',
cfg: {
radius: 4,
padding: 6,
},
} as PatternOption;
const pattern = getCanvasPattern(patternOption);
expect(pattern.toString()).toEqual('[object CanvasPattern]');
});

it('line-pattern without cfg', () => {
const pattern = getCanvasPattern({ type: 'line' });
expect(pattern.toString()).toEqual('[object CanvasPattern]');
});

it('line-pattern with cfg', () => {
const patternOption = {
type: 'dot',
cfg: {
rotation: 0,
spacing: 12,
stroke: '#FFF',
},
} as PatternOption;
const pattern = getCanvasPattern(patternOption);
expect(pattern.toString()).toEqual('[object CanvasPattern]');
});

it('square-pattern without cfg', () => {
const pattern = getCanvasPattern({ type: 'square' });
expect(pattern.toString()).toEqual('[object CanvasPattern]');
});

it('square-pattern with cfg', () => {
const patternOption = {
type: 'dot',
cfg: {
size: 4,
padding: 10,
backgroundColor: 'transparent',
fill: 'transparent',
},
} as PatternOption;
const pattern = getCanvasPattern(patternOption);
expect(pattern.toString()).toEqual('[object CanvasPattern]');
});

it('pattern without option', () => {
//@ts-ignore
const pattern = getCanvasPattern({});
expect(pattern).toEqual(undefined);
});

it('pattern with error type', () => {
//@ts-ignore
const pattern = getCanvasPattern({ type: 'xxx' });
expect(pattern).toEqual(undefined);
});
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"lint": "eslint --ext .ts ./src ./__tests__ && prettier --check ./src ./__tests__ && lint-md ./examples ./docs",
"lint-staged": "lint-staged",
"test": "jest",
"test-live": "cross-env DEBUG_MODE=1 jest --watch ./__tests__",
"test-live": "cross-env DEBUG_MODE=1 jest --watch ./__tests__/",
"coverage": "jest -w 16 --coverage",
"ci": "run-s lint coverage build",
"changelog": "generate-changelog",
Expand Down
18 changes: 15 additions & 3 deletions src/plots/dual-axes/util/legend.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { reduce, get } from '@antv/util';
import { reduce, get, isEmpty, isFunction } from '@antv/util';
import { View, Util } from '@antv/g2';
import { findGeometry } from '../../../utils';
import { deepAssign, findGeometry } from '../../../utils';
import { GeometryOption } from '../types';
import { Legend } from '../../../types/legend';
import { isLine } from './option';
Expand All @@ -24,7 +24,19 @@ export function getViewLegendItems(params: {
const color = colorAttribute.values[0];

const marker =
userMarker ||
(isFunction(userMarker)
? userMarker
: !isEmpty(userMarker) &&
deepAssign(
{},
{
style: {
stroke: color,
fill: color,
},
},
userMarker
)) ||
(isLine(geometryOption)
? {
symbol: (x: number, y: number, r: number) => {
Expand Down
5 changes: 3 additions & 2 deletions src/types/pattern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ export type PatternCfg = {
strokeOpacity?: number;
/** lines thickness. 描边粗细 */
lineWidth?: number;

/** 图案以及背景色 */
opacity?: number; // 整个贴图透明
/** 贴图模式 */
mode?: 'repeat' | 'no-repeat' | 'repeat-x' | 'repeat-y';
opacity: number; // 整个贴图透明
};

/**
Expand Down
36 changes: 21 additions & 15 deletions src/utils/pattern/dot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@ import { deepAssign } from '../../utils';
*/
export function initCanvas(canvas: HTMLCanvasElement, width: number, height: number = width) {
// ~~~ 后续再行测试 ~~~
const pixelRatio = window?.devicePixelRatio || 2;
const logicalWidth = width;
const logicalHeight = height;
// const pixelRatio = window?.devicePixelRatio || 2;
// const logicalWidth = width;
// const logicalHeight = height;
// 画布尺寸
canvas.width = logicalWidth * pixelRatio;
canvas.height = logicalHeight * pixelRatio;
// canvas.width = logicalWidth * pixelRatio;
// canvas.height = logicalHeight * pixelRatio;
// 显示尺寸
canvas.style.width = `${logicalWidth}px`;
canvas.style.height = `${logicalHeight}px`;
// canvas.style.width = `${logicalWidth}px`;
// canvas.style.height = `${logicalHeight}px`;
// ~~~ 后续再行测试 ~~~
canvas.width = width;
canvas.height = height;
}

/**
Expand Down Expand Up @@ -64,7 +66,7 @@ function drawDot(context: CanvasRenderingContext2D, cfg: DotPatternCfg, x: numbe
* @param cfg
* @returns HTMLCanvasElement
*/
export function createDotPattern(cfg: DotPatternCfg): CanvasPattern {
export function createDotPattern(cfg?: DotPatternCfg): CanvasPattern {
const dotCfg = deepAssign(
{},
{
Expand All @@ -77,30 +79,34 @@ export function createDotPattern(cfg: DotPatternCfg): CanvasPattern {
stroke: 'transparent',
lineWidth: 0,
isStagger: true,
mode: 'repeat',
},
cfg
);

/** 大小 */
const { radius, padding, isStagger } = dotCfg;
const dots = [[padding / 2 + radius, padding / 2 + radius]];

let size = radius * 2 + padding;
let unitSize = radius * 2 + padding;

const dotCenterPos = unitSize / 2;
const dots = [[dotCenterPos, dotCenterPos]];

// 如果交错, size 放大两倍 交错绘制 dot
if (isStagger) {
dots.push([size + radius, size + radius]);
size *= 2;
dots.push([dotCenterPos * 3, dotCenterPos * 3]);
unitSize *= 2;
}

const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');

initCanvas(canvas, size);
drawBackground(ctx, dotCfg, size);
initCanvas(canvas, unitSize);
drawBackground(ctx, dotCfg, unitSize);
// 绘制图案
for (const [x, y] of dots) {
drawDot(ctx, dotCfg, x, y);
}

return ctx.createPattern(canvas, cfg.mode || 'repeat');
return ctx.createPattern(canvas, dotCfg.mode || 'repeat');
}
5 changes: 3 additions & 2 deletions src/utils/pattern/line.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function drawLine(context: CanvasRenderingContext2D, cfg: LinePatternCfg, d: str
context.stroke(path);
}

export function createLinePattern(cfg: LinePatternCfg): CanvasPattern {
export function createLinePattern(cfg?: LinePatternCfg): CanvasPattern {
const lineCfg = deepAssign(
{},
{
Expand All @@ -24,6 +24,7 @@ export function createLinePattern(cfg: LinePatternCfg): CanvasPattern {
strokeOpacity: 1,
stroke: '#FFF',
lineWidth: 1,
mode: 'repeat',
},
cfg
);
Expand Down Expand Up @@ -86,5 +87,5 @@ export function createLinePattern(cfg: LinePatternCfg): CanvasPattern {
drawBackground(ctx, lineCfg, w, h);
drawLine(ctx, lineCfg, d);

return ctx.createPattern(canvas, cfg.mode || 'repeat');
return ctx.createPattern(canvas, lineCfg.mode || 'repeat');
}
31 changes: 18 additions & 13 deletions src/utils/pattern/square.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,19 @@ function drawSquare(context: CanvasRenderingContext2D, cfg: SquarePatternCfg, x:
context.strokeStyle = stroke;
context.lineWidth = lineWidth;
context.fillStyle = fill;
context.fillRect(x, y, size, size);

// todo 控制旋转
// ctx.translate(x, y);
// ctx.rotate(radians);
// ctx.translate(-x, -y);
// ctx.strokeRect(x - size / 2, y - size / 2, size, size);
// // reset to identity matrix 重制成单位矩阵
// ctx.setTransform(1, 0, 0, 1, 0, 0);
context.translate(x, y);
context.rotate(radians);
context.translate(-x, -y);
context.strokeRect(x - size / 2, y - size / 2, size, size);
// 因为正方形绘制从左上角开始,所以x,y做个偏移
context.fillRect(x - size / 2, y - size / 2, size, size);
// reset to identity matrix 重制成单位矩阵
context.setTransform(1, 0, 0, 1, 0, 0);
}

export function createSquarePattern(cfg: SquarePatternCfg): CanvasPattern {
export function createSquarePattern(cfg?: SquarePatternCfg): CanvasPattern {
const squareCfg = deepAssign(
{},
{
Expand All @@ -35,6 +36,7 @@ export function createSquarePattern(cfg: SquarePatternCfg): CanvasPattern {
stroke: 'transparent',
lineWidth: 0,
isStagger: true,
mode: 'repeat',
},
cfg
);
Expand All @@ -43,19 +45,22 @@ export function createSquarePattern(cfg: SquarePatternCfg): CanvasPattern {
const ctx = canvas.getContext('2d');

const { size, padding, isStagger } = squareCfg;
const squares = [[padding / 2, padding / 2]];

let unitSize = size + padding;
// 如果交错, size 放大两倍 交错绘制 dot

const squareCenterPos = unitSize / 2;
const squares = [[squareCenterPos, squareCenterPos]];

// 如果交错, size 放大两倍 交错绘制 square
if (isStagger) {
squares.push([unitSize + padding / 2, unitSize + padding / 2]);
squares.push([squareCenterPos * 3, squareCenterPos * 3]);
unitSize *= 2;
}

initCanvas(canvas, size, unitSize);
initCanvas(canvas, unitSize, unitSize);
drawBackground(ctx, squareCfg, unitSize);
for (const [x, y] of squares) {
drawSquare(ctx, squareCfg, x, y);
}
return ctx.createPattern(canvas, cfg.mode || 'repeat');
return ctx.createPattern(canvas, squareCfg.mode || 'repeat');
}

0 comments on commit 7397bad

Please sign in to comment.