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(brush): support resize and custom #5012

Merged
merged 1 commit into from
May 15, 2023
Merged

feat(brush): support resize and custom #5012

merged 1 commit into from
May 15, 2023

Conversation

pearmini
Copy link
Member

Brush

支持八个方向的 resize 和自定义对应的 handle。

开始使用

export function penguinsPointBrush(): G2Spec {
  return {
    type: 'point',
    data: {
      type: 'fetch',
      value: 'data/penguins.csv',
    },
    encode: {
      color: 'species',
      x: 'culmen_length_mm',
      y: 'culmen_depth_mm',
    },
    state: {
      inactive: { stroke: 'gray', opacity: 0.5 },
    },
    interaction: {
      brushHighlight: true,
    },
  };

设置样式

八个方向的 handle 的名字分别如下(按照东南西北命名),按照 mask[handleName][styleAttribute] 格式设置对应的属性,也可以通过 maskHandleSize 设置宽度。

export function penguinsPointBrushHandleStyle(): G2Spec {
  return {
    type: 'point',
    data: {
      type: 'fetch',
      value: 'data/penguins.csv',
    },
    encode: {
      color: 'species',
      x: 'culmen_length_mm',
      y: 'culmen_depth_mm',
    },
    state: {
      inactive: { stroke: 'gray', opacity: 0.5 },
    },
    interaction: {
      brushHighlight: {
        maskHandleNFill: 'blue',
        maskHandleEFill: 'red',
        maskHandleSFill: 'green',
        maskHandleWFill: 'yellow',
        maskHandleNWFill: 'black',
        maskHandleNEFill: 'steelblue',
        maskHandleSEFill: 'pink',
        maskHandleSWFill: 'orange',
      },
    },
  };
}

自定义 Handle

可以通过 mask[handleName]Render 指定 handle 的渲染函数,用于渲染自定义的 handle。其中该函数签名如下。

function render(
  g, // 挂载容器
  options, // 样式属性,通过 mask[handleName][styleAttribute] 设置
  document, // 画布 document,用于创建自图形
) {
  // 需要返回创建的图形
}

下面是一个创建 path handle 的例子:

function renderPath(group, options, document) {
  // 创建逻辑
  // 如果是第一次渲染,就创建并且挂在图形
  if (!group.handle) {
    // 通过 document.createElement 去新建图形
    const path = document.createElement('path');
    group.handle = path;
    group.appendChild(group.handle);
  }

  // 更新逻辑
  const { handle } = group;
  const { width, height, ...rest } = options;
  if (width === undefined || height === undefined) return handle;
  handle.attr(rest);

  // 返回对应的 shape
  return handle;
};
function createPathRender(path) {
  return (group, options, document) => {
    if (!group.handle) {
      const path = document.createElement('path');
      group.handle = path;
      group.appendChild(group.handle);
    }
    const { handle } = group;
    const { width, height, ...rest } = options;
    if (width === undefined || height === undefined) return handle;
    handle.style.d = path(width, height);
    handle.attr(rest);
    return handle;
  };
}

export function penguinsPointBrushHandleCustom(): G2Spec {
  return {
    type: 'point',
    data: {
      type: 'fetch',
      value: 'data/penguins.csv',
    },
    encode: {
      color: 'species',
      x: 'culmen_length_mm',
      y: 'culmen_depth_mm',
    },
    state: {
      inactive: { stroke: 'gray', opacity: 0.5 },
    },
    interaction: {
      brushHighlight: {
        maskHandleSize: 30,
        maskHandleNRender: createPathRender(
          (width, height) =>
            `M0,${height / 2}L${width / 2},${-height / 2}L${width},${
              height / 2
            },Z`,
        ),
        maskHandleERender: createPathRender(
          (width, height) =>
            `M${width / 2},0L${(width * 3) / 2},${height / 2}L${
              width / 2
            },${height},Z`,
        ),
        maskHandleSRender: createPathRender(
          (width, height) =>
            `M0,${height / 2}L${width / 2},${(height / 2) * 3}L${width},${
              height / 2
            },Z`,
        ),
        maskHandleWRender: createPathRender(
          (width, height) =>
            `M${width / 2},0L${-width},${height / 2}L${width / 2},${height},Z`,
        ),
        maskHandleNWRender: createPathRender(
          (width, height) =>
            `M0,0L${width},${height / 2}L${width / 2},${height},Z`,
        ),
        maskHandleNERender: createPathRender(
          (width, height) =>
            `M0,${height / 2}L${width},0L${width / 2},${height},Z`,
        ),
        maskHandleSERender: createPathRender(
          (width, height) =>
            `M${width / 2},0L${width},${height}L0,${height / 2},Z`,
        ),
        maskHandleSWRender: createPathRender(
          (width, height) =>
            `M${width / 2},0L${width},${height / 2}L0,${height},Z`,
        ),
        maskHandleNFill: 'blue',
        maskHandleEFill: 'red',
        maskHandleSFill: 'green',
        maskHandleWFill: 'yellow',
        maskHandleNWFill: 'black',
        maskHandleNEFill: 'steelblue',
        maskHandleSEFill: 'pink',
        maskHandleSWFill: 'orange',
      },
    },
  };
}

@pearmini pearmini requested review from hustcc and lvisei May 12, 2023 07:00
@pearmini pearmini force-pushed the feat/resizable-brush branch 2 times, most recently from 040bda1 to 78a4232 Compare May 12, 2023 07:31
Copy link

@accesslint accesslint bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are accessibility issues in these changes.

site/docs/spec/interaction/brushHighlight.zh.md Outdated Show resolved Hide resolved
site/docs/spec/interaction/brushHighlight.zh.md Outdated Show resolved Hide resolved
@hustcc hustcc merged commit 85f0cb8 into v5 May 15, 2023
2 of 3 checks passed
@hustcc hustcc deleted the feat/resizable-brush branch May 15, 2023 01:25
hustcc pushed a commit that referenced this pull request May 16, 2023
hustcc pushed a commit that referenced this pull request May 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants