Hi ~ I am Yefeng, the front-end apprentice. Have you watched the live broadcast of cloud Computing conference a few days ago? I’ve been flooded with “Shadowless”… In addition to cloud computers, there are also a large number of large screens that can be directly experienced online. So what kind of components do we use to develop large screens in Ali?

I’m going to share a series of visualizations about how our front end open source charting library 📈 CloudCharts (Github) can chart with a few configuration items based on G2 packaging, eventually serving nearly two hundred internal products and many external cloud products.

I will elaborate on the problems encountered by G2 in large-scale usage scenarios:

  1. What is the overall architecture of the component library? How to use React gracefully while managing the code inside components?

  2. How to unify the constraint data format?

  3. How to achieve out of the box, reduce the threshold of use?

  4. How to converge chart theme presentation and quickly switch themes?

  5. How to build diagrams in low code?

Today is the first in a series on the first two questions

Problem decomposition

1. What is the overall architecture of the component library? How to use React gracefully while managing the code inside components?

There are schemes like BizCharts and Viser to use G2 in React, but they just make simple syntactic sugar and are a long way from being truly out of the box. Therefore, we need to develop a program that can not only make it easy for users to use, but also manage the code inside the component library to ensure maintainability.

2. How to unify constraint data format?

G2 data mapping is flexible and powerful, but it increases the learning threshold and reduces efficiency in actual service use. Therefore, the data format of the component was uniformly constrained to the data format similar to HighCharts, and data mapping was carried out internally.

With ideas, the next kangkang specific how to achieve 👀 :

1. Establish the life cycle

First, build the overall architecture of the component library, so that the project can be maintained and developed for a long time, and reduce the possible historical burden as far as possible. React allows us to use our component library elegantly and manage component internal code.

It doesn’t matter if you don’t have a good idea at the beginning, let’s first list the entire process of component graphing:

Looking at the process of diagramming, we can divide it into several parts of the component lifecycle: creation, existence, and destruction. This is basically the same as the React lifecycle.

We found that a large part of these drawing processes can be reused, with most components differing only in the “declare drawing logic” step to establish a lifecycle management mechanism.

The component code, implemented by native code, is responsible for declaring G2’s graphical syntax. The intermediate factory function is responsible for creating the diagram instance, calling the lifecycle, and some reusable logic, and finally returning the React component.

Example factory function

The factory function is the core of the management lifecycle, and the code for the factory function is shown briefly here. The actual logic will be much more, interested students can go to Github to check the source code: portal

import G2 from '@antv/g2';
import React from 'react';

function factory(name, component) {
  class CloudCharts extends React.Component {
    componentDidMount() {
      // Set the initial width and height
      this.initSize();
      // Initialize the chart
      this.initChart(this.props);
    }

    componentDidUpdate(prevProps) {
      // The configuration item has changed
      this.rerender();
      // Update the data
      component.changeData(data);
    }

    componentWillUnmount() {
      this.destroy();
    }

    // Initializes the height and width of the adaptation
    initSize(props) {}

    // Initialize the chart
    initChart(props) {
      this.chart = new G2.Chart({
        container: this.chartDom,
      });
      // Call component code
      component.init(this.chart);
    }

    destroy() {
      component.destroy();
    }

    render() {
      return (
        <div ref={dom= > (this.chartDom = dom)} />
      );
    }
  }

  CloudCharts.displayName = `CloudCharts${name}`;

  return CloudCharts;
}
Copy the code

2. Data format mapping

With unified lifecycle management in place, the next step is to constrain the data formats that users pass in. We built a layer of data transformation into the factory function, allowing users to pass in data in HighCharts format. So how does that work internally?

Let’s look at this ordinary chart, which consists of just one broken line and point:

The corresponding G2 data format is a very simple JSON array, where each entry corresponds to a data point on the chart:

const data = [
  { year: '1995'.value: 4.9 },
  { year: '1996'.value: 6 },
  { year: '1997'.value: 7 },
  { year: '1998'.value: 9 },
  { year: '1999'.value: 13},];Copy the code

Data fields (year * value) must be specified after G2 is passed

The Highcharts format is slightly more complicated, but the key content (data values) is the same:

const data = [
  {
    // name is used to distinguish multiple groups of data
    name: 'Fold one'.data: [['1995'.5],
      ['1996'.6],
      ['1997'.7],
      ['1998'.9],
      ['1999'.13]],},];Copy the code

So it can be converted to G2 format through loop processing:

const newData = [];

data.forEach(oneData= > {
  const { name: dataName } = oneData;

  oneData.data.forEach((d, i) = > {
    const [x, y, ...extra] = d;
    newData.push({
      x,
      y,
      extra,
      type: dataName,
    });
  });
});
Copy the code

The x, y, and type returned here correspond to fields in the graph syntax:

chart.geom().position(['x'.'y']).color('type')
Copy the code

Data fields are fixed inside the charting library so that users can use data in HighCharts format, which also facilitates the migration of businesses using HighCharts to the new charting library.

Halftime dividing line

With the two steps above, the framework of the entire chart library has been formed.

That’s it for this issue, and we’ll continue to break it down next time!

📢 📢 what do you think? Feel free to post in the comments


✏️ Next announcement

I’ll focus on the third question

“How to do it out of the box, lower the threshold of use”

This article was first published on wechat, remember to keep following us oh ~