2014-01-05 47 views
2

第一次使用D3.js.我坚持让条形图在条上显示数值标签,并在刷新数据时转换x/y轴。我没有收到任何错误,代码来自于将几个例子放在一起。代码如下,jfiddle here工作示例。在真正的代码中,我使用d3.json来拉取数据,在jsfiddle中我使用了静态变量fyi。任何帮助表示赞赏。下面D3.js条形图 - 轴和标签不工作/正在转换

代码:

var data; 

var margin = { 
    top: 20, 
    right: 0, 
    bottom: 30, 
    left: 30 
}, 
width = 838 - margin.left - margin.right, 
    height = 300 - margin.top - margin.bottom; 

var x = d3.scale.ordinal() 
    .rangeRoundBands([0, width], 0.05); 

var y = d3.scale.linear() 
    .range([height, 0]); 

var xAxis = d3.svg.axis() 
    .scale(x) 
    .orient("bottom"); 

var yAxis = d3.svg.axis() 
    .scale(y) 
    .orient("left") 
    .ticks(10); 

var svg = d3.select("#daychart") 
    .attr("width", width + margin.left + margin.right) 
    .attr("height", height + margin.top + margin.bottom) 
    .append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 


d3.json("http://10.0.0.13/sma/sma-php/inverterdata.php?var=CDAY&id=C1200031", function (error, data) { 
data.forEach(function (d) { 
    d.max_energy = +d.max_energy; 
}); 

x.domain(data.map(function (d) { 
    return d.xaxis; 
})); 
y.domain([0, d3.max(data, function (d) { 
    return d.max_energy; 
})]); 

svg.append("g") 
    .attr("class", "x axis") 
    .attr("transform", "translate(0," + height + ")") 
    .call(xAxis) 
    .append("text") 
    .attr("transform", "rotate(0)") 
    .attr("y", 23) 
    .attr("x", 340) 
    .attr("dy", ".71em") 
    .style("text-anchor", "bottom") 
    .text("Timeline"); 

svg.append("g") 
    .attr("class", "y axis") 
    .call(yAxis) 
    .append("text") 
    .attr("transform", "rotate(0)") 
    .attr("y", -15) 
    .attr("x", -25) 
    .attr("dy", ".71em") 
    .style("text-anchor", "top") 
    .text("Energy - KWh"); 

svg.selectAll(".bar") 
    .data(data) 
    .enter().append("rect") 
    .attr("class", "bar") 
    .attr("x", function (d) { 
    return x(d.xaxis); 
}) 
    .attr("width", x.rangeBand()) 
    .attr("y", function (d) { 
    return y(d.max_energy); 
}) 
    .transition().delay(function (d, i) { 
    return i * 10; 
}).duration(10) 
    .attr("height", function (d) { 
    return height - y(d.max_energy); 
}); 

//Create labels 
svg.selectAll("text") 
    .data(data) 
    .enter() 
    .append("text") 
    .text(function (d) { 
    return parseFloat(Math.round(d.max_energy * 100)/100).toFixed(1); 
}) 
    .attr("x", function (d) { 
    return x(d.xaxis) + x.rangeBand()/2; 
}) 
    .attr("y", function (d) { 
    return height - y(d.max_energy) + 14; 
}) 
    .attr("text-anchor", "middle") 
    .attr("font-family", "sans-serif") 
    .attr("font-size", "11px") 
    .attr("fill", "black"); 

//}); 

//On click, update with new data    
d3.select("p").on("click", function() { 

    // Get the data again 
     d3.json("http://10.0.0.13/sma/sma-php/inverterdata.php?var=PDAY&id=P100023", function (error, data) { 
    data.forEach(function (d) { 
     d.max_energy = +d.max_energy; 
    }); 

    // Scale the range of the data again 
    x.domain(data.map(function (d) { 
     return d.xaxis; 
    })); 
    y.domain([0, d3.max(data, function (d) { 
     return d.max_energy; 
    })]); 

    // Make the changes 
    svg.selectAll(".bar") // change the bar 
    .data(data) // Update the data within. 
    .transition().delay(function (d, i) { 
     return i/data.length * 1000; 
    }) 
     .duration(500) 
     .attr("x", function (d) { 
     return x(d.xaxis); 
    }) 
     .attr("y", function (d) { 
     return y(d.max_energy); 
    }) 
     .attr("width", x.rangeBand()) 
     .attr("height", function (d) { 
     return height - y(d.max_energy); 
    }); 

    //Update all labels 
    svg.selectAll("text") 
     .data(data).transition() 
     .delay(function (d, i) { 
     return i/data.length * 1000; 
    }) 
     .duration(500) 
     .text(function (d) { 
     return parseFloat(Math.round(d.max_energy * 100)/100).toFixed(1); 
    }) 
     .attr("x", function (d, i) { 
     return x(i) + x.rangeBand()/2; 
    }) 
     .attr("y", function (d) { 
     return height - y(d.max_energy) + 24; 
    }); 

    }); 

}); 

HTML:

<p>CLICK ME</p> 
<svg id="daychart"></svg> 

回答

2

它比你想象的其实更容易。你只需要再次调用轴功能:

svg.select("g.x").call(xAxis); 
svg.select("g.y").call(yAxis); 

更改的jsfiddle here

要让标签起作用,您可以为这些text元素指定一个特定的类并进行相应的选择。默认情况下,D3会根据索引匹配元素。也就是说,在通过调用轴添加轴标签后,将选择这些轴并与数据匹配。因此,.enter()选择将是空的,不添加新的标签。

Jsfiddle以及here

+0

拉斯您好,感谢!你的JFiddle链接虽然不起作用。另外,为什么我的条形图标签不显示?谢谢! – TheRealPapa

+0

哎呀,对不起。不知道哪里出了问题 - 链接固定。不确定你想要什么类型的标签 - 就像[本教程](http://bost.ocks.org/mike/bar/)中的东西? –

+0

嗨拉尔斯,再次感谢!是的,这是我从代码中提取代码的教程,但不幸的是,栏上的值标签不起作用。我想将这个值放在每个小节的顶部。非常感谢您花时间! – TheRealPapa

2

对于你的问题的第二部分:

,因为你只是使用selectAll("text")抓住他们将标签无法正确显示了。问题在于,坐标轴上的刻度标签也是文本元素,所以它们被选中并分配了数据 - 但不包含在“输入”中。这也是为什么当您更新数据时轴标签移出屏幕的原因(因为在这种情况下,您正在设置所有元素的属性,而不仅仅是新元素)。

要解决:添加类酒吧标签,并用它来选择它们具体是:

svg.selectAll("text.barLabels") //use this selector in your update as well 
    .data(data) 
    .enter() 
    .append("text") 
    .classed("barLabels", true) //remember to actually add the class! 

它现在应该所有的工作......几乎。

你也许可以自己弄清楚这一点,但是你的标签y-定位功能没有考虑到你使用的是反转比例的事实,所以标签都以奇怪的位置结束了。你还需要改变

.attr("y", function (d) { 
    return height - y(d.max_energy) + 24; 
}); 

.attr("y", function (d) { 
    return y(d.max_energy) + 24; 
}) 

.attr("y", function (d) { 
    return Math.min(y(d.max_energy) + 24, height); 
}) 

让 “0.0” 的标签没有被定位超出轴线;或者甚至

.attr("y", function (d,i) { 
    return Math.min(y(d.max_energy) + 24*(1+i%2), height); 
}) 

因此如果相邻标签对于条太宽而不相互重叠。 (对于偶数,i%2只返回0,奇数返回1;模运算符%从整数除法返回“余数”。)

的最后一个版本就是我来到这里实现:http://jsfiddle.net/h8Rsg/40/

+0

嗨阿米莉亚,谢谢你的建议!真棒帮助! – TheRealPapa