用canvas绘制象素概率图,做数据新闻用得上的小工具

Posted on 2017-03-10 by 毛三胖

摘要

本文简要介绍了用canvas绘制象素概率图的基本过程,附带制图小工具。用象素概率图表示概率的大小,十分的直观和形象,尤其是用来表示小概率事件。文中附带了程序代码,你可以动手来试一下,十分的简单。


1.象素概率图

随着社会的进步,概率(百分数)与生活的关系也越来越紧密。足球比赛的概率、交通事故发生的概率、中彩票的概率、涨工资的概率等等不一而足。概率的百分数表示不够直观和形象,尤其是对小概率的表示。用象素概率图表示事件发生可能性,则会比较直观,易于理解。1000乘1000象素的图片即可表示百万级别的分数,象素概率图可以广泛的应用于数据新闻生产。

1.1双色球五等奖【10元】概率图(约为0.77%):

双色球五等奖概率图

1.2小编今年涨工资的概率图(约为0.01%):

涨工资的概率图

从以上对比图中可以清晰的得出结论,还是买彩票比较靠谱。俺们涨工资的难度比得上巴萨6-1惊天逆转巴黎了吧。

2.象素概率图小工具

地址:象素概率图工具

象素概率图工具

利用该小工具,你可以定义画布的大小,点个数,背景颜色,点颜色等变量。

因为性能等原因,对自定义变量做了一些限制,其中画布最大宽度5000px,最小宽度10px;画布最大高度5000px,最小高度10px;最多点数量50000个,最少点数量1个。

3.象素概率图程序

程序的基本思路是在X轴(画布宽),Y轴(画布高)上随机选点放到集合SET中,直到集合在点数达到指定个数为止,用canvas的fillRect方法绘制背景后,取集合中的(x,y)绘制一象素大小的点。

3.1 页面程序:

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>【42度】象素概率图生成工具</title>
</head>
<script language="javascript" src="/media/js/collection.js"></script>
<body>
<canvas id="myCanvas" width="1000" height="1000">your browser does not support the canvas tag </canvas>
<script type="text/javascript">
    var xs = new Set();
    var canvas=document.getElementById('myCanvas');
    var ctx=canvas.getContext('2d');
    ctx.fillStyle="#ff0000";
    ctx.fillRect(0,0,1000,1000);
    ctx.fillStyle="#0000ff";
    while(xs.size() < 2000) {
        var x = Math.floor(Math.random()*1000 +1);
        var y = Math.floor(Math.random()*1000 +1);
        var val1 = x+"_"+y;
        xs.add(val1);
    }
    for( var i = 0; i < xs.size(); i++) {
        var val2 = xs.values()[i];
        var loc = val2.indexOf("_");
        var x2 = val2.substr(0,loc);
        var y2 = val2.substr(loc+1,val2.length);
        ctx.fillRect(parseInt(x2),parseInt(y2),1,1);
    }
</script>
</body>
</html>

3.2 JS集合类(collection.js):

function Set(){
    var items = {};
    this.has = function(value) {
        return items.hasOwnProperty(value)
    };
    this.add = function(value) {
        if (!this.has(value)) {
            items[value] = value;
            return true;
        }
        return false;
    };
    this.remove = function(value) {
        if (this.has(value)) {
            delete items[value];
            return true;
        }
        return false;
    };
    this.clear = function() {
        this.items = {};
    };
    this.size = function() {
        return Object.keys(items).length;
    }
    this.sizeLegacy = function() {
        var count = 0;
        for (var prop in items) {
            if (items.hasOwnProperty(prop)) {
                ++count;
            }
        }
        return count;
    }
    this.values = function() {
        return Object.keys(items);
    };
    this.valuesLegacy = function() {
        var keys = [];
        for (var key in items) {
            keys.push(key)
        };
        return keys;
    };
}