Hello I’m currently creating a line chart that takes in as x values the seconds in my .csv file and takes in as y values the value of the signal that represents a patients electrodermal activity.
I’ve followed the d3 code from this page https://d3-graph-gallery.com/graph/line_basic.html but for some reason the g element representing x-axis does not show even when appended to the svg element
I’m using react with d3 so svg variable is a reference to the svg element i’m rendering here is my code:
useEffect(() => {
console.log("state updated");
console.log(sprSheet);
if(sprSheet.length != 0){
let max_signal = d3.max(sprSheet, (row) => row['raw_signal']);
let min_signal = d3.min(sprSheet, (row) => row['raw_signal']);
let min_sec = sprSheet[0]['time'];
let max_sec = sprSheet[sprSheet.length - 1]['time'];
console.log(`max signal: ${max_signal}`);
console.log(`min_signal: ${min_signal}`);
console.log(`max_sec: ${max_sec}`);
console.log(`min_sec: ${min_sec}`);
// const width = 'clamp(500px, 75vw, 1260px)';
// const height = '250px';
const margin = {top: 10, right: 30, bottom: 30, left: 60, }
const width = 1024 - margin["left"] - margin["right"];
const height = 512 - margin["top"] - margin["bottom"];
// recall translate takes in x and y coordinates of how much
// to move the element along the x and y axis respectively
const svg = d3.select(svgRef.current)
.attr("width", width + margin.left + margin.right) // still is 768 since we add back the subtracted values from margin top and margin bottom
.attr("height", height + margin.top + margin.bottom) // still is 486 since we add back the subtracted values from margin top and margin bottom
// .attr("viewBox", [0, 0, width * 1.5, height * 1.5])
.append("g")
.attr("class", "cartesian-plane")
.attr("transform", `translate(${margin["left"]}, ${margin["top"]})`); // this is the g element which draws the line
// x here is a callback function
let x = d3.scaleTime()
.domain([min_sec, max_sec])
.range([0, width]);
// we create a g element which will draw the x-axis
svg.append('g')
.attr("class", "x-axis")
.attr('transform', `translate(0, ${height})`)
.call(d3.axisBottom);
// y here is also callback function
let y = d3.scaleTime()
.domain([0, max_signal])
.range([height, 0]);
// we create a g element which will draw the y-axis
svg.append("g")
.attr("class", "y-axis")
.call(d3.axisLeft(y));
// Set the gradient
svg.append("linearGradient")
.attr("class", "line-gradient")
.attr("id", "line-gradient")
.attr("gradientUnits", "userSpaceOnUse")
.attr("x1", 0)
.attr("y1", y(0))
.attr("x2", 0)
.attr("y2", y(max_signal))
.selectAll("stop")
.data([
{offset: "0%", color: "#c78324"},
{offset: "50%", color: "#ab229d"},
{offset: "100%", color: "#2823ba"}
])
.enter().append("stop")
.attr("offset", (d) => d["offset"])
.attr("stop-color", (d) => d["color"]);
// Add the line
svg.append("path")
.datum(sprSheet)
.attr("fill", "none")
.attr("stroke", "url(#line-gradient)" )
.attr("stroke-width", 2)
.attr("d", d3.line()
.x((d) => x(d['time']))
.y((d) => y(d['raw_signal']))
)
}else{
console.log('spreadsheet input mounted');
}
Here’s also a picture of how the react app renders the d3 graph: