javascript - 使用分类 ("active"鼠标悬停时 D3 颜色变化,真)

标签 javascript svg d3.js onmouseover heatmap

我是 js 和 D3 的新手。我已经生成了各种热图,并想使用 D3 的 on.mouseover 更改图 block 的颜色。我可以显式更改颜色,但想使用 CSS 事件规则。可能很容易修复。任何帮助将不胜感激。完整代码如下。

谢谢。

<!DOCTYPE html>
<meta charset="utf-8">
<head>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<title>MJ-Heatmap</title>
<header>
<H1>Country By District_Port_Nme Heatmap</H1>
<p></p>
</header>   
<style>
body {
font: 10px sans-serif;
}
.label {
font-weight: bold;
}
.tile {
shape-rendering: crispEdges;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
<!-- CSS active state not working -- >
.tile active {
fill: red;
}
</style>
</head>
<body>
<script type="text/javascript">
var buckets = [
{country:"Brazil", distrinct_port_nme:"Baltimore, Maryland", sum_teu: 2, sum_weight: 18585, count_shipments: 1}, 
{country:"Colombia", distrinct_port_nme:"Baltimore, Maryland", sum_teu:28, sum_weight:258028, count_shipments:11}, 
{country:"Brazil", distrinct_port_nme:"Chicago, Illinois", sum_teu: 2, sum_weight: 18585, count_shipments: 1}, 
{country:"Colombia", distrinct_port_nme:"Houston, Texas", sum_teu:14, sum_weight: 95995, count_shipments: 7}, 
{country:"Brazil", distrinct_port_nme:"Long Beach, California", sum_teu: 2, sum_weight: 18584, count_shipments: 1}, 
{country:"China", distrinct_port_nme:"Long Beach, California", sum_teu: 2, sum_weight: 19180, count_shipments: 1}, 
{country:"Colombia", distrinct_port_nme:"Long Beach, California", sum_teu:12, sum_weight:117873, count_shipments: 6}, 
{country:"Singapore", distrinct_port_nme:"Long Beach, California", sum_teu: 6, sum_weight: 77176, count_shipments: 4}, 
{country:"Belgium", distrinct_port_nme:"Los Angeles, California", sum_teu: 2, sum_weight: 17780, count_shipments: 1}, 
{country:"Brazil", distrinct_port_nme:"Los Angeles, California", sum_teu: 2, sum_weight: 18584, count_shipments: 1}, 
{country:"Colombia", distrinct_port_nme:"Los Angeles, California", sum_teu: 7, sum_weight: 52046, count_shipments: 5}, 
{country:"Hong Kong", distrinct_port_nme:"Los Angeles, California", sum_teu: 2, sum_weight: 19180, count_shipments: 1}, 
{country:"India", distrinct_port_nme:"Los Angeles, California", sum_teu:48, sum_weight:460563, count_shipments:24}, 
{country:"Singapore", distrinct_port_nme:"Los Angeles, California", sum_teu:12, sum_weight:115384, count_shipments: 6}, 
{country:"Brazil", distrinct_port_nme:"New York, New York", sum_teu: 4, sum_weight: 27032, count_shipments: 2}, 
{country:"Colombia", distrinct_port_nme:"New York, New York", sum_teu: 8, sum_weight: 42885, count_shipments: 4}, 
{country:"India", distrinct_port_nme:"New York, New York", sum_teu:14, sum_weight:129116, count_shipments: 7}, 
{country:"Singapore", distrinct_port_nme:"New York, New York", sum_teu:42, sum_weight:560628, count_shipments:27}, 
{country:"Brazil", distrinct_port_nme:"Newark, New Jersey", sum_teu: 2, sum_weight: 18584, count_shipments: 1}, 
{country:"Colombia", distrinct_port_nme:"Newark, New Jersey", sum_teu:83, sum_weight:785372, count_shipments:42}, 
{country:"India", distrinct_port_nme:"Newark, New Jersey", sum_teu:62, sum_weight:587654, count_shipments:31}, 
{country:"Brazil", distrinct_port_nme:"Norfolk, Virginia", sum_teu: 8, sum_weight: 33622, count_shipments: 4}, 
{country:"India", distrinct_port_nme:"Norfolk, Virginia", sum_teu: 2, sum_weight: 17780, count_shipments: 1}, 
{country:"Brazil", distrinct_port_nme:"Philadelphia, Pennsylvania", sum_teu: 2, sum_weight: 20160, count_shipments: 1}
];
// margins
var margin = {top: 20, right: 90, bottom: 30, left: 100, left_padding: 100},
width = 700 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// axes and color scale
var x = d3.scale.ordinal()
.rangeBands([0, width], .2),
y = d3.scale.ordinal()
.rangeBands([height,0], .2),
z = d3.scale.linear().range(["lightgrey", "steelblue"]);
var xStep = .5,
yStep = 50;
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + 0 + "," + margin.top + ")");
// Compute the scale domains.
x.domain(buckets.map(function(d){return d.country}));
y.domain(buckets.map(function(d){return d.distrinct_port_nme}));
z.domain([0, d3.max(buckets.map(function(d){return d.count_shipments}))]);
// Display the tiles for each bucket.
svg.selectAll(".tile")
.data(buckets)
.enter().append("rect")
.attr("class", "tile")
.attr("x", function(d) { return x(d.country) + margin.left+margin.left_padding; })
.attr("y", function(d) { return y(d.distrinct_port_nme); })
.attr("width",x.rangeBand())
.attr("height",y.rangeBand())
.style("stroke","goldenrod")
.style("fill", function(d) { return z(d.count_shipments); })
.on("mouseover", function() { d3.select(this).classed("active", true ) })       // classed("active",boolean) not working
.on("mouseout",  function() { d3.select(this).classed("active", false) });
//  .on("mouseover", function() { d3.select(this).style("fill", "aliceblue");});    // this change work fine
//  .on("mouseout", function(){d3.select(this).style("fill", "white");});           // this change work fine
svg.selectAll("text")
.data(buckets)
.enter().append("text")
.text("text")
.attr("x", function(d) { return x(d.country) + margin.left + margin.left_padding + x.rangeBand()/2; })
.attr("y", function(d) { return y(d.distrinct_port_nme) + y.rangeBand()/2; })
.attr("dx",0)
.attr("dy",".35em")
.attr("text-anchor","middle")
.style("fill","black").attr("font-size","14").attr("font-weight","Bold")
.text( function(d) { return d.count_shipments; });
// Add a legend for the color values.
var legend = svg.selectAll(".legend")
.data(z.ticks(6).slice(1).reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(" + 0 + "," + (10 + i * 20) + ")"; });
legend.append("rect")
.attr("width", 20)
.attr("height", 20)
.style("fill", z);
legend.append("text")
.attr("x", 26)
.attr("y", 10)
.attr("dy", ".35em")
.text(String);
svg.append("text")
.attr("class", "label")
.attr("x", 0)
.attr("y", 0)
.attr("dy", ".35em")
.text("count_shipments");
// Add an x-axis with label.
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate("+ (margin.left+margin.left_padding) + "," + height + ")")
.attr("text_anchor", "top")
.call(d3.svg.axis().scale(x).orient("bottom"))
.append("text")
.attr("class", "label")
.attr("x", width-10)
.attr("y", -5)
.attr("text-anchor", "end")
.text("Country");
// Add a y-axis with label.
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate("+ (margin.left+margin.left_padding) + "," + 0 + ")")
.attr("text-anchor","right")
.call(d3.svg.axis().scale(y).orient("left"))
.append("text")
.attr("class", "label")
.attr("y", 3)
.attr("dy", ".71em")
.attr("text-anchor", "end")
.attr("transform", "rotate(-90)")
.text("distrinct_port_nme");
</script>
</body>
</html>  

最佳答案

编辑

首先,您的 CSS 略有偏差是对的。

.tile active {
  fill: red;
}

应该是:

.tile.active {
  fill: red;
}

然后,就像我在下面解释的那样,您要应用到元素的填充

.style("fill", function(d) { return z(d.count_shipments); })

最终优先于 active 类应用的填充。

但是,与我最初建议的不同,您可以通过简单地将 styleattr 交换来解决它,因此您需要:

.attr("fill", function(d) { return z(d.count_shipments); })

(对于中风可能也应该这样做)。

这是一个 updated, working jsFiddle


原帖

我怀疑它按应有的方式工作——即类“active”及其关联的填充被适本地添加/删除——你可以通过右键单击并检查开发工具中的元素来验证这一点.

我认为真正的问题是您还直接在元素上设置了填充(.on("mouseover"...) 调用之前的一行),它总是会覆盖填写由您的类(class)申请。通常在 CSS 中,您可以(不是说您应该)使用 !important 关键字强制它接受类应用的填充。但我很确定这不适用于 SVG(与普通 HTML 元素相反)。

所以,我认为你唯一的选择是:

.style("fill", function(d) { return z(d.count_shipments); })
.on("mouseover", function() {
  d3.select(this)
    .attr('fill', '') // Un-sets the "explicit" fill (might need to be null instead of '')
    .classed("active", true ) // should then accept fill from CSS
})
.on("mouseout",  function() {
  d3.select(this)
    .classed("active", false)
    .attr('fill', function(d) { return z(d.count_shipments); }) // Re-sets the "explicit" fill
  });

希望这能奏效....

关于javascript - 使用分类 ("active"鼠标悬停时 D3 颜色变化,真),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15709304/

相关文章:

javascript - Snap.js - 如何将属性设置为加载的 svg

Javascript bug,重复提示,仅出现在 GitHub 中

javascript - 迭代对象属性,属性长度等于 JQuery 中的数字

javascript - 使用 React 的 Material UI

javascript - 将 D3 Graph 插入 CMS 中的 div 中

javascript - 在圆形 svg 中添加阴影

javascript - 单击按钮时动画 svg 矩形

d3.js - 使用过渡的 d3 (v4) 缩放似乎不起作用

javascript - D3.js 路径转换中这句话的确切含义是什么

javascript - 如何在create-react-app中使用react-d3-components