我的简单绘图软件允许将不同的颜色应用于县。我一直在努力解决一个相当奇怪的错误,它只允许索引值大于当前颜色索引的颜色覆盖颜色。
代码很长,但我不确定如果不粘贴整个代码是否可以说明问题。我将从主要部分开始:
这是填充十六进制颜色数组的 getColor()
函数,我认为部分问题在于:
function getColor(index) {
var colorarray = [
'550000',
'801515',
'aa3939',
'd46a6a',
'ffaaaa',
'003333',
'0d4d4d',
'226666',
'407f7f',
'669999',
'004400',
'116611',
'2d882d',
'55aa55',
'88cc88',
'552700',
'804515',
'aa6c39',
'd49a6a',
'ffd1aa',
];
return colorarray[index];
}
这是完整的代码。如果你选择数组中的最后一种颜色(右下角,粉红色),选择一些县,然后尝试覆盖,这个错误很快就会被发现。你会看到它失败了。如果您选择右上角的深红色,您可以用任何其他颜色覆盖该颜色,因为所有颜色都位于数组列表的下方。
它使用 colorsjs.js 和 d3.js 库。
<!DOCTYPE html>
<title>Heartland Remapping Tool</title>
<link rel="shortcut icon" type="image/png" href="/faviconpng.png" />
<style>
svg {
width: 100%;
height: auto;
}
input {
border-width: 0px;
border: none;
width: 30px;
height: 30px;
cursor: pointer;
margin: 3px;
}
.c550000 {
fill: #550000;
stroke-width: .5px;
}
.c801515 {
fill: #801515;
stroke-width: .5px;
}
.caa3939 {
fill: #aa3939;
stroke-width: .5px;
}
.cd46a6a {
fill: #d46a6a;
stroke-width: .5px;
}
.cffaaaa {
fill: #ffaaaa;
stroke-width: .5px;
}
.c003333 {
fill: #003333;
stroke-width: .5px;
}
.c0d4d4d {
fill: #0d4d4d;
stroke-width: .5px;
}
.c226666 {
fill: #226666;
stroke-width: .5px;
}
.c407f7f {
fill: #407f7f;
stroke-width: .5px;
}
.c669999 {
fill: #669999;
stroke-width: .5px;
}
.c004400 {
fill: #004400;
stroke-width: .5px;
}
.c116611 {
fill: #116611;
stroke-width: .5px;
}
.c2d882d {
fill: #2d882d;
stroke-width: .5px;
}
.c55aa55 {
fill: #55aa55;
stroke-width: .5px;
}
.c88cc88 {
fill: #88cc88;
stroke-width: .5px;
}
.c552700 {
fill: #552700;
stroke-width: .5px;
}
.c804515 {
fill: #804515;
stroke-width: .5px;
}
.caa6c39 {
fill: #aa6c39;
stroke-width: .5px;
}
.cd49a6a {
fill: #d49a6a;
stroke-width: .5px;
}
.cffd1aa {
fill: #ffd1aa;
stroke-width: .5px;
}
.counties {
fill: white;
stroke: #7887AB;
stroke-width: .5px;
}
.counties .hovered,
.counties :hover {
fill: #061539;
stroke-width: .5px;
}
.selected {
fill: #061539;
}
.erase {
fill: none;
}
.deselected {
fill: white;
stroke-width: .5px;
}
.deselected :hover {
fill: #061539;
stroke-width: .5px;
}
.county-borders {
fill: none;
stroke: #F0F8FF;
stroke-width: .2px;
stroke-linejoin: round;
stroke-linecap: round;
pointer-events: none;
}
.state-borders {
fill: none;
stroke: #162955;
opacity: .8;
stroke-linejoin: round;
stroke-linecap: round;
pointer-events: none;
}
.toolTip {
position: absolute;
display: none;
min-width: 80px;
height: auto;
background: none repeat scroll 0 0 #ffffff;
border: 1px solid #6F257F;
padding: 14px;
text-align: center;
}
</style>
<script>
var selcolor;
window.onload = function() {
var defaultcolor = document.getElementById("first");
getSeletedColor(defaultcolor);
};
//this may be the cause of the fact that I can only overwrite colors with a color farther down the list.
function getColor(index) {
var colorarray = [
'550000',
'801515',
'aa3939',
'd46a6a',
'ffaaaa',
'003333',
'0d4d4d',
'226666',
'407f7f',
'669999',
'004400',
'116611',
'2d882d',
'55aa55',
'88cc88',
'552700',
'804515',
'aa6c39',
'd49a6a',
'ffd1aa',
];
return colorarray[index];
}
function getSeletedColor(val) {
var coloritem = document.getElementById('selcolor');
coloritem.value = val.value;
var dispitem = document.getElementById('current_color');
dispitem.style.background = val.style.backgroundColor;
dispitem.value = val.value;
}
</script>
<input id="selcolor" hidden="true" value="hhhhhh"></input>
<div id="option">
<input style="width: 90px; height: 18px;" name="updateButton" type="button" value="Print Regions" onclick="dl_csv()" />
</div>
<div id="option">
<input style="width: 90px; height: 18px;" name="updateButton" type="button" value="Reset" onclick="window.location.reload()" />
</div>
<br/>
<div>
<form id="colorlist">
<input id="first" style="background-color:#550000; color: #550000;" value="550000" onmousedown="getSeletedColor(this)">
<input spellcheck="false" style="background-color:#801515; color: #801515;" value="801515" onmousedown="getSeletedColor(this)">
<input spellcheck="false" style="background-color:#aa3939; color: #aa3939;" value="aa3939" onmousedown="getSeletedColor(this)">
<input spellcheck="false" style="background-color:#d46a6a; color: #d46a6a;" value="d46a6a" onmousedown="getSeletedColor(this)">
<input spellcheck="false" style="background-color:#ffaaaa; color: #ffaaaa;" value="ffaaaa" onmousedown="getSeletedColor(this)">
<br/>
<input spellcheck="false" style="background-color:#003333; color: #003333;" value="003333" onmousedown="getSeletedColor(this)">
<input spellcheck="false" style="background-color:#0d4d4d; color: #0d4d4d;" value="0d4d4d" onmousedown="getSeletedColor(this)">
<input spellcheck="false" style="background-color:#226666; color: #226666;" value="226666" onmousedown="getSeletedColor(this)">
<input spellcheck="false" style="background-color:#407f7f; color: #407f7f;" value="407f7f" onmousedown="getSeletedColor(this)">
<input spellcheck="false" style="background-color:#669999; color: #669999;" value="669999" onmousedown="getSeletedColor(this)">
<br/>
<input spellcheck="false" style="background-color:#004400; color: #004400;" value="004400" onmousedown="getSeletedColor(this)">
<input spellcheck="false" style="background-color:#116611; color: #116611;" value="116611" onmousedown="getSeletedColor(this)">
<input spellcheck="false" style="background-color:#2d882d; color: #2d882d;" value="2d882d" onmousedown="getSeletedColor(this)">
<input spellcheck="false" style="background-color:#55aa55; color: #55aa55;" value="55aa55" onmousedown="getSeletedColor(this)">
<input spellcheck="false" style="background-color:#88cc88; color: #88cc88;" value="88cc88" onmousedown="getSeletedColor(this)">
<br/>
<input spellcheck="false" style="background-color:#552700; color: #552700;" value="552700" onmousedown="getSeletedColor(this)">
<input spellcheck="false" style="background-color:#804515; color: #804515;" value="804515" onmousedown="getSeletedColor(this)">
<input spellcheck="false" style="background-color:#aa6c39; color: #aa6c39;" value="aa6c39" onmousedown="getSeletedColor(this)">
<input spellcheck="false" style="background-color:#d49a6a; color: #d49a6a;" value="d49a6a" onmousedown="getSeletedColor(this)">
<input spellcheck="false" style="background-color:#ffd1aa; color: #ffd1aa;" value="ffd1aa" onmousedown="getSeletedColor(this)">
</form>
<br/>
<input readonly hidden="true" style="background:white; width: 50px;" id="current_color" value="550000"></input>
<form action="">
<input style="margin: default; height: 18px; width: 15px;" type="radio" name="tool" value="zoompan" id="zoompan"> <u>Z</u>oom/Pan
<input style="margin: default; height: 18px; width: 15px;" type="radio" name="tool" value="select" id="select" checked> <u>S</u>elect
<input style="margin: default; height: 18px; width: 15px;" type="radio" name="tool" value="erase" id="erase"> <u>E</u>rase
</form>
<form action="">
<input style="margin: default; height: 18px; width: 15px;" type="radio" name="map" value="county" checked> County
<input style="margin: default; height: 18px; width: 15px;" type="radio" name="map" value="state"> State
<input style="margin: default; height: 18px; width: 15px;" type="radio" name="map" value="other"> Other
</form>
</div>
<svg width="960" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jscolor/2.0.4/jscolor.js"></script>
<!--<script src="jscolor.js"></script>-->
<script>
var svg = d3.select("svg");
var path = d3.geoPath();
var tooltip = d3.select("body").append("div").attr("class", "toolTip");
var clickDown = true;
var color_selcounties = [];
for (i = 0; i < 20; i++) {
color_selcounties[getColor(i)] = [];
}
var selectedCounties = [];
var uniqueCounties = [];
var selectedCountiesNum = selectedCounties.length;
var t = [
['color', 'fips']
];
var csvRows = [];
var expArray = [
['color', 'fips']
];
var region = function() {
//Dedupes the list of counties, this ensures no counties are double bucketed.
uniqueCounties = selectedCounties.filter(function(elem, pos) {
return selectedCounties.indexOf(elem) == pos;
});
console.log("Master: " + uniqueCounties);
//Dedupes the list of counties by region.
for (i = 0; i < 20; i++) {
if (color_selcounties[getColor(i)].length >= 1) {
var uniqueColorCounties = color_selcounties[getColor(i)].filter(function(elem, pos) {
return color_selcounties[getColor(i)].indexOf(elem) == pos;
});
console.log(getColor(i) + ": " + uniqueColorCounties);
t.push([getColor(i), uniqueColorCounties]);
}
}
}
var tools = function() {
if (document.getElementById("zoompan").checked) {
alert("zoompan");
} else if (document.getElementById("select").checked) {
alert("select");
} else if (document.getElementById("erase").checked) {
document.body.style.cursor = "pointer";
} else {
}
}
function dl_csv() {
region();
var csvString = expArray.join("%0A");
var a = document.createElement('a');
a.href = 'data:attachment/csv,' + csvString;
a.target = '_blank';
a.download = 'myFile.csv';
document.body.appendChild(a);
a.click();
}
d3.json("https://d3js.org/us-10m.v1.json", function(error, us) {
if (error) throw error;
let hoverEnabled = false;
var mousedown = function() {
if (document.getElementById("select").checked) {
var self = d3.select(this);
hoverEnabled = !self.classed('hovered');
if (hoverEnabled) {
selectedCounties.push(this.__data__.id);
var color = document.getElementById('selcolor').value;
self.classed("c" + color, true);
color_selcounties[color].push(this.__data__.id);
expArray.push([color, this.__data__.id]);
} else {
var ix = selectedCounties.indexOf(this.__data__.id);
selectedCounties.splice(ix, 1);
}
} else if (document.getElementById("erase").checked) {
var self = d3.select(this);
self.classed('deselected', true);
var ix = selectedCounties.indexOf(this.__data__.id);
selectedCounties.splice(ix, 1);
}
}
svg.append("g")
.attr("class", "counties")
.selectAll("path")
.data(topojson.feature(us, us.objects.counties).features)
.enter()
.append("path")
.attr("d", path);
svg.append("g")
.attr("class", "state-borders")
.selectAll("path")
.data(topojson.feature(us, us.objects.nation).features)
.enter()
.append("path")
.attr("d", path);
svg.append("path")
.attr("class", "state-borders")
.attr("d", path(topojson.mesh(us, us.objects.nation, function(a, b) {
return a !== b;
})));
svg.append("path")
.attr("class", "state-borders")
.attr("d", path(topojson.mesh(us, us.objects.states, function(a, b) {
return a !== b;
})));
svg.append("path")
.attr("class", "county-borders")
.attr("d", path(topojson.mesh(us, us.objects.counties, function(a, b) {
return a !== b;
})));
svg.selectAll('.counties path')
.on('mousedown', mousedown)
.on('mouseup', function() {
hoverEnabled = false;
})
.on('mouseover', function() {
tooltip
.style("left", 500 + "px")
.style("top", 70 + "px")
.style("display", "inline-block")
.html(this.__data__.id);
var color = document.getElementById('selcolor').value;
var self = d3.select(this);
if (hoverEnabled) {
self.classed("deselected", false);
self.classed("c" + color, true);
selectedCounties.push(this.__data__.id);
color_selcounties[color].push(this.__data__.id);
expArray.push([color, this.__data__.id]);
}
})
.on('mouseout', function(d) {
tooltip.style("display", "none");
});
});
</script>
最佳答案
当你这样做时......
self.classed("c" + color, true);
您只是添加类(以“十六进制顺序”),而不是删除现有类。
因此,您的元素将有多个类...
class = "foo bar baz"
... 并且流行颜色将是样式表中最后一个类 设置的颜色,它解释了您现在看到的行为。
解决方案:一个简单的解决方案就是将其更改为:
self.attr("class", "c" + color);
它会覆盖任何以前存在的类。对其他 classed
函数执行相同的操作。
这是您的工作代码:https://jsfiddle.net/zbvxk4xv/
关于javascript - 如果我选择索引值大于当前颜色索引的颜色,则只能覆盖通过 mousedown 应用的颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43132603/