D3.js 旋转地图会破坏样式
D3.js Rotating a map breaks styling
我正在尝试旋转地球仪(正投影)。
我现在拥有的确实旋转了地球,虽然它非常不稳定,并且它打破了我拖动地图后的样子(经纬网和海洋填充)
如何改进我的代码以使其更好?
相关代码如下:
const svg = d3.select('svg');
const projection = d3.geoOrthographic()
const graticule = d3.geoGraticule();
let pathGenerator = d3.geoPath().projection(projection);
const g = svg.append('g');
g.append('path')
.attr('class', 'sphere')
.attr('d', pathGenerator({type: 'Sphere'}));
g.append('path')
.datum(graticule)
.attr("class", "graticule")
.attr("d", pathGenerator);
g.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
g.call(d3.zoom().on('zoom', () => {
g.attr('transform', d3.event.transform)
}));
function dragstarted(){
console.log("started");
}
function dragged(){
const rotate = projection.rotate()
const k = 75 / projection.scale()
//console.log(k);
projection.rotate([
rotate[0] + d3.event.dx * k,
rotate[1] - d3.event.dy * k
])
pathGenerator = d3.geoPath().projection(projection)
svg.selectAll("path").attr("d", pathGenerator)
}
function dragended(){
console.log("drag ended");
}
编辑:
现场演示:https://vizhub.com/Glebenator/f44ac266b14f4c92b88113fcc89c389d?edit=files&file=index.html
好的,我做了两件事。
在 dragged
函数内部,我没有选择所有路径元素,而是单独选择它们...所以将行 svg.selectAll("path").attr("d", pathGenerator)
替换为 svg.selectAll(".graticule").attr("d", pathGenerator)
和 svg.selectAll(".country").attr("d", pathGenerator)
.
当你附加国家时你使用 selectAll('path') 像这样 g.selectAll('path').data(countries.features)
...我认为这混淆了 d3 因为你已经附加了一些路径元素所以我将其更改为这样的唯一选择器 g.selectAll('.country').data(countries.features)
.
我不是 100% 确定为什么 d3 会这样(也许@AndrewReid 可以阐明一些问题)但我从经验中了解到,在使用 d3 附加和更新 SVG 元素时使用唯一选择器是最佳做法。
我正在尝试旋转地球仪(正投影)。 我现在拥有的确实旋转了地球,虽然它非常不稳定,并且它打破了我拖动地图后的样子(经纬网和海洋填充)
如何改进我的代码以使其更好? 相关代码如下:
const svg = d3.select('svg');
const projection = d3.geoOrthographic()
const graticule = d3.geoGraticule();
let pathGenerator = d3.geoPath().projection(projection);
const g = svg.append('g');
g.append('path')
.attr('class', 'sphere')
.attr('d', pathGenerator({type: 'Sphere'}));
g.append('path')
.datum(graticule)
.attr("class", "graticule")
.attr("d", pathGenerator);
g.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
g.call(d3.zoom().on('zoom', () => {
g.attr('transform', d3.event.transform)
}));
function dragstarted(){
console.log("started");
}
function dragged(){
const rotate = projection.rotate()
const k = 75 / projection.scale()
//console.log(k);
projection.rotate([
rotate[0] + d3.event.dx * k,
rotate[1] - d3.event.dy * k
])
pathGenerator = d3.geoPath().projection(projection)
svg.selectAll("path").attr("d", pathGenerator)
}
function dragended(){
console.log("drag ended");
}
编辑: 现场演示:https://vizhub.com/Glebenator/f44ac266b14f4c92b88113fcc89c389d?edit=files&file=index.html
好的,我做了两件事。
在
dragged
函数内部,我没有选择所有路径元素,而是单独选择它们...所以将行svg.selectAll("path").attr("d", pathGenerator)
替换为svg.selectAll(".graticule").attr("d", pathGenerator)
和svg.selectAll(".country").attr("d", pathGenerator)
.当你附加国家时你使用 selectAll('path') 像这样
g.selectAll('path').data(countries.features)
...我认为这混淆了 d3 因为你已经附加了一些路径元素所以我将其更改为这样的唯一选择器g.selectAll('.country').data(countries.features)
.
我不是 100% 确定为什么 d3 会这样(也许@AndrewReid 可以阐明一些问题)但我从经验中了解到,在使用 d3 附加和更新 SVG 元素时使用唯一选择器是最佳做法。