简单的折线图连接顶部的直方图

时间:2016-11-03 12:34:44

标签: javascript d3.js charts linechart

在以下示例中,我在字母与频率上映射了直方图。现在,我想要一个折线图也可以用于相同的数据而不需要做太多改变。这意味着只有红线连接直方图的顶部。有人可以帮我吗?

<html>

<head> 

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.min.js"></script> 

</head>

<body> 

<svg width="960" height="500"></svg>

<script>

//Our basic data 
var data = [
    {frequency:0.08, letter:"A"},
    {frequency:0.11,letter:"B"},
    {frequency:0.13,letter:"C"}
];

var svg = d3.select("svg");
var margin = {top: 40, bottom: 40, left: 40, right: 40};
var width = svg.attr("width") - margin.left - margin.right;
var height = svg.attr("height") - margin.top - margin.bottom;

var x = d3.scaleBand().rangeRound([0, width]).padding(0.6);
var y = d3.scaleLinear().rangeRound([height, 0]);

//defining our main g in svg 
var g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

//Looping for data bars 
data.forEach(function(){

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

    g
        .append("g")
        .attr("transform", "translate(0," + height + ")")
        .call(d3.axisBottom(x));

    g
        .append("g")
        .call(d3.axisLeft(y).ticks(10, "%"));

    g
        .selectAll(".bar")
        .data(data)
        .enter()
        .append("rect")
        .attr("x", function(d) { return x(d.letter); })
        .attr("y", function(d) { return y(d.frequency); })
        .attr("width", x.bandwidth())
        .attr("height", function(d) { return height - y(d.frequency); });

});

</script> 

</body> 

</html> 

HISTOGRAM:

enter image description here

1 个答案:

答案 0 :(得分:2)

首先,摆脱data.forEach:你为什么要画三次?

之后,定义你的线路生成器:

var line = d3.line()
    .x(function(d){ return x(d.letter) + x.bandwidth()/2})
    .y(function(d){ return y(d.frequency)})
    .curve(d3.curveCardinal);;

此处,x.bandwidth()/2会将该行放在每个条形图顶部的中间位置。我正在使用d3.curveCardinal,但您有曲线other options

然后,添加以下行:

g.append("path")
    .datum(data)
    .attr("d", line);

以下是演示:

<head> 

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.min.js"></script> 

</head>

<body> 

<svg width="960" height="500"></svg>

<script>

//Our basic data 
var data = [
    {frequency:0.08, letter:"A"},
    {frequency:0.11,letter:"B"},
    {frequency:0.13,letter:"C"}
];

var svg = d3.select("svg");
var margin = {top: 40, bottom: 40, left: 40, right: 40};
var width = svg.attr("width") - margin.left - margin.right;
var height = svg.attr("height") - margin.top - margin.bottom;

var x = d3.scaleBand().rangeRound([0, width]).padding(0.6);
var y = d3.scaleLinear().rangeRound([height, 0]);

//defining our main g in svg 
var g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

//Looping for data bars 


    x.domain(data.map(function(d) { return d.letter; }));
    y.domain([0, d3.max(data, function(d) { return d.frequency; })]);
		
		var line = d3.line()
			.x(function(d){ return x(d.letter) + x.bandwidth()/2})
			.y(function(d){ return y(d.frequency)})
        .curve(d3.curveCardinal);

    g
        .append("g")
        .attr("transform", "translate(0," + height + ")")
        .call(d3.axisBottom(x));

    g
        .append("g")
        .call(d3.axisLeft(y).ticks(10, "%"));

    g
        .selectAll(".bar")
        .data(data)
        .enter()
        .append("rect")
        .attr("x", function(d) { return x(d.letter); })
        .attr("y", function(d) { return y(d.frequency); })
        .attr("width", x.bandwidth())
        .attr("height", function(d) { return height - y(d.frequency); });
				
				g.append("path")
				.datum(data)
				.attr("d", line)
				.attr("stroke", "red")
				.attr("fill", "none");


</script>