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

🐛 自定义单元格,重写drawTextShape方法,如果这个方法自定义了多个TextShape会报错Cannot read properties of undefined (reading 'includes') #2471

Closed
4 tasks
bT0nG opened this issue Dec 12, 2023 · 2 comments · Fixed by #2472
Labels
🐛 bug 这个是一个 bug

Comments

@bT0nG
Copy link

bT0nG commented Dec 12, 2023

🏷 Version

Package Version
@antv/s2 1.53.0
@antv/s2-react 1.45.0
@antv/s2-vue

Sheet Type

[ * ] PivotSheet

  • TableSheet
  • GridAnalysisSheet
  • StrategySheet
  • EditableSheet

🖋 Description

自定义单元格展示内容,比如:

数据单元格 class CustomDataCell extends DataCell

行单元格 class CustomRowCell extends RowCell

列单元格 class CustomColCell extends ColCell

这三个单元格的基类DataCell,RowCell,ColCell都继承自BaseCell,问题就出在BaseCell的this.getActualText()方法中,如果重写单元格的drawTextShape()方法,在该方法中添加了多个TextShape文字图层,即:

// ...其他代码
this.title = this.addShape('text', {
  attrs: {
    ...this.getCellArea(),
    x,
    y: value ? y1 : y1 + 10,
    text: value,
    fontSize: 12,
    opacity: 0.65,
    width: 5,
    textAlign: 'start',
    fontFamily: 'PingFangSC',
    fill: '#000',
  },
});

this.subTitle = this.addShape('text', {
  ...this.getCellArea(),
  zIndex: 100,
  attrs: {
    x,
    y: y2,
    text: `${value}%`,
    opacity: 0.45,
    textAlign: 'start',
    fontFamily: 'PingFangSC',
    fontSize: 12,
    fill: '#000',
  },
});
// ...其他代码

this.getActualText()就会取不到this.actualText,this.actualText为undefined,导致BaseCell另一个方法isTextOverflowing()报错

public getActualText() {
  return this.actualText;
}

// TODO: 2.0 使用 G 内置的方法
public isTextOverflowing() {
  return this.getActualText().includes(ELLIPSIS_SYMBOL);
}

只要鼠标hover到对应的单元格就会报 Cannot read properties of undefined (reading 'includes')错误。

⌨️ Code Snapshots

s2Options

const s2Options = {
  showDefaultHeaderActionIcon: false,
  interaction: {
    enableCopy: true,
    copyWithHeader: true,
    copyWithFormat: true,
    hoverHighlight: false,
    overscrollBehavior: 'none',
    brushSelection: {
      data: true, // 默认开启
      row: false,
      col: false,
    },
    rangeSelection: false,
    multiSelection: false,
    hoverFocus: false,
    linkFields: ['displayName'],
  },
  style: {
    layoutWidthType: 'colAdaptive',
    colCfg: {
      width: 180,
      height: 90,
      hideMeasureColumn: true,
    },
    rowCfg: {
      width: 220,
    },
    cellCfg: {
      height: 14,
    },
  },
  rowCell: (node: Node, s2: SpreadSheet, headConfig: unknown) => {
    return new CustomRowCell(node, s2, headConfig);
  },
}

自定义行单元格

class CustomRowCell extends RowCell {
  title: any;

  subTitle: any;

  drawTextShape() {
    const { data } = this.meta || {};
    const position = this.getTextPosition();
    const { x = 0, y = 0 } = position;
    const {
      value
    } = data || {};
    const y1 = y + 2;
    const y2 = y1 + 20;
    this.title = this.addShape('text', {
      attrs: {
        ...this.getCellArea(),
        x,
        y: value ? y1 : y1 + 10,
        text: value,
        fontSize: 12,
        opacity: 0.65,
        width: 5,
        textAlign: 'start',
        fontFamily: 'PingFangSC',
        fill: '#000',
      },
    });

    this.subTitle = this.addShape('text', {
      ...this.getCellArea(),
      zIndex: 100,
      attrs: {
        x,
        y: y2,
        text: `${value}%`,
        opacity: 0.45,
        textAlign: 'start',
        fontFamily: 'PingFangSC',
        fontSize: 12,
        fill: '#000',
      },
    });
  }
}

🔗 Reproduce Link

https://codesandbox.io/p/sandbox/mystifying-rosalind-3xx4xw?file=%2Findex.ts

复现代码:

import { PivotSheet, DataCell, ViewMeta } from "@antv/s2";

class CustomDataCell extends DataCell {
  title: any;
  subTitle: any;

  drawTextShape() {
    const { data } = this.meta || {};
    const position = this.getTextPosition();
    const { x = 0, y = 0 } = position;
    const { number } = data || {};
    const y1 = y + 2;
    const y2 = y1 + 20;
    this.title = this.addShape("text", {
      attrs: {
        ...this.getCellArea(),
        x: x - 40,
        y,
        text: number,
        fontSize: 12,
        opacity: 0.65,
        width: 5,
        textAlign: "start",
        fontFamily: "PingFangSC",
        fill: "#000",
      },
    });

    this.subTitle = this.addShape("text", {
      ...this.getCellArea(),
      zIndex: 100,
      attrs: {
        x: x - 60,
        y: y2 - 5,
        text: `数量:${number}`,
        opacity: 0.45,
        textAlign: "start",
        fontFamily: "PingFangSC",
        fontSize: 12,
        fill: "#000",
      },
    });
  }
}

fetch(
  "https://gw.alipayobjects.com/os/bmw-prod/2a5dbbc8-d0a7-4d02-b7c9-34f6ca63cff6.json"
)
  .then((res) => res.json())
  .then((dataCfg) => {
    const container = document.getElementById("container");

    const s2Options = {
      width: 600,
      height: 480,
      style: {
        cellCfg: {
          height: 40,
        },
      },
      dataCell: (viewMeta: ViewMeta) => {
        return new CustomDataCell(viewMeta, viewMeta?.spreadsheet);
      },
    };
    const s2 = new PivotSheet(container, dataCfg, s2Options);

    s2.render();
  });

🤔 Steps to Reproduce

  1. 透视表配置s2Options的自定义单元格
  2. 自定义单元格类继承自对应S2的基类,重写drawTextShape
  3. drawTextShape方法内添加多个TextShape
  4. 渲染透视表后,鼠标Hover到被自定义的单元格上报错Cannot read properties of undefined (reading 'includes')

😊 Expected Behavior

希望采用自定义单元格添加多个TextShape,不会报错Cannot read properties of undefined (reading 'includes')

😅 Current Behavior

目前在自定义单元格类中显式声明actualText就不会再报错了,但我认为这仍然是一个Bug。具体代码:

import { PivotSheet, DataCell, ViewMeta, SpreadSheet } from "@antv/s2";

class CustomDataCell extends DataCell {
  title: any;
  subTitle: any;
  actualText: string;

  constructor(viewMeta: ViewMeta, spreadsheet: SpreadSheet) {
    super(viewMeta, spreadsheet);
    this.title = null;
    this.subTitle = null;
    this.actualText = "";
  }

  drawTextShape() {
    const { data } = this.meta || {};
    const position = this.getTextPosition();
    const { x = 0, y = 0 } = position;
    const { number } = data || {};
    const y1 = y + 2;
    const y2 = y1 + 20;
    this.title = this.addShape("text", {
      attrs: {
        ...this.getCellArea(),
        x: x - 40,
        y,
        text: number,
        fontSize: 12,
        opacity: 0.65,
        width: 5,
        textAlign: "start",
        fontFamily: "PingFangSC",
        fill: "#000",
      },
    });
    this.actualText = number;
    this.subTitle = this.addShape("text", {
      ...this.getCellArea(),
      zIndex: 100,
      attrs: {
        x: x - 60,
        y: y2 - 5,
        text: `数量:${number}`,
        opacity: 0.45,
        textAlign: "start",
        fontFamily: "PingFangSC",
        fontSize: 12,
        fill: "#000",
      },
    });
  }
}

fetch(
  "https://gw.alipayobjects.com/os/bmw-prod/2a5dbbc8-d0a7-4d02-b7c9-34f6ca63cff6.json"
)
  .then((res) => res.json())
  .then((dataCfg) => {
    const container = document.getElementById("container");

    const s2Options = {
      width: 600,
      height: 480,
      style: {
        cellCfg: {
          height: 40,
        },
      },
      dataCell: (viewMeta: ViewMeta) => {
        return new CustomDataCell(viewMeta, viewMeta?.spreadsheet);
      },
    };
    const s2 = new PivotSheet(container, dataCfg, s2Options);

    s2.render();
  });

💻 System information

Environment Info
System MacOS Sonoma 14.0
Browser Chrome版本 119.0.6045.199(正式版本) (arm64)
@lijinke666
Copy link
Member

已知问题,近期修复

@lijinke666 lijinke666 added the 🐛 bug 这个是一个 bug label Dec 12, 2023
Copy link
Contributor

你好 @bT0nG,很抱歉给你带来了不好的体验, 我们会尽快排查问题并修复, 请关注后续发布日志.

Hello, @bT0nG, We are so sorry for the bad experience. We will troubleshoot and fix the problem as soon as possible. Please pay attention to the follow-up change logs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛 bug 这个是一个 bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants