Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
149 changes: 97 additions & 52 deletions site/docs/manual/core/transform/diffY.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,67 +3,112 @@ title: diffY
order: 2
---

对 y 和 y1 通道求差集。
## 概述

## 开始使用
`diffY` 是一个比较特殊的通道变化,主要是针对 encode.y 中的 y1 进行变换。对于面积图来说,它具备有 y 和 y1 通道,分别代表着面积图形的上边界和下边界,`diffY` 会对每一个面积图形的 y1 做以下处理:

<img alt="diffY" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*CJn4T4_Rf98AAAAAAAAAAAAADmJ7AQ/original" width="600" />
1. 计算每个 x 对应的 y1 的最大值 y1max
2. 然后针对每个图形的 y 去判断和 y1max 的大小,如果 y1max > y 则移除这个数据,否则设置 y1 = y1max

在对应的 mark 中有 transform 方法可以使用数据的变换
常用于面积图、柱形图等这类具有 y1 的 mark,因为视觉上,最终效果是只显示两个柱子、面积图形交叠的地方,所以命名为 `diffY`

```ts
import { Chart } from '@antv/g2';
## 使用场景

const chart = new Chart({
container: 'container',
});
`diffY` 基本专用于面积图,用于突出看到对比情况下的最值情况,在其他 mark 下使用相对比较少。

例如下面的的案例是看 `New York` 和 `San Francisco` 两个城市的天气情况的趋势,通过 `diffY` 就可以凸显出在同一个时间 x 下,到底那个城市的温度更高。

chart.data({
type: 'fetch',
value: 'https://assets.antv.antgroup.com/g2/temperature-compare.json',
transforms: [
```js | ob
(() => {
const chart = new G2.Chart();

chart.options({
type: "view",
data: {
type: "fetch",
value: "https://assets.antv.antgroup.com/g2/temperature-compare.json",
},
children: [
{
type: 'map',
callback: (d) => (d) => ({
...d,
date: new Date(d.date),
})
}
]
type: "area",
data: {
transform: [
// 将两个城市的添加 fold 成两个字段:city + temperature。
{
type: "fold",
fields: ["New York", "San Francisco"],
key: "city",
value: "temperature",
},
],
},
encode: {
x: (d) => new Date(d.date),
y: "temperature",
color: "city",
shape: "hvh",
},
transform: [{ type: "diffY" }], // 在这里对分组的 y 进行差值计算。
style: { opacity: 0.5 },
},
{
type: "line",
encode: { x: (d) => new Date(d.date), y: "San Francisco", shape: "hvh" },
style: { stroke: "#000" },
},
],
});

chart
.area()
.data({
transform: [
{
type: 'fold',
fields: ['New York', 'San Francisco'],
key: 'city',
value: 'temperature',
},
],
})
.transform([{ type: 'diffY' }]) // Diff the 2 area shape.
.encode('x', 'date')
.encode('y', 'temperature')
.encode('color', 'city')
.encode('shape', 'hvh')
.scale('color', { range: ['#67a9cf', '#ef8a62'] });

chart
.line()
.encode('x', 'date')
.encode('y', 'San Francisco')
.encode('shape', 'hvh')
.style('stroke', '#000');

chart.render();
chart.render();

return chart.getContainer();
})();
```

## 配置项

| 属性 | 描述 | 类型 | 默认值 |
|-------------------|------------------------------------------------|------------------------------------|-----------------------|
| groupBy | 按照哪个通道分组数据 | `ChannelTypes` \| `ChannelTypes[]` | `x` |


### groupBy

在 `diffY` 执行的时候,需要将数据进行分组,在每个分组中执行 `diffY` 的计算逻辑,比如对于面积图,需要把同一个 x 值下的 y 数据变成一个组,然后在组内做最大最小值的处理逻辑,所以 `groupBy` 设置为 `x` 通道。

理论上,`groupBy` 可以设置为所有的通道值,具体可以参考 [encode](/manual/core/encode) 文档。所有的枚举值如下:

```ts
export type ChannelTypes =
| 'x'
| 'y'
| 'z'
| 'x1'
| 'y1'
| 'series'
| 'color'
| 'opacity'
| 'shape'
| 'size'
| 'key'
| 'groupKey'
| 'position'
| 'series'
| 'enterType'
| 'enterEasing'
| 'enterDuration'
| 'enterDelay'
| 'updateType'
| 'updateEasing'
| 'updateDuration'
| 'updateDelay'
| 'exitType'
| 'exitEasing'
| 'exitDuration'
| 'exitDelay'
| `position${number}`;
```

## 选项
## 示例

| 属性 | 描述 | 类型 | 默认值 |
|-------------------|------------------------------------------------|-------------------------|-----------------------|
| groupBy | 按照哪个通道分组数据 | `string` \| `string[]` | `x` |
| series | 是否存在分组 | `boolean` | `true` |
见上述`使用场景`文档。
1 change: 0 additions & 1 deletion src/spec/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ export type SymmetryYTransform = {
export type DiffYTransform = {
type?: 'diffY';
groupBy?: string | string[];
series?: boolean;
};

export type Selector =
Expand Down
8 changes: 2 additions & 6 deletions src/transform/diffY.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { deepMix } from '@antv/util';
import { TransformComponent as TC } from '../runtime';
import { DiffYTransform } from '../spec';
import { column, columnOf, maybeColumnOf } from './utils/helper';
import { column, columnOf } from './utils/helper';
import { createGroups } from './utils/order';

export type DiffYOptions = Omit<DiffYTransform, 'type'>;
Expand All @@ -11,16 +11,12 @@ export type DiffYOptions = Omit<DiffYTransform, 'type'>;
* Keep y unchanged, set y1 = max(otherY), if y1 > y, remove the data.
*/
export const DiffY: TC<DiffYOptions> = (options = {}) => {
const { groupBy = 'x', series = true } = options;
const { groupBy = 'x' } = options;
return (I, mark) => {
const { encode } = mark;
const [Y] = columnOf(encode, 'y');
const [_, fy1] = columnOf(encode, 'y1');

const [S] = series
? maybeColumnOf(encode, 'series', 'color')
: columnOf(encode, 'color');

// Create groups and apply specified order for each group.
const groups = createGroups(groupBy, I, mark);

Expand Down
1 change: 1 addition & 0 deletions src/transform/utils/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export function maybeColumnOf(
encode,
...K: (string | Primitive[])[]
): [Primitive[], string] {
console.log('maybeColumnOf', encode, K);
for (const key of K) {
if (typeof key === 'string') {
const [KV, fv] = columnOf(encode, key);
Expand Down
Loading