一、题目要求及文件格式
1)要求:
读取csv文件,绘制出100个圆表示全球的100人,并根据鼠标点击分类标准实现动态的交互。
2)文件格式:
3)效果图:
二、实现思路
1)通过随机数方法Math.random()创建初始的100个随机点。
var maxRange = 100;
for (var i = 0; i < numDataPoints; i++) {
var newNumber1 = Math.floor(Math.random() * maxRange);
var newNumber2 = Math.floor(Math.random() * maxRange);
dataset.push([newNumber1, newNumber2]);
}
接下来若想实现图中效果,可以区分为两个部分看待:
第一部分:如何绘制均匀分布的直线?
第二部分:如何绘制排列整齐的散点?
2)编写绘制直线初始坐标的函数
//创建一个函数,输入要分为几组的数字num,获取均匀分布的初始坐标的数组。
//假定每条线长20px
var avg_axis=function(num){
var len=w/num;
var start_position=(len-20)/2;
var new_arr=[];
new_arr.push(start_position);
for(var i=1;i<num;i++)
{
var position=start_position+i*len;
new_arr.push(position);
}
return new_arr;
}
有此函数获得的数组,便是直线的初始x坐标,便可以根据不同的分组数获得不同的画线坐标。
3)编写绘制均匀排列的点的函数
//通过此函数可以获得读取的文件中,某一种分类的数组
//格式为:
//[[female,40],[male,60]],也就是最终返回一个嵌套数组,由此服务下面的画圆函数lay_main()
var sort_it = function(name) {
var sum=45;//总共有45条数据
arr=[];
for(var i=0;i<sum;i++)
{
if(data[i].Category==name)
{
array=[];
array.push(data[i].Subcategory);
array.push(data[i].Value);
arr.push(array);
}
}
return arr;
}
//此函数通过输入上述函数得到的数组,数组长度,画线的初始位置数组,数据集数组dataset
//便可通过“取余”、“做除法”的操作,使用for循环逐个把每一个点的坐标放到dataset里
var lay_main=function(arr_new,length,position_arr,dataset){
for(var i=0;i<length;i++)
{
//分几组循环几次
var circle_sum=arr_new[i][1];//获取圆的个数
quzheng=parseInt(circle_sum/10);
quyu=circle_sum%10;
var ww=6;
var hh=6;
var position_x=position_arr[i]+2;
var position_y=300;
for(var j=0;j<quzheng;j++)//先填入取整部分的值
{
for(var k=0;k<10;k++)
{
var newNumber1=position_x+k*ww;
var newNumber2=position_y-(j+1)*hh;
dataset.push([newNumber1, newNumber2]);
}
}
if(quyu!=0)
{
for(var l=0;l<quyu;l++)
{
var newNumber1=position_x+l*ww;
var newNumber2=position_y-(quzheng+1)*hh;
dataset.push([newNumber1, newNumber2]);
}
}
}
return dataset;
}
4)交互与动态变化
通过对span文字的点击,实现数据的变更和图像的绘制。
再加上transition()完成动态的变化。
d3.select("span[class=p2]")
.on("click", function() {
svg.selectAll("line").remove();
svg.selectAll("text").remove();
arr_new=sort_it(diff[0]);
//console.log(arr_new);
length=arr_new.length;
//console.log(length);
position_arr=avg_axis(length);
//console.log(position_arr);
for(var i=0;i<length;i++)
{
svg.append("line")
.attr("x1", position_arr[i])
.attr("y1", 300)
.attr("x2", position_arr[i]+60)
.attr("y2", 300)
.attr("stroke", "#FF0000")
.attr("stroke-width", "2px");
svg.append('text')
.text(arr_new[i][0])
.attr("x",position_arr[i]+30)
.attr('y',320)
.attr('text-anchor',"middle")
.style("font-size",10)
.style("fill","#FF8C00");
}
//更新散点坐标值
var maxRange = 100;
dataset = [];
dataset=lay_main(arr_new,length,position_arr,dataset); //调用函数添加新的散点数据
//更新绘图
svg.selectAll("circle")
.data(dataset)
.transition()
.duration(1000)
.attr("cx", function(d) {
return d[0];
})
.attr("cy", function(d) {
return d[1];
});
});