DataEase project source code analysis – in-depth analysis of the style of view components and custom style implementation

In-depth analysis of the styles of view components and custom style implementation

Write in front

1. The project in this article is based on the description and testing of DateEase version 1.18.0; DateEase official website
2. Through this document, you can basically realize the visual parameter configuration modification and customization of almost all view component styles. For more view generation methods, please refer to (Component Generation)

Documents involved

1. src\views\chart\chart\util.js: view permission configuration file
2. src\views\chart\chart\chart.js: View style default parameter configuration file
3. src\views\chart\view\ChartStyle.vue: view style visual configuration entry file
4. src\views\chart\view\ChartEdit.vue related operation entry file in editing mode

Fields and methods involved

1. chart.customStyle: View data storage field, JSON string format; in the later rendering process, the set parameters are mainly obtained from this field.
2. Properties: Visual configuration first-level permission fields; from src\views\chart\chart\util.js file.
3. showPropertiesCollapse: first-level permission verification method; from src\views\chart\view\ChartStyle.vue, and related sub-components
4. propertyInner: Visually configure the secondary permission field; from the src\views\chart\chart\util.js file.
5. showProperties: Secondary permission verification method; from src\views\chart\view\ChartStyle.vue, and related subcomponents

Explanation of principles and field transfer

1. During initialization, “chart” is parsed and divided into two steps and simultaneously passed to the rendering component and the relevant operation entry file in editing mode (ChartEdit.vue)
2. After the rendering component parses “chart.customStyle”, it will perform further processing based on its own logic and configuration. Please refer to the following example for details.
3. In editing mode, the relevant operation entry file (ChartEdit.vue) passes the parameter “chart” downward to the view style visualization configuration entry file (ChartStyle.vue)
4. ChartStyle.vue and related subcomponents process the “properties” and “propertyInner” fields through the “showPropertiesCollapse” and “showProperties” methods to control the display of visual configuration items
5. ChartStyle.vue and related subcomponents finally pass the configured data to ChartEdit.vue through the “.$emit” method, then call the “calcStyle” method, and finally save it to the backend database. Then return “chart.customStyle” through the interface to form a closed loop

As an example, the following is to uniformly add outer spacing (margin) to antV components

Prerequisite instructions

1. DataEase’s antv mainly uses @antv/g2plot and @antv/s2
2. Relevant documents

  1. src\views\chart\chart\common\common_antv.js (all views public methods)
  2. src\views\chart\chart\common\common_table.js (table table public method)
  3. src\views\chart\components\ChartComponentS2.vue (table table rendering component)
  4. src\views\chart\chart\table\table-info.js (table table rendering method)

3. The g2plot component mainly uses “appendPadding”. DataEase has officially implemented a public method “getPadding”, but this method only returns a fixed value.
4. Since the s2 component does not have the concept of outer spacing (margin), it is mainly implemented by setting the “padding” value of the outer DIV and the width and height of the component.

The specific code is as follows

util.js view permission configuration code is as follows
 properties: [
      ....
      "margin-selector" //Outer spacing (margin) first-level permissions
    ],
    propertyInner: {
      ....
      'margin-selector': [//Outer spacing (margin) secondary permissions
        'marginTop', //top
        'marginBottom', // Next
        'marginLeft', // left
        'marginRight' // right
      ],
    }
ChartStyle.vue component controls the display of margin-selector component
<el-collapse-item
    v-show="showPropertiesCollapse(['margin-selector'])"
    name="margin"
    :title="$t('panel.margin')"
>
<margin-selector
    v-if="showProperties('margin-selector')"
    :param="param"
    class="attr-selector"
    :chart="chart"
    :property-inner="propertyInnerAll['margin-selector']"
    @onMarginChange="onMarginChange($event, 'margin-selector')"
/>

</el-collapse-item>

The margin-selector component controls the display of the marginTop configuration item
<el-form-item
v-show="showProperty('marginTop')"
:label="$t('chart.text_pos_top')"
class="form-item"
prop="marginTop"
>
<el-slider
    v-model="marginForm.marginTop"
    show-input
    :show-input-controls="false"
    input-size="mini"
    :min="0"
    :max="99"
    @change="changeMarginStyle(marginForm.marginTop, 'marginTop')"
/>
</el-form-item>

Modification of getPadding method in common_antv.js
export function getPadding(chart) {
  if (chart.customStyle) {
    const customStyle = JSON.parse(chart.customStyle)
    if (customStyle.margin) {
      const s = JSON.parse(JSON.stringify(customStyle.margin))
      const a=["marginTop","marginRight","marginBottom","marginLeft"]
      let b=0,c=[];
      for (const key in a) {
        const element = a[key];
        if(typeof s[element] !='undefined' & amp; & amp; typeof s[element]!=null & amp; & amp; s[element]!='' & amp; & amp; s[element]!=0){
          b + + ;
          c.push(Number(s[element]))
        }else{
          c.push(0)
        }
      }
      if(b>0){
        return c
      }
    }
  }

  if (chart.drill) {
    return [0, 10, 26, 10]
  } else {
    return [0, 10, 14, 10]
  }
}

Implementation of antV component table
1. Common_table.js new method
//Calculate component margins
export function getSize(chart) {
  const size = {}
  let customAttr = {}
  if (chart.customAttr) {
    customAttr = JSON.parse(chart.customAttr)
    // size
    if (customAttr.size) {
      const s = JSON.parse(JSON.stringify(customAttr.size))
      size.colCfg = {
        height: s.tableTitleHeight
      }
      size.cellCfg = {
        height: s.tableItemHeight
      }
      if (s.tableColumnMode & amp; & amp; s.tableColumnMode === 'adapt') {
        delete size.cellCfg.width
        size.layoutWidthType = 'compact'
      } else {
        delete size.layoutWidthType
        size.cellCfg.width = s.tableColumnWidth
      }
    }
  }

  return size
}

//Calculate component width and height
export function getWidthHeight(chart,containerDom) {
  let offsetWidth=containerDom.offsetWidth;
  let offsetHeight=containerDom.offsetHeight;
  var getnum=(ele)=>{
    if(typeof ele !='undefined' & amp; & amp; typeof ele!=null & amp; & amp; ele!='' & amp; & amp; ele!=0){
      returnNumber(ele)
    }
    return 0
  }
  if (chart.customStyle) {
    const customStyle = JSON.parse(chart.customStyle)
    if (customStyle.margin) {
      const s = JSON.parse(JSON.stringify(customStyle.margin))
      const Top=getnum(s['marginTop']);
      const Right=getnum(s['marginRight']);
      const Bottom=getnum(s['marginBottom']);
      const Left=getnum(s['marginLeft']);
      offsetWidth=offsetWidth-Right-Left;
      offsetHeight=offsetHeight-Top-Bottom;
    }
  }
  return {
    offsetWidth,
    offsetHeight
  }
}

2. table-info.js introduces getWidthHeight and configures it to the width (width) height (height) attributes of s2
 const WidthHeight=getWidthHeight(chart,containerDom)
  // options
  const s2Options = {
    width: WidthHeight.offsetWidth,
    height: WidthHeight.offsetHeight,
    showSeriesNumber: customAttr.size.showIndex,
    style: getSize(chart),
    conditions: getConditions(chart)
  }

3. ChartComponentS2.vue uses the method getSize to set the padding value of the outer DIV

VUE part code, configuration parameter “container_padding”

<div
    v-if="chart.type === 'table-pivot'"
    :id="chartId"
    style="width: 100%;overflow: hidden;"
    :style="{padding:container_padding}"
    class="table-dom-normal"
    />

JS part, set the parameter “container_padding” in the “drawView” method

drawView() {
    const chart = this.chart

    .......


    //margin
    this.container_padding=getPadding(chart)

    .......

}