here im facing some small issue line dot points are not placed according to the x-axis points i dont know why dot points are moved 1cm before the actual values of x-points
issue-1 how can we match the dots exact with the x-axis points
issue-2 how can i avoid the zero postion grid line(i dont want to show grid line if value is zero 0 on y-axis)
i want to align like this
but i got like this
here i want to align the months vales and dot points position has to be same when we see x-axis to the dots postions
const convertRemToPixels = (rem) => {
return (
rem * parseFloat(getComputedStyle(document.documentElement).fontSize)
);
};
const data = [
{ x: "Jan", y: "0.03" },
{ x: "Feb", y: "5" },
{ x: "Mar", y: "10" },
{ x: "Apr", y: "6" },
{ x: "May", y: "11" },
{ x: "Jun", y: "2" },
];
const margin = { top: 10, right: 30, bottom: 30, left: 60 },
width = 600 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
// append the svg object to the body of the page
const svg = d3
.select("#mainChart")
.attr("width", width margin.left margin.right)
.attr("height", height margin.top margin.bottom)
.select("#mainGroup")
.attr("transform", `translate(${margin.left},${margin.top})`);
let tooltip = d3
.select("#tooltipContainer")
.style("position", "absolute")
.style("top", 0)
.style("left", 0)
.style("display", "none");
// grid function
function make_y_gridlines() {
return d3.axisLeft(y).ticks(6);
}
// Add X axis --> it is a date format
const x = d3.scaleBand().range([0, width]);
const y = d3
.scaleLinear()
.domain([0, d3.max(data.map((e) => parseInt(e.y)))])
.range([height, 0]);
var xAxis = d3.axisBottom(x);
var yAxis = d3.axisLeft(y).ticks(6);
x.domain(
data.map(function (d) {
console.log(d);
return d.x;
})
).padding([0.2]);
svg
.select("#XAxis")
.transition()
.attr("transform", "translate(0," height ")")
.call(xAxis)
.style("color", "#a4a4a4");
svg
.select("#XAxis")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", ".6em")
.attr("dy", "1em")
.style("font-size", ".8rem")
.attr("transform", "rotate(0)")
.style("font-family", '"Roboto", sans-serif');
// Add Y axis
svg
.select("#YAxis")
.transition()
.call(yAxis)
.style("color", "#a4a4a4")
.style("font-size", ".7rem");
svg
.select("#linePath")
.datum(data)
.attr("fill", "none")
.attr("stroke", "#14c884")
.transition()
.attr(
"d",
d3
.line()
.x(function (d) {
console.log(d);
return x(d.x);
})
.y(function (d) {
return y(d.y);
})
.curve(d3.curveCatmullRom.alpha(1.1))
);
const circle = d3.select("#LineDots");
circle
.selectAll(".point")
.data(data)
.join("circle")
.on("mouseover", (e, i) => {
d3.select(e.target).transition().attr("r", 4);
tooltip.transition().duration(0).style("display", "block");
tooltip
.html(`<div>${i.x} : <span>${i.y}</span></div>`)
.style("left", e.pageX convertRemToPixels(-1.6) "px")
.style("top", e.pageY - convertRemToPixels(2) "px");
})
.on("mouseout", (e) => {
d3.select(e.target).transition().attr("r", 2);
tooltip.transition().duration(0);
tooltip
.style("left", "0px")
.style("top", "0px")
.style("display", "none");
})
.transition()
.attr("class", "point")
.attr("stroke", "#14c884")
.attr("fill", function (d, i) {
return "#14c884";
})
.attr("cx", function (d, i) {
return x(d.x);
})
.attr("cy", function (d, i) {
console.log(d.y);
return y(d.y);
})
.attr("r", function (d, i) {
return 2;
})
.style("opacity", 1);
d3.select("#Grid")
.transition()
.call(make_y_gridlines().tickSize(-width).tickFormat(""))
.attr("id", "gridSystem");
#gridSystem line{
stroke: lightgrey;
stroke-opacity: 0.7;
shape-rendering: crispEdges;
stroke-dasharray: 2 2;
stroke-width : .05rem ;
}
#gridSystem path {
stroke-width: 0;
}
/* tooltip */
.barTitle{
text-align: center;
font-weight: bolder;
padding: .2em 0;
font-size: .8rem;
color: black;
}
#tooltipContainer div span{
color: #536876;
font-weight: bold;
}
.bar{
border-top-left-radius: 1em !important;
}
#tooltipContainer {
line-height: 1.1;
font-weight: bold;
padding: .6em 1em .6em 1em;
background:white;
color: #9cb3c3;
border-radius: .4em;
font-weight: 600;
box-shadow: 0em 0em .5em rgb(165, 163, 163);
font-size: .6rem;
font-family: 'Roboto', sans-serif;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.6.1/d3.min.js"></script>
<div id="tooltipContainer"></div>
<svg id="mainChart">
<g id="mainGroup">
<g id="XAxis"></g>
<g id="YAxis"></g>
<g id="Grid"></g>
<path id="linePath"></path>
<g id="LineDots"></g>
</g>
</svg>
here is the codepan source code for fixing https://codepen.io/codingdarci/pen/ZERpNOG
can anyone please give me some suggetion how to figure it out and how to fix this issue
thanks advance
CodePudding user response:
Regarding the position of the circles, you want a point scale instead of a band scale, because band scales have an associated bandwidth:
const x = d3.scalePoint().range([0, width]);
For the y axis, simply remove the ticks for zero:
axis.selectAll(".tick")
.filter(d => d === 0)
.remove();
Here is your code with those changes:
const convertRemToPixels = (rem) => {
return (
rem * parseFloat(getComputedStyle(document.documentElement).fontSize)
);
};
const data = [{
x: "Jan",
y: "0.03"
},
{
x: "Feb",
y: "5"
},
{
x: "Mar",
y: "10"
},
{
x: "Apr",
y: "6"
},
{
x: "May",
y: "11"
},
{
x: "Jun",
y: "2"
},
];
const margin = {
top: 10,
right: 30,
bottom: 30,
left: 60
},
width = 600 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
// append the svg object to the body of the page
const svg = d3
.select("#mainChart")
.attr("width", width margin.left margin.right)
.attr("height", height margin.top margin.bottom)
.select("#mainGroup")
.attr("transform", `translate(${margin.left},${margin.top})`);
let tooltip = d3
.select("#tooltipContainer")
.style("position", "absolute")
.style("top", 0)
.style("left", 0)
.style("display", "none");
// grid function
function make_y_gridlines() {
return d3.axisLeft(y).ticks(6);
}
// Add X axis --> it is a date format
const x = d3.scalePoint().range([0, width]);
const y = d3
.scaleLinear()
.domain([0, d3.max(data.map((e) => parseInt(e.y)))])
.range([height, 0]);
var xAxis = d3.axisBottom(x);
var yAxis = d3.axisLeft(y).ticks(6);
x.domain(
data.map(function(d) {
console.log(d);
return d.x;
})
).padding([0.2]);
svg
.select("#XAxis")
.transition()
.attr("transform", "translate(0," height ")")
.call(xAxis)
.style("color", "#a4a4a4");
svg
.select("#XAxis")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", ".6em")
.attr("dy", "1em")
.style("font-size", ".8rem")
.attr("transform", "rotate(0)")
.style("font-family", '"Roboto", sans-serif');
// Add Y axis
svg
.select("#YAxis")
.transition()
.call(yAxis)
.style("color", "#a4a4a4")
.style("font-size", ".7rem")
.selectAll(".tick")
.filter(d => d === 0)
.remove();
svg
.select("#linePath")
.datum(data)
.attr("fill", "none")
.attr("stroke", "#14c884")
.transition()
.attr(
"d",
d3
.line()
.x(function(d) {
console.log(d);
return x(d.x);
})
.y(function(d) {
return y(d.y);
})
.curve(d3.curveCatmullRom.alpha(1.1))
);
const circle = d3.select("#LineDots");
circle
.selectAll(".point")
.data(data)
.join("circle")
.on("mouseover", (e, i) => {
d3.select(e.target).transition().attr("r", 4);
tooltip.transition().duration(0).style("display", "block");
tooltip
.html(`<div>${i.x} : <span>${i.y}</span></div>`)
.style("left", e.pageX convertRemToPixels(-1.6) "px")
.style("top", e.pageY - convertRemToPixels(2) "px");
})
.on("mouseout", (e) => {
d3.select(e.target).transition().attr("r", 2);
tooltip.transition().duration(0);
tooltip
.style("left", "0px")
.style("top", "0px")
.style("display", "none");
})
.transition()
.attr("class", "point")
.attr("stroke", "#14c884")
.attr("fill", function(d, i) {
return "#14c884";
})
.attr("cx", function(d, i) {
return x(d.x);
})
.attr("cy", function(d, i) {
console.log(d.y);
return y(d.y);
})
.attr("r", function(d, i) {
return 2;
})
.style("opacity", 1);
d3.select("#Grid")
.transition()
.call(make_y_gridlines().tickSize(-width).tickFormat(""))
.attr("id", "gridSystem")
.selectAll(".tick")
.filter(d => d === 0)
.remove();
#gridSystem line {
stroke: lightgrey;
stroke-opacity: 0.7;
shape-rendering: crispEdges;
stroke-dasharray: 2 2;
stroke-width: .05rem;
}
#gridSystem path {
stroke-width: 0;
}
/* tooltip */
.barTitle {
text-align: center;
font-weight: bolder;
padding: .2em 0;
font-size: .8rem;
color: black;
}
#tooltipContainer div span {
color: #536876;
font-weight: bold;
}
.bar {
border-top-left-radius: 1em !important;
}
#tooltipContainer {
line-height: 1.1;
font-weight: bold;
padding: .6em 1em .6em 1em;
background: white;
color: #9cb3c3;
border-radius: .4em;
font-weight: 600;
box-shadow: 0em 0em .5em rgb(165, 163, 163);
font-size: .6rem;
font-family: 'Roboto', sans-serif;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.6.1/d3.min.js"></script>
<div id="tooltipContainer"></div>
<svg id="mainChart">
<g id="mainGroup">
<g id="XAxis"></g>
<g id="YAxis"></g>
<g id="Grid"></g>
<path id="linePath"></path>
<g id="LineDots"></g>
</g>
</svg>