简体   繁体   中英

How can I change the color of a circle created via d3 each time I click the mouse?

I have researched this pretty thoroughly on stackoverflow as well as the rest of the internet. The problem I am having is with d3 and having a circle change color each time the mouse is clicked.

The Idea: I have already implemented working code to add a circle each time the mouse is clicked showing where the person clicked. However, I want the color of each circle and thus each click to be different. I have looked into a toggle feature but that doesn't change the color of each circle created via each click.

Here is the code so far:

HTML:    
<svg class="plot">
</svg>

CSS:
.plot 
{
    background-color: #000;
    width: 500px;
    height: 500px;
}

JavaScript:
(function() {
    var svg = d3.select('svg');

    function drawCircle(x, y, size) {
        console.log('Drawing circle at', x, y, size);
        svg.append("circle")
            .style("fill","red")
            .attr("cx", x)
            .attr("cy", y)
            .attr("r", size);
    }

    svg.on('click', function() {
        var coords = d3.mouse(this);
        console.log(coords);
        drawCircle(coords[0], coords[1], 5);
    });


})();

Any help would be great! Also here is the jsfiddle link: https://jsfiddle.net/pwilliams/2yczn6q3/

Use this:

svg.style("fill",'#'+Math.floor(Math.random()*16777215).toString(16));

as the function :

'#'+Math.floor(Math.random()*16777215).toString(16);

would return an Hex number from 000000 to FFFFFF.

Ps: 16777215 is FFFFFF in decimale.

Hope this helped you.

You need to provide a different value for the style("fill", ...) property on each circle. This will cause each new circle to have a different color but will not change the color of existing circles (that is somewhat more complex).

If you want a random selection from a prepared list of colors, you should create an array of colors (by name or hex code) and a function to return a random color. Each time you draw a circle, call the function and it will select and return a color from the array.

Something like so:

 var colors = ["red", "green", "blue", "yellow", "orange", "purple", "gray"]; function getColor() { return colors[Math.round(Math.random() * colors.length)]; } (function() { var svg = d3.select('svg'); function drawCircle(x, y, size) { console.log('Drawing circle at', x, y, size); svg.append("circle") .style("fill", getColor()) .attr("cx", x) .attr("cy", y) .attr("r", size); } svg.on('click', function() { var coords = d3.mouse(this); console.log(coords); drawCircle(coords[0], coords[1], 5); }); })(); 
 .plot { background-color: #000; width: 500px; height: 500px; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <svg class="plot"> </svg> 

To use the colors in order, you would just keep a counter like:

var colors = ["red", "green", "blue", "yellow", "orange", "purple", "gray"];
var colorState = 0;

function getColor() {
  var color = colors[colorState];
  colorState = (colorState + 1) % colors.length; // keep it from going OOB
  return color;
}

With the help of this answer for the random color, here is what you could do:

(function() {
    var svg = d3.select('svg');

    function getRandomColor() {
        var letters = '0123456789ABCDEF'.split('');
        var color = '#';
        for (var i = 0; i < 6; i++ ) {
            color += letters[Math.floor(Math.random() * 16)];
        }
        return color;
    }

    function drawCircle(x, y, size) {
        console.log('Drawing circle at', x, y, size);
        svg.append("circle")
            .style('fill',getRandomColor())
            .attr("cx", x)
            .attr("cy", y)
            .attr("r", size);
    }

    svg.on('click', function() {
        var coords = d3.mouse(this);
        console.log(coords);
        drawCircle(coords[0], coords[1], 5);
    });


})();

I updated you jsFiddle: https://jsfiddle.net/2yczn6q3/19/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM