I am new to using D3 charts and am having an issue making my multi line chart responsive. I have reviewed some examples on how to make D3 responsive, but I can not make it work on my graph. If someone could assist me in making the code I currently have responsive I would really appreciate it.
Here is the code:
const svg = d3.select("#lineChart").attr("height", 400).attr("width", 850);
const width = +svg.attr("width");
const height = +svg.attr("height");
let hasMoreThan0 = false;
const render = (data) => {
const xValue = (d) => d.dateTest;
const yValue = (d) => d.total;
const margin = { top: 60, right: 40, bottom: 88, left: 105 };
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
const xScale = d3
.scaleTime()
.domain(d3.extent(data, xValue))
.range([0, innerWidth])
.nice();
let yScale;
let totalArray = [];
data.forEach((element) => {
totalArray.push(element.total);
});
const reducer = (accumulator, currentValue) => accumulator + currentValue;
let tc = totalArray.reduce(reducer);
data.forEach((d) => {
if (tc == 0) {
yScale = d3
.scaleLinear()
.domain([0, 51])
.range([innerHeight, 0])
.nice();
} else {
yScale = d3
.scaleLinear()
.domain(d3.extent(data, yValue))
.range([innerHeight, 0])
.nice();
}
});
const g = svg
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
const xAxis = d3
.axisBottom(xScale)
.tickPadding(15)
.ticks(d3.timeDay)
.tickFormat(d3.timeFormat("%a %d %B %y"));
const yAxis = d3.axisLeft(yScale).tickSize(-innerWidth).tickPadding(10);
const yAxisG = g.append("g").call(yAxis);
yAxisG.selectAll(".domain").remove();
yAxisG
.append("text")
.attr("class", "axis-label")
.attr("y", -60)
.attr("x", -innerHeight / 2)
.attr("fill", "black")
.attr("transform", `rotate(-90)`)
.attr("text-anchor", "middle");
const xAxisG = g
.append("g")
.call(xAxis)
.attr("transform", `translate(0,${innerHeight})`);
xAxisG.select(".domain").remove();
xAxisG
.append("text")
.attr("class", "axis-label")
.attr("y", 80)
.attr("x", innerWidth / 2)
.attr("fill", "black");
const areaGenerator = d3
.area()
.x((d) => xScale(xValue(d)))
.y0(innerHeight)
.y1((d) => yScale(yValue(d)))
.curve(d3.curveMonotoneX);
g.append("path")
.attr("class", "area-path")
.attr("d", areaGenerator(data));
const lineGenerator = d3
.line()
.x((d) => xScale(xValue(d)))
.y((d) => yScale(yValue(d)))
.curve(d3.curveMonotoneX);
g.append("path")
.attr("class", "line-path")
.attr("d", lineGenerator(data));
// g.append("text").attr("class", "title").attr("y", -10).text(title);
svg.append("line").attr("class", "line-dashet");
svg.append("line").attr("class", "line-dashet");
svg
.selectAll("circle")
.data(data)
.join("circle")
.attr("cx", function (d) {
return xScale(xValue(d)) + 105;
})
.attr("cy", function (d) {
return yScale(yValue(d)) + 60;
})
.attr("r", 4)
.on("mouseout", function (e) {
let toolTip = document.getElementsByClassName("tooltip")[0];
toolTip.classList.remove("tooltip-open");
})
.on("mouseover", function (e) {
let selectPoint = d3.select(this);
let xLineAnim = selectPoint._groups[0][0].cx.animVal.value;
let yLineAnim = selectPoint._groups[0][0].cy.animVal.value;
let selectPointData = selectPoint._groups[0][0].__data__;
let dateFormated = formatDate(selectPointData.dateTest, a, "-");
let toolTip = document.getElementsByClassName("tooltip")[0];
toolTip.style.top = yLineAnim - 55 + "px";
toolTip.style.left = xLineAnim + 5 + "px";
toolTip.innerHTML =
"<div><span>Day: </span>" +
dateFormated +
"</div><div><span>Total: </span>" +
selectPointData.total +
"</div>";
toolTip.classList.add("tooltip-open");
svg
.select(".line-dashet")
.attr("x1", xLineAnim)
.attr("y1", margin.top)
.attr("x2", xLineAnim)
.attr("y2", innerHeight + margin.top);
});
};
getTimeData();