D3.js v5从值获取数据

D3.js v5从值获取数据,d3.js,data-visualization,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

我试着从我创建的一些圆圈中提取数据,然后编写代码。圆圈必须包含这些信息,但我不知道它是否包含这些信息

圆圈中数据的代码为:

<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;
    }
 }

如果我把鼠标放在圆圈上,我想做的是在圆圈内查找数据,但是当鼠标离开这个圆圈时,悬停消失了。然后,有了这些数据,我想写一篇关于国家和人口的文章

现在,所有代码:

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;
            })
})


你的问题有点难理解,但听起来你想做的是:

  • 响应某些事件,例如
    鼠标悬停
  • 以某种方式更改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。例如,如果我想要一些文本用作工具提示。请注意,您必须加入到
svg:g
并在其中附加圆,而不是加入到
circle
(因为您不能在
circle
中添加
文本
节点)

请注意,清理同样简单,在
mouseexit
事件中,您可以从
svg:g

d3.select(this)
  .selectAll("text")
  .remove();

你的问题有点难理解,但听起来你想做的是:

  • 响应某些事件,例如
    鼠标悬停
  • 以某种方式更改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。例如,如果我想要一些文本用作工具提示。请注意,您必须加入到
svg:g
并在其中附加圆,而不是加入到
circle
(因为您不能在
circle
中添加
文本
节点)

请注意,清理同样简单,在
mouseexit
事件中,您可以从
svg:g

d3.select(this)
  .selectAll("text")
  .remove();

您可以在.on('mouseover')事件类型console.log(d)中将数据打印到控制台,检查是否已将数据正确分配给圆圈对象,并检查控制台中出现的内容。如果数据已正确分配,则可以使用.on('mouseenter')、.on('mousemove')和.on('mouseout')事件创建弹出窗口。为了修改年份值以更新图像,为了简单起见,如果数据中存在每年的按钮,则在单击每个按钮时会附加一个事件。然后,您可以使用“.each”更新图形,或者完全删除图形,更改“year”变量,并使用您创建的函数重新绘制它。如果你编辑你的问题并包含完整的代码和数据,我会帮你看看。是的!!!!我已经编写了console.log(d),我在圆圈内有所有数据。谢谢现在,你知道我怎样才能只取我鼠标悬停的圆的值吗?我曾经遇到的另一个问题是,如果我将鼠标悬停在“更改圆圈颜色”上,当我退出圆圈时,错误的颜色仍然存在,这很好:),.on('mouseover',function(d){console.log(d)});应该返回您正在跳过的圆的数据。你可以上传你的csv文件的一部分吗?它不必全部都是,这样我就可以测试你的代码了。你可以通过将数据打印到控制台上('mouseover')事件类型console.log(d)来检查你的数据是否被正确分配给了圆圈对象,并检查控制台中出现了什么。如果数据已正确分配,则可以使用.on('mouseenter')、.on('mousemove')和.on('mouseout')事件创建弹出窗口。为了修改年份值以更新图像,为了简单起见,如果数据中存在每年的按钮,则在单击每个按钮时会附加一个事件。然后,您可以使用“.each”更新图形,或者完全删除图形,更改“year”变量,并使用您创建的函数重新绘制它。如果你编辑你的问题并包含完整的代码和数据,我会帮你看看。是的!!!!我已经编写了console.log(d),我在圆圈内有所有数据。谢谢现在,你知道我怎样才能只取我鼠标悬停的圆的值吗?我曾经遇到的另一个问题是,如果我将鼠标悬停在“更改圆圈颜色”上,当我退出圆圈时,错误的颜色仍然存在,这很好:),.on('mouseover',function(d){console.log(d)});应该返回您正在跳过的圆的数据。你能上传你的csv文件的一部分吗?它不必全部都是,这样我就可以测试你的代码了。@Krakenudo没问题,如果这有帮助的话,我希望能投赞成票并将答案标记为接受:)@Krakenudo没问题,如果这有帮助的话,我希望能投赞成票并将答案标记为接受:)