“This is my NTH day of participating in the First Challenge 2022. For details: First Challenge 2022.”

preface

Recently, the weather in Hangzhou has not been very good, sometimes it rains and sometimes it snows. The design side gave me a version of the data visualization design draft for me to do at the beginning of the project, and I selected one worthy of recording (it seems not worthy, because it is not difficult 🐢🐢), which is the following one

The whole thing is not difficult, the key is to draw the column, how to draw the column is actually very easy to use Echarts custom chart to manually draw the path.

You can see that we are going to draw a blue pillar and a yellow diamond, so we need to draw two separate paths here and render them separately

Start drawing πŸ”›

So first we have to define acustomType diagram, as shown belowThe next thing we care about isrenderItemWhat do I have to return hereparamsandapiWhat are the parameters, because it’s a little bit too much, so I’m just going to explain it in the official documentation, and what are we going to use hereapi.value()andapi.coord()Two methods

Remember that renderItem is called once for each data item in data above

  • Api.value () : Retrieves the data value for the given dimension

  • @return {number} The value on the given dimension.

    • api.value(0): get the subscript of the data item — the first execution gets 0 (corresponding to the first data item above)
    • api.value(1)Get the value of the data item — the first execution gets 120 (corresponding to the first data item in the figure above)
  • Api.coord () : Maps data values to the coordinate system. The above data is passed in as an array

    • @param {Array.} data Indicates the data value.

    • Polar: [x, y, radius, Angle] polar: [x, y, radius, Angle]

Use custom charts πŸ’š

renderItem: function (params, api) {
  // Get the top coordinates of the bar chart
  const topAxis = api.coord([api.value(0), api.value(1)]);
  // Here are the coordinates at the bottom of the bar chart
  const bottomAxis = api.coord([api.value(0), 0]);
  return {
    type: 'InclinedRoofBar'.// This is a custom type,
    shape: {  // Here are the parameters to pass
      topAxis,
      bottomAxis
    }
  };
}
Copy the code

Note: the x – and Y-axis [0, 0] points are in the upper left corner

That’s what we got abovetopAxis ε’Œ bottomAxisThe attributes are the X-axis and Y-axis of the top point and the X-axis and Y-axis of the bottom point

According to the two coordinate points obtained above, we can draw the graph according to the coordinate points, which involves the canvas drawing path, so those who are not familiar with it can have a look at this article: πŸšͺ Portal: Canvas tutorial ✈️

Also write the following methods to draw custom graphics, using the following two methods, see πŸšͺ portal :Echarts documentation ✈️

Draw the blue column path and register using πŸ’™

const InclinedRoofBar = echarts.graphic.extendShape({
  // CTX: draw the path as a canvas
  Shape: The data contained in the shape argument returned by renderItem
  buildPath: function (ctx, shape) {
    // topAxis,bottomAxis
    let topAxis = shape.topAxis;
    let bottomAxis = shape.bottomAxis;
    // The initial point to draw
    const path0 = [topAxis[0] + 10, topAxis[1]].// The first line drawn
    const path1 = [topAxis[0] - 10, topAxis[1] + 10];
    Draw the second line
    const path2 = [bottomAxis[0] - 10, bottomAxis[1]].Draw the third line
    const path3 = [bottomAxis[0] + 10, bottomAxis[1]].// Diagonal cut column
    ctx
      .moveTo(path0[0], path0[1])
      .lineTo(path1[0], path1[1])
      .lineTo(path2[0], path2[1])
      .lineTo(path3[0], path3[1])
      // Close the path.closePath(); }});// After drawing, you need to register to use it
echarts.graphic.registerShape('InclinedRoofBar', InclinedRoofBar);



option = {
  xAxis: {
    type: 'category'.data: ['Mon'.'Tue'.'Wed'.'Thu'.'Fri'.'Sat'.'Sun']},yAxis: {
    type: 'value'
  },
  series: [{data: [120.200.150.80.70.110.130].type: 'custom'.renderItem: function (params, api) {
        const topAxis = api.coord([api.value(0), api.value(1)]);
        const bottomAxis = api.coord([api.value(0), 0]);
        return {
          type: 'InclinedRoofBar'.// Use the custom registration type !!!!!
          shape: {
            topAxis,
            bottomAxis
          },
          style: {// Add a color style to the column
             fill:'blue'}}; }}};Copy the code

The above code is dominated by the buildPath method passed in the graphic.extendShape() method, which takes two arguments to analyze and draw the path

  • CTX: Use it as a canvas to draw paths
  • Shape: The data contained in the shape argument returned by renderItem

It should be noted that the starting point of X-axis and Y-axis in canvas is the upper left corner [0, 0], X-axis +10 will move to the right, and Y-axis +10 will move down. This gives us the following chart

Draw a yellow diamond path and register it for use

We have already drawn the blue column above, and then we can directly copy and modify it, because the first point and the second point of the yellow diamond coincide with the blue column, so we only need to modify the third, fourth points

Draw the second line
const path2 = [topAxis[0] -10, topAxis[1] + 20];
Draw the third line
const path3 = [topAxis[0] + 10,  topAxis[1] + 10];
Copy the code

Replace the registered diamond path with the original column to see the effect

Merge two custom types πŸ’›

Combine two custom types using the group type

A group is the only container that can have child nodes. Groups can be used to position a group of graphic elements as a whole.

renderItem: function (params, api) {
  const topAxis = api.coord([api.value(0), api.value(1)]);
  const bottomAxis = api.coord([api.value(0), 0]);
  return {
    type: 'group'.// Use a custom registration type
    children: [{type: 'InclinedRoofBar'.// Column path
        shape: {
          topAxis,
          bottomAxis
        },
        style: {
          / / color
          fill: 'blue'}}, {type: 'InclinedRoofBar2'.// Rhombus path
        shape: {
          topAxis,
          bottomAxis
        },
        style: {
          / / color
          fill: '#fee082'}}}; }Copy the code

The final code (pasted into an Echarts instance) 🧑

const InclinedRoofBar = echarts.graphic.extendShape({
  // CTX: draw the path as a canvas
  Shape: The data contained in the shape argument returned by renderItem
  buildPath: function (ctx, shape) {
    // topAxis,bottomAxis
    let topAxis = shape.topAxis;
    let bottomAxis = shape.bottomAxis;
    // The initial point to draw
    const path0 = [topAxis[0] + 10, topAxis[1]].// The first line drawn
    const path1 = [topAxis[0] - 10, topAxis[1] + 10];
    Draw the second line
    const path2 = [bottomAxis[0] - 10, bottomAxis[1]].Draw the third line
    const path3 = [bottomAxis[0] + 10, bottomAxis[1]].// Diagonal cut column
    ctx
      .moveTo(path0[0], path0[1])
      .lineTo(path1[0], path1[1])
      .lineTo(path2[0], path2[1])
      .lineTo(path3[0], path3[1])
      // Close the path.closePath(); }});// After drawing, you need to register to use it
echarts.graphic.registerShape('InclinedRoofBar', InclinedRoofBar);

// Yellow diamond
const InclinedRoofBar2 = echarts.graphic.extendShape({
  // CTX: draw the path as a canvas
  Shape: The data contained in the shape argument returned by renderItem
  buildPath: function (ctx, shape) {
    // topAxis,bottomAxis
    let topAxis = shape.topAxis;
    let bottomAxis = shape.bottomAxis;
    // The initial point to draw
    const path0 = [topAxis[0] + 10, topAxis[1]].// The first line drawn
    const path1 = [topAxis[0] - 10, topAxis[1] + 10];
    Draw the second line
    const path2 = [topAxis[0] -10, topAxis[1] + 20];
    Draw the third line
    const path3 = [topAxis[0] + 10,  topAxis[1] + 10];
    // Diagonal cut column
    ctx
      .moveTo(path0[0], path0[1])
      .lineTo(path1[0], path1[1])
      .lineTo(path2[0], path2[1])
      .lineTo(path3[0], path3[1])
      // Close the path.closePath(); }});// After drawing, you need to register to use it
echarts.graphic.registerShape('InclinedRoofBar2', InclinedRoofBar2);

option = {
  xAxis: {
    type: 'category'.data: ['Mon'.'Tue'.'Wed'.'Thu'.'Fri'.'Sat'.'Sun']},yAxis: {
    type: 'value'
  },
  series: [{data: [120.200.150.80.70.110.130].type: 'custom'.renderItem: function (params, api) {
        const topAxis = api.coord([api.value(0), api.value(1)]);
        const bottomAxis = api.coord([api.value(0), 0]);
        return {
          type: 'group'.// Use a custom registration type
          children: [{type: 'InclinedRoofBar'.// Use a custom registration type
              shape: {
                topAxis,
                bottomAxis
              },
              style: {
                / / color
                fill: 'blue'}}, {type: 'InclinedRoofBar2'.// Use a custom registration type
              shape: {
                topAxis,
                bottomAxis
              },
              style: {
                / / color
                fill: '#fee082'}}}; }}};Copy the code

‘πŸ’―

The article is not very good. If you have any questions, you can comment and reply πŸ˜