score:2

Accepted answer

first, get rid of that data.foreach: why do you want to paint everything 3 times?

after that, define your line generator:

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

here, x.bandwidth()/2 will put the line in the middle of the top of each bar. i'm using d3.curvecardinal, but you have other options for the curve.

then, append the line:

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

here is the demo:

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


Related Query

More Query from same tag