首页 > 解决方案 > d3/jQuery - 在开始时全选,但当一个被选中时 - 除那个外取消全选,但允许再次单独选择每个元素

问题描述

我正在努力使用我的选择器功能。也就是说,允许用户从使用应用于每个弧的 .selected 类选择的所有内容移动到明确地单击一个并取消选择所有其他元素,同时仍然允许用户再次选择所有项目。在我的 JS 脚本快结束时,我尝试包含一些可以执行此操作的 jQuery。但是我发现它不起作用,或者由于某种原因 d3 和 jquery 冲突并且我的代码没有被读取。

你能帮我弄清楚这个控制流程吗?谢谢你。

脚步:

  1. 所有元素都被选中。
  2. 选了一个。
  3. 删除除步骤 2 中选定元素之外的所有元素的选定类别
  4. 允许用户一次重新选择一个元素。所以,从 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>

标签: javascriptjqueryd3.js

解决方案


如果我理解正确,您想要的是选择和取消选择切片,但如果没有选择任何切片,那么您想要选择所有切片。不要使用类来存储这种信息,而是将它们存储在数组中。我使用了 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>


推荐阅读