sasu
sasu

Reputation: 3

Line graph is not working in d3.js

I am trying to create line graph from this data. Year should be in x-axis and value should be in y-axis

[{"year":2000,"value":1},{"year":2001,"value":2},
{"year":2002,"value":3},
{"year":2003,"value":4},{"year":2004,"value":5},
{"year":2005,"value":6}];

I don't understand why it is not working.

Code is in jsfiddle. https://jsfiddle.net/u58x99vh/1/

Upvotes: 0

Views: 345

Answers (2)

Mark
Mark

Reputation: 108507

Lots of issues here:

  1. You are assigned "text" to a g element, it does not have such a thing.
  2. Your x-axis is rotated back vertical, it shouldn't be. Also it's not placed at the bottom of the graph.
  3. Finally, you are creating the path incorrectly. And you have no declaration of CSS class viiva.

Putting this all together:

let dataSorc = [{"vuosi":2000,"arvo":1},{"vuosi":2001,"arvo":2},{"vuosi":2002,"arvo":3},
			{"vuosi":2003,"arvo":4},{"vuosi":2004,"arvo":5},{"vuosi":2005,"arvo":6}];
            
// 2. Use the margin convention practice 
let margin = {top: 50, right: 50, bottom: 50, left: 50}
  , width = window.innerWidth - margin.left - margin.right // Use the window's width 
  , height = window.innerHeight - margin.top - margin.bottom; // Use the window's height

// The number of datapoints
//let kokoelma = d3.values(dataSorc);
//console.log(kokoelma);

// 5. X scale will use the index of our data
let xScale = d3.scaleLinear()
    .domain(d3.extent(dataSorc, d => d.vuosi)) // input
    .range([0, width]); // output
// 6. Y
let yScale = d3.scaleLinear()
    .domain(d3.extent(dataSorc, d => d.arvo))
     // input 
    .range([height, 0]); // output
//console.log("yScale"); 
//console.log(yScale);
//console.log("xScale");
//console.log(xScale);

// 7. d3's line generator
let line = d3.line(dataSorc)
    .x( d => xScale(d.vuosi)) // set the x values for the line generator
    .y( d =>  yScale(d.arvo)); // set the y values for the line generator 
console.log("line");
console.log(line);

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

//let g = svg.append("g").
//console.log("svg");
//console.log(svg);
// 3. Call the x axis in a group tag
svg.append("g")
		.attr("transform", "translate(0," + height + ")")
    .call(d3.axisBottom(xScale))
    .attr("class", "x_axis")
    //.text("x_axis");
     // Create an axis component with d3.axisBottom

// 4. Call the y axis in a group tag
svg.append("g")
    .call(d3.axisLeft(yScale))
    .attr("class", "y_axis")
    //.text("y_axis"); 
    // Create an axis component with d3.axisLeft
// 12. Appends a line for each datapoint 
svg.append("path")
    .datum(dataSorc)
    //.enter().append("path") // Uses the enter().append() method
    .attr("class", "viiva")
    .attr("d", line); // Assign a class for styling
    //console.log("data tulostetaan");
//console.log(dataSorc);    
//console.log("svg kaikki data on laitettu");
//console.log(svg);

//console.log("testaa path");
//console.log(d3.selectAll("path"));
.viiva {
  stroke: steelblue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<p>
testi
</p>
<div id="taulu">

</div>

Upvotes: 3

Mikhail Shabrikov
Mikhail Shabrikov

Reputation: 8509

I reworked your fiddle, check it. There is a diff between your code and my.

You should parse your date this way:

const parseTime = d3.timeParse("%Y");

dataSorc.forEach(item => {
  item.vuosi = parseTime(item.vuosi);
  item.arvo = item.arvo;
});

And use scaleTime for x axis instead of scaleLinear:

let xScale = d3.scaleTime()
    .domain(d3.extent(dataSorc, d => d.vuosi)) // input
    .range([0, width]); // output

You have only one line, so you can draw it like this:

svg.append("path")
    .attr("class", "viiva")
    .attr("stroke", "#000")
    .attr("d",item => line(dataSorc)); 

Upvotes: 1

Related Questions