<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: 方帅</title>
    <description>The latest articles on DEV Community by 方帅 (@fangsmile).</description>
    <link>https://dev.to/fangsmile</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1440742%2F1f3e031c-cd34-4987-b534-c2d41dc2111b.jpeg</url>
      <title>DEV Community: 方帅</title>
      <link>https://dev.to/fangsmile</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fangsmile"/>
    <language>en</language>
    <item>
      <title>VTable Configuration Optimization Guide: Creating a Productive front-end table Experience</title>
      <dc:creator>方帅</dc:creator>
      <pubDate>Sun, 05 Jan 2025 04:45:46 +0000</pubDate>
      <link>https://dev.to/fangsmile/vtable-configuration-optimization-guide-creating-a-productive-front-end-table-experience-aej</link>
      <guid>https://dev.to/fangsmile/vtable-configuration-optimization-guide-creating-a-productive-front-end-table-experience-aej</guid>
      <description>&lt;p&gt;For front-end developers, vtable is a powerful and flexible table component that can help us build table interfaces that meet various business needs. To fully leverage the advantages of vtable, we need to have a deep understanding of its configuration items and optimize them skillfully. The following is a VTable configuration optimization guide for front-end developers. Let's explore together how to create an efficient front-end table experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  keyboardOptions: Keyboard Configuration for Enhanced Interaction Efficiency
&lt;/h2&gt;

&lt;p&gt;During the development process, we often need to add shortcut key functionality to tables to improve user interaction efficiency. keyboardOptions provides a series of keyboard-related configuration items, enabling us to easily implement various shortcut operations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;selectAllOnCtrlA: This configuration item is used to enable the shortcut key for selecting all. When the user presses Ctrl + A, all cells in the table will be selected. We can enable or disable this function by passing a Boolean value, or we can pass a SelectAllOnCtrlAOption object for more detailed control. For example, if the business requirements do not require selecting the table header or row serial numbers, we can set disableHeaderSelect and disableRowSeriesNumberSelect to true. In this way, when dealing with a large amount of data, users can quickly select all the data they need to operate on without being disturbed by the table header and row numbers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;copySelected and pasteValueToCell: These two configuration items are used to enable the shortcut key functions for copying and pasting, respectively. They are consistent with the default shortcut keys of the browser, allowing users to seamlessly copy and paste data when using the table. It should be noted that pasteValueToCell only takes effect for cells configured with an editor. This means that during the development process, we need to configure the corresponding editor for the cells that need to be edited so that users can paste data into the correct cells. The vtable validation of the editor is not strict. Even if an invalid configuration such as an empty string is used, pasting into cells will still work. For a specific example, please refer to: &lt;a href="https://visactor.io/vtable/demo/interaction/copy-paste-cell-value" rel="noopener noreferrer"&gt;https://visactor.io/vtable/demo/interaction/copy-paste-cell-value&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;moveFocusCellOnTab and moveFocusCellOnEnter: These two configuration items determine the behavior of the Tab and Enter keys in the table. By default, moveFocusCellOnTab is set to true, which means that when the Tab key is pressed, the focus will move to the next cell. If the current cell is in the editing state, after the focus moves, the next cell will automatically enter the editing state. And moveFocusCellOnEnter is also set to true by default, which means that when the Enter key is pressed, the currently selected cell will enter the editing state. If both moveFocusCellOnEnter is set to true, the Enter key will first move the focus to the next cell. During development, we need to determine the values of these two configuration items according to the specific business logic. For example, in a table where continuous data entry is required, we can set moveFocusCellOnEnter to false. In this way, after the user presses the Enter key, they can continue to enter data in the current cell without jumping to the next cell.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;moveEditCellOnArrowKeys: After enabling this configuration item, when the user is editing a cell, they can use the arrow keys to move to the next cell and automatically enter the editing state. This is very useful when multiple cells need to be edited continuously. For example, in a table containing multiple text input cells, users can quickly jump from editing one cell to editing the next cell without having to click on the cell to activate the editing state each time. It should be noted that the behavior of using the arrow keys to switch the selected cell is not affected by this configuration item.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ctrlMultiSelect: This configuration item is used to enable the Ctrl multi-select function, and it is set to true by default. During the development process, we can use this function to allow users to perform multi-select operations using the Ctrl key. For example, in a table containing multiple options, users can hold down the Ctrl key and click on multiple cells to select them, and then perform batch operations such as batch deletion or batch modification. This can improve the efficiency of users when dealing with multiple data items. The following table lists the behaviors of VTable in response to various keyboard clicks:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7tzz6wyzblsdufqxxv1r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7tzz6wyzblsdufqxxv1r.png" alt="Image description" width="800" height="597"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  eventOptions: A Powerful Tool for Customizing Event Behavior
&lt;/h2&gt;

&lt;p&gt;eventOptions provides a series of configuration items related to event triggering, allowing us to customize the event behavior in the table to meet different business needs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
preventDefaultContextMenu: This configuration item is used to prevent the default behavior of the right mouse button. When set to true, when the user right-clicks in the table, the browser's default right-click menu will not pop up. This is very useful for customizing the right-click menu or preventing users from performing certain operations. For example, in a report where only data viewing is allowed, we can enable this configuration item to prevent users from copying data or performing other operations through the right-click menu, thus protecting the security of the data. At the same time, on this basis, we can also combine the custom right-click menu function of vtable to provide users with more rich right-click operation options, such as exporting data, viewing details, etc. If certain business requirements need the browser's default behavior, this configuration can be set to false.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  excelOptions: Empowering the Table with Excel-like Functions
&lt;/h2&gt;

&lt;p&gt;excelOptions allows us to implement some Excel-like functions in vtable, greatly enhancing the capabilities and user experience of the table.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
fillHandle: This configuration item is used to enable the fill handle function. When set to true, after the user selects a cell, the fill handle will be displayed at the bottom right of the cell. Users can drag the fill handle to copy the content of the selected cell to other cells, or double-click the fill handle to automatically fill a series of values. For example, when creating a sales forecast table, we can use this function to allow users to first enter the sales data for the first few months and then drag the fill handle to predict the sales trend for the next few months, quickly generating complete forecast data. This not only improves the efficiency of data entry but also provides users with a more intuitive way to operate data. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By properly configuring keyboardOptions, eventOptions, and excelOptions, we can create a front-end table that is efficient, easy to use, and feature-rich. During the development process, we need to flexibly apply these configuration items according to the specific business scenarios and user needs to achieve the best table experience. Let's explore more configurations and functions of vtable together and provide users with even better front-end table solutions!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>VTable table component, how to listen for mouse hover events on the elements?</title>
      <dc:creator>方帅</dc:creator>
      <pubDate>Sun, 30 Jun 2024 03:14:05 +0000</pubDate>
      <link>https://dev.to/fangsmile/vtable-table-component-how-to-listen-for-mouse-hover-events-on-the-elements-517h</link>
      <guid>https://dev.to/fangsmile/vtable-table-component-how-to-listen-for-mouse-hover-events-on-the-elements-517h</guid>
      <description>&lt;h2&gt;
  
  
  Question Description
&lt;/h2&gt;

&lt;p&gt;When customizing cell content using customLayout, including Text and Image, I would like to have some custom logic when hovering over the Image. Currently, the mouse-enter event for the cell cannot distinguish between specific targets.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F88fp9cjk9tdkoo1qzise.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F88fp9cjk9tdkoo1qzise.png" alt="Image description" width="336" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For DOM elements in JavaScript, the mouseenter event is triggered only once when the mouse pointer enters (moves over) the element. So is there an event like mouseenter_cell to monitor specified content in custom cells?&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;You can bind the mouseenter and mouseleave events to the image dom of the custom layout 'customLayout'.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxia9rf8q62lxzjfdi506.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxia9rf8q62lxzjfdi506.png" alt="Image description" width="800" height="197"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code example
&lt;/h2&gt;

&lt;p&gt;You can paste it into the official editor to test:&lt;br&gt;
&lt;a href="https://visactor.io/vtable/demo/custom-render/custom-cell-layout-jsx"&gt;https://visactor.io/vtable/demo/custom-render/custom-cell-layout-jsx&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const VGroup = VTable.VGroup;
const VText = VTable.VText;
const VImage = VTable.VImage;
const VTag = VTable.VTag;

const option = {
  container: document.getElementById('container'),
  columns: [
    {
      field: 'bloggerId',
      title: 'bloggerId'
    },
    {
      field: 'bloggerName',
      title: 'bloggerName',
      width: 330,
      customLayout: args =&amp;gt; {
        const { table, row, col, rect } = args;
        const { height, width } = rect || table.getCellRect(col, row);
        const record = table.getRecordByRowCol(col, row);
        // const jsx = jsx;
        const container = (
          &amp;lt;VGroup
            attribute={{
              id: 'container',
              width,
              height,
              display: 'flex',
              flexWrap: 'nowrap',
              justifyContent: 'flex-start',
              alignContent: 'center'
            }}
          &amp;gt;
            &amp;lt;VGroup
              id="container-right"
              attribute={{
                id: 'container-right',
                width: width - 60,
                height,
                fill: 'yellow',
                opacity: 0.1,
                display: 'flex',
                flexWrap: 'nowrap',
                flexDirection: 'column',
                justifyContent: 'space-around',
                alignItems: 'center'
              }}
            &amp;gt;
              &amp;lt;VGroup
                attribute={{
                  id: 'container-right-top',
                  fill: 'red',
                  opacity: 0.1,
                  width: width - 60,
                  height: height / 2,
                  display: 'flex',
                  flexWrap: 'wrap',
                  justifyContent: 'flex-start',
                  alignItems: 'center'
                }}
              &amp;gt;
                &amp;lt;VText
                  attribute={{
                    id: 'bloggerName',
                    text: record.bloggerName,
                    fontSize: 13,
                    fontFamily: 'sans-serif',
                    fill: 'black',
                    textAlign: 'left',
                    textBaseline: 'top',
                    boundsPadding: [0, 0, 0, 10]
                  }}
                &amp;gt;&amp;lt;/VText&amp;gt;
                &amp;lt;VImage
                  attribute={{
                    id: 'location-icon',
                    width: 15,
                    height: 15,
                    image:
                      '&amp;lt;svg t="1684484908497" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2429" width="200" height="200"&amp;gt;&amp;lt;path d="M512 512a136.533333 136.533333 0 1 1 136.533333-136.533333 136.533333 136.533333 0 0 1-136.533333 136.533333z m0-219.272533a81.92 81.92 0 1 0 81.92 81.92 81.92 81.92 0 0 0-81.92-81.92z" fill="#0073FF" p-id="2430"&amp;gt;&amp;lt;/path&amp;gt;&amp;lt;path d="M512 831.214933a27.306667 27.306667 0 0 1-19.2512-8.055466l-214.493867-214.357334a330.5472 330.5472 0 1 1 467.490134 0l-214.357334 214.357334a27.306667 27.306667 0 0 1-19.387733 8.055466z m0-732.091733a275.933867 275.933867 0 0 0-195.106133 471.04L512 765.269333l195.106133-195.106133A275.933867 275.933867 0 0 0 512 99.1232z" fill="#0073FF" p-id="2431"&amp;gt;&amp;lt;/path&amp;gt;&amp;lt;path d="M514.321067 979.490133c-147.456 0-306.107733-37.000533-306.107734-118.3744 0-45.602133 51.746133-81.92 145.681067-102.4a27.306667 27.306667 0 1 1 11.605333 53.384534c-78.370133 17.066667-102.673067 41.915733-102.673066 49.015466 0 18.432 88.064 63.761067 251.4944 63.761067s251.4944-45.192533 251.4944-63.761067c0-7.3728-25.258667-32.768-106.496-49.834666a27.306667 27.306667 0 1 1 11.195733-53.384534c96.6656 20.343467 150.186667 56.9344 150.186667 103.2192-0.273067 80.964267-158.9248 118.3744-306.3808 118.3744z" fill="#0073FF" p-id="2432"&amp;gt;&amp;lt;/path&amp;gt;&amp;lt;/svg&amp;gt;',
                    boundsPadding: [0, 0, 0, 10],
                    cursor: 'pointer'
                  }}
                  stateProxy={stateName =&amp;gt; {
                    if (stateName === 'hover') {
                      return {
                        background: {
                          fill: 'green',
                          cornerRadius: 5,
                          expandX: 1,
                          expandY: 1
                        }
                      };
                    }
                  }}
                  onPointerEnter={event =&amp;gt; {
                    event.currentTarget.addState('hover', true, false);
                    event.currentTarget.stage.renderNextFrame();
                  }}
                  onPointerLeave={event =&amp;gt; {
                    event.currentTarget.removeState('hover', false);
                    event.currentTarget.stage.renderNextFrame();
                  }}
                &amp;gt;&amp;lt;/VImage&amp;gt;
                &amp;lt;VText
                  attribute={{
                    id: 'locationName',
                    text: record.city,
                    fontSize: 11,
                    fontFamily: 'sans-serif',
                    fill: '#6f7070',
                    textAlign: 'left',
                    textBaseline: 'top'
                  }}
                &amp;gt;&amp;lt;/VText&amp;gt;
              &amp;lt;/VGroup&amp;gt;
            &amp;lt;/VGroup&amp;gt;
          &amp;lt;/VGroup&amp;gt;
        );

        // decode(container)
        return {
          rootContainer: container,
          renderDefault: false
        };
      }
    },
    {
      field: 'fansCount',
      title: 'fansCount',
      fieldFormat(rec) {
        return rec.fansCount + 'w';
      },
      style: {
        fontFamily: 'Arial',
        fontSize: 12,
        fontWeight: 'bold'
      }
    },
    {
      field: 'worksCount',
      title: 'worksCount',
      style: {
        fontFamily: 'Arial',
        fontSize: 12,
        fontWeight: 'bold'
      }
    },
    {
      field: 'viewCount',
      title: 'viewCount',
      fieldFormat(rec) {
        return rec.fansCount + 'w';
      },
      style: {
        fontFamily: 'Arial',
        fontSize: 12,
        fontWeight: 'bold'
      }
    },
    {
      field: 'viewCount',
      title: 'viewCount',
      fieldFormat(rec) {
        return rec.fansCount + 'w';
      },
      style: {
        fontFamily: 'Arial',
        fontSize: 12,
        fontWeight: 'bold'
      }
    },
    {
      field: '',
      title: 'operation',
      width: 100,
      icon: ['favorite', 'message']
    }
  ],
  records: [
    {
      bloggerId: 6,
      bloggerName: 'Virtual anchor bird',
      bloggerAvatar: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/bird.jpeg',
      introduction:
        'Hello everyone, I am the virtual anchor Xiaoniao. I like singing, acting and variety shows. I hope to be happy with everyone through the live broadcast.',
      fansCount: 900,
      worksCount: 12,
      viewCount: 8,
      city: 'Happy City',
      tags: ['music', 'performance', 'variety']
    }
  ],
  defaultRowHeight: 80
};

const instance = new VTable.ListTable(document.getElementById(CONTAINER_ID), option);
window.tableInstance = instance;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  documents
&lt;/h2&gt;

&lt;p&gt;demo: &lt;a href="https://visactor.io/vtable/demo/custom-render/custom-cell-layout-jsx"&gt;https://visactor.io/vtable/demo/custom-render/custom-cell-layout-jsx&lt;/a&gt;&lt;br&gt;
Relevant api：&lt;a href="https://visactor.io/vtable/option/ListTable-columns-text#customLayout"&gt;https://visactor.io/vtable/option/ListTable-columns-text#customLayout&lt;/a&gt;&lt;br&gt;
Tutorial：&lt;a href="https://visactor.io/vtable/guide/custom_define/custom_layout"&gt;https://visactor.io/vtable/guide/custom_define/custom_layout&lt;/a&gt;&lt;br&gt;
github：&lt;a href="https://github.com/VisActor/VTable"&gt;https://github.com/VisActor/VTable&lt;/a&gt;&lt;/p&gt;

</description>
      <category>visactor</category>
      <category>vtable</category>
      <category>webdev</category>
      <category>excel</category>
    </item>
    <item>
      <title>After custom rendering in the column configuration of the VTable component, the icon configuration fails. How to solve this?</title>
      <dc:creator>方帅</dc:creator>
      <pubDate>Sun, 30 Jun 2024 03:07:36 +0000</pubDate>
      <link>https://dev.to/fangsmile/after-custom-rendering-in-the-column-configuration-of-the-vtable-component-the-icon-configuration-fails-how-to-solve-this-39he</link>
      <guid>https://dev.to/fangsmile/after-custom-rendering-in-the-column-configuration-of-the-vtable-component-the-icon-configuration-fails-how-to-solve-this-39he</guid>
      <description>&lt;h2&gt;
  
  
  Problem Description
&lt;/h2&gt;

&lt;p&gt;We have used the customLayout or customRender configuration for custom rendering in business scenarios, but we also want to use the icon button icon feature of VTable itself. However, after both configurations are enabled, the icon does not display correctly. Is there any way to make both configurations work properly?&lt;br&gt;
As shown below, only the content of customRender is displayed. The icon configuration icon is not displayed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqz9omnqzw43ovejud425.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqz9omnqzw43ovejud425.png" alt="Image description" width="800" height="165"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;You can solve this problem by using renderDefault of the custom rendering configuration.&lt;br&gt;
However, after configuration, you may find unwanted content being drawn.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuv33tpryydn5onxv8mo2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuv33tpryydn5onxv8mo2.png" alt="Image description" width="800" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpajzide399df1krd0hpg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpajzide399df1krd0hpg.png" alt="Image description" width="800" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To solve this problem, you can use fieldFormat to directly return an empty value with this custom function, so that the default text content will not be drawn.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbo228lpckfusohdsemsb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbo228lpckfusohdsemsb.png" alt="Image description" width="800" height="160"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Code Examples
&lt;/h2&gt;

&lt;p&gt;You can paste it into the official editor for testing:&lt;br&gt;
&lt;a href="https://visactor.io/vtable/demo/custom-render/custom-render"&gt;https://visactor.io/vtable/demo/custom-render/custom-render&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const option = {
    columns:[
    {
      field: 'not_urgency',
      title:'not urgency',
      width:400,
      headerStyle:{
          lineHeight:50,
          bgColor:'#4991e3',
          color:'white',
          textAlign:'center',
          fontSize:26,
          fontWeight:600,
      },
      style:{
        fontFamily:'Arial',
        fontSize:12,
        fontWeight:'bold'
      },
      fieldFormat:()=&amp;gt;'',
      icon:{
              name: 'detail',
              type: 'svg',
              svg: `&amp;lt;svg t="1710211168958" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3209" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"&amp;gt;&amp;lt;path d="M722.944 256l-153.6 153.6c-3.072 3.072-5.12 6.656-7.168 10.24-1.536 4.096-2.56 8.192-2.56 12.288v1.536c0 4.096 1.024 7.68 2.56 11.264 1.536 3.584 3.584 6.656 6.656 9.728 3.072 3.072 6.656 5.12 10.24 7.168 4.096 1.536 8.192 2.56 12.288 2.56 4.096 0 8.192-1.024 12.288-2.56 4.096-1.536 7.168-4.096 10.24-7.168l153.6-153.6v114.688c0 2.048 0 4.096 0.512 6.144 0.512 2.048 1.024 4.096 2.048 6.144 1.024 2.048 1.536 3.584 3.072 5.632 1.024 1.536 2.56 3.584 4.096 4.608 1.536 1.536 3.072 2.56 4.608 4.096 1.536 1.024 3.584 2.048 5.632 3.072 2.048 1.024 4.096 1.536 6.144 2.048 2.048 0.512 4.096 0.512 6.144 0.512 2.048 0 4.096 0 6.144-0.512 2.048-0.512 4.096-1.024 6.144-2.048 2.048-1.024 3.584-1.536 5.632-3.072 1.536-1.024 3.584-2.56 4.608-4.096 1.536-1.536 2.56-3.072 4.096-4.608 1.024-1.536 2.048-3.584 3.072-5.632 1.024-2.048 1.536-4.096 2.048-6.144 0.512-2.048 0.512-4.096 0.512-6.144V223.744c0-4.096-1.024-8.192-2.56-12.288-1.536-4.096-4.096-7.168-7.168-10.24h-0.512c-3.072-3.072-6.656-5.12-10.24-6.656-4.096-1.536-7.68-2.56-12.288-2.56h-192c-2.048 0-4.096 0-6.144 0.512-2.048 0.512-4.096 1.024-6.144 2.048-2.048 1.024-3.584 1.536-5.632 3.072-1.536 1.024-3.584 2.56-4.608 4.096-1.536 1.536-2.56 3.072-4.096 4.608-1.024 1.536-2.048 3.584-3.072 5.632-1.024 2.048-1.536 4.096-2.048 6.144-0.512 2.048-0.512 4.096-0.512 6.144s0 4.096 0.512 6.144c0.512 2.048 1.024 4.096 2.048 6.144 1.024 2.048 1.536 3.584 3.072 5.632 1.024 1.536 2.56 3.584 4.096 4.608 1.536 1.536 3.072 2.56 4.608 4.096 1.536 1.024 3.584 2.048 5.632 3.072 2.048 1.024 4.096 1.536 6.144 2.048 2.048 0.512 4.096 0.512 6.144 0.512h115.712z m-268.288 358.4l-153.6 153.6h114.688c2.048 0 4.096 0 6.144 0.512 2.048 0.512 4.096 1.024 6.144 2.048 2.048 1.024 3.584 1.536 5.632 3.072 1.536 1.024 3.584 2.56 4.608 4.096 1.536 1.536 2.56 3.072 4.096 4.608 1.024 1.536 2.048 3.584 3.072 5.632 1.024 2.048 1.536 4.096 2.048 6.144 0.512 2.048 0.512 4.096 0.512 6.144 0 2.048 0 4.096-0.512 6.144-0.512 2.048-1.024 4.096-2.048 6.144-1.024 2.048-1.536 3.584-3.072 5.632-1.024 1.536-2.56 3.584-4.096 4.608-1.536 1.536-3.072 2.56-4.608 4.096-1.536 1.024-3.584 2.048-5.632 3.072-2.048 1.024-4.096 1.536-6.144 2.048-2.048 0.512-4.096 0.512-6.144 0.512H224.256c-2.048 0-4.096 0-6.144-0.512-2.048-0.512-4.096-1.024-6.144-2.048-2.048-1.024-3.584-1.536-5.632-3.072-1.536-1.024-3.584-2.56-4.608-4.096-1.536-1.536-2.56-3.072-4.096-4.608-1.024-1.536-2.048-3.584-3.072-5.632-1.024-2.048-1.536-4.096-2.048-6.144-0.512-2.048-0.512-4.096-0.512-6.144v-192.512c0-2.048 0-4.096 0.512-6.144 0.512-2.048 1.024-4.096 2.048-6.144 1.024-2.048 1.536-3.584 3.072-5.632 1.024-1.536 2.56-3.584 4.096-4.608 1.536-1.536 3.072-2.56 4.608-4.096 1.536-1.024 3.584-2.048 5.632-3.072 2.048-1.024 4.096-1.536 6.144-2.048 2.048-0.512 4.096-0.512 6.144-0.512s4.096 0 6.144 0.512c2.048 0.512 4.096 1.024 6.144 2.048 2.048 1.024 3.584 1.536 5.632 3.072 1.536 1.024 3.584 2.56 4.608 4.096 1.536 1.536 2.56 3.072 4.096 4.608 1.024 1.536 2.048 3.584 3.072 5.632 1.024 2.048 1.536 4.096 2.048 6.144 0.512 2.048 0.512 4.096 0.512 6.144v114.688l153.6-153.6c3.072-3.072 6.656-5.12 10.24-7.168 4.096-1.536 8.192-2.56 12.288-2.56 4.096 0 8.192 1.024 12.288 2.56 4.096 1.536 7.168 3.584 10.24 6.656h0.512c3.072 3.072 5.12 6.656 7.168 10.24 1.536 4.096 2.56 8.192 2.56 12.288 0 4.096-1.024 8.192-2.56 12.288-3.072 5.12-5.12 8.704-8.192 11.264z" p-id="3210" fill="#999999"&amp;gt;&amp;lt;/path&amp;gt;&amp;lt;/svg&amp;gt;`,
              marginRight: 8,
              positionType: VTable.TYPES.IconPosition.absoluteRight,
              width: 16,
              height: 16,
              cursor: 'pointer',
              visibleTime: 'mouseenter_cell',
              funcType: 'record_detail',
              tooltip: {
                title:'展开详情',
                style: {
                  fontSize: 12,
                  padding: [8, 8, 8, 8],
                  bgColor: '#46484a',
                  arrowMark: true,
                  color: 'white',
                  maxHeight: 100,
                  maxWidth: 200
                },
                placement: VTable.TYPES.Placement.top
              }
            },
      customRender(args){
        const { width, height}= args.rect;
        const {dataValue,table,row} =args;
        const elements=[];
        let top=30;
        const left=15;
        let maxWidth=0;
          elements.push({
            type: 'text',
            fill: 'red',
            fontSize: 20,
            fontWeight: 500, 
            textBaseline: 'middle',
            text: row===1? 'important but not urgency':'not important and not urgency',
            x: left+50,
            y: top-5,
          });
        return {
          elements,
          expectedHeight:top+20,
          expectedWidth: 300,
          renderDefault:true
        }
      }
    }, 
    ],
    records:[
      {
        'type': 'important',
        "urgency": ['crisis','urgent problem','tasks that must be completed within a limited time'],
        "not_urgency": ['preventive measures','development relationship','identify new development opportunities','establish long-term goals'],
      },
      {
        'type': 'Not\nimportant',
        "urgency": ['Receive visitors','Certain calls, reports, letters, etc','Urgent matters','Public activities'],
        "not_urgency": ['Trivial busy work','Some letters','Some phone calls','Time-killing activities','Some pleasant activities'],
      },
    ],
    defaultRowHeight:80,
    heightMode:'autoHeight',
    widthMode:'standard',
    autoWrapText:true,
  };

const tableInstance = new VTable.ListTable(document.getElementById(CONTAINER_ID),option);
window['tableInstance'] = tableInstance;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Relevant Documents
&lt;/h2&gt;

&lt;p&gt;Related API: &lt;a href="https://visactor.io/vtable/option/ListTable-columns-text#customRender.renderDefault"&gt;https://visactor.io/vtable/option/ListTable-columns-text#customRender.renderDefault&lt;/a&gt;&lt;br&gt;
Tutorial：&lt;a href="https://visactor.io/vtable/demo/custom-render/custom-render"&gt;https://visactor.io/vtable/demo/custom-render/custom-render&lt;/a&gt;&lt;br&gt;
github：&lt;a href="https://github.com/VisActor/VTable"&gt;https://github.com/VisActor/VTable&lt;/a&gt;&lt;/p&gt;

</description>
      <category>visactor</category>
      <category>vtable</category>
      <category>visiualization</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Does the tooltip of the VTable component support selecting text and having a scrolling effect for overflowing content?</title>
      <dc:creator>方帅</dc:creator>
      <pubDate>Fri, 21 Jun 2024 08:06:46 +0000</pubDate>
      <link>https://dev.to/fangsmile/does-the-tooltip-of-the-vtable-component-support-selecting-text-and-having-a-scrolling-effect-for-overflowing-content-1cdk</link>
      <guid>https://dev.to/fangsmile/does-the-tooltip-of-the-vtable-component-support-selecting-text-and-having-a-scrolling-effect-for-overflowing-content-1cdk</guid>
      <description>&lt;h2&gt;
  
  
  Problem Description
&lt;/h2&gt;

&lt;p&gt;I utilized the tooltip feature of the VTable component, which means when the cell content is too long, a tooltip will appear when the mouse hovers over the cell.&lt;br&gt;
However, I found that the content of this tooltip cannot be selected because when the mouse leaves the cell and tries to move to the tooltip, the tooltip disappears and it is impossible to move the mouse over it. Also, when the content is too long, the tooltip will be stretched very large, resulting in an ugly effect. I hope that when the content is very long, I can scroll through it. Can VTable achieve the effect I need?&lt;/p&gt;
&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;VTable provides a configuration solution to this problem. First, normally, as soon as the mouse leaves the cell with the overflowing text, the tooltip disappears immediately, making it impossible to move the mouse to the tooltip. Therefore, a new configuration called overflowTextTooltipDisappearDelay is added to the tooltip configuration to delay the disappearance of the tooltip. After configuring this, the mouse has enough time to move to the tooltip, thus solving the need to select and copy text. (The usage of tooltips for Icons is similar!)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  /** tooltip相关配置 */
  tooltip?: {
    /** html目前实现较完整 先默认html渲染方式 */
    renderMode?: 'html'; // 目前暂不支持canvas方案
    /**  Whether to show the thumbnail tooltip. Instead of the original hover:isShowTooltip configuration, it is temporarily necessary to set the renderMode configuration to html in order to display it. canvas has not been developed yet.*/
    isShowOverflowTextTooltip?: boolean;
 /** Abbreviation text prompt box delayed disappearance time **/
    overflowTextTooltipDisappearDelay?: number;
    /** 是否将 tooltip 框限制在画布区域内，默认开启。针对renderMode:"html"有效 */
    confine?: boolean;
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To limit the size of a tooltip pop-up box, you can configure it in the style of the tooltip. The specific style definition is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * Bubble box, button explanation information
 */
export type TooltipStyle = {
  fontFamily?: string;
  fontSize?: number;
  color?: string;
  padding?: number[];
  bgColor?: string;
  maxWidth?: number;
  maxHeight?: number;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure it by putting it in the theme.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const option={
   tooltip: {
      renderMode: 'html',
      isShowOverflowTextTooltip: true,
      overflowTextTooltipDisappearDelay: 1000
    },
    theme:{
        tooltipStyle:{
            maxWidth：200，
            maxHeight：100
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Code Examples
&lt;/h2&gt;

&lt;p&gt;You can paste it into the official editor for testing:&lt;br&gt;
&lt;a href="https://visactor.io/vtable/demo/component/tooltip"&gt;https://visactor.io/vtable/demo/component/tooltip&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let tableInstance;
fetch('https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/North_American_Superstore_data.json')
  .then(res =&amp;gt; res.json())
  .then(data =&amp;gt; {
    const columns = [
      {
        field: 'Order ID',
        title: 'Order ID',
        width: 'auto'
      },
      {
        field: 'Customer ID',
        title: 'Customer ID',
        width: 'auto'
      },
      {
        field: 'Product Name',
        title: 'Product Name',
        width: '200'
      },
      {
        field: 'Category',
        title: 'Category',
        width: 'auto'
      },
      {
        field: 'Sub-Category',
        title: 'Sub-Category',
        width: 'auto'
      },
      {
        field: 'Region',
        title: 'Region',
        width: 'auto'
      },
      {
        field: 'City',
        title: 'City',
        width: 'auto'
      },
      {
        field: 'Order Date',
        title: 'Order Date',
        width: 'auto'
      },
      {
        field: 'Quantity',
        title: 'Quantity',
        width: 'auto'
      },
      {
        field: 'Sales',
        title: 'Sales',
        width: 'auto'
      },
      {
        field: 'Profit',
        title: 'Profit',
        width: 'auto'
      }
    ];

    const option = {
      records: data,
      columns,
      widthMode: 'standard',
      tooltip: {
        renderMode: 'html',
        isShowOverflowTextTooltip: true,
        overflowTextTooltipDisappearDelay: 1000
      },
      theme:{
          tooltipStyle:{
              maxWidth:200,
              maxHeight:60
          }
      }
    };
    tableInstance = new VTable.ListTable(document.getElementById(CONTAINER_ID), option);
    window['tableInstance'] = tableInstance;

  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Result Presentation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05f63vg5lx3r0i27sd9e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05f63vg5lx3r0i27sd9e.png" alt="Image description" width="800" height="577"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Documentation
&lt;/h2&gt;

&lt;p&gt;Related API: &lt;a href="https://www.visactor.io/vtable/api/Methods#showTooltip"&gt;https://www.visactor.io/vtable/api/Methods#showTooltip&lt;/a&gt;&lt;br&gt;
Tutorial: &lt;a href="https://www.visactor.io/vtable/guide/components/tooltip"&gt;https://www.visactor.io/vtable/guide/components/tooltip&lt;/a&gt;&lt;br&gt;
github：&lt;a href="https://github.com/VisActor/VTable"&gt;https://github.com/VisActor/VTable&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vtable</category>
      <category>visactor</category>
      <category>visiualization</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to control the timing of exiting edit mode after implementing editable cells in VTable components?</title>
      <dc:creator>方帅</dc:creator>
      <pubDate>Fri, 21 Jun 2024 08:00:38 +0000</pubDate>
      <link>https://dev.to/fangsmile/how-to-control-the-timing-of-exiting-edit-mode-after-implementing-editable-cells-in-vtable-components-132f</link>
      <guid>https://dev.to/fangsmile/how-to-control-the-timing-of-exiting-edit-mode-after-implementing-editable-cells-in-vtable-components-132f</guid>
      <description>&lt;h2&gt;
  
  
  Question Description
&lt;/h2&gt;

&lt;p&gt;Referring to the flowchart provided on the official website, if a user clicks another cell or presses the Enter key while in edit mode, will VTable definitely trigger the onEnd event to exit edit mode? In my project, there is a scenario where I do not want the edit mode to be exited when these interactions are triggered. Is there a way to achieve this currently?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjp0psibmsm6mmts0wymu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjp0psibmsm6mmts0wymu.png" alt="Image description" width="800" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Click without exit edit
&lt;/h3&gt;

&lt;p&gt;You can use a custom editor to control when to exit the edit state. Because the VTable logic calls the editor's isEditorElement method, if it returns false, the VTable will follow the exit edit logic; if it returns true, it will not exit the edit mode. Therefore, we can use this method to meet the requirement of not exiting the edit mode. The specific tutorial address is: &lt;a href="https://visactor.io/vtable/guide/edit/edit_cell"&gt;https://visactor.io/vtable/guide/edit/edit_cell&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbynmb33ookifyex50874.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbynmb33ookifyex50874.png" alt="Image description" width="800" height="710"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Type enter without exiting edit
&lt;/h3&gt;

&lt;p&gt;This can listen to the keydown event of editing dom, directly organize bubbling, and prevent VTable from listening, so it will not exit editing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let  tableInstance;
 class MyInputEditor {
  createElement() {
     const input = document.createElement('input');
    input.setAttribute('type', 'text');
    input.style.position = 'absolute';
    input.style.padding = '4px';
    input.style.width = '100%';
    input.style.boxSizing = 'border-box';
    this.element = input;
    this.container.appendChild(input);
    // 监听键盘事件
    input.addEventListener('keydown', (e) =&amp;gt; {
        // 阻止冒泡
        e.stopPropagation();
    });
  }
  setValue(value) {
    this.element.value = typeof value !== 'undefined' ? value : '';
  }
  getValue() {
    return this.element.value;
  }
  onStart({ value, referencePosition, container, endEdit }){
    this.container = container;
    this.successCallback = endEdit;
    if (!this.element) {
      this.createElement();

      if (value !== undefined &amp;amp;&amp;amp; value !== null) {
        this.setValue(value);
      }
      if (referencePosition?.rect) {
        this.adjustPosition(referencePosition.rect);
      }
    }
    this.element.focus();
  }

  adjustPosition(rect) {
    this.element.style.top = rect.top + 'px';
    this.element.style.left = rect.left + 'px';
    this.element.style.width = rect.width + 'px';
    this.element.style.height = rect.height + 'px';
  }
  onEnd() {
    this.container.removeChild(this.element);
    this.element = undefined;
  }

  isEditorElement(target) {
    // 仅允许点击到表格外部才会结束编辑
    if(target.tagName === 'CANVAS')
      return true;
    return target === this.element;
  }
}

const my_editor = new MyInputEditor();
VTable.register.editor('my_editor', my_editor);

const option = {
  container: document.getElementById(CONTAINER_ID),
  columns: [
    {
      field: 'bloggerName',
      title: 'bloggerName'
    },
    {
      field: 'fansCount',
      title: 'fansCount',
      fieldFormat(rec) {
        return rec.fansCount + 'w';
      },
      style: {
        fontFamily: 'Arial',
        fontSize: 12,
        fontWeight: 'bold'
      }
    },
    {
      field: 'worksCount',
      title: 'worksCount',
      style: {
        fontFamily: 'Arial',
        fontSize: 12,
        fontWeight: 'bold'
      }
    },
    {
      field: 'viewCount',
      title: 'viewCount',
      fieldFormat(rec) {
        return rec.fansCount + 'w';
      },
      style: {
        fontFamily: 'Arial',
        fontSize: 12,
        fontWeight: 'bold'
      }
    },
    {
      field: 'viewCount',
      title: 'viewCount',
      fieldFormat(rec) {
        return rec.fansCount + 'w';
      },
      style: {
        fontFamily: 'Arial',
        fontSize: 12,
        fontWeight: 'bold'
      }
    },
  ],
  records: [
    {
      bloggerId: 1,
      bloggerName: 'Virtual Anchor Xiaohua',
     fansCount: 400,
      worksCount: 10,
      viewCount: 5,
      city: 'Dream City',
      tags: ['game', 'anime', 'food']
    },
    {
      bloggerId: 2,
      bloggerName: 'Virtual anchor little wolf',
      fansCount: 800,
      worksCount: 20,
      viewCount: 15,
      city: 'City of Music',
      tags: ['music', 'travel', 'photography']
    },
    {
      bloggerId: 3,
      bloggerName: 'Virtual anchor bunny',
      fansCount: 600,
      worksCount: 15,
      viewCount: 10,
      city: 'City of Art',
      tags: ['painting', 'handmade', 'beauty makeup']
    },
    {
      bloggerId: 4,
      bloggerName: 'Virtual anchor kitten',
      fansCount: 1000,
      worksCount: 30,
      viewCount: 20,
      city: 'Health City',
      tags: ['dance', 'fitness', 'cooking']
    },
    {
      bloggerId: 5,
      bloggerName: 'Virtual anchor Bear',
      fansCount: 1200,
      worksCount: 25,
      viewCount: 18,
      city: 'City of Wisdom',
      tags: ['Movie', 'Literature']
    },
    {
      bloggerId: 6,
      bloggerName: 'Virtual anchor bird',
      fansCount: 900,
      worksCount: 12,
      viewCount: 8,
      city: 'Happy City',
      tags: ['music', 'performance', 'variety']
    }
  ],
  enableLineBreak: true,

  editCellTrigger: 'click',
  editor:'my_editor'
};
tableInstance = new VTable.ListTable(option);
tableInstance.on('change_cell_value', arg =&amp;gt; {
  console.log(arg);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Related documents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Editing form demo: &lt;a href="https://visactor.io/vtable/demo/edit/edit-cell"&gt;https://visactor.io/vtable/demo/edit/edit-cell&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Editing form tutorial: &lt;a href="https://visactor.io/vtable/guide/edit/edit_cell"&gt;https://visactor.io/vtable/guide/edit/edit_cell&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Related API: 
&lt;a href="https://visactor.io/vtable/option/ListTable#editor"&gt;https://visactor.io/vtable/option/ListTable#editor&lt;/a&gt;
&lt;a href="https://visactor.io/vtable/option/ListTable-columns-text#editor"&gt;https://visactor.io/vtable/option/ListTable-columns-text#editor&lt;/a&gt;
github：&lt;a href="https://github.com/VisActor/VTable"&gt;https://github.com/VisActor/VTable&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>visactor</category>
      <category>vtable</category>
      <category>visiualization</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Usage issues of the editing cell ability of the VTable component: How to configure the editor and whether it can be reused?</title>
      <dc:creator>方帅</dc:creator>
      <pubDate>Fri, 14 Jun 2024 10:42:41 +0000</pubDate>
      <link>https://dev.to/fangsmile/usage-issues-of-the-editing-cell-ability-of-the-vtable-component-how-to-configure-the-editor-and-whether-it-can-be-reused-31dc</link>
      <guid>https://dev.to/fangsmile/usage-issues-of-the-editing-cell-ability-of-the-vtable-component-how-to-configure-the-editor-and-whether-it-can-be-reused-31dc</guid>
      <description>&lt;h2&gt;
  
  
  Problem Description
&lt;/h2&gt;

&lt;p&gt;In business scenarios, there are many columns in the table. If each column needs to be configured with an editor, it will be more cumbersome. Is there a simple way to define it?&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;You can decide which way to configure the editor according to the specific degree of business reuse:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Only configure a global editor and use it for all cells:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { DateInputEditor, InputEditor, ListEditor, TextAreaEditor } from '@visactor/vtable-editors';
const option={
  editor: new InputEditor()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After configuration, you can click on any cell to edit it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmsbmsuodixhjr5r3pnf9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmsbmsuodixhjr5r3pnf9.png" alt="Image description" width="800" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If a few columns can share the same editor, you can declare the same editor name in the columns column configuration for reuse.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { DateInputEditor, InputEditor, ListEditor, TextAreaEditor } from '@visactor/vtable-editors';
const input_editor = new InputEditor();
VTable.register.editor('input-editor', input_editor);

const option={
  columns:[
      {field:'id',title: 'ID'},
      {field:'name',title: 'NAME',editor:'input-editor'},
      {field:'address',title: 'ADDRESS',editor:'input-editor'},
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After configuration, you will find that the cells in this column can all be edited.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw7c15qwd7cpfmp90hk6d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw7c15qwd7cpfmp90hk6d.png" alt="Image description" width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can modify and debug the demo on the official website in the above two ways to verify. demo URL:&lt;a href="https://visactor.io/vtable/demo/edit/edit-cell"&gt;https://visactor.io/vtable/demo/edit/edit-cell&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Related documents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Editing form demo: &lt;a href="https://visactor.io/vtable/demo/edit/edit-cell"&gt;https://visactor.io/vtable/demo/edit/edit-cell&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Editing form tutorial: &lt;a href="https://visactor.io/vtable/guide/edit/edit_cell"&gt;https://visactor.io/vtable/guide/edit/edit_cell&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Related API: &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://visactor.io/vtable/option/ListTable#editor"&gt;https://visactor.io/vtable/option/ListTable#editor&lt;/a&gt;&lt;br&gt;
  &lt;a href="https://visactor.io/vtable/option/ListTable-columns-text#editor"&gt;https://visactor.io/vtable/option/ListTable-columns-text#editor&lt;/a&gt;&lt;br&gt;
github：&lt;a href="https://github.com/VisActor/VTable"&gt;https://github.com/VisActor/VTable&lt;/a&gt;&lt;/p&gt;

</description>
      <category>visactor</category>
      <category>vtable</category>
      <category>visiualization</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to delete the content of the selected cell using hotkeys in VTable?</title>
      <dc:creator>方帅</dc:creator>
      <pubDate>Fri, 14 Jun 2024 10:37:58 +0000</pubDate>
      <link>https://dev.to/fangsmile/how-to-delete-the-content-of-the-selected-cell-using-hotkeys-in-vtable-4p0</link>
      <guid>https://dev.to/fangsmile/how-to-delete-the-content-of-the-selected-cell-using-hotkeys-in-vtable-4p0</guid>
      <description>&lt;h2&gt;
  
  
  Question Description
&lt;/h2&gt;

&lt;p&gt;We have implemented the editable table business scenario using the editing capabilities provided by VTable. However, there is a requirement to delete the content of the selected cell when the delete key or backspace key is pressed on the keyboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;Currently, VTable itself does not support this feature. You can implement it yourself by listening for keyboard events and calling the VTable interface to update cell values.&lt;br&gt;
First, listen for the keydown event and call the changeCellValue interface to update cell values in the event.&lt;br&gt;
See the demo for implementation logic: &lt;a href="https://visactor.io/vtable/demo/interaction/context-menu"&gt;https://visactor.io/vtable/demo/interaction/context-menu&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // 监听键盘事件
    document.addEventListener('keydown', (e) =&amp;gt; {
       if (e.key === 'Delete'||e.key === 'Backspace') {
         let selectCells = tableInstance.getSelectedCellInfos();
        if (selectCells?.length &amp;gt; 0) {
          // 如果选中的是范围，则删除范围内的所有单元格
          deleteSelectRange(selectCells);
        } else {
          // 否则只删除单个单元格
          tableInstance.changeCellValue(args.col, args.row, '');
        }
      }
    });
    //将选中单元格的值设置为空
    function deleteSelectRange(selectCells) {
      for (let i = 0; i &amp;lt; selectCells.length; i++) {
        for (let j = 0; j &amp;lt; selectCells[i].length; j++) {
          tableInstance.changeCellValue(selectCells[i][j].col, selectCells[i][j].row, '');
        }
      }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Code Examples
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let tableInstance;
fetch('https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/North_American_Superstore_data.json')
  .then(res =&amp;gt; res.json())
  .then(data =&amp;gt; {
    const columns = [
      {
        field: 'Order ID',
        title: 'Order ID',
        width: 'auto'
      },
      {
        field: 'Customer ID',
        title: 'Customer ID',
        width: 'auto'
      },
      {
        field: 'Product Name',
        title: 'Product Name',
        width: 'auto'
      },
      {
        field: 'Category',
        title: 'Category',
        width: 'auto'
      },
      {
        field: 'Sub-Category',
        title: 'Sub-Category',
        width: 'auto'
      },
      {
        field: 'Region',
        title: 'Region',
        width: 'auto'
      },
      {
        field: 'City',
        title: 'City',
        width: 'auto'
      },
      {
        field: 'Order Date',
        title: 'Order Date',
        width: 'auto'
      },
      {
        field: 'Quantity',
        title: 'Quantity',
        width: 'auto'
      },
      {
        field: 'Sales',
        title: 'Sales',
        width: 'auto'
      },
      {
        field: 'Profit',
        title: 'Profit',
        width: 'auto'
      }
    ];

    const option = {
      records: data,
      columns,
      widthMode: 'standard',
      menu: {
        contextMenuItems: ['copy', 'paste', 'delete', '...']
      }
    };
    tableInstance = new VTable.ListTable(document.getElementById(CONTAINER_ID), option);
    window['tableInstance'] = tableInstance;

    // 监听键盘事件
    document.addEventListener('keydown', (e) =&amp;gt; {
      debugger
       if (e.key === 'Delete'||e.key === 'Backspace') {
         let selectCells = tableInstance.getSelectedCellInfos();
        if (selectCells?.length &amp;gt; 0 ) {
          // 如果选中的是范围，则删除范围内的所有单元格
          deleteSelectRange(selectCells);
        } else {
          // 否则只删除单个单元格
          tableInstance.changeCellValue(args.col, args.row, '');
        }
      }
    });
  });

      //将选中单元格的值设置为空
    function deleteSelectRange(selectCells) {
      for (let i = 0; i &amp;lt; selectCells.length; i++) {
        for (let j = 0; j &amp;lt; selectCells[i].length; j++) {
          tableInstance.changeCellValue(selectCells[i][j].col, selectCells[i][j].row, '');
        }
      }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Result Display
&lt;/h2&gt;

&lt;p&gt;You can copy the code to the official website's code editor and test the effect directly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5tkyy6je628r8atum7bj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5tkyy6je628r8atum7bj.png" alt="Image description" width="800" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Related documents
&lt;/h2&gt;

&lt;p&gt;Demo of deleting data: &lt;a href="https://visactor.io/vtable/demo/interaction/context-menu"&gt;https://visactor.io/vtable/demo/interaction/context-menu&lt;/a&gt;&lt;br&gt;
Tutorial of data update: &lt;a href="https://visactor.io/vtable/guide/data/data_format"&gt;https://visactor.io/vtable/guide/data/data_format&lt;/a&gt;&lt;br&gt;
Related API:&lt;br&gt;
&lt;a href="https://visactor.io/vtable/api/Methods#changeCellValue"&gt;https://visactor.io/vtable/api/Methods#changeCellValue&lt;/a&gt;&lt;br&gt;
github：&lt;a href="https://github.com/VisActor/VTable"&gt;https://github.com/VisActor/VTable&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vtable</category>
      <category>visactor</category>
      <category>visiualization</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to manually update the state when using the Checkbox in the VTable component?</title>
      <dc:creator>方帅</dc:creator>
      <pubDate>Fri, 14 Jun 2024 10:33:32 +0000</pubDate>
      <link>https://dev.to/fangsmile/how-to-manually-update-the-state-when-using-the-checkbox-in-the-vtable-component-505o</link>
      <guid>https://dev.to/fangsmile/how-to-manually-update-the-state-when-using-the-checkbox-in-the-vtable-component-505o</guid>
      <description>&lt;h2&gt;
  
  
  Problem Title
&lt;/h2&gt;

&lt;p&gt;Problem Description&lt;br&gt;
Is there a way to manually set the checkbox of the ListTable in VTable, and how to clear the selected state of all checkboxes?&lt;/p&gt;
&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;Call the interface to update the state&lt;br&gt;
You can call the interface setCellCheckboxState. This interface can set the checkbox state of a cell, and is defined as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;setCellCheckboxState(col: number, row: number, checked: boolean) =&amp;gt; void
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Parameter description:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;col: Column number&lt;/li&gt;
&lt;li&gt;row: Row number&lt;/li&gt;
&lt;li&gt;checked: Whether checked
Example: tableInstance.setCellCheckboxState(0, 3, true) sets the Checkbox state of the cell at position (0, 3) to checked state. The demo effect after modifying the official website is as follows: &lt;a href="https://visactor.io/vtable/demo/cell-type/checkbox"&gt;https://visactor.io/vtable/demo/cell-type/checkbox&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhqi2a79w9ykz13uho03c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhqi2a79w9ykz13uho03c.png" alt="Image description" width="800" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Batch update status:&lt;br&gt;
For the second question about batch update, currently, there is no dedicated interface to reset the status of all checkboxes. However, you can achieve the goal of updating all checkbox statuses by resetting the data using setRecords or updating the column configuration using updateColumns.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Update through column configuration
Add "checked" as true or false in the column configuration to set the status of the entire column. However, if there is a field in the data records indicating the status, the data record will prevail.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyudmbk9gtocvcywjwbvz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyudmbk9gtocvcywjwbvz.png" alt="Image description" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;To batch set the checkbox status by updating the records data source, it is required to explicitly specify the checkbox value fields in the records.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq4jndaw136f39tij3jvs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq4jndaw136f39tij3jvs.png" alt="Image description" width="800" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Related documents
&lt;/h2&gt;

&lt;p&gt;Tutorial on checkbox type usage: &lt;a href="https://visactor.io/vtable/guide/cell_type/checkbox"&gt;https://visactor.io/vtable/guide/cell_type/checkbox&lt;/a&gt;&lt;br&gt;
Checkbox demo: &lt;a href="https://visactor.io/vtable/demo/cell-type/checkbox"&gt;https://visactor.io/vtable/demo/cell-type/checkbox&lt;/a&gt;&lt;br&gt;
Related API：&lt;a href="https://visactor.io/vtable/option/ListTable-columns-checkbox#cellType"&gt;https://visactor.io/vtable/option/ListTable-columns-checkbox#cellType&lt;/a&gt;&lt;br&gt;
&lt;a href="https://visactor.io/vtable/api/Methods#setCellCheckboxState"&gt;https://visactor.io/vtable/api/Methods#setCellCheckboxState&lt;/a&gt;&lt;br&gt;
github：&lt;a href="https://github.com/VisActor/VTable"&gt;https://github.com/VisActor/VTable&lt;/a&gt;&lt;/p&gt;

</description>
      <category>visactor</category>
      <category>vtable</category>
      <category>webdev</category>
      <category>visiualization</category>
    </item>
    <item>
      <title>How to implement dimension drill-down function when using VTable pivot table component?</title>
      <dc:creator>方帅</dc:creator>
      <pubDate>Fri, 14 Jun 2024 10:28:19 +0000</pubDate>
      <link>https://dev.to/fangsmile/how-to-implement-dimension-drill-down-function-when-using-vtable-pivot-table-component-49pk</link>
      <guid>https://dev.to/fangsmile/how-to-implement-dimension-drill-down-function-when-using-vtable-pivot-table-component-49pk</guid>
      <description>&lt;h2&gt;
  
  
  Problem Description
&lt;/h2&gt;

&lt;p&gt;Does the VTable pivot table support drill-down interaction on the front end?&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffb081ncj0brl4esdeee8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffb081ncj0brl4esdeee8.png" alt="Image description" width="800" height="663"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Configuring this will give you an icon and listen for events (&lt;a href="https://visactor.io/vtable/api/events#DRILLMENU_CLICK"&gt;https://visactor.io/vtable/api/events#DRILLMENU_CLICK&lt;/a&gt;). Call the interface updateOption to update the full configuration after obtaining new data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Example
&lt;/h2&gt;

&lt;p&gt;You can refer to the official demo: &lt;a href="https://visactor.io/vtable/demo/data-analysis/pivot-analysis-table-drill"&gt;https://visactor.io/vtable/demo/data-analysis/pivot-analysis-table-drill&lt;/a&gt;.&lt;br&gt;
Key configuration for drillDown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const option = {
  records: data,
  rows: [
    {
      dimensionKey: 'Category',
      title: 'Category',
      drillDown: true,
      headerStyle: {
        textStick: true
      },
      width: 'auto'
    }
  ],
  columns: [
    {
      dimensionKey: 'Region',
      title: 'Region',
      headerStyle: {
        textStick: true
      },
      width: 'auto'
    }
  ],
  indicators: ...
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After configuration, the drill-down icon is displayed, and the click event of the icon drillmenu_click is listened. In the event processing logic, updateOption is called to update the configuration, and the configured drill-down icon changes to the drill-up icon drillUp.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tableInstance.on('drillmenu_click', args =&amp;gt; {
  if (args.drillDown) {
    if (args.dimensionKey === 'Category') {
      tableInstance.updateOption({
        records: newData,
        rows: [
          {
            dimensionKey: 'Category',
            title: 'Category',
            drillUp: true,
            headerStyle: {
              textStick: true
            },
            width: 'auto'
          },
          {
            dimensionKey: 'Sub-Category',
            title: 'Sub-Catogery',
            headerStyle: {
              textStick: true
            },
            width: 'auto'
          }
        ],
        columns: ...,
        indicators: ...
      });
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Result Display
&lt;/h2&gt;

&lt;p&gt;Here is the official website example effect:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb7w91e00s7e1e3qbv7vq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb7w91e00s7e1e3qbv7vq.png" alt="Image description" width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  related resources:
&lt;/h2&gt;

&lt;p&gt;Tutorial on using drill-down and drill-through in pivot tables: &lt;a href="https://visactor.io/vtable/guide/data_analysis/pivot_table_dataAnalysis"&gt;https://visactor.io/vtable/guide/data_analysis/pivot_table_dataAnalysis&lt;/a&gt;&lt;br&gt;
Demo of using Drill Down and Drill Through in pivot tables: &lt;a href="https://visactor.io/vtable/demo/data-analysis/pivot-analysis-table-drill?open_in_browser=true"&gt;https://visactor.io/vtable/demo/data-analysis/pivot-analysis-table-drill?open_in_browser=true&lt;/a&gt;&lt;br&gt;
Related APIs: &lt;a href="https://visactor.io/vtable/option/PivotTable-columns-text#drillDown"&gt;https://visactor.io/vtable/option/PivotTable-columns-text#drillDown&lt;/a&gt;&lt;br&gt;
&lt;a href="https://visactor.io/vtable/api/events?open_in_browser=true#DRILLMENU_CLICK"&gt;https://visactor.io/vtable/api/events?open_in_browser=true#DRILLMENU_CLICK&lt;/a&gt;&lt;br&gt;
github：&lt;a href="https://github.com/VisActor/VTable"&gt;https://github.com/VisActor/VTable&lt;/a&gt;&lt;/p&gt;

</description>
      <category>visactor</category>
      <category>vtable</category>
      <category>webdev</category>
      <category>visiualization</category>
    </item>
    <item>
      <title>How can I increase the gap between adjacent sparklines in the VTable component?</title>
      <dc:creator>方帅</dc:creator>
      <pubDate>Fri, 14 Jun 2024 10:25:57 +0000</pubDate>
      <link>https://dev.to/fangsmile/how-can-i-increase-the-gap-between-adjacent-sparklines-in-the-vtable-component-1neh</link>
      <guid>https://dev.to/fangsmile/how-can-i-increase-the-gap-between-adjacent-sparklines-in-the-vtable-component-1neh</guid>
      <description>&lt;h2&gt;
  
  
  Question Description
&lt;/h2&gt;

&lt;p&gt;The mini graph in the product uses VTable, but the effect of generating the mini graph with data is that the users feel the distance between adjacent line segments is too close. How to adjust this spacing?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftvhsdkary3hogjzgmuxi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftvhsdkary3hogjzgmuxi.png" alt="Image description" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;First, it is necessary to clarify that the width and height of a cell include two parts: the padding margin and the content. The padding margin in the VTable is set to [10, 16, 10, 16] by default, and the row height of the VTable is 40px by default, with the top and bottom padding margins taking up 20px. Therefore, the height of the content is reduced to 20px.&lt;br&gt;
The top and bottom padding margins take up 20px, so the minimum distance between two adjacent  sparklines charts is also 20px. In other words, the minimum distance between two adjacent  sparklines charts is determined by the padding margin. In the official example, padding margin is adjusted to 20, and it is found that the line curve becomes a straight line after the adjustment. This is because the 40px row height is occupied by the padding margin, leaving no space for the line chart to stretch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F262jrg92likk288neyyn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F262jrg92likk288neyyn.png" alt="Image description" width="800" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So in this case, we need to increase the row height accordingly. The effect of setting defaultRowHeight to 60 is as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feg7rcxylk2pogtqos2ab.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feg7rcxylk2pogtqos2ab.png" alt="Image description" width="800" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const records = [
  {
   'lineData':[50,20,20,40,60,50,70],
   'lineData2':[{x:1,y:1500},{x:2,y:1480},{x:3,y:1520},{x:4,y:1550},{x:5,y:1600}],
  },
  {
   'lineData':[50,20,60,40,60,50,70],
   'lineData2':[{x:1,y:1500},{x:2,y:1480},{x:3,y:1520},{x:4,y:1550},{x:5,y:1600}],
  },
  {
   'lineData':[50,50,20,40,10,50,70],
   'lineData2':[{x:1,y:1500},{x:2,y:1480},{x:3,y:1520},{x:4,y:1550},{x:5,y:1600}],
  },
  {
   'lineData':[70,20,20,40,60,50,70],
   'lineData2':[{x:1,y:1500},{x:2,y:1480},{x:3,y:1520},{x:4,y:1550},{x:5,y:1600}],
  }
];

const columns = [
  {
    field: 'lineData',
    title: 'sparkline',
    cellType: 'sparkline',
    width:300,
    style:{
      padding:20
    },
    sparklineSpec: {
        type: 'line',
        pointShowRule: 'none',
        smooth: true,
        line: {
          style: {
            stroke: '#2E62F1',
            strokeWidth: 2,
          },
        },
        point: {
          hover: {
              stroke: 'blue',
              strokeWidth: 1,
              fill: 'red',
              shape: 'circle',
              size: 4,
          },
          style: {
            stroke: 'red',
            strokeWidth: 1,
            fill: 'yellow',
            shape: 'circle',
            size: 2,
          },
        },
        crosshair: {
          style: {
            stroke: 'gray',
            strokeWidth: 1,
          },
        },
      },
  },
  {
    field: 'lineData2',
    title: 'sparkline 2',
    cellType: 'sparkline',
    width:300,
    style:{
      padding:20
    },
    sparklineSpec: {
        type: 'line', 
        xField: 'x',
        yField: 'y',
        pointShowRule: 'all',
        smooth: true,
        line: {
          style: {
            stroke: '#2E62F1',
            strokeWidth: 2,
          },
        },
      },
  },
];
const option = {
  records,
  columns,
  defaultRowHeight:60
};
const tableInstance = new VTable.ListTable(document.getElementById(CONTAINER_ID), option);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Result Display
&lt;/h2&gt;

&lt;p&gt;Just paste the code from the example directly into the official editor and it will be displayed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkslbnfn6ucucq6fkfl5l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkslbnfn6ucucq6fkfl5l.png" alt="Image description" width="800" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Relevant Documents
&lt;/h2&gt;

&lt;p&gt;Sparkline Usage Reference Demo：&lt;a href="https://visactor.io/vtable/guide/cell_type/sparkline"&gt;https://visactor.io/vtable/guide/cell_type/sparkline&lt;/a&gt;&lt;br&gt;
Style Usage Toturial：&lt;a href="https://visactor.io/vtable/guide/theme_and_style/style"&gt;https://visactor.io/vtable/guide/theme_and_style/style&lt;/a&gt;&lt;br&gt;
Related api：&lt;a href="https://visactor.io/vtable/option/ListTable-columns-sparkline#style.padding"&gt;https://visactor.io/vtable/option/ListTable-columns-sparkline#style.padding&lt;/a&gt;&lt;br&gt;
github：&lt;a href="https://github.com/VisActor/VTable"&gt;https://github.com/VisActor/VTable&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>vtable</category>
      <category>visactor</category>
      <category>visiualization</category>
    </item>
    <item>
      <title>When using the pivot table of the VTable component, how to display the calculated indicator results in a separate column?</title>
      <dc:creator>方帅</dc:creator>
      <pubDate>Sun, 02 Jun 2024 09:00:17 +0000</pubDate>
      <link>https://dev.to/fangsmile/when-using-the-pivot-table-of-the-vtable-component-how-to-display-the-calculated-indicator-results-in-a-separate-column-3993</link>
      <guid>https://dev.to/fangsmile/when-using-the-pivot-table-of-the-vtable-component-how-to-display-the-calculated-indicator-results-in-a-separate-column-3993</guid>
      <description>&lt;h2&gt;
  
  
  Question Description
&lt;/h2&gt;

&lt;p&gt;Is there any configuration that can generate derived indicators? Calculate the indicator results after aggregation, and then display them in the indicator.&lt;br&gt;
Description: For example, my row dimension is region - area, column dimension is month, and indicator is target, actual, and achievement (this achievement is calculated as actual / target). Achievement is the indicator I want to derive, because there is no achievement field in my data.&lt;br&gt;
Screenshot of the problem:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk2jo73ljwhdgfj29ode3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk2jo73ljwhdgfj29ode3.png" alt="Image description" width="800" height="154"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;Taking the pivot table on the official website of VTable as an example for similar target modifications, we add an indicator called Profit Ratio to the original demo, and use the format function to calculate the displayed value. The calculation logic depends on the values of the Sales and Profit indicators. That is, we calculate a profit ratio where profit ratio = profit / sales.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
          indicatorKey: 'Profit Ratio',
          title: 'Profit Ratio',
          width: 'auto',
          showSort: false,
          headerStyle: {
            fontWeight: 'normal'
          },
          format: (value,col,row,table) =&amp;gt; {
            const sales=table.getCellOriginValue(col-2,row);
            const profit=table.getCellOriginValue(col-1,row);
            const ratio= profit/sales;
            var percentage = ratio * 100;
            return percentage.toFixed(2) + "%";
          }
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Code Examples
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let tableInstance;
fetch('https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/North_American_Superstore_Pivot_data.json')
  .then(res =&amp;gt; res.json())
  .then(data =&amp;gt; {
    const option = {
      records: data,
      rows: [
        {
          dimensionKey: 'City',
          title: 'City',
          headerStyle: {
            textStick: true
          },
          width: 'auto'
        }
      ],
      columns: [
        {
          dimensionKey: 'Category',
          title: 'Category',
          headerStyle: {
            textStick: true
          },
          width: 'auto'
        }
      ],
      indicators: [
        {
          indicatorKey: 'Quantity',
          title: 'Quantity',
          width: 'auto',
          showSort: false,
          headerStyle: {
            fontWeight: 'normal'
          },
          style: {
            padding: [16, 28, 16, 28],
            color(args) {
              if (args.dataValue &amp;gt;= 0) return 'black';
              return 'red';
            }
          }
        },
        {
          indicatorKey: 'Sales',
          title: 'Sales',
          width: 'auto',
          showSort: false,
          headerStyle: {
            fontWeight: 'normal'
          },
          format: rec =&amp;gt; {
            return '$' + Number(rec).toFixed(2);
          },
          style: {
            padding: [16, 28, 16, 28],
            color(args) {
              if (args.dataValue &amp;gt;= 0) return 'black';
              return 'red';
            }
          }
        },
        {
          indicatorKey: 'Profit',
          title: 'Profit',
          width: 'auto',
          showSort: false,
          headerStyle: {
            fontWeight: 'normal'
          },
          format: rec =&amp;gt; {
            return '$' + Number(rec).toFixed(2);
          },
          style: {
            padding: [16, 28, 16, 28],
            color(args) {
              if (args.dataValue &amp;gt;= 0) return 'black';
              return 'red';
            }
          }
        },
        {
          indicatorKey: 'Profit Ratio',
          title: 'Profit Ratio',
          width: 'auto',
          showSort: false,
          headerStyle: {
            fontWeight: 'normal'
          },
          format: (value,col,row,table) =&amp;gt; {
            const sales=table.getCellOriginValue(col-2,row);
            const profit=table.getCellOriginValue(col-1,row);
            const ratio= profit/sales;
            var percentage = ratio * 100;
            return percentage.toFixed(2) + "%";
          }
        }
      ],
      corner: {
        titleOnDimension: 'row',
        headerStyle: {
          textStick: true
        }
      },
      dataConfig: {
        sortRules: [
          {
            sortField: 'Category',
            sortBy: ['Office Supplies', 'Technology', 'Furniture']
          }
        ]
      },
      widthMode: 'standard'
    };
    tableInstance = new VTable.PivotTable(document.getElementById(CONTAINER_ID), option);
    window['tableInstance'] = tableInstance;
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Result Display
&lt;/h2&gt;

&lt;p&gt;Just paste the code in the example code directly into the official editor to display it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fanfpwxmvekoug17s7ukz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fanfpwxmvekoug17s7ukz.png" alt="Image description" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Related documents
&lt;/h2&gt;

&lt;p&gt;Tutorial on pivot table usage: &lt;a href="https://visactor.io/vtable/guide/table_type/Pivot_table/pivot_table_useage"&gt;https://visactor.io/vtable/guide/table_type/Pivot_table/pivot_table_useage&lt;/a&gt;&lt;br&gt;
Demo of pivot table usage: &lt;a href="https://visactor.io/vtable/demo/table-type/pivot-analysis-table"&gt;https://visactor.io/vtable/demo/table-type/pivot-analysis-table&lt;/a&gt;&lt;br&gt;
Related API: &lt;a href="https://visactor.io/vtable/option/PivotTable#indicators"&gt;https://visactor.io/vtable/option/PivotTable#indicators&lt;/a&gt;&lt;br&gt;
github：&lt;a href="https://github.com/VisActor/VTable"&gt;https://github.com/VisActor/VTable&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>visactor</category>
      <category>vtable</category>
      <category>visiualization</category>
    </item>
    <item>
      <title>How to make text automatically omitted based on cell width when using custom rendering with VTable components?</title>
      <dc:creator>方帅</dc:creator>
      <pubDate>Sun, 02 Jun 2024 08:41:08 +0000</pubDate>
      <link>https://dev.to/fangsmile/how-to-make-text-automatically-omitted-based-on-cell-width-when-using-custom-rendering-with-vtable-components-4266</link>
      <guid>https://dev.to/fangsmile/how-to-make-text-automatically-omitted-based-on-cell-width-when-using-custom-rendering-with-vtable-components-4266</guid>
      <description>&lt;h2&gt;
  
  
  Question Description
&lt;/h2&gt;

&lt;p&gt;When using custom rendering with VTable in the product, the cell contains icon and text elements. It is expected that the column width can be automatically calculated based on the content at initial, and when manually dragging to resize the column width, the text can automatically be omitted instead of having the button float over the text. I am not sure how to write the code to achieve this effect of shrinking the column width and making the text turn into an sign '...'&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2r2wc8en0c15kyyf4ur1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2r2wc8en0c15kyyf4ur1.png" alt="Image description" width="800" height="654"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;We use the customLayout provided by VTable, which can automatically layout and automatically measure the width to adapt to the cell width. The specific writing method is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  customLayout: (args) =&amp;gt; {
        const { table,row,col,rect } = args;
        const record = table.getRecordByCell(col,row);
        const  {height, width } = rect ?? table.getCellRect(col,row);
        const container = new VTable.CustomLayout.Group({
          height,
          width,
          display: 'flex',
          flexWrap:'no-wrap',
          alignItems: 'center',
          justifyContent: 'flex-front'
       });
        const bloggerAvatar = new VTable.CustomLayout.Image({
          id: 'icon0',
          width: 20,
          height: 20,
          image:record.bloggerAvatar,
          cornerRadius: 10,
        });
        container.add(bloggerAvatar);
        const bloggerName = new VTable.CustomLayout.Text({
          text:record.bloggerName,
          fontSize: 13,
          x:20,
          fontFamily: 'sans-serif',
          fill: 'black',
          maxLineWidth:width===null?undefined:width-20+1
        });
        container.add(bloggerName);
        return {
          rootContainer: container,
          renderDefault: false,
        };
      }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CustomLayout needs to return a rootContainer, usually a Group object, to serve as a container for other content. Here, flexWrap is set so that internal elements (icon and text) do not wrap, and alignItems and justifyContent are used for horizontal and vertical alignment. The Group contains an Image and Text. If you want the text to automatically truncate with... when the space is compressed, you need to configure maxLineWidth. A special point here is that when column is set to 'auto', the value of width received by the customLayout function is null, so you need to check if it is null. If it is null, set maxLineWidth to undefined to automatically expand the width of the cell. If it is not null, set maxLineWidth according to the value of width. Subtracting 20 here avoids the width of the image, and the additional +1 is a buffer value that can be ignored.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Examples
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const option = {
    columns:[
      {
        field: 'bloggerId',
        title:'order number'
      }, 
      {
        field: 'bloggerName',
        title:'anchor nickname',
        width:'auto',
        style:{
          fontFamily:'Arial',
          fontWeight:500
        },
      customLayout: (args) =&amp;gt; {
        const { table,row,col,rect } = args;
        const record = table.getRecordByCell(col,row);
        const  {height, width } = rect ?? table.getCellRect(col,row);
        const container = new VTable.CustomLayout.Group({
          height,
          width,
          display: 'flex',
          flexWrap:'no-wrap',
          alignItems: 'center',
          justifyContent: 'flex-front'
       });
        const bloggerAvatar = new VTable.CustomLayout.Image({
          id: 'icon0',
          width: 20,
          height: 20,
          image:record.bloggerAvatar,
          cornerRadius: 10,
        });
        container.add(bloggerAvatar);
        const bloggerName = new VTable.CustomLayout.Text({
          text:record.bloggerName,
          fontSize: 13,
          x:20,
          fontFamily: 'sans-serif',
          fill: 'black',
          maxLineWidth:width===null?undefined:width-20+1
        });
        container.add(bloggerName);
        return {
          rootContainer: container,
          renderDefault: false,
        };
      }
    },
    {
      field: 'fansCount',
      title:'fansCount',
      fieldFormat(rec){
        return rec.fansCount + 'w'
      },
      style:{
        fontFamily:'Arial',
        fontSize:12,
        fontWeight:'bold'
      }
    }, 
    ],
   records:[
   {
      'bloggerId': 1,
      "bloggerName": "Virtual Anchor Xiaohua duoduo",
      "bloggerAvatar": "https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/flower.jpg",
      "introduction": "Hi everyone, I am Xiaohua, the virtual host. I am a little fairy who likes games, animation and food. I hope to share happy moments with you through live broadcast.",
      "fansCount": 400,
      "worksCount": 10,
      "viewCount": 5,
      "city": "Dream City",
      "tags": ["game", "anime", "food"]
    },
    {
      'bloggerId': 2,
      "bloggerName": "Virtual anchor little wolf",
      "bloggerAvatar": "https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/wolf.jpg",
      "introduction": "Hello everyone, I am the virtual anchor Little Wolf. I like music, travel and photography, and I hope to explore the beauty of the world with you through live broadcast.",
      "fansCount": 800,
      "worksCount": 20,
      "viewCount": 15,
      "city": "City of Music",
      "tags": ["music", "travel", "photography"]
      }
    ],
    defaultRowHeight:30
  };

const tableInstance = new VTable.ListTable(document.getElementById(CONTAINER_ID),option);
window['tableInstance'] = tableInstance;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Result Display
&lt;/h2&gt;

&lt;p&gt;Just paste the code in the example code directly into the official editor to present it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhvw9fming96c6nnpe9pg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhvw9fming96c6nnpe9pg.png" alt="Image description" width="388" height="142"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Related documents
&lt;/h2&gt;

&lt;p&gt;Tutorial on customLayout usage: &lt;a href="https://visactor.io/vtable/guide/custom_define/custom_layout"&gt;https://visactor.io/vtable/guide/custom_define/custom_layout&lt;/a&gt;&lt;br&gt;
Demo of customLayout usage: &lt;a href="https://visactor.io/vtable/demo/custom-render/custom-cell-layout"&gt;https://visactor.io/vtable/demo/custom-render/custom-cell-layout&lt;/a&gt;&lt;br&gt;
Related API: &lt;a href="https://visactor.io/vtable/option/ListTable-columns-text#customLayout"&gt;https://visactor.io/vtable/option/ListTable-columns-text#customLayout&lt;/a&gt;&lt;br&gt;
github：&lt;a href="https://github.com/VisActor/VTable"&gt;https://github.com/VisActor/VTable&lt;/a&gt;&lt;/p&gt;

</description>
      <category>visactor</category>
      <category>vtable</category>
      <category>webdev</category>
      <category>visiualization</category>
    </item>
  </channel>
</rss>
