D3.js v5从价值中获取数据

时间:2018-07-15 19:32:51

标签: d3.js data-visualization

我正在尝试从我创建的某些圈子中获取数据,并严格限制代码。圈子必须包含此信息,但我不知道它是否包含该信息。

圆圈中数据的代码为:

<script src="https://d3js.org/d3.v5.min.js"></script>
var year=1970
function typeClean(row){
  r = {}
  r.country = row.Country;
  r.continente = row.Continent;
  r.year = +row.Year;
  r.fertility = +row.fertility;
  r.esperanza = +row.life;
  r.population = +row.population;
  r.region = row.region;
  //return r;

    if(r.year==year){
        return r;
    }
 }

然后,我定义一些这样的圆圈:

var colorScale = d3.scaleOrdinal(d3.schemeCategory10)
var chart = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
    chart.selectAll("body").data(datos).enter()
           .append("circle")
           .attr("cx", d => xScale(d.esperanza))
           .attr("cy", d => yScale(d.fertility))
           .attr("r", d => rScale(d.population))
           .attr("fill", d => colorScale(d.region))
           .attr("stroke", "#FFF")
           .attr("stroke-width", 1.5)
           .on("mouseover", function (d) {
               var thatCountry = ...;
           }
      )

circles by countries

我想做的是,如果我将鼠标悬停在圆圈上,则在圆圈内查找数据,但是当鼠标退出该圆圈时,悬停就会消失。然后,根据数据,我想写一个有关国家和人口的文字。

现在,所有代码:

const totalWidth = 900;
const totalHeight = 420;

var margin = {top: 20, right: 10, bottom: 80, left: 90};
var width = totalWidth - margin.left - margin.right;
var height = totalHeight - margin.top - margin.bottom;

var svg = d3.select("body")
            .append("svg")
            .attr("width",totalWidth)
            .attr("height",totalHeight)

var year = 1970;

function typeClean(row){
  r = {}
  r.country = row.Country;
  r.continente = row.Continent;
  r.year = +row.Year;
  r.fertility = +row.fertility;
  r.esperanza = +row.life;
  r.population = +row.population;
  r.region = row.region;
  //return r;

    if(r.year==year){
        return r;
    }
 }



d3.csv("gapminder_data.csv",row => typeClean(row)).then(datos => {
//Scales
const xMax = d3.max(datos, d => d.esperanza)
const xScale = d3.scaleLinear().domain([30,82]).range([0, width])

const yMax = d3.max(datos, d => d.fertility)
const yScale = d3.scaleLinear().domain([0, 9]).range([height, 0])    

const rMax = d3.max(datos, d => d.population)
const rMin = d3.min(datos, d => d.population)
const rScale = d3.scaleSqrt().domain([rMin, rMax]).range([4, 25])

const xAxis = d3.axisBottom()
                .scale(xScale)
const yAxis = d3.axisLeft()
                .scale(yScale)
var colorScale = d3.scaleOrdinal(d3.schemeCategory10)

var chart = svg.append("g")
               .attr("transform", `translate(${margin.left},${margin.top})`);
    chart.append('g')
         .attr("transform", `translate(0,${height})`)
         .call(xAxis)
         .append("text")
         .text("Esperanza_vida")
         .attr("x",width/2)
         .attr("y",48)
         .attr("fill","black")
         .attr("class","axis")

    chart.append('g')
         .call(yAxis)
         .append("text")
         .text("Fertilidad")
         .attr("x",-78)
         .attr("y",-26)
         .attr("fill","black")
         .attr("class","axis")
         .attr("size",-30)
         .attr("transform","rotate(-90)");


    chart.selectAll("body").data(datos).enter()
         .append("circle")
         .attr("cx", d => xScale(d.esperanza))
         .attr("cy", d => yScale(d.fertility))
         .attr("r",d => rScale(d.population))
         .attr("fill", d => colorScale(d.region))
         .attr("stroke", "#FFF")
         .attr("stroke-width",1.5)
            .on("mouseover", function (d) {
            console.log(d)
           var thatCountry;
            })

})

Country,Year,fertility,life,population,child_mortality,gdp,region
Afghanistan,1964,7.671,33.639,10474903.0,339.7,1182.0,South Asia
Afghanistan,1965,7.671,34.152,10697983.0,334.1,1182.0,South Asia
Afghanistan,1966,7.671,34.662,10927724.0,328.7,1168.0,South Asia
Albania,1964,5.711,65.475,1817098.0,122.67,3023.0,Europe & Central Asia
Albania,1965,5.593999999999999,65.863,1869942.0,120.09,3129.0,Europe & Central Asia
Albania,1966,5.483,66.122,1922993.0,117.56,3242.0,Europe & Central Asia
Algeria,1964,7.653,47.953,11654905.0,247.3,5693.0,Middle East & North Africa
Algeria,1965,7.655,48.388999999999996,11923002.0,248.2,5916.0,Middle East & North Africa
Algeria,1966,7.657,48.806000000000004,12229853.0,248.9,5478.0,Middle East & North Africa
Angola,1964,7.425,34.604,5337063.0,305.2,4573.0,Sub-Saharan Africa
Angola,1965,7.43,35.007,5431135.0,297.55,4840.0,Sub-Saharan Africa
Angola,1966,7.422000000000001,35.41,5524090.0,289.99,5043.0,Sub-Saharan Africa

1 个答案:

答案 0 :(得分:2)

从您的问题中很难理解,但听起来您想做的是:

  • 响应某些事件,例如mouseover
  • 以某种方式更改DOM作为响应

因此,首先,您的选择中存在一个错误,这将搞砸数据绑定,这对于这一点非常重要。以下行:

chart.selectAll("body").data(datos).enter().append("circle")

应阅读更多类似内容:

chart.select("body").selectAll("circle").data(datos).enter().append("circle");

基本上,您应该为要附加的内容致电selectAll。您稍后可以偏离此模式以进行更高级的可视化。


要响应事件,请在执行操作时订阅,第一个参数d代表您绑定到的datum或数据行。

.on("mouseover", function(datum, index, elements) { 
    // datum can have additional information on
})

在这一点上,我通常会手动修改DOM。例如。例如,如果我想将某些文本用作工具提示。请注意,除了加入circle之外,还必须加入svg:g并在其中附加圆圈(因为您无法在{{1}中添加text节点}。

circle

请注意,清理非常简单,在.on("mouseover", function(datum) { // this represents the element selected d3.select(this) .append("text") .attr("class", "tooltip") .text(d => d.name); }); 事件中,您可以从mouseexit删除所有文本元素

svg:g