json 파일의 데이터와 함께 javascript, d3를 사용하여 호에서 방사형 그래디언트를 만드는 문제
나는 자바 스크립트와 d3 (v6)을 사용하고 있으며 햇살 유형 플롯 또는 각 호가 잠재적으로 자체 그라디언트 (중심에서 주변까지 방사형 그라디언트)가있는 다른 방사형 거리 에서 호가 있는 플롯 을 만들기 위해 노력 하고 있습니다. 이 시점에서 몇 가지 예제 (예 : here , here )를 따랐습니다. 여기 에서 RadialGradient 요소 세트를 설정 한 다음 그 ID를 사용하여 실제 호에 채우기를 생성했습니다. 그러나 json 파일의 데이터에서 호와 그라디언트를 생성하고 있으며 svg 요소 생성이 d3.json 호출 (예 : 여기 ) 내에 있기 때문에 이전 질문과 다릅니다 . 두 가지 문제가 있습니다. (1) 그라디언트 설정에는 다음과 같은 선이 있습니다.
grads.append("stop")
.attr("offset", "0%").style("stop-color", "white")
.attr("offset", "100%").style("stop-color", "green");
그러나 이것들은 실제로 grads 요소에 추가되지 않는 것 같습니다 (웹 페이지에서 검사기를 볼 때).
(2) 호에 대한 링크가 작동하지 않는 것 같습니다. 아마도 첫 번째 문제 때문일 수 있습니다.
JAVASCRIPT ( 여기 에서 찾을 수 있음 )
var width = window.innerWidth,
height = window.innerHeight;
var body = d3.select('body')
// append svg to the DIV
chart = d3.select(".chart");
const svg = chart.append("svg:svg")
.attr("width", width)
.attr("height", height);
/////////////////////////////////////// Global variables controlling the arc appearance //////////////////
const arcMin = 30;
const arcWidth = 45.5;
const arcPad = 1;
///////////////////////////////////////////////////////////////////////////////////////////////
d3.json('dataExample.json')
.then(function (data) {
const grads = svg.append("defs").selectAll("radialGradient").data(data.sequences);
grads.enter().append("radialGradient")
.attr("gradientUnits", "objectBoundingBox")
.attr("cx", 0)
.attr("cy", 0)
.attr("fr", (d, i) => arcMin + (d.pulse-1) * (arcWidth))
.attr("r", (d, i) => arcMin + d.pulse * (arcWidth))
.attr("id", function (d) {
return "grad" + d.code;
});
grads.append("stop")
.attr("offset", "0%").style("stop-color", "white")
.attr("offset", "100%").style("stop-color", "green");//eventually this gradient will go between two colors that are functions of the data that is read in from the json file
console.log(grads);
var arc = svg.selectAll('path.arc-path')
.data(data.sequences);
arc.enter()
.append('svg:path')
.attr('d', d3.arc()
.innerRadius((d, i) => arcMin + (d.pulse - 1) * (arcWidth) + arcPad)
.outerRadius((d, i) => arcMin + d.pulse * (arcWidth))
.startAngle(function (d, i) {
ang = (i * 30) * Math.PI / 180;
return ang;
})
.endAngle(function (d, i) {
ang = ((i + 1) * 30) * Math.PI / 180;
return ang;
})
)
.attr("class", ".arc-path") // assigns a class for easier selecting
.attr("transform", "translate(600,300)")
//.style('fill',(d) => `rgb(${d.code * 10},${d.code*20},${255 -d.code * 7})`); this works - but doesn't use the gradients
.style("fill", function (d) {return "url(#grad" + d.code + ")";})
})
JSONFILE (위의 dataExample.json이라고 함)은 여기 에서 찾을 수 있습니다.
{"type":"sequenceData","sequences":[{"pulse":1,"code":0},{"pulse":1,"code":1},{"pulse":1,"code":2},{"pulse":2,"code":3},{"pulse":2,"code":4},{"pulse":2,"code":5},{"pulse":2,"code":6},{"pulse":2,"code":7},{"pulse":2,"code":8},{"pulse":2,"code":9},{"pulse":2,"code":10},{"pulse":3,"code":12}]}
index.html ( 여기 에서 찾을 수 있음 )
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Gradient arc test</title>
</style>
<script type="text/javascript" src="https://d3js.org/d3.v6.min.js"></script>
</head>
<body>
<div class="chart"></div>
<script src="arcExample.js"> </script>
</body>
</html>
그리고 다른 문제 나 잘못된 코딩 관행이 있으면이 기능을 처음 사용하므로 알려주십시오. 감사.
(편집 됨)
Ruben Helsloot의 의견을 바탕으로 여러 부분으로 jsfiddles를 만들었습니다. 바이올린이 4 개 있습니다. (1) json 파일을 읽는 방법과 (2) 채우기가 생성되는 방법의 두 가지 측면에서 다릅니다. 최종 목적을 위해 로컬 또는 URL에서 json 파일을 읽을 수 있어야합니다.
(1) jsfiddle 버전 1 URL에서 json을 읽고 채우기를 위해 그라디언트를 사용하려고합니다. . URL에서 읽는 데 문제가 있고 그라디언트 채우기 문제가 있다고 생각합니다.
(2) jsfiddle 버전 2 URL에서 json을 읽으려고 시도하지만 채우기에 그라디언트를 사용하지 않습니다. URL을 읽는 데 문제가 있습니다. 로컬 파일에서 json을 읽는 로컬 컴퓨터에서이 작업을 수행하면이 버전이 출력을 생성합니다 (그래디언트는 아님).
(3) jsfiddle Version 3 이것은 json을 data라는 지역 변수에 넣은 다음 그것을 사용합니다. 또한 채우기를 위해 그라디언트를 사용하려고합니다.
(4) jsfiddle 버전 4 이것은 json을 data라는 지역 변수에 넣은 다음 그것을 사용합니다. 채우기를 위해 그라디언트를 사용하지 않습니다. 이것은 jsfiddle에 출력을 제공하는 4 개 중 유일한 것입니다.
답변
기본 SVG 1.1 사양을 먼저 배운 다음 올바른 SVG 구조에 요소 (속성이 아님)를 추가하는 방법을 배워야합니다.
아래는 고정 코드이지만 달성하려는 그라디언트가 정확히 무엇인지 모르겠습니다. gradientUnits 속성을 objectBoundingBox로 다시 변경하려고 시도 할 수 있지만 먼저 r 속성을 사용해보십시오 .
var width = window.innerWidth,
height = window.innerHeight;
var body = d3.select('body')
// append svg to the DIV
chart = d3.select(".chart");
const svg = chart.append("svg:svg")
.attr("width", width)
.attr("height", height)
.attr("xmlns", "http://www.w3.org/2000/svg")
.attr("xmlns:xlink", "http://www.w3.org/1999/xlink");
/////////////////////////////////////// Global variables controlling the arc appearance //////////////////
const arcMin = 30;
const arcWidth = 45.5;
const arcPad = 1;
///////////////////////////////////////////////////////////////////////////////////////////////
var data = {"type":"sequenceData","sequences":[{"pulse":1,"code":0},{"pulse":1,"code":1},{"pulse":1,"code":2},{"pulse":2,"code":3},{"pulse":2,"code":4},{"pulse":2,"code":5},{"pulse":2,"code":6},{"pulse":2,"code":7},{"pulse":2,"code":8},{"pulse":2,"code":9},{"pulse":2,"code":10},{"pulse":3,"code":12}]};
const grads = svg.append("defs").selectAll("radialGradient").data(data.sequences);
gradsWrap = grads.enter().append("radialGradient")
//.attr("gradientUnits", "objectBoundingBox")
.attr("gradientUnits", "userSpaceOnUse")
.attr("cx", 0)
.attr("cy", 0)
//.attr("fr", (d, i) => arcMin + (d.pulse-1) * (arcWidth))
//.attr("r", (d, i) => arcMin + (d.pulse-1) * (arcWidth))
.attr("fr", "0%")
.attr("r", "25%")
.attr("id", function (d) {
return "grad" + d.code;
})
gradsWrap.append("stop")
.attr("offset", "0%")
.attr("stop-color", "white");
gradsWrap.append("stop")
.attr("offset", "100%").attr("stop-color", "green");//eventually this gradient will go between two colors that are functions of the data that is read in from the json file
console.log(grads);
var arc = svg.selectAll('path.arc-path')
.data(data.sequences);
arc.enter()
.append('svg:path')
.attr('d', d3.arc()
.innerRadius((d, i) => arcMin + (d.pulse - 1) * (arcWidth) + arcPad)
.outerRadius((d, i) => arcMin + d.pulse * (arcWidth))
.startAngle(function (d, i) {
ang = (i * 30) * Math.PI / 180;
return ang;
})
.endAngle(function (d, i) {
ang = ((i + 1) * 30) * Math.PI / 180;
return ang;
})
)
.attr("class", ".arc-path") // assigns a class for easier selecting
.attr("transform", "translate(" + width/2 + "," + height/2 + ")")
.attr('stroke', 'white')
.style('stroke-width', '2px')
.attr("fill", function (d) {
//return "red";
return "url(#grad" + d.code + ")";
})
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<title>Gradient arc test</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
</head>
<body>
<div class="chart"></div>
</body>