在d3中设置一个隐藏所有其他元素的click事件

时间:2013-11-09 19:24:58

标签: svg d3.js mouseover chord-diagram

我对使用d3相当新,但我想要做的是制作一些网站流量的和弦图,我试图通过在用户点击群组时更改路径的颜色来使其交互对于某个站点。我的代码的样式和脚本部分:

<style type="text/css">

.group text {
  font: 11px sans-serif;
  pointer-events: none;
}

#circle circle {
fill: none;
pointer-events: all;
}
.group path {
  stroke: #000;
  fill-opacity: .5;
}

path.chord {
  stroke-width: .75;
  fill-opacity: .75;
}

#circle:hover path.fade {
display: none;
}
</style>
</head>

<body>
<script type="text/javascript">



// Chart dimensions.
var w = 600,
h = 700,
r1 = Math.min(w, h) / 2 - 4,
r0 = r1 - 20,
format = d3.format(",.3r");

// Square matrices, asynchronously loaded; credits is the transpose of sitename.
var sitename = [];

// The chord layout, for computing the angles of chords and groups.
var layout = d3.layout.chord()
.sortGroups(d3.descending)
.sortSubgroups(d3.descending)
.sortChords(d3.descending)
.padding(.04);

// The color scale, for different categories of "worrisome" risk.
var fill = d3.scale.ordinal();

// The arc generator, for the groups.
var arc = d3.svg.arc()
.innerRadius(r0)
.outerRadius(r1);

// The chord generator (quadratic Bézier), for the chords.
var chord = d3.svg.chord()
.radius(r0);

// Add an SVG element for each diagram, and translate the origin to the center.
var svg = d3.select("body").selectAll("div")
.data([sitename])
.enter().append("div")
.style("display", "inline-block")
.style("width", w + "px")
.style("height", h + "px")
.append("svg:svg")
.attr("width", w)
.attr("height", h)
.append("svg:g")
.attr("transform", "translate(" + w / 2 + "," + h / 2 + ")");

// Load our data file…
d3.csv("data2.csv", function(data) {
var uniqueids = {},
  array = [],
  n = 0;

// Compute a unique id for each site.
data.forEach(function(d) {
d.siteid1 = uniqueIDMaker(d.siteid1);
d.siteid2 = uniqueIDMaker(d.siteid2);
d.valueOf = value; // convert object to number implicitly
});


// Initialize a square matrix of sitename and users
for (var i = 0; i < n; i++) {
sitename[i] = [];
for (var j = 0; j < n; j++) {
  sitename[i][j] = 0;
}
}

// Populate the matrices, and stash a map from id to site.
 data.forEach(function(d) {
sitename[d.siteid1.id][d.siteid2.id] = d;
array[d.siteid1.id] = d.siteid1;
array[d.siteid2.id] = d.siteid2;
});

// For each diagram…
svg.each(function(matrix, j) {
var svg = d3.select(this);

// Compute the chord layout.
layout.matrix(matrix);

// Add chords.
svg.selectAll(".chord")
    .data(layout.chords)
  .enter().append("svg:path")
    .attr("class", "chord")
    .style("fill", function(d) { return fill(d.source.value); })
    .style("stroke", function(d) { return d3.rgb(fill(d.source.value)).darker(); })
    .attr("d", chord)
    .on("dblclick",function(){
        d3.select(this)
        .style("fill","red")
        .style("stroke","yellow")
    })
  .append("svg:title")
    .text(function(d) { return "site " + d.source.value.siteid2.name + " and site " + d.source.value.siteid1.name + " have " + format(d.source.value) + " common users"; })
    ;

// Add groups.
var g = svg.selectAll("g.group")
    .data(layout.groups)
  .enter().append("svg:g")
    .attr("class", "group");

// Add the group arc.
g.append("svg:path")
    .style("fill", function(d) { return fill(array[d.index]); })
    .attr("id", function(d, i) { return "group" + d.index + "-" + j; })
    .attr("d", arc) 

    .append("svg:title")
    .text(function(d) { return "site " + array[d.index].name + " has " + format(d.value) + "users"; });

g.append("svg:text")
    .attr("x", 6)
    .attr("dy", 15)
    .filter(function(d) { return d.value > 110; })
  .append("svg:textPath")
    .attr("xlink:href", function(d) { return "#group" + d.index + "-" + j; })
    .text(function(d) { return array[d.index].name; });
 });

function uniqueIDMaker(d) {
return uniqueids[d] || (uniqueids[d] = {
  name: d,
  id: n++
});
}

function value() {
return +this.count;
}});

</script>

任何帮助将不胜感激

http://jsfiddle.net/Rw3aK/2/是脚本的jsFiddle,不知道如何从文件中读取它,所以这里是data2.csv的内容:

siteid1,siteid2,计数,pubid1,pubid2

8,94,11132,57141,57141

201,94,10035,57141,57141

201,8,9873,57141,57141

0,94,8488,45020,57141

0,8,8258,45020,57141

0,201,7644,45020,57141

0,1,6973,45020,45020

94,1,5719,57141,45020

8,1,5670,57141,45020

1,201,5410,57141,45020

1 个答案:

答案 0 :(得分:3)

我分叉你的jsfiddle并将你的CSV数据转换为JSON,现在变量datahttp://jsfiddle.net/mdml/K6FHW/

我还稍微修改了你的代码,这样当你点击一个组时,所有传出和弦都会突出显示为红色。再次单击组时,和弦会变回原始颜色。这是相关的片段:

添加和弦时,请根据和弦的来源为每个和弦标记

svg.selectAll(".chord")
    .data(layout.chords)
    .enter().append("svg:path")
    .attr("class", function(d){ return "chord chord-" + d.source.index; })

...

单击某个组时,请检查该组的和弦是否突出显示。

  • 如果是,请使用默认颜色填充和弦
  • 如果没有,请填充红色和弦
  • 然后记录组的和弦是否在变量d.chordHighlighted

    中突出显示
    g.append("svg:path")
    ...
        .attr("id", function (d, i) {
            return "group" + d.index + "-" + j;
        })
    ...
        .on("click", function(d){
            if (d.chordHighlighted)
                d3.selectAll(".chord-" + d.index)
                    .style("fill", fill(d.value));
            else{
                d3.selectAll(".chord-" + d.index)
                    .style("fill", "red");
            }
            d.chordHighlighted = d.chordHighlighted ? false : true;
        })