HIV数据可视-可交互式地图+可拖动时间条(D3+Javascript)

演示视频:数据可视化大作业_HIV可视化分析_哔哩哔哩_bilibili

PPT汇报:数据可视化大作业 (HIV数据研究及可视化 javascript d3 +python 爬虫 + 页面整合)_阿阿阿扶的博客-CSDN博客_数据可视化大作业

参考代码来源:Codepen

演示GIF:

1.数据的读入和字段含义:

读取文件,共两个文件—geo地理位置json文件和各国HIV感染现状csv文件;使用d3.v4.js,读取代码如下:

d3.queue()
  .defer(d3.json, "./content1/50m.json")
  .defer(d3.csv, "./content1/m7.csv", row => {
     return {
        continent: row.Continent,
        country:row.Country,
        countryCode: row["Code"],
        DeathRate: +row["HIV_AIDS_ALL_Deaths"],
        InfectionRate: +row["Prevalence"],
        region: row.Region,
        year: +row.Year,
        inc:+row["inc"]
     }
    })

m7.csv表格中共包含5700条数据,数据来源于http://ghdx.healthdata.org/gbd-results

-tool,下载的单个原数据集只包含一个艾滋相关的字段值,将地域信息和年份进行匹配之后,得到如下的表格,表格预览和字段解释如下: 

图8 m7.csv表格数据

若想获取使用的数据集,点击下载数据即可。

图9 点击按钮

D3分别将表中的国家信息,和地理编码读入,根据countryCode字段值在50m.json匹配地理的位置;将每年艾滋死亡率占比总死亡率、人口感染率、新增艾滋感染患者字段的值分别存入 DeathRate,InfectionRate和inc,用于渲染视图;国家的对应的信息(大洲)也读入continent,用于按洲信息绘制饼图。年份信息用于更新各个视图。

2.地图的可视化和信息更新:

地图有两种模式,分别是DeathRate和InfectionRate。HTML中代码如下所示,默认为DeathRate模型的地图可视,根据单选框Radio实现地图模式的切换:

 图10 两种地图模式

 HTML代码实现如下:

      <input type="radio" name="data-type" value="DeathRate" checked>
      <label>艾滋死亡占总死亡比率</label>
      <input type="radio" name="data-type" value="InfectionRate">
      <label>人口感染艾滋比例</label>

在js中,根据data-type的value进行相应更换,更换的代码如下:

 var currentDataType = d3.select('input[name="data-type"]:checked') //读取data-type类型
                          .attr("value");
..........  
d3.selectAll('input[name="data-type"]')                     //根据data-type切换数据
      .on("change", () => {
        var active = d3.select(".active").data()[0];
        drawPie(data, currentYear, currentDataType); 
drawMap(geoData, data, currentYear, currentDataType);
      });

我们还添加了时间进度条,根据不同年份数据渲染地图、饼图;拖动进度条,查看不同年份数据详情。

 

 图 11时间进度条选择

在HTML中增添类型为range的时间条,年份间隔为1:

 <p>
      年份选择: <span id="year-val"></span>
      <input id="year" type="range" step="1">
    </p>

在js中,根据年份信息匹配数据:

  d3.select("#year")                      
      .property("min", currentYear)
      .property("max", extremeYears[1])
      .property("value", currentYear)              //获得当前年份信息
      .on("input", () => {                      
        currentYear = +d3.event.target.value;        //根据年份绘制地图,饼图
        drawMap(geoData, data, currentYear, currentDataType);
      });

画地图函数为drawMap(geoData, HIVData, year, dataType),geoData即我们的地理数据,HIVData为艾滋病相关数据。根据年份和选择模式进行地图的渲染,效果为下:

 图 12地图渲染

地图的titile更换如下,需要根据数据类型和当前的年份做调整;

d3.select(".map-title")
      .text("" +(dataType === "DeathRate" ? "Share of deaths from HIV/AIDS" : "Share of the population infected with HIV")+graphTitle(dataType) +","+ year);

Tooltip的应用,用于在视图上更好的交互信息:

  d3.selectAll("#map")
    .on("mousemove touchmove", updateTooltip);
  d3.selectAll("#pie")
    .on("mousemove touchmove", updateTooltip);
  d3.selectAll("#bar")
    .on("mousemove touchmove", updateTooltip);

主要把国家的信息,要展示的HIV数据情况和年份信息并进行交互。其中地图、柱形图和其中一个饼图的tooltip是一样的,因为展现New case饼图只根据每年每国的新增病例来提供交互信息。

地图国家的颜色根据对应艾滋数据更改,颜色偏红黑调:

//地图颜色的更改
var colors=["#FFEFD5","#f1c40f","#FFB90F","#FF4500","#800000"];
   var domains = {
    DeathRate: [0,0.03, 0.5, 1.0, 6,20],
    InfectionRate: [0,0.03, 0.5,1.0,5,10]
  };

3.地图和柱状图之间的联动:

选中地图中的国家,可以就将该国家的近30年来的艾滋数据显示在右侧的柱形图中,用于研究各国近期艾滋的详情和对应的趋势变化,从而达到数据可视和数据分析的效果。如下图所示:

 图13 交互地图和图表联动

例如,在地图中点击选中Russia,右图中将Russia这个国家近30年对应地图模式的信息使用条形图展现出来,同时根据时间进度条的年份高亮对应的年份的条形。

条形图绑定国家信息:一开始先绘制好所有的图表,在我们未在地图中选中国家时,条形图不展示任何信息,只有坐标轴在视图中。根据d3.select(".active").data()[0]来获取我们选中的国家的名称,根据国家名称来绘制条形图,同时条形图也有逐渐弹升和逐渐消失的效果,更加美观,给用户更多反应的时间。JS中的代码实现如下:

  d3.selectAll('input[name="data-type"]')
      .on("change", () => {
        var active = d3.select(".active").data()[0];
        var country = active ? active.properties.country : ""; //绑定选中国家名称
        currentDataType = d3.event.target.value;
        drawMap(geoData, data, currentYear, currentDataType);
        drawBar(data, currentDataType, country);  //绘制对应国家30年具体数据条形图
      });

在地图绘制函数中添加对应的更新函数,使在地图上先选中该国家后,右边条形图随着动画效果绘制近三十年的艾滋数据情况,再次选中该国家,则条形图消失:

update
    .enter()
    .append("path")
      .classed("country", true)
      .attr("d", path)
      .on("click", function() {
        var currentDataType = d3.select("input:checked")
                                .property("value");
        var country = d3.select(this);
        var isActive = country.classed("active");
        var countryName = isActive ? "" : country.data()[0].properties.country;
        drawBar(climateData, currentDataType, countryName);//绘制对应国家30年具体数据条形图
        highlightBars(+d3.select("#year").property("value"));//高亮
        d3.selectAll(".country").classed("active", false);  //再次选中该国家则条形图消失
        country.classed("active", !isActive);
      })
    .merge(update)
      .transition()               
      .duration(750)                                //条形图的过渡效果
      .attr("fill", d => {
        var val = d.properties[dataType];
        return val ? mapColorScale(val) : "#ccc"; });

根据鼠标选中的国家信息和模式信息,作为参数传入drawBar函数中,绘制该国家的近30年艾滋数据详情。

高亮条形:根据拖动的当前年份信息,传入highlightBars函数,高亮这条条形,将选中额年份的条形颜色加深,使得研究者更加方便地查看信息:

 d3.select("#year")
      .property("min", currentYear)
      .property("max", extremeYears[1])
      .property("value", currentYear)
      .on("input", () => {
        currentYear = +d3.event.target.value;
        drawMap(geoData, data, currentYear, currentDataType);
     highlightBars(currentYear);    //高亮选中年份对应条形图
      });  

4.按各国家地域信息(洲)展示饼图:

将处于一个洲的国家绘制通一个颜色,并且聚集在一处。饼图显示当前年份国家艾滋数据占全球数据的占比构成,根据当前年份和模式会进行更新变化。因为在读入数据时,已经把国家的地域信息(洲)存在continent字段中,根据地域信息和数据详情使得国家排序:

  var pie = d3.select("#pie");
  var arcs = d3.pie()
               .sort((a,b) => {
                 if (a.continent < b.continent) return -1;
                 if (a.continent > b.continent) return 1;
                 return a[dataType] - b[dataType];})
               .value(d => d[dataType]);

js中根据洲信息来使得位于同一个洲的国家在饼图中表现为一个颜色,代码如下所示:

var colorScale = d3.scaleOrdinal()
                     .domain(continents)
                    .range(["#26a69a", "#87CEEB","#42a5f5", "#4682B4","#3CB371",
"#ab47bc", "#7e57c2"]);
........
 update
   ......     
    .merge(update)
      .attr("fill", d => colorScale(d.data.continent))
      .attr("d", path);  

以此,可以允许研究者以洲的角度为切入,观察各个国家新增病例随着时间改变在全球的占比情况及死亡率,感染率占比情况等,也可以探索邻近国家的感染原因的关系等。饼图的可视化结果如下:

 图14各国每年新增艾滋病例饼图

猜你喜欢

转载自blog.csdn.net/cangzhexingxing/article/details/125322687