Drawing charts in wechat applet (Part2)

Time:2021-6-23

Outline of this issue

1. Determine the range of ordinate and draw

2. Draw broken line according to real data

Related reading:
Drawing chart in wechat applet (Part1)
Drawing charts in wechat applet (Part3)

Follow megithubProject view full code.

Determine the range of ordinate and draw

In order to avoid decimals in the scale of the ordinate, we divide the ordinate into five blocks. We take the minimum unit scale as 10 (which can be divided by 5). Of course, the real situation will be more complicated than this. We will discuss it later.

So our processing input and output should be the following result

(5, 34.1)  => (10, 40)
(10, 34)   => (10, 40)
(-5.1, 40) => (-10, 40)
//Determine the value range of y-axis
function findRange (num, type, limit) {
    limit = limit || 10;
    
    //Upper looks up and lower looks down
    type = type ? type : 'upper';

    //Carry out rounding operation to avoid entering dead loop when while
    if (type === 'upper') {
        num = Math.ceil(num);
    } else {
        num = Math.floor(num);
    }
    while (num % limit !== 0) {
        if (type === 'upper') {
            num++;
        } else {
            num--;
        }
    }

    return num;
}

OK, the preliminary determination range has been completed, but it is not ideal to think about this range. For example, the data passed in by users is decimal level, such as(0.2, 0.8)Our output range is(0, 5)This range is too large, and the effect of the chart will be that most of the data above is left blank. Similarly, the data input by the user is very large, such as(10000, 18000)The range we get is(10000, 18010)This range is meaningless, so we need to determine our minimum unit scale according to the range of the incoming data.

Our parameter format is as follows:

opts = {
    ...
    series: [{
            ...
            data: [15, 20, 45, 37, 4, 80]
        }, {
            ...
            data: [70, 40, 65, 100, 34, 18]
        }
    ]
}

Let’s continue to optimize

//Merge data, and integrate each data item in series into an array
function dataCombine(series) {
    return series.reduce(function(a, b) {
        return (a.data ? a.data : a).concat(b.data);
    }, []);
}

//Determine the minimum unit scale according to the data range
function getLimit (maxData, minData)
    var limit = 0;
    var range = maxData - minData;
    if (range >= 10000) {
        limit = 1000;
    } else if (range >= 1000) {
        limit = 100;
    } else if (range >= 100) {
        limit = 10;
    } else if (range >= 10) {
        limit = 5;
    } else if (range >= 1) {
        limit = 1;
    } else if (range >= 0.1) {
        limit = 0.1;
    } else {
        limit = 0.01;
    }
}

var dataList = dataCombine(opts.series);
//Gets the minimum value of the incoming data
var minData = Math.min.apply(this, dataList);
//Gets the maximum value of the incoming data
var maxData = Math.max.apply(this, dataList);

var limit = getLimit(maxData, minData);

var minRange = findRange(minData, 'lower', limit);
var maxRange = findRange(maxData, 'upper', limit);

Now let’s dynamically determine the appropriate minimum scale range. Next, let’s optimize the abovefindRangeMethod, mainly to increase the support for decimals

function findRange (num, type, limit) {
    limit = limit || 10;
    type = type ? type : 'upper';
    var multiple = 1;
    while (limit < 1) {
        limit *= 10;
        multiple *= 10;
    }
    if (type === 'upper') {
        num = Math.ceil(num * multiple);
    } else {
        num = Math.floor(num * multiple);
    }
    while (num % limit !== 0) {
        if (type === 'upper') {
            num++;
        } else {
            num--;
        }
    }

    return num / multiple;
}

Now we have determined the value range of y-axis. For how to draw y-axis, please refer topart1The method of drawing the x-axis is no longer cumbersome here.

Y-axis rendering:

opts = {
    ...
    series: [{
            ...
            data: [15, 20, 45, 37, 4, 80]
        }, {
            ...
            data: [70, 40, 65, 100, 34, 18]
        }
    ]
}

Drawing charts in wechat applet (Part2)

opts = {
    ...
    series: [{
            ...
            data: [0.15, 0.2, 0.45, 0.37, 0.4, 0.8]
        }, {
            ...
            data: [0.30, 0.37, 0.65, 0.78, 0.69, 0.94]
        }
    ]
}

Drawing charts in wechat applet (Part2)

It’s not bad. Let’s move on

Draw broken line according to real data

The key of the problem is to determine the location of each data point(x, y)Coordinates,xIt’s easy to determine the coordinates. Let’s use the width of the canvas andopts.categoriesIt can be determined.

Our configuration is as follows:

config = {
    Xaxisheight: 30, // X-axis height
    Yaxiswdith: 30 // Y-axis width
}
var data = [15, 20, 45, 37, 4, 80];
var xPoints = [];
var validWidth = opts.width - config.yAxisWidth;
var eachSpace = validWidth / opts.categories.length;
var start = config.yAxisWidth;

data.forEach(function (item, index) {
    xPoints.push(start + (index + 0.5) * eachSpace);
});

yThe coordinates will be a little more complicated and need to be calculated according to the range of Y axis.

Drawing charts in wechat applet (Part2)

So we worked it outyIt should be

y = validHeight * (data - min) / (max - min);
//Since the upper left corner of the canvas is the origin coordinate, let's change it
//Get the final y drawing point
y = valideHeight - y;

The code is as follows:

var data = [15, 20, 45, 37, 4, 80];
var yPoints = [];
var validHeight = opts.height - config.xAxisHeight;
data.forEach(function(item) {
    var y = validHeight * (item - min) / (max - min);
    y = validHeight - y;

    yPoints.push(y);
}

Now that we have determined the drawing coordinates of the data points on the canvas, please see how to draw thempart1This is no longer cumbersome.

The final picture is as follows:

Drawing charts in wechat applet (Part2)

Notice: in the next part, we will discuss some skills in the drawing process, animation effects and how to engineer our project.

Related reading

Drawing chart in wechat applet (Part1)
Drawing charts in wechat applet (Part3)