成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

在微信小程序中繪制圖表(part2)

canopus4u / 1828人閱讀

摘要:本期大綱確定縱坐標(biāo)的范圍并繪制根據(jù)真實數(shù)據(jù)繪制折線相關(guān)閱讀在微信小程序中繪制圖表在微信小程序中繪制圖表關(guān)注我的項目查看完整代碼。相關(guān)閱讀在微信小程序中繪制圖表在微信小程序中繪制圖表

本期大綱

1、確定縱坐標(biāo)的范圍并繪制

2、根據(jù)真實數(shù)據(jù)繪制折線

相關(guān)閱讀:
在微信小程序中繪制圖表(part1)
在微信小程序中繪制圖表(part3)

關(guān)注我的 github 項目 查看完整代碼。

確定縱坐標(biāo)的范圍并繪制

為了避免縱坐標(biāo)的刻度出現(xiàn)小數(shù)的情況,我們把縱坐標(biāo)分為5個區(qū)塊,我們?nèi)∽钚挝豢潭葹槔?0(能夠被5整除),當(dāng)然真實情況會比這復(fù)雜,待會兒我們再討論。

所以我們的處理輸入輸出應(yīng)該是下面的結(jié)果

(5, 34.1)  => (10, 40)
(10, 34)   => (10, 40)
(-5.1, 40) => (-10, 40)
// 確定Y軸取值范圍
function findRange (num, type, limit) {
    limit = limit || 10;
    
    // upper向上查找,lower向下查找
    type = type ? type : "upper";

    // 進行取整操作,避免while時進入死循環(huán)
    if (type === "upper") {
        num = Math.ceil(num);
    } else {
        num = Math.floor(num);
    }
    while (num % limit !== 0) {
        if (type === "upper") {
            num++;
        } else {
            num--;
        }
    }

    return num;
}

好了,初步的確定范圍已經(jīng)完成了,但是細(xì)想一下這個范圍還是不是很理想,比如用戶傳入的數(shù)據(jù)都是小數(shù)級別的,比如 (0.2, 0.8),我們輸出的范圍是(0, 5)這個范圍偏大,圖表展現(xiàn)的效果則會是上面有大部分的留白,同樣用戶輸入的數(shù)據(jù)很大,比如(10000, 18000),我們得到的范圍是(10000, 18010),這個范圍則沒什么意義,所以我們需要根據(jù)傳入的數(shù)據(jù)的范圍來分別確定我們的最小單位刻度。

規(guī)定我們的參數(shù)格式是這樣的:

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

讓我們繼續(xù)進行優(yōu)化

// 合并數(shù)據(jù),將series中的每項data整合到一個數(shù)組當(dāng)中
function dataCombine(series) {
    return series.reduce(function(a, b) {
        return (a.data ? a.data : a).concat(b.data);
    }, []);
}

// 根據(jù)數(shù)據(jù)范圍確定最小單位刻度
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);
// 獲取傳入數(shù)據(jù)的最小值
var minData = Math.min.apply(this, dataList);
// 獲取傳入數(shù)據(jù)的最大值
var maxData = Math.max.apply(this, dataList);

var limit = getLimit(maxData, minData);

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

現(xiàn)在我們動態(tài)的確定除了合適的最小刻度范圍,接下來我們接著優(yōu)化一下上面的findRange方法,主要是增加對小數(shù)的支持

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;
}

現(xiàn)在我們已經(jīng)確定好了Y軸的取值范圍,關(guān)于如何畫出Y軸可以參看 part1 中X軸的繪制方法,此處不再累贅。

Y軸效果圖:

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

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]
        }
    ]
}

效果還不錯,我們接著往下

根據(jù)真實數(shù)據(jù)繪制折線

問題的關(guān)鍵在于確定每個數(shù)據(jù)點的(x, y)坐標(biāo),x坐標(biāo)比較好確定,我們根據(jù)畫布的寬度以及opts.categories即可確定。

規(guī)定我們的配置為:

config = {
    xAxisHeight: 30, // X軸高度
    yAxisWdith: 30   // Y軸寬度
}
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);
});

y坐標(biāo)稍微會復(fù)雜一點,需要根據(jù)Y軸的范圍已經(jīng)本身的數(shù)值進行計算得出。

所以我們計算出的y應(yīng)該為

y = validHeight * (data - min) / (max - min);
// 由于canvas畫布是左上角為原點坐標(biāo),故我們變化一下
// 得到最終的y繪制點
y = valideHeight - y;

代碼如下:

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);
}

現(xiàn)在我們已經(jīng)確定了數(shù)據(jù)點在畫布上的繪制坐標(biāo),關(guān)于如何繪制折現(xiàn)請查看 part1 中相關(guān)內(nèi)容,此處不再累贅。

最終效果圖如下:

預(yù)告:下一部分我們一起討論繪制過程中的一些技巧、動畫效果和如何工程化我們的項目。

相關(guān)閱讀

在微信小程序中繪制圖表(part1)
在微信小程序中繪制圖表(part3)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/91259.html

相關(guān)文章

  • 在微信小程序繪制圖表(part1)

    摘要:微信小程序中提供了的支持,利用自行繪制圖表。關(guān)注我的項目查看完整代碼。 微信小程序中圖表現(xiàn)狀 由于微信小程序本身框架的限制,很難集成目前已有的圖表工具,顯示圖表目前有兩種方案:1、服務(wù)器端渲染圖表,輸出圖片,微信小程序中直接顯示渲染好的圖片,比如highcharts提供了服務(wù)端渲染的能力hightcharts server render,這種方式需要后臺有一套渲染服務(wù),并且有一定的網(wǎng)絡(luò)...

    chaosx110 評論0 收藏0
  • 在微信小程序繪制圖表(part3)

    摘要:本期大綱餅圖繪制如何添加動畫效果使用構(gòu)建項目相關(guān)閱讀在微信小程序中繪制圖表在微信小程序中繪制圖表關(guān)注我的項目查看完整代碼。 本期大綱 1、餅圖繪制2、如何添加動畫效果3、使用rollup構(gòu)建項目 相關(guān)閱讀:在微信小程序中繪制圖表(part1)在微信小程序中繪制圖表(part2) 關(guān)注我的 github 項目 查看完整代碼。 很久沒更新了,最近事情比較多,今天來把坑填上! 餅圖繪制 ...

    褰辯話 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<