javascript - 如果我选择索引值大于当前颜色索引的颜色,则只能覆盖通过 mousedown 应用的颜色

标签 javascript html css arrays d3.js

我的简单绘图软件允许将不同的颜色应用于县。我一直在努力解决一个相当奇怪的错误,它只允许索引值大于当前颜色索引的颜色覆盖颜色。

代码很长,但我不确定如果不粘贴整个代码是否可以说明问题。我将从主要部分开始:

这是填充十六进制颜色数组的 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/

相关文章:

html - border curved css - 带 flex 端的圆

javascript - jquery循环遍历 anchor 以匹配悬停 anchor 的类并应用css

javascript - 如何使用jquery删除重复的meta标签?

javascript - 是否可以向任何 slider 控件添加单击事件

javascript - 将自定义服务插入 UI 路由

java - 如何用引号在 Thymeleaf 问题中添加 <i class ="something"></i>

javascript - 为什么无法解析此 JSON 对象?

javascript - 通过 HTTPS 的 Soundcloud API

html-顶部菜单和正文冲突

JQuery JQGrid - 如何在不触及网格线的情况下使 CSS 右/左对齐?