I am working with d3
to create and svg as following
// 1 DATA
const data = [
{ "x": 50, "y": 0.10 },
{ "x": 100, "y": 0.15 },
{ "x": 150, "y": 0.25 },
{ "x": 200, "y": 0.35 },
{ "x": 250, "y": 0.45 },
{ "x": 300, "y": 0.55 },
{ "x": 350, "y": 0.65 },
{ "x": 400, "y": 0.75 },
{ "x": 450, "y": 0.85 },
{ "x": 500, "y": 0.87 },
{ "x": 550, "y": 0.92 },
{ "x": 600, "y": 0.98 }
]
height = 400,
width = 720;
padding = {
top: 70,
bottom: 50,
left: 70,
right: 70
}
const boundHeight = height - padding.top - padding.bottom;
const boundWidth = width - padding.right - padding.left;
// 2 CREATE SCALE
const scaleY = d3.scaleLinear()
.range([boundHeight, 0])
.domain(d3.extent(data, d => d.y))
// 3 SVG
const svgns = 'http://www.w3.org/2000/svg'
const svg = d3.select('svg')
svg
.attr('xmlns', svgns)
.attr('viewBox', `0 0 ${width} ${height}`)
//create bound element
bound = svg.append('g')
.attr('class', 'bound')
.style('transform', `translate(${padding.left}px,${padding.top}px)`)
bound.append('g').attr('class', 'yAxis1')
.append('g').attr('class', 'yAxisLeft')
.call(d3.axisLeft(scaleY).tickSizeInner([(-(boundWidth))])
.tickFormat(d3.format(",.0%")))
console.log(d3.mean(data.map(d => d.y)))
<script type="text/javascript" src="https://d3js.org/d3.v7.min.js"></script>
<svg></svg>
<div id="container" ></div>
<script src="next.js"></script>
The mean
of data.y=0.5724999999999999
. How can I pass on this value to the axis generator to create a label
and tick
for this, apart from the auto-generated y-axis
tick and labels.
CodePudding user response:
Get the scale's auto-generated ticks array (scaleY.ticks()
), add the mean value to that array and pass it to axis.tickValues
:
.tickValues(scaleY.ticks().concat(mean))
Here is your code with that change:
////////////////////////////////////////////////////////////
//////////////////////// 1 DATA ///////////////////////////
////////////////////////////////////////////////////////////
const data = [{
"x": 50,
"y": 0.10
},
{
"x": 100,
"y": 0.15
},
{
"x": 150,
"y": 0.25
},
{
"x": 200,
"y": 0.35
},
{
"x": 250,
"y": 0.45
},
{
"x": 300,
"y": 0.55
},
{
"x": 350,
"y": 0.65
},
{
"x": 400,
"y": 0.75
},
{
"x": 450,
"y": 0.85
},
{
"x": 500,
"y": 0.87
},
{
"x": 550,
"y": 0.92
},
{
"x": 600,
"y": 0.98
}
]
height = 400,
width = 720;
padding = {
top: 70,
bottom: 50,
left: 70,
right: 70
}
const boundHeight = height - padding.top - padding.bottom;
const boundWidth = width - padding.right - padding.left;
////////////////////////////////////////////////////////////
//////////////////////// 2 CREATE SCALE ////////////////////
////////////////////////////////////////////////////////////
const scaleY = d3.scaleLinear()
.range([boundHeight, 0])
.domain(d3.extent(data, d => d.y))
////////////////////////////////////////////////////////////
//////////////////////// 3 SVG// ///////////////////////////
////////////////////////////////////////////////////////////
const svgns = 'http://www.w3.org/2000/svg'
const svg = d3.select('svg')
svg
.attr('xmlns', svgns)
.attr('viewBox', `0 0 ${width} ${height}`)
//create bound element
bound = svg.append('g')
.attr('class', 'bound')
.style('transform', `translate(${padding.left}px,${padding.top}px)`)
const mean = d3.mean(data.map(d => d.y));
bound.append('g').attr('class', 'yAxis1')
.append('g').attr('class', 'yAxisLeft')
.call(d3.axisLeft(scaleY)
.tickValues(scaleY.ticks().concat(mean))
.tickSizeInner([(-(boundWidth))])
.tickFormat(d3.format(",.0%")))
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<script type="text/javascript" src="https://d3js.org/d3.v7.min.js"></script>
<body>
<svg>
</svg>
<div id="container" ></div>
<script src="next.js"></script>
</body>
</html>