javascript - 这个数据可视化代码有什么问题?

标签 javascript svg d3.js

我正在尝试运行 This Code使用我手动添加的一组不同的数据。下面是我的脚本,但是当我打开文件时出现了一个空白屏幕。我的代码有什么问题?我认为我输入数据的方式有问题。我能够在我的屏幕上出现统一的气泡,但是当我尝试添加将更改大小以匹配变量的函数时,代码停止工作。数据中的前两个变量是占位符,用于匹配原始代码的 csv 文件以获得相似的样式结果,但它们并不一定重要。我只需要最终代码即可在鼠标悬停时输出数据并在查看时更改气泡的大小和形状。

<script>

  // set the dimensions and margins of the graph
  var width = 500
  var height = 500
  
  // append the svg object to the body of the page
  var svg = d3.select("#my_dataviz")
    .append("svg")
      .attr("width", width)
      .attr("height", height)
  
  // create dummy data -> just one element per circle
  var data = [
  { "Asia": "Southeast Asia", "Burundi": 3.14 }, 
  { "Asia": "Southeast Asia", "South Sudan": 3.39 }, 


  var color = d3.scaleOrdinal()
    .domain(["Asia", "Europe", "Africa", "Oceania", "Americas"])
    .range(d3.schemeSet1);

   // Size scale for countries
   var size = d3.scaleLinear()
    .domain([0, 1010])
    .range([7,55])

  var node = svg.append("g")
    .selectAll("circle")
    .data(data)
    .enter()
    .append("circle")
      .attr("class", "node")
      .attr("r", function(d){ return size(d.value)})
      .attr("cx", width / 2)
      .attr("cy", height / 2)
      .style("fill", function(d){ return color(d.region)})
      .style("fill-opacity", 0.8)
      .attr("stroke", "black")
      .style("stroke-width", 1)
      .on("mouseover", mouseover)

最佳答案

您看不到圆圈,因为圆圈的半径未定义:检查页面将显示您的圆圈在那里,但由于它们没有有效的半径,因此它们不会呈现。
您在此处设置半径:

.attr("r", function(d){ return size(d.value)})
但是您的数据数组中的项目没有名为 value 的属性。 . d表示数据数组中的单个项目。链接代码解析一个 csv,其中有一列名为 value ,它创建一个数组,其中每个项目都有一个名为 `value.我们将需要处理您的数据以赋予我们的数据该属性,可能类似于:
 data = data.map(function(d) {
    let entries = Object.entries(d);
    return {region: entries[0][0] ,subregion: entries[0][1] ,country: entries[1][0], value: entries[1][1]}
 })
就个人而言,我最初会生成具有一致字段名称的数据,而不是依赖于依赖于键/对象对与 JavaScript 对象方法的排序的事实处理,因为这可能会引入一些跨浏览器问题,我不是最熟悉。

// set the dimensions and margins of the graph
  var width = 500
  var height = 500
  
  // append the svg object to the body of the page
  var svg = d3.select("body")
    .append("svg")
      .attr("width", width)
      .attr("height", height)
  
  // create dummy data -> just one element per circle
  var data = [
  { "Asia": "Southeast Asia", "Burundi": 3.14 }, 
  { "Asia": "Southeast Asia", "South Sudan": 3.39 }, 
  { "Asia": "Southeast Asia", "Malawi": 7.63 }, 
  { "Asia": "Southeast Asia", "Mozambique": 14.22 }, 
  { "Asia": "Southeast Asia", "Democratic Republic of the Congo": 40.92 }, 
  { "Asia": "Southeast Asia", "Central African Republic": 2.32 }, 
  { "Asia": "Southeast Asia", "Afghanistan": 19.44 }, 
  { "Asia": "Southeast Asia", "Madagascar": 14.26 }, 
  { "Asia": "Southeast Asia", "Sierra Leone": 4.14}, 
  { "Asia": "Southeast Asia", "Niger": 12.97}, 
  { "Asia": "Southeast Asia", "Eritrea": 2.08}, 
  { "Asia": "Southeast Asia", "Chad": 10.51}, 
  { "Asia": "Southeast Asia", "Yemen": 19.24}, 
  { "Asia": "Southeast Asia", "Liberia": 3.31}, 
  { "Asia": "Southeast Asia", "Togo": 5.71}, 
  { "Asia": "Southeast Asia", "Haiti": 8.35}, 
  { "Asia": "Southeast Asia", "Sudan": 32.21}, 
  { "Asia": "Southeast Asia", "Gambia": 1.8},
  { "Asia": "Southeast Asia", "Guinea-Bissau": 1.51}, 
  { "Asia": "Southeast Asia", "Burkina Faso": 16.07}, 
  { "Americas": "Caribbean", "Jeff Bezos": 189.3}, 
  { "Americas": "Caribbean", "Elon Musk": 182.2}, 
  { "Americas": "Caribbean", "Bernard Arnault": 157.7},
  { "Americas": "Caribbean", "Bill Gates": 123.7}, 
  { "Americas": "Caribbean", "Mark Zuckerberg": 95.7}, 
  { "Americas": "Caribbean", "Warren Buffet": 91.7}, 
  { "Americas": "Caribbean", "Larry Page": 90.9},
  { "Americas": "Caribbean", "Zhong Shanshan": 89.8}, 
  { "Americas": "Caribbean", "Sergey Brin": 88.2}, 
  { "Americas": "Caribbean", "Larry Elison": 85.2}, 
  { "Americas": "Caribbean", "Steve Ballmer": 80.4},
  { "Americas": "Caribbean", "Mukesh Ambani": 78}, 
  { "Americas": "Caribbean", "Francois Bettencourt Meyers": 75.6}, 
  { "Americas": "Caribbean", "Armando Ortega": 74}, 
  { "Americas": "Caribbean", "Colin Zheng Huang": 69.1}, 
  { "Americas": "Caribbean", "Alice Walton": 65.1}, 
  { "Americas": "Caribbean", "Jim Walton": 64.9}, 
  { "Americas": "Caribbean", "Rob Walton": 64.6},
  { "Americas": "Caribbean", "Carlos Slim Helu": 64}, 
  { "Americas": "Caribbean", "Jack Ma": 62}, 
  { "Africa": "Western Africa", "Total of 20 Poorest Countries": 232.22},
  { "Europe": "Southern Europe", "Wealth Gained by American Billionaires during Coronavirus Pandemic": 1010}]


     data = data.map(function(d) {
        let entries = Object.entries(d);
        return {region: entries[0][0] ,subregion: entries[0][1] ,country: entries[1][0], value: entries[1][1]}
     })


  var color = d3.scaleOrdinal()
    .domain(["Asia", "Europe", "Africa", "Oceania", "Americas"])
    .range(d3.schemeSet1);

   // Size scale for countries
   var size = d3.scaleLinear()
    .domain([0, 1010])
    .range([7,55])

     // create a tooltip
  var Tooltip = d3.select("#my_dataviz")
    .append("div")
    .style("opacity", 0)
    .attr("class", "tooltip")
    .style("background-color", "white")
    .style("border", "solid")
    .style("border-width", "2px")
    .style("border-radius", "5px")
    .style("padding", "5px")

     // Three function that change the tooltip when user hover / move / leave a cell
  var mouseover = function(d) {
    Tooltip
      .style("opacity", 1)
  }
  var mousemove = function(d) {
    Tooltip
      .html('<u>' + d.key + '</u>' + "<br>" + d.value + " billion dollars")
      .style("left", (d3.mouse(this)[0]+20) + "px")
      .style("top", (d3.mouse(this)[1]) + "px")
  }
  var mouseleave = function(d) {
    Tooltip
      .style("opacity", 0)
  }

  // Initialize the circle: all located at the center of the svg area
  var node = svg.append("g")
    .selectAll("circle")
    .data(data)
    .enter()
    .append("circle")
      .attr("class", "node")
      .attr("r", function(d){ return size(d.value)})
      .attr("cx", width / 2)
      .attr("cy", height / 2)
      .style("fill", function(d){ return color(d.region)})
      .style("fill-opacity", 0.8)
      .attr("stroke", "black")
      .style("stroke-width", 1)
      .on("mouseover", mouseover) // What to do when hovered
      .on("mousemove", mousemove)
      .on("mouseleave", mouseleave)
      .call(d3.drag() // call specific function when circle is dragged
         .on("start", dragstarted)
         .on("drag", dragged)
         .on("end", dragended));
  
  // Features of the forces applied to the nodes:
  var simulation = d3.forceSimulation()
      .force("center", d3.forceCenter().x(width / 2).y(height / 2)) // Attraction to the center of the svg area
      .force("charge", d3.forceManyBody().strength(0.5)) // Nodes are attracted one each other of value is > 0
      .force("collide", d3.forceCollide().strength(0.5).radius(function(d){ return size(d.value)+5}).iterations(1)) // Force that avoids circle overlapping
  
  // Apply these forces to the nodes and update their positions.
  // Once the force algorithm is happy with positions ('alpha' value is low enough), simulations will stop.
  simulation
      .nodes(data)
      .on("tick", function(d){
        node
            .attr("cx", function(d){ return d.x; })
            .attr("cy", function(d){ return d.y; })
      });

    // What happens when a circle is dragged?
function dragstarted(d) {
  if (!d3.event.active) simulation.alphaTarget(.03).restart();
  d.fx = d.x;
  d.fy = d.y;
}
function dragged(d) {
  d.fx = d3.event.x;
  d.fy = d3.event.y;
}
function dragended(d) {
  if (!d3.event.active) simulation.alphaTarget(.03);
  d.fx = null;
  d.fy = null;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

我更新了力布局的半径属性以反射(reflect)半径(并篡改了强度以产生更好的结果)

关于javascript - 这个数据可视化代码有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67475091/

相关文章:

javascript - 如何使用 vanilla javascript 触发窗口调整大小事件?

html - svg 元素的位置

javascript - 如何使用 d3 更新/覆盖 map 和图例内容

d3.js - 在 D3.js 中创建元素 "in memory",就像 jQuery 一样

javascript - D3 : unable to access data within anonymous function

javascript - jQuery:在页面上的每个 ajax 请求上将子对象添加到 "data"对象

javascript - Safari 中奇怪的 JavaScript 错误(?)

javascript - 如何使用 JavaScript 测试和计算动态编号的类名

javascript - 如何在强制布局 D3.js 中生成指向右侧的链接

html - Flexbox 中的 SVG 弄乱了其他元素的高度