我試圖理解為什么d3.line在結合比例時在空值周圍表現不同。
詳細地說,我的資料集看起來像這樣,它總是包含一些null
const data = [
{ "x": 50, "y": 97.04013083865155 },
{ "x": 100, "y": null },
{ "x": 150, "y": 98.62594214598816 },
{ "x": 200, "y": 76.49419950954189 },
{ "x": 250, "y": 29.30639006661442 },
{ "x": 300, "y": 29.366842697148176 },
{ "x": 350, "y": 51.587600132998325 },
{ "x": 400, "y": null },
{ "x": 450, "y": null },
{ "x": 500, "y": 26.90860254816283 },
{ "x": 550, "y": null },
{ "x": 600, "y": 99.1622268038577 }
]
無刻度 null
如果我想生成一條線,而不是使用scale,我會得到以下資訊
顯示代碼片段
////////////////////////////////////////////////////////////
//////////////////////// 1 DATA ///////////////////////////
////////////////////////////////////////////////////////////
const data = [
{ "x": 50, "y": 97.04013083865155 },
{ "x": 100, "y": null },
{ "x": 150, "y": 98.62594214598816 },
{ "x": 200, "y": 76.49419950954189 },
{ "x": 250, "y": 29.30639006661442 },
{ "x": 300, "y": 29.366842697148176 },
{ "x": 350, "y": 51.587600132998325 },
{ "x": 400, "y": null },
{ "x": 450, "y": null },
{ "x": 500, "y": 26.90860254816283 },
{ "x": 550, "y": null },
{ "x": 600, "y": 99.1622268038577 }
]
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 scaleX = d3.scaleLinear()
.range([0, boundWidth])
.domain(d3.extent(data, d => d.x))
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}`)
svg.append('rect')
.attr('class', 'vBoxRect')
.style("overflow", "visible")
.attr('width', `${width}`)
.attr('height', `${height}`)
.attr('stroke', 'red')
.attr('fill', 'none')
//create BOUND rect -- to be deleted later
svg.append('rect')
.attr('class', 'boundRect')
.attr('x', `${padding.left}`)
.attr('y', `${padding.top}`)
.attr('width', `${boundWidth}`)
.attr('height', `${boundHeight}`)
.attr('fill', 'none')
.attr('stroke', 'black')
//create bound element
bound = svg.append('g')
.attr('class', 'bound')
.style('transform', `translate(${padding.left}px,${padding.top}px)`)
//constrcuct line generators
////////////////////////////////////////////////////////////
////////////////////////NO SCALE// /////////////////////////
////////////////////////////////////////////////////////////
noScale = d3.line()
.x(d => d.x)
.y(d => d.y)
(data)
//no Scale
bound.append('path')
.attr('class', 'Black-noScale')
.attr('d', noScale)
.attr('fill', 'none')
.attr('stroke', 'black')
.attr('stroke-width', '2')
console.log(noScale)
<!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" class="svg-container"></div>
<script src="next.js"></script>
</body>
</html>
帶刻度 null
但是,如果我想生成一條線并使用scale,則生成器會失敗
顯示代碼片段
////////////////////////////////////////////////////////////
//////////////////////// 1 DATA ///////////////////////////
////////////////////////////////////////////////////////////
const data = [
{ "x": 50, "y": 97.04013083865155 },
{ "x": 100, "y": null },
{ "x": 150, "y": 98.62594214598816 },
{ "x": 200, "y": 76.49419950954189 },
{ "x": 250, "y": 29.30639006661442 },
{ "x": 300, "y": 29.366842697148176 },
{ "x": 350, "y": 51.587600132998325 },
{ "x": 400, "y": null },
{ "x": 450, "y": null },
{ "x": 500, "y": 26.90860254816283 },
{ "x": 550, "y": null },
{ "x": 600, "y": 99.1622268038577 }
]
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 scaleX = d3.scaleLinear()
.range([0, boundWidth])
.domain(d3.extent(data, d => d.x))
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}`)
svg.append('rect')
.attr('class', 'vBoxRect')
.style("overflow", "visible")
.attr('width', `${width}`)
.attr('height', `${height}`)
.attr('stroke', 'red')
.attr('fill', 'none')
//create BOUND rect -- to be deleted later
svg.append('rect')
.attr('class', 'boundRect')
.attr('x', `${padding.left}`)
.attr('y', `${padding.top}`)
.attr('width', `${boundWidth}`)
.attr('height', `${boundHeight}`)
.attr('fill', 'none')
.attr('stroke', 'black')
//create bound element
bound = svg.append('g')
.attr('class', 'bound')
.style('transform', `translate(${padding.left}px,${padding.top}px)`)
//constrcuct line generators
////////////////////////////////////////////////////////////
////////////////////////WITH SCALE// ////////////////////////
////////////////////////////////////////////////////////////
withScale = d3.line()
.x(d => scaleX(d.x))
.y(d => scaleY(d.y))
(data)
bound.append('path')
.attr('class', 'Orange-withScale')
.attr('d', withScale)
.attr('fill', 'none')
.attr('stroke', 'orange')
.attr('stroke-width', '2')
console.log(withScale);
<!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" class="svg-container"></div>
<script src="next.js"></script>
</body>
</html>
另一方面,生成器可以很好地定義是否使用規模
顯示代碼片段
////////////////////////////////////////////////////////////
//////////////////////// 1 DATA ///////////////////////////
////////////////////////////////////////////////////////////
const data = [
{ "x": 50, "y": 97.04013083865155 },
{ "x": 100, "y": null },
{ "x": 150, "y": 98.62594214598816 },
{ "x": 200, "y": 76.49419950954189 },
{ "x": 250, "y": 29.30639006661442 },
{ "x": 300, "y": 29.366842697148176 },
{ "x": 350, "y": 51.587600132998325 },
{ "x": 400, "y": null },
{ "x": 450, "y": null },
{ "x": 500, "y": 26.90860254816283 },
{ "x": 550, "y": null },
{ "x": 600, "y": 99.1622268038577 }
]
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 scaleX = d3.scaleLinear()
.range([0, boundWidth])
.domain(d3.extent(data, d => d.x))
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}`)
svg.append('rect')
.attr('class', 'vBoxRect')
.style("overflow", "visible")
.attr('width', `${width}`)
.attr('height', `${height}`)
.attr('stroke', 'red')
.attr('fill', 'none')
//create BOUND rect -- to be deleted later
svg.append('rect')
.attr('class', 'boundRect')
.attr('x', `${padding.left}`)
.attr('y', `${padding.top}`)
.attr('width', `${boundWidth}`)
.attr('height', `${boundHeight}`)
.attr('fill', 'none')
.attr('stroke', 'black')
//create bound element
bound = svg.append('g')
.attr('class', 'bound')
.style('transform', `translate(${padding.left}px,${padding.top}px)`)
//constrcuct line generators
////////////////////////////////////////////////////////////
////////////////////////NO SCALE// /////////////////////////
////////////////////////////////////////////////////////////
noScaleWithDefinedFilter = d3.line()
.x(d => d.x)
.y(d => d.y)
.defined(d => d.y)
(data.filter((a) => a.y !== null))
noScaleWithDefined = d3.line()
.x(d => d.x)
.y(d => d.y)
.defined(d => d.y)
(data)
//shows complete line
bound.append('path')
.attr('class', 'Violet-noScale defined filter')
.attr('d', noScaleWithDefinedFilter)
.attr('fill', 'none')
.attr('stroke', 'violet')
.attr('stroke-width', '2')
.style('transform', 'translateY(50px)')
//does not show null Y
bound.append('path')
.attr('class', 'Red-noScale defined')
.attr('d', noScaleWithDefined)
.attr('fill', 'none')
.attr('stroke', 'red')
.attr('stroke-width', '2')
.style('transform', 'translateY(75px)')
////////////////////////////////////////////////////////////
////////////////////////WITH SCALE// /////////////////////////
////////////////////////////////////////////////////////////
withScaleWithDefined = d3.line()
.x(d => scaleX(d.x))
.y(d => scaleY(d.y))
.defined(d => d.y)
(data)
withScaleWithDefinedFilter = d3.line()
.x(d => scaleX(d.x))
.y(d => scaleY(d.y))
.defined(d => d.y)
(data.filter((a) => a.y !== null))
bound.append('path')
.attr('class', 'Salmon-withScale Defined Filter')
.attr('d', withScaleWithDefinedFilter)
.attr('fill', 'none')
.attr('stroke', 'salmon')
.attr('stroke-width', '2')
bound.append('path')
.attr('class', 'Blue-withScale Defined')
.attr('d', withScaleWithDefined)
.attr('fill', 'none')
.attr('stroke', 'blue')
.attr('stroke-width', '2')
.style('transform', 'translateY(-25px)')
console.log(noScaleWithDefinedFilter);
console.log(noScaleWithDefined);
console.log(withScaleWithDefined);
console.log(withScaleWithDefinedFilter);
<!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" class="svg-container"></div>
<script src="next.js"></script>
</body>
</html>
我怎樣才能實作,以下是做什么的
const noScale = d3.line()
.x(d => d.x)
.y(d => d.y)
(data)
但隨著縮放
const withScale = d3.line()
.x(d => scaleX(d.x))
.y(d => scaleY(d.y))
(data)
這可以在不破壞資料的情況下實作嗎?
uj5u.com熱心網友回復:
這是設計和記錄的:如果您將一個null值傳遞給該線性比例,它將回傳undefined,顯然您無法在屬性undefined內部做任何事情。d
秤本身的解決方案是使用unknown,它將未知的回傳值設定為您想要的任何值,例如零:
const scaleY = d3.scaleLinear()
.unknown(0)
etc...
另一方面,如果您想跳過空值,則必須使用 而defined不是比例來更改線生成器本身。
這是您的代碼unknown(0):
顯示代碼片段
////////////////////////////////////////////////////////////
//////////////////////// 1 DATA ///////////////////////////
////////////////////////////////////////////////////////////
const data = [
{ "x": 50, "y": 97.04013083865155 },
{ "x": 100, "y": null },
{ "x": 150, "y": 98.62594214598816 },
{ "x": 200, "y": 76.49419950954189 },
{ "x": 250, "y": 29.30639006661442 },
{ "x": 300, "y": 29.366842697148176 },
{ "x": 350, "y": 51.587600132998325 },
{ "x": 400, "y": null },
{ "x": 450, "y": null },
{ "x": 500, "y": 26.90860254816283 },
{ "x": 550, "y": null },
{ "x": 600, "y": 99.1622268038577 }
]
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 scaleX = d3.scaleLinear()
.range([0, boundWidth])
.domain(d3.extent(data, d => d.x))
const scaleY = d3.scaleLinear()
.unknown(0)
.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}`)
svg.append('rect')
.attr('class', 'vBoxRect')
.style("overflow", "visible")
.attr('width', `${width}`)
.attr('height', `${height}`)
.attr('stroke', 'red')
.attr('fill', 'none')
//create BOUND rect -- to be deleted later
svg.append('rect')
.attr('class', 'boundRect')
.attr('x', `${padding.left}`)
.attr('y', `${padding.top}`)
.attr('width', `${boundWidth}`)
.attr('height', `${boundHeight}`)
.attr('fill', 'none')
.attr('stroke', 'black')
//create bound element
bound = svg.append('g')
.attr('class', 'bound')
.style('transform', `translate(${padding.left}px,${padding.top}px)`)
//constrcuct line generators
////////////////////////////////////////////////////////////
////////////////////////WITH SCALE// ////////////////////////
////////////////////////////////////////////////////////////
withScale = d3.line()
.x(d => scaleX(d.x))
.y(d => scaleY(d.y))
(data)
bound.append('path')
.attr('class', 'Orange-withScale')
.attr('d', withScale)
.attr('fill', 'none')
.attr('stroke', 'orange')
.attr('stroke-width', '2')
console.log(withScale);
<!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" class="svg-container"></div>
<script src="next.js"></script>
</body>
</html>
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/488299.html
標籤:javascript svg d3.js
上一篇:WSL2Nginx PHPFPM在連接到上游時失敗(111:連接被拒絕),客戶端:172.23.0.1,上游:“fastcgi://172.23.0.3:9001”
