Determining the decimal power using the position of a for-loop

After selecting a number, the task is to generate circles using d3.js. Each circle will be assigned a color from an array:

var color =["red", "blue", "yellow", "orange",.....] 

● For instance, if the user picks 593, the first 500 circles should be red (color[0]), the next 90 blue (color[1]), and the last 3 yellow (color[2]) because

593 = 500 + 90 + 3 = 5 * 10^2 + 9 * 10^1 + 3 * 10^0 

or with

var number = 593
var number_as_array = number.toString().split(''); 

Hence,

593 = 5 * number_as_array[0] * 10^(number_as_array.length - 1) + 9 * number_as_array[1] * 10^(number_as_array.length - 2) + 3 * number_as_array[2] * 10^(number_as_array.length - 3)

● If the chosen number is 4168, then 4000 circles will be red, the following 100 blue, another 60 yellow, and the remaining 8 orange.

To set the color for each circle, an array of JS objects is created using a for loop:

var data=[]
for (index = 0; index < number; index++){
circle= {};
        circle.cx = circle_x;
        circle.cy = circle_y;
        circle.color = color[????]
        data.push(circle);

The challenge lies in how to assign colors to circle.color based on the mentioned criteria?

Answer №1

Not to take away from the previous response, here is another way to approach the problem.

Given a total number of circles, this method determines how many significant digits of the total are needed (rounding down) so that any given index is less than the rounded total.

If we have 132 circles in total:

  • Indexes 0 through 99 will be less than 100 (132 rounded down with one significant digit).

  • Indexes 100 through 129 will be less than 130 (132 rounded down with two significant digits).

  • Indexes 130 and 131 will be less than 132 (132 with all significant digits).

Here's a visual representation (each row represents 50 circles):

var svg = d3.select("body")
  .append("svg")
  .attr("width",510)
  .attr("height",510);
  
var n = 377;

var color = d3.scaleOrdinal()
.range(["steelblue","orange","crimson","lawngreen","pink"])

var digits = Math.floor(Math.log10(n));

var circles = svg.selectAll("circle")
  .data(d3.range(n))
  .enter()
  .append("circle")
  .attr("cx",function(d,i) { return i%50 * 10 + 5 })
  .attr("cy",function(d,i) { return Math.floor(i/50) * 10 + 5 })
  .attr("r",5)
  .attr("fill", function(d,i) {
    var exp = digits;
    while (i < Math.floor(n/Math.pow(10,digits-exp))*Math.pow(10,digits-exp)) {
      exp--;
    }
    return color(exp);
  })
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

Answer №2

let colors = ["red","orange", "yellow", "green", "blue", "indigo", "violet"];
let totalCircles = "4192"; // make sure to keep as string
let len = totalCircles.length;
let circleArray = [];
for (let x = 0; x < len; x++) {
    let digitValue = totalCircles.substring(x, x+1);
    let exponentVal = len - x - 1;
    let finalNumber = digitValue * Math.pow(10, exponentVal);
    circleArray.push(finalNumber); // consider using .unshift instead of .push
}
console.log(circleArray);
for (let y = 0; y < circleArray.length; y++) {
    for (let z = 0; z < circleArray[y]; z++) {
        drawCircle(colors[y]);
    }
}

Answer №3

If you're looking for an ideal scenario to utilize D3's Threshold Scales, this is it: input N numbers to indicate color breaks, and receive N+1 colors back for any given value. Take a look at this example straight from the documentation:

var color = d3.scaleThreshold()
    .domain([0, 1])
    .range(["red", "white", "green"]);

color(-1);   // "red"
color(0);    // "white"
color(0.5);  // "white"
color(1);    // "green"
color(1000); // "green"

In your case, the task is figuring out how to transform your input (e.g., 593) into the array of two numbers [500, 590]:

var sinput = 593 + ""; // convert input to string
var digits = sinput.split("").slice(0, -1); // utilize all digits except the last one
var breaks = digits.map((d, i, a) =>
    +(a.slice(0, i+1).join("")) * Math.pow(10, a.length-i)
);

var colors = ["red", "blue", "yellow", "orange"];
var tScale = d3.scaleThreshold()
    .domain(breaks)
    .range(colors);

Values less than 500 are labeled "red," those between 500 and 589 are "blue," and anything greater than or equal to 590 becomes "yellow." The fourth color in the range ("orange") remains unused unless handling a four-digit number as input.

Note: This method assumes the input will be at least two digits long.

Now, instead of pre-defining colors in the data array, you can dynamically assign them during circle creation with code like

.attr("color", (d, i) => tScale(i))

Answer №4

The proposed solutions appear to be excessively intricate. One method involves breaking down the number into individual digits and then creating 10^digitIndex circles with colors corresponding to the index of each digit. A precautionary line has been included to ensure that the number is not too large.

function mapColors(num) {
  var color =['red','blue', 'yellow', 'orange'];
  
  // Check if the number exceeds the length of the color array
  if ((''+num).length > color.length) return;
  
  return (''+num).split('').reduce(function (acc, n, i, arr) {
    for (var j=n*Math.pow(10, arr.length-i-1); j; --j) {
      acc.push({'color':color[i]});
      // Add additional circle properties here
    }
    return acc;
  }, []);
}

console.log(mapColors(23));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Concerns regarding the set-up of the latest React application

My goal is to become proficient in React, so I decided to install Node.js (v 10.16.0 LTS) and run the following commands using Windows Powershell: npx create-react-app my-app cd my-app npm start However, after making changes to the code (such as modifyin ...

Is it possible to dynamically adjust the Semantic UI Progress bar according to the data stored in mongoDB?

I am facing an issue with displaying the progress of a job on the UI in real-time. Every 5 seconds, I retrieve the job progress and store it in mongoDB. I tried using Semantic UI progress bar in my meteor project, but the progress is not incrementing as ex ...

Bootstrap modal's offset returning blank value

One way to navigate to a specific element within a Bootstrap modal is by checking the offset of that particular element. If there are multiple divs within the modal, each with its own unique id (#row-1, #row-2, etc.), you can open the modal and input the f ...

Optimizing Window Width with React.js and CSS

I'm currently in the process of building a responsive website with react. I am utilizing CSS stylesheets for styling and have used @media queries to ensure responsiveness. However, I've encountered an issue while testing in Chrome where the elem ...

Is it possible to retrieve text from various iframes using the rangy library?

Here's a question that follows up on a problem I've been having with grabbing selected text from iframes using rangy. The code works well for the first iframe, but when I try to grab elements from multiple iframes using the same button, it doesn& ...

Problem with the WP Rocket helper plugin that excludes JS scripts from Delay JS only at specific URLs

Looking for assistance with a helper plugin that excludes scripts from "Delay Javascript Execution"? You can find more information about this plugin here. The specific pages where I want to exclude slick.min.js and jquery.min.js are the home page and tabl ...

What steps need to be taken to implement a structured autocomplete feature?

Let me break down the workflow for you: The user inputs something in a text field. Upon keypress, the frontend communicates with our backend script to retrieve and select a specific value. Once the value is selected, on leaving the input field, we query ...

Is there a way to update the parent value when the child is activated?

I need to create a dropdown menu for users to select their email provider - either gmail, hotmail, or outlook. Once they make a selection, I want the button text to update accordingly. The catch is that I can only use bootstrap for this project and cannot ...

Using v-for to show the values of an object in Vuetify

I am currently developing a function in vuejs that allows users to select tables from a database, with the columns' names automatically appearing in a v-list-item component. However, I am facing difficulty in displaying these column names effectively. ...

Integrate Chrome extension using code

Is there a way to programmatically load a Chrome extension? Can it be done using web driver with external extension preferences, or perhaps through JavaScript or another scripting language? ...

"Error: Command 'npm' is not recognized as a valid internal or external command" encountered while using create-react-app

Why won't npm work for me? I've been trying to dive into the world of React and kickstart my learning journey. With Node installed, along with the create-react-app package, I thought I was all set. When I run commands like npm -v or create-reac ...

Issues with debuggers in Chrome and Firefox with AngularJS are causing frustration for developers

Currently, I am in the process of developing a hybrid application that combines AngularJS with Angular 8. As part of my testing procedure, I am attempting to debug the application. However, I have encountered an issue where the debuggers function properly ...

Troubleshooting async/await issues in certain IDEs

I've been experimenting with aysnc and await in my project. While it worked perfectly in FiddleJS, I encountered an error when trying to implement it in my IDE (PHPSTORM 2017): async function test(url){ ^^^^^^^^ SyntaxError: Unexpected token f ...

Troubleshooting script not detecting changes in form

I am currently implementing a script to detect any changes in the form fields and notify the user if there are any. However, instead of triggering the alert box as intended, a different JavaScript box is displayed. Despite my efforts, the script is not re ...

I need to press the button two times to successfully submit

I am experiencing a remote validation issue. When I click on the submit button without focusing on the text box, it triggers a remote ajax call for validation. However, when I press the submit button a second time, the form gets submitted. On the same cl ...

Connect main data to sub-component

Example Vue Structure: <Root> <App> <component> Main function in main.js: function() { axios.get('/app-api/call').then(function (resp, error) { _this.response = resp.data; }) ...

Alter the navigation but keep the URL intact without modifying the view

I have an Angular project that includes a login component. The login component is located in the directory app/main/login. I am trying to navigate to the login component from app.component.html using a button. Below is the code snippet from my app-routi ...

"Successful implementation of Ajax function in local environment but encountering issues when running online

I am facing an issue with my AJAX function. It works perfectly fine on my local server but does not return anything when I move it to my online server. Below is the code snippet: This is the part of the page where I call the showEspece() function: echo ...

The onClick event is not functioning properly with React's select and option elements

Looking for a way to get the option value from each region? const region = ['Africa','America','Asia','Europe','Oceania']; <div className="options"> <select> ...

Utilizing Vue to Embed Multiple Hubspot Forms on one Page

While working on a Vue page, I encountered an issue with loading multiple Hubspot forms simultaneously. Only one form would load at a time. Here is the code snippet I used to append a single Hubspot form: mounted() { const script = document.createElem ...