canvas教程

利用HTML5 Canvas创建交互式Bubble Chart(2)

字号+ 作者:H5之家 来源:H5之家 2017-02-01 10:09 我要评论( )

如果你用Excel打开报告,它看起来只是一堆行。我们需要把数据解析成我们能用的形式。为了解析数据文件,我们需要CSV解析程序。Josh Marinacci从Ben Nadel下载了一个解析程序,很好用。为了下载CSV文件并解析它Josh

如果你用Excel打开报告,它看起来只是一堆行。我们需要把数据解析成我们能用的形式。为了解析数据文件,我们需要CSV解析程序。Josh Marinacci从Ben Nadel下载了一个解析程序,很好用。为了下载CSV文件并解析它Josh Marinacci使用AJAX调用jQuery。


$(“#load”).click(function() { $.ajax({ url: ”data.csv”, context: document.body, success: function(c) { var csvdata = CSVToArray(c); console.log(“got to here “ + csvdata[1]); } }); }



CSV文件被解析成由许多行组成的文件,这些行可以继续进行子划分被划分成列。我们可以通过先列循环再行循环的方式处理CSV文件。


data = []; //start at 9 to skip non-year columns and first few years for(var t=9; t<csvdata[0].length-1; t++) { var cdata = []; //loop through rows by threes for(var i=1; i<csvdata.length-1; i+=3) { var row_mort = csvdata[i]; var row_dens = csvdata[i+1]; var row_total = csvdata[i+2]; var country = (i-1)/3; cdata.push({ x:row_dens[t] , y:row_mort[t], size: row_total[t], country: country, }); } data[t-9] = cdata; }



注意上述代码是从第9列开始处理数据的,不仅跳过了数据不完整的的前几年的数据点也跳过了一些元数据(如国家名字等等)。处理行的时候每次循环是处理三行数据目的是通过一次循环可以处理一个国家或地区的数据。


如果仅仅按照这种方式处理数据,我们将什么都看不到。整个Canvas都被单一的颜色填充,这不是我们想要的结果。这是因为数据并没有按比例进行适当的扩展。例如在1960年东亚和太平洋地区的人口是10亿。为了描绘图表需要按比例缩小这个值。为了适用于这些未修改的数据在绘制图表的时Josh Marinacci使用了可扩展的功能。只需要采用如下方式改变弧度即可:


ctx.arc( d.x*6, canvas.height-d.y*2.5, d.size/(1000*1000*11), 0,Math.PI*2 );



上述代码修改了x、y和气泡大小的值适应Canvas。气泡大小必须除以1100万才能得到合理的气泡半径。Y值由Canvas高度减去y乘以2.5得到。Canvas的标准坐标系要从左上方开始以便被Canvas高度减去之后可以翻转y坐标。


修改数据变量的值是可以任意选取的,选择某个特定的值是为了让表格看起来比较美观。具体选择什么值依赖于正在描绘的数据。可以写一个程序分析数据寻找合理的参数值,比如通过计算每一个变量的最大值或者最小值。


表格看起来如下:

1309.jpg


增加交互性


赋予表格时间这一点很好,增加表格的交互性实际上就是让图表阅读者通过点击不同的气泡获取更多的信息。由于Canvas完全使用像素而不是我们需要的图形,这种图形使得通过程序我们可以计算哪一个图形被点击了。幸运地是Canvas中的气泡都是完美的圆,这将使事情容易很多。我们只需要计算被点击点与气泡圆心的距离即可,如果距离小于半径就认为该气泡被点击。代码如下:


$(“#canvas”).mousedown(function(e) { displayInfo = false; data[time].forEach(function(d) { var x = d.x*6; var y = canvas.height-d.y*2.5; var radius = d.size/(1000*1000*11); var dis = dist(e.offsetX,e.offsetY,x,y); if(dis < radius) { displayInfo = true; displayCountry = d.country; } }); draw(); });



如果读者已经点击了某个图形,显示信息的布尔值将变为“true”,保存当前的国家并触发重绘操作,同时在右上方通过代码嵌入一个小的信息板。


注意在重绘代码中填充的数据是来自于当前时间片而不是用户点击表格时的时间。这就意味着当表格被赋予时间属性之后显示的内容将更新以便用户可以看到随着时间变化的数据。

if(displayInfo) { ctx.save(); ctx.translate(canvas.width-305,5); ctx.fillStyle = ”rgba(200,200,200,0.7)”; ctx.fillRect(0,0,300,100); ctx.strokeStyle = ”black”; ctx.lineWidth = 2; ctx.strokeRect(0,0,300,100); ctx.fillStyle = ”black”; var displayPoint = data[time][displayCountry]; ctx.fillText(“Region: “ + regions[displayPoint.country],5,20); ctx.fillText(“Population Density: “ + displayPoint.x,5,20+20*1); ctx.fillText(“Mortality rate: “ + displayPoint.y,5,20+20*2); ctx.fillText(“Population: “ + displayPoint.size,5,20+20*3); ctx.restore();


}


改变图表的视觉效果


一般而言图报表不应该有这么多的可视元素否则将减损数据的潜在表现性,但是选择一个完美的颜色和模式将产生巨大的差别。为了让这个表看起来更好,Josh Marinacci给每个气泡增加了一层白色覆盖物使圆更加完美。同时也给每个圆增加一个黑色的边框并为每个集合选择不同的颜色。相对于计算每个气泡颜色的渐变度Josh Marinacci采用先选择一个基本的颜色然后改变它的透明度的方式为每个不同的气泡选择颜色。


var radgrad = ctx.createRadialGradient( x-radius/10,y-radius/10,0, x-radius/10,y-radius/10,radius+30); radgrad.addColorStop(0, ’white’); radgrad.addColorStop(0.5, ’white’); radgrad.addColorStop(1, ’rgba(255,255,255,0.3)’); ctx.globalAlpha = 0.6; ctx.fillStyle = radgrad; ctx.fill();



为了使图表更加美观上述代码改变了字体增加了边框,使用了一个来自于Subtle Patterns网站充满娱乐性的背景。最终图表如下:

1310.jpg


总结


 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • html5 Canvas鐢诲浘鏁欑▼(10)鈥旀妸闈㈡媶鎴愮嚎鏉℃ā鎷熷嚭鍦

    html5 Canvas鐢诲浘鏁欑▼(10)鈥旀妸闈㈡媶鎴愮嚎鏉℃ā鎷熷嚭鍦

    2017-02-01 08:00

  • 基于HTML5Canvas和jQuery的画图工具的实现

    基于HTML5Canvas和jQuery的画图工具的实现

    2017-01-31 18:03

  • html5 canvas画图实践

    html5 canvas画图实践

    2017-01-31 11:01

  • html5 Canvas画图教程—画图的基本常识

    html5 Canvas画图教程—画图的基本常识

    2017-01-31 10:00

网友点评