score:3

Accepted answer

Change your data structure to something like this:

var data = [{
    name: "cat",
    value: 10
}, {
    name: "dog",
    value: 3
}, {
    name: "pig",
    value: 7
}, {
    name: "bird",
    value: 7
}];

That way, you can define the line generator (look at the demo to see what those scales are):

var line = d3.line()
    .x(function(d) {
        return xScale(d.name)
    })
    .y(function(d) {
        return yScale(d.value)
    });

Thus, the x argument is the qualitative value of the name variable, while the y is the quantitative value of the value variable.

The important point here is: if you're using a qualitative variable for the x axis, set a qualitative scale for dealing with that qualitative variable, and pass the return of such scale to the line generator.

Here is the demo:

var data = [{
    name: "cat",
    value: 10
}, {
    name: "dog",
    value: 3
}, {
    name: "pig",
    value: 7
}, {
    name: "bird",
    value: 7
}];

var width = 500,
    height = 200;

var svg = d3.selectAll("body")
    .append("svg")
    .attr("width", width)
    .attr("height", height);

var xScale = d3.scalePoint()
    .domain(data.map(function(d) {
        return d.name
    }))
    .range([50, width - 50])
    .padding(0.5);

var yScale = d3.scaleLinear()
    .domain([0, d3.max(data, function(d) {
        return d.value
    }) * 1.1])
    .range([height - 50, 10]);

var line = d3.line()
	.x(function(d){ return xScale(d.name)})
	.y(function(d){ return yScale(d.value)});
	
svg.append("path")
	.attr("d", line(data))
	.attr("stroke", "teal")
	.attr("stroke-width", "2")
	.attr("fill", "none");

var xAxis = d3.axisBottom(xScale);
var yAxis = d3.axisLeft(yScale);

svg.append("g").attr("transform", "translate(0,150)")
    .attr("class", "xAxis")
    .call(xAxis);

svg.append("g")
    .attr("transform", "translate(50,0)")
    .attr("class", "yAxis")
    .call(yAxis);
<script src="https://d3js.org/d3.v4.min.js"></script>


Related Query

More Query from same tag