首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >d3.js:对代码执行顺序的混淆

d3.js:对代码执行顺序的混淆
EN

Stack Overflow用户
提问于 2015-11-10 15:43:36
回答 1查看 756关注 0票数 0

为了便于参考,我试图在D3.jsi 把所有东西都上传到github中制作一个交互式条形图。我在问题的最后还包括了index.html。

我的出发点是包含7个项目(即国家)的data.json。每个国家都有一个属性“名称”和其他四个属性。这些都代表了私人银行和希腊政府对2009年和2014年希腊债务的阐述。

我的目标是创建一个条形图,首先显示每个国家的银行和公共部门在2009年的展示情况(因此每个国家有两个条形图),一旦用户单击相应的按钮,就会改变到2014年。

我设法把这一切做得很好!但是,我必须手动为我需要使用的每个(子)数据集创建单独的列表。例如,我创建了一个名为y2009的程序,其中包括对国家1的银行和州的说明,然后对于国家2,a等等。(我留下了一个列表,并在第43行进行了注释)

我想让我的代码更加灵活,所以我创建了一个for循环,它提取数据并为我创建列表。(见第46-60行)。这不起作用,因为for循环将在实际加载数据之前启动。因此,我最终会得到空的列表。因此,我将for循环分组为一个函数(准备()),并在加载数据的函数中执行该函数(第18-30行)。这个问题解决了..。

..and创造了一个新的!应该设置标度的两个函数(参见第67-73行)不能工作,因为它们的计算需要用到for循环创建的列表之一(即“总计”)。(我假设这是因为在调用scale方法之后创建的列表。)

奇怪的是,如果我运行脚本,然后在控制台中复制xScale和yScale函数,然后复制绘图函数(第101-212行),一切都正常。因此,我试图将所有内容分组到函数中(例如setScales、but ),以便按照脚本末尾(第214-215行)的顺序调用它们,但这会产生问题,因为某些变量(例如xScale和yScale)需要是全局的。我还试图首先在全局空间中创建它们,然后通过setScales修改它们。这也不起作用。

总之,等等,我不明白的是:

  • 我应该按照什么顺序编写代码来使事情(再次)正常工作?在函数中封装操作(例如设置缩放、绘图条和标签),然后按正确的顺序调用函数,这是一个好主意吗?
  • 哪种类型的对象是用比例方法创建的?我对它们是否是实际的功能感到困惑。

我希望这不是太痛苦的阅读和感谢谁通过它!

费德

代码语言:javascript
复制
<!DOCTYPE html>
<html>

<head>
<script type="text/javascript" src="d3.min.js"></script>
</head>

<body>
<p>Introductory text here!</p>

<p>
<button id="change2009"> 2009 </button>
<button id="change2014"> 2014 </button>
</p>

<div id="country"></div>

<script type="text/javascript">

d3.json("data.json", function(error, json) {
    if (error) {
        console.log(error);
    } else{
    console.log(json);
    dataset=json;
    }

prepare (dataset);

});

//load data
var dataset;
var bank09=[];
var state09=[];
var bank14=[];
var state14=[];
var y2009=[];
var y2014=[];
var total=[];
var xScale;
var yScale;
//var total = [4.76, 0, 0.12, 6.36, 4.21, 0, 0.04, 7.96, 78.82, 0, 1.81, 46.56, 45, 0, 13.51, 61.74, 6.86, 0, 1.06, 40.87, 12.21, 0, 1.22, 13.06, 1.21, 0, 0.39, 27.35];


function prepare (dataset){
    for (i in dataset) {bank09.push(dataset[i].bank09);
    state09.push(dataset[i].state09);
    bank14.push(dataset[i].bank14);
    state14.push(dataset[i].state14);
    y2009.push(dataset[i].bank09);
    y2009.push(dataset[i].state09);
    y2014.push(dataset[i].bank14);
    y2014.push(dataset[i].state14); 
    total.push(dataset[i].bank09);
    total.push(dataset[i].state09);
    total.push(dataset[i].bank14);
    total.push(dataset[i].state14);
    }
}

//overwrite dataset
dataset2=y2009;

//scales
function setScales () {
    var xScale = d3.scale.ordinal()
              .domain(d3.range(total.length/2))
              .rangeRoundBands([0, w], 0.1);
    var yScale = d3.scale.linear()
              .domain([0, d3.max(total)])
              .range([0, h]);
    console.log(yScale(89));
}

//layout
var w = 600;
var h = 600;
var barPadding = 1;

//coountry names
var country = ["Austria", "Belgium", "France", "Germany", "Italy", "Holland", "Spain"];

d3.select("#country")
    .data(country)
    .enter()
    .append("rect")
    .attr("class", "country")
    //.append("text")
    //.text(function(d){
    //    return d;
    //  })


//draw svg
var svg = d3.select("body")
            .append("svg")
            .attr("width", w)
            .attr("height", h);

function draw () {
//draw bars
svg.selectAll("rect")
  .data(dataset2)
    .enter()
    .append("rect")
    .attr("x", function(d, i) {
        return xScale(i);
    })
    .attr("y", function(d){
        return h - yScale(d);
    })
    .attr("width", xScale.rangeBand)
    .attr("height", function(d) {
    return yScale(d);
    })
    .attr("fill", "black");


//add labels
svg.selectAll("text")
    .data(dataset2)
    .enter()
      .append("text")
      .text(function(d){
                return d;
            })
      .attr("text-anchor", "middle")
      .attr("font-family", "sans-serif")
      .attr("font-size", "12px")
      .attr("fill", "red")
      .attr("x", function(d, i){
         return xScale(i) + xScale.rangeBand() / 2;
         })
      .attr("y", function(d) {
     if (d<3) {
       return h - 15;
       } else {
         return h - yScale(d) + 15;}
         })


  //interactivity
  d3.select("#change2014")
    .on("click", function() {
    //update data
    dataset2=y2014;
    //update bars
    svg.selectAll("rect")
       .data(dataset2)
       .transition()
       .duration(3000)
       .attr("y", function(d){
       return h - yScale(d);
       })
       .attr("height", function(d) {
       return yScale(d);
       })        
    //update labels
    svg.selectAll("text")
      .data(dataset2)
      .transition()
      .duration(3000)          
      .text(function(d){
        return d;
      })
      .attr("x", function(d, i){
        return xScale(i) + xScale.rangeBand() / 2;
      })
      .attr("y", function(d) {
        if (d<3) {
          return h - 15;
        } else {
          return h - yScale(d) + 15;}
      })
    })


  d3.select("#change2009")
    .on("click", function() {
    //update data
    dataset2=y2009;
    //update bars
    svg.selectAll("rect")
       .data(dataset2)
       .transition()
       .duration(3000)           
       .attr("y", function(d){
       return h - yScale(d);
       })
       .attr("height", function(d) {
       return yScale(d);
       })
    //update labels
    svg.selectAll("text")
      .data(dataset2)
      .transition()
      .duration(3000)          
      .text(function(d){
        return d;
      })
      .attr("x", function(d, i){
        return xScale(i) + xScale.rangeBand() / 2;
      })
      .attr("y", function(d) {
        if (d<3) {
          return h - 15;
        } else {
          return h - yScale(d) + 15;}
      })
    })
}

setScales ();
draw();
</script>

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-11 06:05:01

我应该按照什么顺序编写代码来使事情(再次)正常工作?在函数中封装操作(例如设置缩放、绘图条和标签),然后按正确的顺序调用函数,这是一个好主意吗?

正如Lars所指出的,您可以将所有东西放入d3.json回调中。这是因为您只想在拥有数据之后才开始使用D3进行呈现。d3.json方法是异步的,这意味着在调用d3.json()之后,代码将在d3.json方法中的函数完成之前先执行。有关Javascript中异步行为的更多信息,请查看http://rowanmanning.com/posts/javascript-for-beginners-async/

如果您只想在d3.json方法完成后才开始呈现,那么您也可以将代码的其他部分组织成更小的函数,并从d3.json成功回调中调用某种初始化器函数,类似于您对准备函数所做的操作。这是一种更干净的方法,并开始带您走向模型-视图范例。

哪种类型的对象是用比例方法创建的?我对它们是否是实际的功能感到困惑。

scale方法确实返回一个函数,但是它的原型中添加了额外的函数。试着打印出"someScale.prototype“以查看您可以使用的所有不同方法。我还强烈推荐Scott关于D3的教程。这是关于天平的章节:http://alignedleft.com/tutorials/d3/scales

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33633887

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档