javascript - d3/jQuery - 在开始时全选,但当一个被选中时 - 除那个外取消全选,但允许再次单独选择每个元素
问题描述
我正在努力使用我的选择器功能。也就是说,允许用户从使用应用于每个弧的 .selected 类选择的所有内容移动到明确地单击一个并取消选择所有其他元素,同时仍然允许用户再次选择所有项目。在我的 JS 脚本快结束时,我尝试包含一些可以执行此操作的 jQuery。但是我发现它不起作用,或者由于某种原因 d3 和 jquery 冲突并且我的代码没有被读取。
你能帮我弄清楚这个控制流程吗?谢谢你。
脚步:
- 所有元素都被选中。
- 选了一个。
- 删除除步骤 2 中选定元素之外的所有元素的选定类别
- 允许用户一次重新选择一个元素。所以,从 3,到 1,到 2,到 3,再到 2。本质上是一个仅在启动时起作用的功能。
var w = 800;
var h = 800;
const svg = d3.select('#radial-chart')
.append('svg')
.attr('width', w)
.attr('height', h);
const arc = d3.arc()
var arcData = [
{domain: '1', innerRadius: 0, outerRadius: (h/1.75), startAngle: Math.PI * -20/180, endAngle: Math.PI * 20/180},
{domain: '2', innerRadius: 0, outerRadius: (h/1.25), startAngle: Math.PI * 20/180, endAngle: Math.PI * 60/180},
{domain: '3', innerRadius: 0, outerRadius: (h/1.15), startAngle: Math.PI * 60/180, endAngle: Math.PI * 100/180},
];
// Order needs to be from JSON
var colorScale = d3.scaleOrdinal()
.domain(["1", "2", "3",])
.range(["#E8A82B", "#000000", "#2B55E8"]);
const slices = arcData.map(d => arc(d));
const handleMouseOver = (d, i, n) => {
svg.selectAll('path')
.transition().duration(300)
.style('opacity', 0.35);
d3.select(n[i])
.transition().duration(300)
.style('opacity', 0.35)
}
const handleMouseOut = (d, i, n) => {
svg.selectAll('path')
.transition().duration(300)
.style('opacity', 0.35)
.style('stroke-width', 0)
}
svg.selectAll('path')
.data(slices)
.enter()
.append('path')
.attr('transform', 'translate(325,550)')
.attr("d", d => d)
.attr("id", (d, i) => "arc" + i)
.style("fill", (d,i) => colorScale(i))
.style("z-index", 100)
.style("opacity", 0.5)
.attr('class', 'selected')
.on('mouseover', handleMouseOver)
.on('mouseout', handleMouseOut)
.on('click', function(d, i) {
d3.select(this).classed("selected", d3.select(this).classed("selected") ? false : true)
d3.select('image#arc' + i).classed("selected", d3.select(this).classed("selected") ? true: false)
})
$('path').on('click', function(){
if($(('arc0')&&('arc1')&&('arc2')).hasClass('selected')){
$('path').removeClass('selected')
}})
.selected {
transition: opacity 0.0s linear;
-webkit-transition: opacity 0.0s linear;
-moz-transition: opacity 0.0s linear;
opacity: 1!important
}
image#arc0, image#arc1, image#arc2{
transition: opacity 0s linear;
-webkit-transition: opacity 0s linear;
-moz-transition: opacity 0s linear;
opacity: 0.35
}
image#arc0:hover, image#arc1:hover, image#arc2:hover {
transition: opacity 0.3s linear;
-webkit-transition: opacity 0.3s linear;
-moz-transition: opacity 0.3s linear;
opacity: 1
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>
<script src="radial-chart.js"></script>
<div id="radial-chart"></div>
解决方案
如果我理解正确,您想要的是选择和取消选择切片,但如果没有选择任何切片,那么您想要选择所有切片。不要使用类来存储这种信息,而是将它们存储在数组中。我使用了 aSet()
因为它更容易从中删除项目。
var w = 800;
var h = 800;
var selected = new Set();
const svg = d3.select('#radial-chart')
.append('svg')
.attr('width', w)
.attr('height', h);
const arc = d3.arc()
var arcData = [{
domain: '1',
innerRadius: 0,
outerRadius: (h / 1.75),
startAngle: Math.PI * -20 / 180,
endAngle: Math.PI * 20 / 180
},
{
domain: '2',
innerRadius: 0,
outerRadius: (h / 1.25),
startAngle: Math.PI * 20 / 180,
endAngle: Math.PI * 60 / 180
},
{
domain: '3',
innerRadius: 0,
outerRadius: (h / 1.15),
startAngle: Math.PI * 60 / 180,
endAngle: Math.PI * 100 / 180
},
];
// Order needs to be from JSON
var colorScale = d3.scaleOrdinal()
.domain(["1", "2", "3", ])
.range(["#E8A82B", "#000000", "#2B55E8"]);
const slices = arcData.map(d => arc(d));
const handleMouseOver = (d, i, n) => {
svg.selectAll('path')
.transition().duration(300)
.style('opacity', 0.35);
d3.select(n[i])
.transition().duration(300)
.style('opacity', 0.35)
}
const handleMouseOut = (d, i, n) => {
svg.selectAll('path')
.transition().duration(300)
.style('opacity', 0.35)
.style('stroke-width', 0)
}
svg.selectAll('path')
.data(slices)
.enter()
.append('path')
.attr('transform', 'translate(325,550)')
.attr("d", d => d)
.attr("id", (d, i) => "arc" + i)
.style("fill", (d, i) => colorScale(i))
.style("z-index", 100)
.style("opacity", 0.5)
.attr('class', 'selected')
.on('mouseover', handleMouseOver)
.on('mouseout', handleMouseOut)
.on('click', function(_, i) {
if (selected.has(i)) {
selected.delete(i);
} else {
selected.add(i);
}
d3.selectAll("path")
.classed("selected", function(_, j) {
return selected.size === 0 || selected.has(j);
});
});
.selected {
transition: opacity 0.0s linear;
-webkit-transition: opacity 0.0s linear;
-moz-transition: opacity 0.0s linear;
opacity: 1!important
}
#arc0,
#arc1,
#arc2 {
transition: opacity 0s linear;
-webkit-transition: opacity 0s linear;
-moz-transition: opacity 0s linear;
opacity: 0.35
}
#arc0:hover,
#arc1:hover,
#arc2:hover {
transition: opacity 0.3s linear;
-webkit-transition: opacity 0.3s linear;
-moz-transition: opacity 0.3s linear;
opacity: 1
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src="radial-chart.js"></script>
<div id="radial-chart"></div>
推荐阅读
- laravel - Laravel 顶级销售产品功能
- java - 为什么加入小缓冲图像的 Java 代码不起作用?
- reactjs - 为什么 React 将其错误引用到我的包而不是源映射(Webpack 5.44.8)?
- mysql - 将计算列添加到 MySQL 表 - 版本 5.6.51
- spring - 如何在带有 Kotlin 的 Spring RabbitMQ 中使用多个消费者绑定
- python - Python 使用 itertools 查找所有组合/排列(带替换)
- javascript - 如何从另一个对象构造父子关系对象
- flutter - Flutter Test:测试是否在构建时选中了复选框
- function - PLSQL 函数聚合选择循环
- reactjs - react-router-dom - 如何使用查询参数作为路径?