Skip to content

Commit

Permalink
feat: 增加 pattern 贴图 (#2777)
Browse files Browse the repository at this point in the history
* feat: 初始化pattern (#2763)

Co-authored-by: 酥云 <lisuwen.lsw@antgroup.com>

* feat(pattern): 增加可配置的dot贴图,并将patternAdaptor用于饼图 (#2766)

* feat: 初始化pattern

* feat: 增加可配置的dot贴图,并将patternAdptor用于饼图

* refactor: 将pattern统一赋给color,不用style

Co-authored-by: 酥云 <lisuwen.lsw@antgroup.com>

* feat: Upgrade pattern (#2778)

* feat(pattern): pattern 填充作用在 style 上

* feat(pattern): pattern 通道 & 接入柱条形图、玉珏图

* docs(pattern-demo): 增加若干 demo

* refactor: 优化下代码

* docs: 增加 demos 上新标识

* refactor(pattern): 修改 cr 内容 & 优化 demo

* feat(line-pattern): 添加linePattern (#2780)

* feat: 初始化pattern

* feat: 增加可配置的dot贴图,并将patternAdptor用于饼图

* feat: 初始化pattern (#2763)

Co-authored-by: 酥云 <lisuwen.lsw@antgroup.com>

* refactor: 将pattern统一赋给color,不用style

* fix: 修改pattern文件引入路径

Co-authored-by: 酥云 <lisuwen.lsw@antgroup.com>

* refactor(pattern): 内置 pattern 不使用 class 的方式 (#2781)

* feat(square-pattern): 添加square样式贴图 (#2782)

* feat(square-pattern): 添加square样式贴图

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

Co-authored-by: 酥云 <lisuwen.lsw@antgroup.com>

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

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

* 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(pattern): 修复dot的stagger呈现问题,初步添加util中getCanvasPattern的单测 (#2786)

* 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>

* refactor(pattern): 优化pattern的写法,抽出一些方法 (#2788)

* refactor(pattern): 优化代码写法

* refactor(pattern): 优化pattern的写法,抽出一些方法

* refactor(pattern): 抽出util文件

Co-authored-by: 酥云 <lisuwen.lsw@antgroup.com>

* fix(pattern): 解决 pattern 展示模糊问题

* docs(pattern): 优化下demo

* fix(pattern): 修复square pattern 旋转问题 & 优化默认配置参数

* refactor(pattern): 使用setTransform方法,rotation作用于整个pattern画布 (#2789)

* refactor(pattern): 使用setTransform方法,rotation作用于整个pattern画布

* refactor: 处理transformMatrix成纯函数

* refactor: 处理transformMatrix成纯函数

* test(dot and util): 添加dotPattern和util的单测,并添加getPixelColor获取像素点方法

* test(line-pattern): 添加linePattern的单测

* test(square-pattern): 添加squarePattern的单测

* refactor: 修改变换矩阵的写法

Co-authored-by: 酥云 <lisuwen.lsw@antgroup.com>

* docs(pattern): 添加pattern的文档 (#2798)

* docs: 添加pattern的demo (#2799)

Co-authored-by: 酥云 <lisuwen.lsw@antgroup.com>

* refactor: 抽取获取设备像素比的 util

* docs(pattern): pattern 文档完善

* docs: 完善 legend marker 配置文档 & 优化 pattern demo

* fix(pattern): 修复 dot pattern 单测

* feat(pattern): 直方图、水波图、矩阵树图添加 pattern

* test(pattern): 增加 pattern adaptor 的单测

* chore: 优化官网展示

* feat(pattern): 面积图、热力图、迷你柱状图接入 pattern

* fix: 修复单测

* fix: 尝试修复单测

* fix(line-pattern): 修复linewidth>=spacing 时,绘制异常问题 (#2801)

* test(pattern-in-plot): 逐个给每个plot添加pattern的单测,并添加对应的pattern文档 (#2805)

* test(pattern-in-plot): 逐个给每个plot添加pattern的单测,并添加对应的pattern文档

* docs: 修改部分pattern的文档说明以及默认值等

* fix: 修复pattern回调问题,对应的图形如果没有pattern,默认为主题色

* test: 添加column引入pattern的单测,并添加文档

* test: 添加bar引入pattern的单测,并添加文档

* test: 给pie添加pattern的单测,添加文档

* fix(pattern-util): 处理color为数组导致pie的图形变黑情况,统一返回字符串

* test: 给直方图添加pattern的单测,增加文档

* test: 给treemap添加pattern的单测,增加文档

* test: 给heatmap添加pattern的单测和文档,并给patternAttr的类型增加布尔值

* test: 给radial-bar添加pattern的单测,增加文档

* test: 给tiny-column添加pattern的单测,增加文档

* test: 给circle-packing添加pattern的单测,增加文档

* docs: 修改接入文档方式,把标题抽出来

* fix: 给patternAdaptor补充stackFields映射字段,修复stack模式的直方图添加pattern变黑问题

Co-authored-by: 酥云 <lisuwen.lsw@antgroup.com>

* docs: 更新 pattern demo 的截图

* feat(pattern): 修改下 pattern adaptor 获取 color & 旭日图支持 pattern

* fix: 修复一些 lint 问题

* feat(tiny-area): 迷你面积图支持 pattern,同时添加 pattern 与渐变色无法共存的说明文档 (#2811)

* feat(rose): 玫瑰图支持 pattern & demo (#2810)

* feat(liquid): 水波图支持 pattern & demo (#2812)

* test: 补充旭日图等单测和文档 (#2815)

* test: 补充其旭日图等单测和文档

* refactor: 删除pattern的boolean类型

* test(pattern): 添加rose、tiny-area、liquid的单测和文档

Co-authored-by: 酥云 <lisuwen.lsw@antgroup.com>
Co-authored-by: Visiky <736929286@qq.com>

* feat(dual-axes): 双轴图支持 pattern (#2813)

Co-authored-by: Susan <527971893@qq.com>
Co-authored-by: 酥云 <lisuwen.lsw@antgroup.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 24, 2021
1 parent df6a984 commit b517666
Show file tree
Hide file tree
Showing 117 changed files with 3,086 additions and 124 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Feel free to add more content in the body, if you { think } subject is not self-

e.g.

```
```plain
fix($compile): [BREAKING_CHANGE] couple of unit tests for IE9
Older IEs serialize html uppercased, but IE9 does not...
Expand Down
69 changes: 69 additions & 0 deletions __tests__/unit/adaptor/pattern-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { flow } from '../../../src/utils/flow';
import { Plot } from '../../../src/core/plot';
import { pattern } from '../../../src/adaptor/pattern';
import { theme } from '../../../src/adaptor/common';
import { createDiv } from '../../utils/dom';
import { createSquarePattern } from '../../../src/utils/pattern/square';

describe('pattern adaptor', () => {
class APlot extends Plot<any> {
type: 'a-plot';

getDefaultOptions() {
return {};
}

getSchemaAdaptor() {
return (params: any) => flow(theme, pattern('xxx'))(params);
}
}

const plot = new APlot(createDiv(), {
color: ['red', 'yellow'],
xxx: {
stroke: 'red',
},
});

it('default', () => {
expect(typeof pattern('xxx')).toBe('function');
let params = pattern('xxx')({ chart: plot.chart, options: plot.options });
expect(params.options.xxx.fill).toBeUndefined();

params = pattern('xxx')({ chart: plot.chart, options: { ...plot.options, pattern: { type: 'dot' } } });
expect(params.options.xxx).not.toBeUndefined();
expect(params.options.xxx.call().fill instanceof CanvasPattern).toBe(true);

// callback
params = pattern('xxx')({ chart: plot.chart, options: { ...plot.options, pattern: () => ({ type: 'line' }) } });
expect(params.options.xxx.call().fill instanceof CanvasPattern).toBe(true);

// canvasPattern
const suqarePattern = createSquarePattern({ size: 10, padding: 0, isStagger: true });
params = pattern('xxx')({ chart: plot.chart, options: { ...plot.options, pattern: suqarePattern } });
expect(params.options.xxx.call().fill instanceof CanvasPattern).toBe(true);
});

it('xxx configuration', () => {
let params = pattern('xxx')({ chart: plot.chart, options: { ...plot.options, pattern: { type: 'dot' } } });
expect(params.options.xxx.call().stroke).toBe('red');

params = pattern('xxx')({
chart: plot.chart,
options: { ...plot.options, xxx: () => ({ stroke: 'red', fill: 'yellow' }), pattern: null },
});
expect(params.options.xxx.call().stroke).toBe('red');
expect(params.options.xxx.call().fill).toBe('yellow');

params = pattern('xxx')({
chart: plot.chart,
options: { ...plot.options, xxx: () => ({ stroke: 'red', fill: 'yellow' }), pattern: { type: 'dot' } },
});
expect(params.options.xxx.call().stroke).toBe('red');
expect(params.options.xxx.call().fill instanceof CanvasPattern).toBe(true);
});

afterAll(() => {
plot.destroy();
});
});
77 changes: 77 additions & 0 deletions __tests__/unit/plots/area/pattern-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { Area } from '../../../../src';
import { percentData } from '../../../data/area';
import { createDiv } from '../../../utils/dom';

describe('area', () => {
it('pattern: obj', () => {
const area = new Area(createDiv(), {
data: percentData,
width: 400,
height: 300,
xField: 'year',
yField: 'value',
seriesField: 'country',
pattern: {
type: 'line',
},
});

area.render();

const geometry = area.chart.geometries[0];
const elements = geometry.elements;
expect(elements[0].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(elements[1].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(elements[2].shape.attr('fill') instanceof CanvasPattern).toEqual(true);

area.update({
pattern: {
type: 'dot',
},
});

expect(area.chart.geometries[0].elements[0].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(area.chart.geometries[0].elements[1].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(area.chart.geometries[0].elements[2].shape.attr('fill') instanceof CanvasPattern).toEqual(true);

area.destroy();
});

it('pattern: function', () => {
const area = new Area(createDiv(), {
data: percentData,
width: 400,
height: 300,
xField: 'year',
yField: 'value',
seriesField: 'country',
pattern: ({ country }) => {
if (country === 'Asia') {
return {
type: 'line',
};
}
},
});
area.render();

const geometry = area.chart.geometries[0];
const elements = geometry.elements;
expect(elements[0].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(elements[1].shape.attr('fill') instanceof CanvasPattern).toEqual(false);

area.update({
pattern: ({ country }) => {
if (country === 'Africa') {
return {
type: 'line',
};
}
},
});
expect(area.chart.geometries[0].elements[1].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(area.chart.geometries[0].elements[0].shape.attr('fill') instanceof CanvasPattern).toEqual(false);

area.destroy();
});
});
73 changes: 73 additions & 0 deletions __tests__/unit/plots/bar/pattern-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Bar } from '../../../../src';
import { salesByArea } from '../../../data/sales';
import { createDiv } from '../../../utils/dom';

describe('bar style', () => {
it('pattern: obj', () => {
const bar = new Bar(createDiv(), {
width: 400,
height: 300,
data: salesByArea,
xField: 'sales',
yField: 'area',
pattern: {
type: 'line',
},
});

bar.render();

const geometry = bar.chart.geometries[0];
const elements = geometry.elements;
expect(elements[0].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(elements[1].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(elements[2].shape.attr('fill') instanceof CanvasPattern).toEqual(true);

bar.update({
pattern: {
type: 'dot',
},
});

expect(bar.chart.geometries[0].elements[0].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(bar.chart.geometries[0].elements[1].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(bar.chart.geometries[0].elements[2].shape.attr('fill') instanceof CanvasPattern).toEqual(true);

bar.destroy();
});

it('pattern: callback', () => {
const bar = new Bar(createDiv(), {
width: 400,
height: 300,
data: salesByArea,
xField: 'sales',
yField: 'area',
pattern: ({ area }) => {
if (area === '华北') {
return { type: 'dot' };
}
},
});

bar.render();

const geometry = bar.chart.geometries[0];
const elements = geometry.elements;
expect(elements[2].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(elements[0].shape.attr('fill') instanceof CanvasPattern).toEqual(false);

bar.update({
pattern: ({ area }) => {
if (area === '西南') {
return { type: 'dot' };
}
},
});

expect(bar.chart.geometries[0].elements[0].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(bar.chart.geometries[0].elements[1].shape.attr('fill') instanceof CanvasPattern).toEqual(false);

bar.destroy();
});
});
66 changes: 66 additions & 0 deletions __tests__/unit/plots/circle-packing/pattern-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { CirclePacking } from '../../../../src';
import { createDiv } from '../../../utils/dom';
import { DATA } from '../../../data/circle-packing';

describe('Circle-Packing', () => {
const div = createDiv();
it('pattern: obj', () => {
const plot = new CirclePacking(div, {
padding: 0,
data: DATA,
hierarchyConfig: {
sort: (a, b) => b.depth - a.depth,
},
pattern: {
type: 'line',
},
});
plot.render();

const geometry = plot.chart.geometries[0];
const elements = geometry.elements;
expect(elements[0].shape.attr('fill') instanceof CanvasPattern).toEqual(true);

plot.update({
pattern: null,
});

expect(plot.chart.geometries[0].elements[0].shape.attr('fill') instanceof CanvasPattern).toEqual(false);

plot.destroy();
});

it('pattern: callback', () => {
const plot = new CirclePacking(div, {
padding: 0,
data: DATA,
hierarchyConfig: {
sort: (a, b) => b.depth - a.depth,
},
pattern: ({ depth }) => {
if (depth === 0) {
return { type: 'line' };
}
},
});
plot.render();

const geometry = plot.chart.geometries[0];
const elements = geometry.elements;
expect(elements[0].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(elements[1].shape.attr('fill') instanceof CanvasPattern).toEqual(false);

plot.update({
pattern: ({ depth }) => {
if (depth === 1) {
return { type: 'square' };
}
},
});

expect(plot.chart.geometries[0].elements[0].shape.attr('fill') instanceof CanvasPattern).toEqual(false);
expect(plot.chart.geometries[0].elements[1].shape.attr('fill') instanceof CanvasPattern).toEqual(true);

plot.destroy();
});
});
73 changes: 73 additions & 0 deletions __tests__/unit/plots/column/pattern-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Column } from '../../../../src';
import { salesByArea } from '../../../data/sales';
import { createDiv } from '../../../utils/dom';

describe('column', () => {
it('pattern: obj', () => {
const column = new Column(createDiv(), {
width: 400,
height: 300,
data: salesByArea,
xField: 'area',
yField: 'sales',
pattern: {
type: 'line',
},
});

column.render();

const geometry = column.chart.geometries[0];
const elements = geometry.elements;
expect(elements[0].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(elements[1].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(elements[2].shape.attr('fill') instanceof CanvasPattern).toEqual(true);

column.update({
pattern: {
type: 'dot',
},
});

expect(column.chart.geometries[0].elements[0].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(column.chart.geometries[0].elements[1].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(column.chart.geometries[0].elements[2].shape.attr('fill') instanceof CanvasPattern).toEqual(true);

column.destroy();
});

it('pattern: function', () => {
const column = new Column(createDiv(), {
width: 400,
height: 300,
data: salesByArea,
xField: 'area',
yField: 'sales',
pattern: ({ area }) => {
if (area === '华北') {
return { type: 'dot' };
}
},
});

column.render();

const geometry = column.chart.geometries[0];
const elements = geometry.elements;
expect(elements[3].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(elements[0].shape.attr('fill') instanceof CanvasPattern).toEqual(false);

column.update({
pattern: ({ area }) => {
if (area === '中南') {
return { type: 'line' };
}
},
});

expect(column.chart.geometries[0].elements[1].shape.attr('fill') instanceof CanvasPattern).toEqual(true);
expect(column.chart.geometries[0].elements[0].shape.attr('fill') instanceof CanvasPattern).toEqual(false);

column.destroy();
});
});
Loading

0 comments on commit b517666

Please sign in to comment.