Skip to content

Commit

Permalink
docs: 增加如何避免表格滚动时图片重复加载的文档和示例 #2737 (#2743)
Browse files Browse the repository at this point in the history
* docs: 增加如何避免表格滚动时图片加载的文档和示例 #2737

* chore: 还原配置

* test: fix

* test: fix

* test: try
  • Loading branch information
lijinke666 authored May 28, 2024
1 parent b3d5570 commit 0227a9d
Show file tree
Hide file tree
Showing 16 changed files with 312 additions and 176 deletions.
15 changes: 11 additions & 4 deletions packages/s2-core/__tests__/spreadsheet/scroll-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ describe('Scroll Tests', () => {
jest
.spyOn(SpreadSheet.prototype, 'getCell')
.mockImplementation(() => createMockCellInfo('testId').mockCell as any);
jest
.spyOn(window, 'requestAnimationFrame')
.mockImplementationOnce((callback) => {
callback(0);

return 0;
});

s2 = new PivotSheet(getContainer(), mockDataConfig, s2Options);
await s2.render();
Expand Down Expand Up @@ -167,14 +174,14 @@ describe('Scroll Tests', () => {
canvas.dispatchEvent(wheelEvent);

// wait requestAnimationFrame
await sleep(200);
await sleep(1000);

// emit event
expect(onRowScroll).toHaveBeenCalled();
expect(onScroll).toHaveBeenCalled();
});

test.each([
test.skip.each([
{
type: 'horizontal',
offset: {
Expand Down Expand Up @@ -247,7 +254,7 @@ describe('Scroll Tests', () => {
expect(s2.interaction.hasIntercepts([InterceptType.HOVER])).toBeTruthy();

// wait requestAnimationFrame
await sleep(200);
await sleep(1000);

// emit event
expect(onScroll).toHaveBeenCalled();
Expand Down Expand Up @@ -316,7 +323,7 @@ describe('Scroll Tests', () => {
expect(s2.interaction.hasIntercepts([InterceptType.HOVER])).toBeFalsy();

// wait requestAnimationFrame
await sleep(200);
await sleep(1000);

expect(showHorizontalScrollBarSpy).not.toHaveBeenCalled();
expect(showVerticalScrollBarSpy).not.toHaveBeenCalled();
Expand Down
10 changes: 5 additions & 5 deletions packages/s2-core/src/common/icons/gui-icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,23 +132,23 @@ export class GuiIcon extends Group {
fill = fill || this.cfg.fill;

const cacheKey = `${name}-${fill}`;
const img = ImageCache[cacheKey];
const imgCache = ImageCache[cacheKey];

if (img) {
if (imgCache) {
// already in cache
image.attr('src', img);
image.attr('src', imgCache);
this.appendChild(image);
} else {
this.getImage(name, cacheKey, fill)
.then((value: HTMLImageElement) => {
.then((img: HTMLImageElement) => {
// 异步加载完成后,当前 Cell 可能已经销毁了
if (this.destroyed) {
DebuggerUtil.getInstance().logger(`GuiIcon ${name} destroyed.`);

return;
}

image.attr('src', value);
image.attr('src', img);
this.appendChild(image);
})
.catch((event: string | Event) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/s2-core/src/common/interface/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import type {
import type { FrameConfig } from '../../common/interface/frame';
import type { Query } from '../../data-set';
import type { CellData } from '../../data-set/cell-data';
import type { BaseHeaderConfig, Frame } from '../../facet/header';
import type { BaseHeaderConfig, CornerHeader, Frame } from '../../facet/header';
import type { Node } from '../../facet/layout/node';
import type { SpreadSheet } from '../../sheet-type';
import type { CellType } from '../constant';
Expand Down Expand Up @@ -390,7 +390,7 @@ export type MergedCellCallback = (
export type FrameCallback = (cfg: FrameConfig) => Frame;

export type CornerHeaderCallback = (
parent: S2CellType,
cornerHeader: CornerHeader,
spreadsheet: SpreadSheet,
...restOptions: unknown[]
) => void;
Expand Down
9 changes: 2 additions & 7 deletions packages/s2-core/src/facet/header/corner.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { Rect, type PointLike } from '@antv/g';
import { includes } from 'lodash';
import { CornerCell } from '../../cell/corner-cell';
import type { S2CellType } from '../../common/interface';
import { S2Event } from '../../common';
import { CornerNodeType } from '../../common/interface/node';
import type { CornerBBox } from '../bbox/corner-bbox';
import type { PanelBBox } from '../bbox/panel-bbox';
import { Node } from '../layout/node';
import { translateGroupX } from '../utils';
import { S2Event } from '../../common';
import {
getDefaultCornerText,
getDefaultSeriesNumberText,
Expand Down Expand Up @@ -249,11 +248,7 @@ export class CornerHeader extends BaseHeader<CornerHeaderConfig> {
const cornerHeader = spreadsheet.options?.cornerHeader;

if (cornerHeader) {
cornerHeader(
this as unknown as S2CellType,
spreadsheet,
this.headerConfig,
);
cornerHeader(this, spreadsheet, this.headerConfig);

return;
}
Expand Down
7 changes: 4 additions & 3 deletions packages/s2-react/playground/config.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
/* eslint-disable max-classes-per-file */
/* eslint-disable no-console */
import {
EMPTY_PLACEHOLDER,
ResizeType,
customMerge,
type CustomHeaderField,
type CustomTreeNode,
type S2DataConfig,
type S2TableSheetFrozenOptions,
type ThemeCfg,
EMPTY_PLACEHOLDER,
} from '@antv/s2';
import { getBaseSheetComponentOptions } from '@antv/s2-shared';
import { PivotSheetMultiLineTextDataCfg } from '@antv/s2/__tests__/data/data-multi-line-text';
Expand Down Expand Up @@ -361,8 +362,8 @@ export const s2Options: SheetComponentOptions = {
rowCell: true,
},
resize: {
rowResizeType: ResizeType.SELECTED,
colResizeType: ResizeType.SELECTED,
rowResizeType: ResizeType.ALL,
colResizeType: ResizeType.ALL,
},
},
// totals: {
Expand Down
37 changes: 16 additions & 21 deletions s2-site/docs/manual/advanced/chart-in-cell.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ const s2DataConfig = {

自定义 `DataCell`, 然后使用 `drawCustomContent` 接管绘制逻辑

```ts
```ts | pure
import { DataCell, drawCustomContent } from '@antv/s2';

class CustomDataCell extends DataCell {
Expand Down Expand Up @@ -428,29 +428,24 @@ S2 的每一个单元格对应 [`AntV/G`](https://g.antv.antgroup.com/) 的一

#### 3.1 自定义单元格,重写绘制逻辑,添加任意图形

```ts
```ts | pure
import { Image as GImage } from '@antv/g';
import { CornerCell } from '@antv/s2';

class CustomCornerCell extends CornerCell {
drawBackgroundShape() {
const img = new Image();

img.src =
'https://gw.alipayobjects.com/zos/antfincdn/og1XQOMyyj/1e3a8de1-3b42-405d-9f82-f92cb1c10413.png';

img.onload = () => {
this.backgroundShape = this.appendChild(
new GImage({
style: {
...this.getBBoxByType(),
src: img,
},
}),
);

this.drawTextShape();
};
const url = 'https://gw.alipayobjects.com/zos/antfincdn/og1XQOMyyj/1e3a8de1-3b42-405d-9f82-f92cb1c10413.png';

this.backgroundShape = this.appendChild(
new GImage({
style: {
...this.getBBoxByType(),
src: url,
},
}),
);

this.drawTextShape();
}
}

Expand All @@ -465,7 +460,7 @@ const s2Options = {

通过 `s2.getCanvas()` 获取 `G``Canvas` 实例。

```ts
```ts | pure
import { Rect } from '@antv/g';

await s2.render();
Expand All @@ -492,7 +487,7 @@ s2.getCanvas().appendChild(

#### 3.3 手动获取指定单元格实例 (Group) 后绘制任意图形

```ts
```ts | pure
import { Rect } from '@antv/g';

await s2.render();
Expand Down
70 changes: 70 additions & 0 deletions s2-site/docs/manual/faq.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,76 @@ const s2Options = {
}
```

### 自定义单元格后绘制图片,滚动表格时图片重复加载并造成闪烁?

1. G 的 [Image 图形](https://g.antv.antgroup.com/api/basic/image#src) 支持传入图片地址字符串,内部会缓存起来,无需创建 [HTMLImageElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image), 适用于固定的宽高等场景。

```ts | pure
import { Image as GImage } from '@antv/g';

class CustomColCell extends ColCell {
drawBackgroundShape() {
new GImage({
style: {
x: 200,
y: 100,
width: 200,
height: 200,
src: 'https://gw.alipayobjects.com/zos/antfincdn/og1XQOMyyj/1e3a8de1-3b42-405d-9f82-f92cb1c10413.png',
},
})
}
}
```

2. 如果图片宽高未知,则可以创建 [HTMLImageElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image) 后再添加 G 的 [Image 图形](https://g.antv.antgroup.com/api/basic/image#src), 此时需要手动增加缓存,避免图片重复加载

```ts | pure
const ImageCache = new Map<string, HTMLImageElement>();

class CustomColCell extends ColCell {
drawBackgroundShape() {
const url = 'https://gw.alipayobjects.com/zos/antfincdn/og1XQOMyyj/1e3a8de1-3b42-405d-9f82-f92cb1c10413.png'

const imgCache = ImageCache.get(url)
if (imgCache) {
this.appendChild(
new GImage({
style: {
x: 200,
y: 100,
width: imgCache.width,
height: imgCache.height,
src: imgCache
},
})
)
return;
}

const img = new Image();
img.src = url
img.crossOrigin = 'Anonymous';
img.onload = () => {
// 图片加载成功后创建
this.appendChild(
new GImage({
style: {
x: 200,
y: 100,
width: img.width,
height: img.height,
src: img
},
})
)
};
}
}
```

请查看 [自定义特定单元格](/examples/custom/custom-cell#custom-specified-cell) 示例。

### S2 有对应的 `Vue` 或者 `Angular` 版本吗?如何获取新版本发布通知?

<embed src="@/docs/common/packages.zh.md"></embed>
Expand Down
10 changes: 4 additions & 6 deletions s2-site/examples/case/art/demo/lost-text.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
/* eslint-disable max-classes-per-file */
import React from 'react';
import { SheetComponent, SheetComponentOptions } from '@antv/s2-react';
import { Tag } from 'antd';
import {
BaseEvent,
CellType,
getTheme,
InterceptType,
S2Event,
CornerCell,
S2Theme,
getTheme,
} from '@antv/s2';
import { Rect } from '@antv/g';
import { SheetComponent, SheetComponentOptions } from '@antv/s2-react';
import { Tag } from 'antd';
import React from 'react';
import '@antv/s2-react/dist/style.min.css';

const Theme: S2Theme = {
Expand Down
44 changes: 31 additions & 13 deletions s2-site/examples/case/art/demo/time-spend-abstract.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,33 +41,51 @@ const paletteLegendMap = [
},
];

const ImageCache = new Map<string, HTMLImageElement>();

/**
* 自定义 DataCell, 给单元格添加图表
* 查看更多方法 https://github.com/antvis/S2/blob/next/packages/s2-core/src/cell/data-cell.ts
*/
class CustomDataCell extends DataCell {
drawTextShape() {
drawTextShape() {}

renderImage(img: HTMLImageElement) {
const { x, y, width, height } = this.meta;

this.backgroundShape = this.appendChild(
new GImage({
style: {
x: x + (width - img?.width) / 2,
y: y + (height - img?.height) / 2,
width: img?.width ?? width,
height: img?.height ?? height,
src: img,
},
}),
);
}

drawBackgroundShape() {
const { fieldValue } = this.meta;
const url =
paletteLegendMap.find((legend) => legend.text === fieldValue)?.src ??
'https://gw.alipayobjects.com/mdn/rms_56cbb2/afts/img/A*e5A3SKifw1EAAAAAAAAAAAAAARQnAQ';

if (ImageCache.get(url)) {
this.renderImage(ImageCache.get(url));

return;
}

const img = new Image();

img.src = url;
const { x, y, width, height } = this.meta;
img.crossOrigin = 'anonymous';

img.onload = () => {
this.textShape = this.appendChild(
new GImage({
style: {
x: x + (width - img?.width) / 2,
y: y + (height - img?.height) / 2,
width: img?.width ?? width,
height: img?.height ?? height,
src: img,
},
}),
);
this.renderImage(img);
ImageCache.set(url, img);
};
}
}
Expand Down
Loading

0 comments on commit 0227a9d

Please sign in to comment.