如何修复 d3 中的这个切换功能?
How to fix this toggle function in d3?
我这里有两个问题:
1/ 这些按钮(您可以 运行 下面的代码片段)应该在第二次点击时恢复到原来的不透明度,但它们没有!有人可以向我解释代码有什么问题吗?
2/ 如何在第二次点击时返回 text
之前的颜色 而无需在切换功能中定义之前的颜色(再次!) . ?
解释:正如您在 运行 执行以下代码片段时看到的那样,text
(1,2,3...) 在第一个 [=17] 处变为 white
=].我想在第二次点击时将它设置回原来的颜色,而不必写:
var newTextFill = active ? "white" : "**former_color**";
例如,在 this example 中,作者没有指定 font-size
图例应该 return 在第二次点击时出现,但你可以看到它缩小回原来的样子尺寸。我怎样才能在这里对字体颜色做同样的事情?
var name = ["123456789"];
var color = d3.scaleOrdinal()
.range(["#00baff", "#0014fe", "#00dbaf", "#f4bf02", "#ffa600", "#ff0000", "#ff00c4", "#ee693e", "#99958f"]);
var svg = d3.select("body")
.append("svg")
.attr("width", 300)
.attr("height",300)
var legende = svg.selectAll("bar")
.data(name)
.enter()
.append("g")
.attr("x", 0)
.attr("y", function (d,i) {return 12 + i * 20})
legende.append("text")
.text(function(d,i) { return name[i]})
.attr("class", "legtext")
.style("font-family", "helvetica")
.style("fill-opacity", 0.8)
.attr("x", 4)
.attr("y", function (d,i) {return 12 + i * 20})
.style("font-size", 10)
.style("fill", function(d,i) { return color(i)})
.style("text-decoration", "none")
.style("opacity", 1);
legende.append("rect")
.attr("class", "recta")
.attr("x", 2)
.attr("y", function (d,i) {return 1 + i * 20})
.attr("width", 65)
.attr("height", 15)
.style("fill", function(d,i) { return color(i)})
.style("opacity", 0.09);
legende.append("rect")
.attr("class", "rectastroke")
.attr("id", function(d,i) {return "str" + i})
.attr("x", 2)
.attr("y", function (d,i) {return 1 + i * 20})
.attr("width", 65)
.attr("height", 15)
.style("stroke", function(d,i) { return color(i)})
.style("stroke-width", 0.5)
.style("fill", "none")
.attr("display", "none");
legende.on("click", function (d,i)
{var active = d.active ? false : true;
var newOpacity = active ? 1 : 0.1;
var newTextFill = active ? "white" : "blue";
d3.select(this)
.select("rect")
.style("opacity", newOpacity)
d3.select(this)
.select("text")
.style("fill", newTextFill)
.raise()
d.active = active });
legende.on("mouseover", function(d, i)
{d3.select(this).selectAll(".rectastroke").attr("display", "true")});
legende.on("mouseout", function(d, i)
{d3.select(this).selectAll(".rectastroke").attr("display", "none")});
body {font-family: 'Open Sans', sans-serif;
font-size: 11px;
font-weight: 300;
fill: #242424;
text-align: center;
cursor: default;}
.legende {cursor: pointer;}
.recta {cursor: pointer;}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="colored buttons"></div>
</body>
</html>
在您链接的 bl.ocks 中,她实际上指定了图例在第二次单击时 return 的字体大小...在 CSS.
发生的事情是,如果 active
为假,则 setter 将 return undefined
...
d3.select(this)
.style("font-size", function() {
if (active) {return "25px"}
})
... 并且UA会根据CSS.
设置样式
您可以在不指定任何矩形的情况下对矩形执行相同的操作 newOpacity
:
d3.select(this)
.select("rect")
.style("opacity", function() {
if (active) return 1;
})
这是演示:
var data = "123456789".split("").map(function(d) {
return {
value: d
}
});
var color = d3.scaleOrdinal()
.range(["#00baff", "#0014fe", "#00dbaf", "#f4bf02", "#ffa600", "#ff0000", "#ff00c4", "#ee693e", "#99958f"]);
var svg = d3.select("body")
.append("svg")
.attr("width", 300)
.attr("height", 300)
var legende = svg.selectAll("bar")
.data(data)
.enter()
.append("g")
.attr("x", 0)
.attr("y", function(d, i) {
return 12 + i * 20
})
legende.append("text")
.text(function(d, i) {
return d.value
})
.attr("class", "legtext")
.style("font-family", "helvetica")
.style("fill-opacity", 0.8)
.attr("x", 4)
.attr("y", function(d, i) {
return 12 + i * 20
})
.style("font-size", 10)
.style("fill", function(d, i) {
return color(i)
})
.style("text-decoration", "none")
.style("opacity", 1);
legende.append("rect")
.attr("class", "recta")
.attr("x", 2)
.attr("y", function(d, i) {
return 1 + i * 20
})
.attr("width", 65)
.attr("height", 15)
.style("fill", function(d, i) {
return color(i)
});
legende.on("click", function(d, i) {
var active = d.active ? false : true;
d3.select(this)
.select("rect")
.style("opacity", function() {
if (active) return 1;
})
d3.select(this)
.select("text")
.style("fill", function(e, j) {
if (active) {
return "white";
} else {
return color(i)
}
})
.raise()
d.active = active
});
.legende {
cursor: pointer;
}
.recta {
opacity: 0.1;
cursor: pointer;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
然而,对于文本颜色,由于您未在 CSS 中指定它,因此您必须使用正常的 if...else
代码。
我这里有两个问题:
1/ 这些按钮(您可以 运行 下面的代码片段)应该在第二次点击时恢复到原来的不透明度,但它们没有!有人可以向我解释代码有什么问题吗?
2/ 如何在第二次点击时返回 text
之前的颜色 而无需在切换功能中定义之前的颜色(再次!) . ?
解释:正如您在 运行 执行以下代码片段时看到的那样,text
(1,2,3...) 在第一个 [=17] 处变为 white
=].我想在第二次点击时将它设置回原来的颜色,而不必写:
var newTextFill = active ? "white" : "**former_color**";
例如,在 this example 中,作者没有指定 font-size
图例应该 return 在第二次点击时出现,但你可以看到它缩小回原来的样子尺寸。我怎样才能在这里对字体颜色做同样的事情?
var name = ["123456789"];
var color = d3.scaleOrdinal()
.range(["#00baff", "#0014fe", "#00dbaf", "#f4bf02", "#ffa600", "#ff0000", "#ff00c4", "#ee693e", "#99958f"]);
var svg = d3.select("body")
.append("svg")
.attr("width", 300)
.attr("height",300)
var legende = svg.selectAll("bar")
.data(name)
.enter()
.append("g")
.attr("x", 0)
.attr("y", function (d,i) {return 12 + i * 20})
legende.append("text")
.text(function(d,i) { return name[i]})
.attr("class", "legtext")
.style("font-family", "helvetica")
.style("fill-opacity", 0.8)
.attr("x", 4)
.attr("y", function (d,i) {return 12 + i * 20})
.style("font-size", 10)
.style("fill", function(d,i) { return color(i)})
.style("text-decoration", "none")
.style("opacity", 1);
legende.append("rect")
.attr("class", "recta")
.attr("x", 2)
.attr("y", function (d,i) {return 1 + i * 20})
.attr("width", 65)
.attr("height", 15)
.style("fill", function(d,i) { return color(i)})
.style("opacity", 0.09);
legende.append("rect")
.attr("class", "rectastroke")
.attr("id", function(d,i) {return "str" + i})
.attr("x", 2)
.attr("y", function (d,i) {return 1 + i * 20})
.attr("width", 65)
.attr("height", 15)
.style("stroke", function(d,i) { return color(i)})
.style("stroke-width", 0.5)
.style("fill", "none")
.attr("display", "none");
legende.on("click", function (d,i)
{var active = d.active ? false : true;
var newOpacity = active ? 1 : 0.1;
var newTextFill = active ? "white" : "blue";
d3.select(this)
.select("rect")
.style("opacity", newOpacity)
d3.select(this)
.select("text")
.style("fill", newTextFill)
.raise()
d.active = active });
legende.on("mouseover", function(d, i)
{d3.select(this).selectAll(".rectastroke").attr("display", "true")});
legende.on("mouseout", function(d, i)
{d3.select(this).selectAll(".rectastroke").attr("display", "none")});
body {font-family: 'Open Sans', sans-serif;
font-size: 11px;
font-weight: 300;
fill: #242424;
text-align: center;
cursor: default;}
.legende {cursor: pointer;}
.recta {cursor: pointer;}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="colored buttons"></div>
</body>
</html>
在您链接的 bl.ocks 中,她实际上指定了图例在第二次单击时 return 的字体大小...在 CSS.
发生的事情是,如果 active
为假,则 setter 将 return undefined
...
d3.select(this)
.style("font-size", function() {
if (active) {return "25px"}
})
... 并且UA会根据CSS.
设置样式您可以在不指定任何矩形的情况下对矩形执行相同的操作 newOpacity
:
d3.select(this)
.select("rect")
.style("opacity", function() {
if (active) return 1;
})
这是演示:
var data = "123456789".split("").map(function(d) {
return {
value: d
}
});
var color = d3.scaleOrdinal()
.range(["#00baff", "#0014fe", "#00dbaf", "#f4bf02", "#ffa600", "#ff0000", "#ff00c4", "#ee693e", "#99958f"]);
var svg = d3.select("body")
.append("svg")
.attr("width", 300)
.attr("height", 300)
var legende = svg.selectAll("bar")
.data(data)
.enter()
.append("g")
.attr("x", 0)
.attr("y", function(d, i) {
return 12 + i * 20
})
legende.append("text")
.text(function(d, i) {
return d.value
})
.attr("class", "legtext")
.style("font-family", "helvetica")
.style("fill-opacity", 0.8)
.attr("x", 4)
.attr("y", function(d, i) {
return 12 + i * 20
})
.style("font-size", 10)
.style("fill", function(d, i) {
return color(i)
})
.style("text-decoration", "none")
.style("opacity", 1);
legende.append("rect")
.attr("class", "recta")
.attr("x", 2)
.attr("y", function(d, i) {
return 1 + i * 20
})
.attr("width", 65)
.attr("height", 15)
.style("fill", function(d, i) {
return color(i)
});
legende.on("click", function(d, i) {
var active = d.active ? false : true;
d3.select(this)
.select("rect")
.style("opacity", function() {
if (active) return 1;
})
d3.select(this)
.select("text")
.style("fill", function(e, j) {
if (active) {
return "white";
} else {
return color(i)
}
})
.raise()
d.active = active
});
.legende {
cursor: pointer;
}
.recta {
opacity: 0.1;
cursor: pointer;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
然而,对于文本颜色,由于您未在 CSS 中指定它,因此您必须使用正常的 if...else
代码。