2013-03-29 35 views
5

Tôi mới sử dụng js và D3. Tôi đã tạo ra một bản đồ nhiệt của các loại và muốn thay đổi màu sắc của một gạch bằng cách sử dụng của D3 on.mouseover. Tôi có thể thay đổi màu sắc một cách rõ ràng nhưng muốn sử dụng một quy tắc hoạt động CSS. Có lẽ một cái gì đó đơn giản để sửa chữa. Mọi sự trợ giúp sẽ rất được trân trọng. Mã đầy đủ bên dưới.Thay đổi màu D3 khi di chuột qua sử dụng phân loại ("hoạt động", đúng)

Cảm ơn.

<!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> 

Trả lời

13

EDIT

Trước hết, bạn đã đúng rằng CSS của bạn là hơi off.

.tile active { 
    fill: red; 
} 

nên là:

.tile.active { 
    fill: red; 
} 

Sau đó, loại giống như tôi đã giải thích dưới đây, điền bạn đang áp dụng để nguyên tố này với

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

kết thúc lên lấy được ưu tiên hơn các điền được áp dụng bởi lớp học active.

Tuy nhiên, không giống như những gì tôi ban đầu gợi ý, bạn có thể làm việc xung quanh nó bằng cách đơn giản trao đổi style với attr, vì vậy bạn cần:

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

(có lẽ nên làm điều này cho đột quỵ cũng).

Dưới đây là một updated, working jsFiddle


ORIGINAL POST

tôi nghi ngờ nó hoạt động cách nó nên - tức là lớp "hoạt động" với điền liên quan đang được thêm/gỡ bỏ một cách thích hợp - và bạn có thể xác minh điều này bằng cách nhấp chuột phải và kiểm tra phần tử trong công cụ dev.

Tôi nghĩ rằng vấn đề thực sự là bạn cũng đang đặt điền trực tiếp vào phần tử (một dòng trước cuộc gọi .on("mouseover"...)), LUÔN LUÔN ghi đè phần điền được lớp của bạn áp dụng. Nói chung trong CSS bạn có thể (không nói bạn nên) sử dụng các từ khóa !important để buộc nó chấp nhận điền được áp dụng bởi lớp. Nhưng tôi khá chắc chắn rằng sẽ không làm việc với SVG (như trái ngược với các yếu tố HTML bình thường).

Vì vậy, tôi nghĩ rằng lựa chọn duy nhất của bạn là:

.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 
    }); 

Hope làm việc này ....

+0

Nhờ sự giúp đỡ. Điều này đã không làm việc hoặc kết thúc của tôi. Tôi tự hỏi nếu có một lỗi newbie trong quy tắc CSS của tôi hoặc làm thế nào tôi tham khảo nó. – glynnsc

+0

sửa lỗi này http://jsfiddle.net/glynnsc/WEsUe/ – glynnsc

+0

@glynnsc OK! Xem chỉnh sửa của tôi. – meetamit

Các vấn đề liên quan