Extract information from an array for specific keys without applying any filters

My d3 pie chart reads data from a JSON file, which in this example is represented as an array variable. Some of the key names are not very descriptive, so I am attempting to use a map function to replace certain strings with more meaningful ones. However, there are also key names that I'm fine with and want to keep as they are. If a key name is not defined in my function, it returns undefined and the names are not added to the legend.

While I know all the key names, I prefer to skip over the ones I haven't specifically defined, allowing them to remain unchanged. This way, if new keys are added to the data, the code remains versatile. In a previous test where all key names were declared, while it no longer threw undefined errors, it still didn't add the new key names to the legend.

You can find the full implementation on JSFiddle: https://jsfiddle.net/lharby/ugweordj/6/

Below is a truncated version of my JavaScript function:


var w = 400,
    h = 400,
    r = 180,
    inner = 70,
    color = d3.scale.category20c();

data = [{"label":"OOS", "value":194}, 
        {"label":"TH10", "value":567}, 
        {"label":"OK", "value":1314},
        {"label":"KO", "value":793},
        {"label":"Spark", "value":1929}];

mapData = data.map(function(d){
    if(d.label == 'OOS'){
        return 'Out of scope';
    }else if(d.label == 'TH10'){
        return 'Threshold 10';
    }else{
       // For other keys, no modification needed
        continue;
    }
});

var total = d3.sum(data, function(d) {
    return d3.sum(d3.values(d));
});

var vis = d3.select("#chart")
    .append("svg:svg")
    .data([data])
    .attr("width", w)
    .attr("height", h)
    .append("svg:g")
    .attr("transform", "translate(" + r * 1.1 + "," + r * 1.1 + ")")

var arc = d3.svg.arc()
    .innerRadius(inner)
    .outerRadius(r);

var pie = d3.layout.pie()
    .value(function(d) { return d.value; });

var arcs = vis.selectAll("g.slice")
    .data(pie)
    .enter()

arcs.append("svg:path")
    .attr("fill", function(d, i) { return color(i); })
    .attr("d", arc);

var legend = d3.select("#chart").append("svg")
    .attr("class", "legend")
    .attr("width", r)
    .attr("height", r * 2)
    .selectAll("g")
    .data(mapData) 
    .enter().append("g")
    .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

legend.append("rect")
    .attr("width", 18)
    .attr("height", 18)
    .style("fill", function(d, i) { return color(i); });

legend.append("text")
    .attr("x", 24)
    .attr("y", 9)
    .attr("dy", ".35em")
    .text(function(d) { return d.label; }); 

The HTML structure consists of a single element with an ID of #chart.

Answer №1

To iterate through your data and modify specific labels while leaving others unchanged, you can utilize the .forEach() method:

data = [{"label":"OOS", "value":194}, 
        {"label":"TH10", "value":567}, 
        {"label":"OK", "value":1314},
        {"label":"KO", "value":793},
        {"label":"Spark", "value":1929}];

data.forEach(d => {
  if(d.label == 'OOS'){
    d.label = 'Out of scope';
  } else if(d.label == 'TH10'){
    d.label = 'Threshold 10';
  }
});

console.log(data);

Answer №2

It is not possible to skip elements when using map. However, you can achieve this by utilizing reduce:

var data = [
    {"label":"OOS", "value":194}, 
    {"label":"TH10", "value":567}, 
    {"label":"OK", "value":1314},
    {"label":"KO", "value":793},
    {"label":"Spark", "value":1929}
];

var mapData = data.reduce(function(result, d) {
    if (d.label == 'OOS') {
        result.push('Out of scope');
    } else if (d.label == 'TH10') {
        result.push('Threshold 10');
    };
    return result;
}, []);

console.log(mapData)

UPDATE: Following your feedback, the desired outcome is now clearer. You can use map to accomplish this task by returning the property's value:

var data = [{"label":"OOS", "value":194}, 
        {"label":"TH10", "value":567}, 
        {"label":"OK", "value":1314},
        {"label":"KO", "value":793},
        {"label":"Spark", "value":1929}];

var mapData = data.map(function(d) {
  if (d.label == 'OOS') {
    return 'Out of scope';
  } else if (d.label == 'TH10') {
    return 'Threshold 10';
  } else {
    return d.label
  }
});

console.log(mapData);

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

Having trouble retrieving the webpage title using Cucumber-Protractor

Hey there! I'm facing an issue with Cucumber-Protractor where I can't seem to console log the webpage title in the "Given" tag, even though all my tests are passing. I've checked my Protractor.conf.js file and it looks fine to me. Here&apos ...

Page loaded with activated Flash functionality

Curious if there's a way, To have my flash map on the site automatically activated upon page load, as opposed to requiring a click to interact with it. I've noticed that some websites already have their flash content active when the page loads, ...

Jquery functionality fails to execute post-Ajax request

Here is the function in question: $(document).ready(function() { $('.post_button, .btn_favorite').click(function() { //Fade in the Popup $('.login_modal_message').fadeIn(500); // Add the mask to body $('body').append(' ...

Using the .get() method to retrieve Firebase documents results in an error message saying "'is not a function'"

I'm currently attempting to retrieve all the documents from a specific collection in Firebase using the following code snippet: const userCollectionRef = collection(db, currentUser?.uid) const snapshot = await userCollectionRef.get() for (const doc of ...

Synchronize custom directive controller data with data from a factory

As a newcomer to angularjs, I stumbled upon this example that I found somewhere and it works perfectly well. However, I am puzzled by how the data within the customized directive controller remains synchronized with the factory data. Here is the snippet of ...

ES6/When.js - Dealing with promise fulfillment within a recursive chain of promises

I am currently implementing a promise chain that is recursive, meaning it calls itself until a value reaches zero. The functionality works as expected, however, I noticed that when the promise finally resolves, the output contains extra "undefined" values. ...

Hydration has finished, but there are some discrepancies - Utilizing Ascii art within a vue component

I encountered an issue with displaying ascii art in the {{ name }} section of my component. While developing, a Vue warning popped up: Hydration text content mismatch in <pre> Followed by an error message: Hydration completed but contains mismatch ...

Alter the truth value of an item contained within an array

Embarking on my JavaScript journey, so please bear with me as I'm just getting started :) I am working on a small app where the images on the left side are stored in an array. When a user clicks on one of them, I want to change its height and also tog ...

Executing additional code after all tests have finished in Mocha.js

In the world of MochaJS testing, it is customary to have before and after blocks for setup and teardown operations. But what if we want to execute an extra cleanup step after all test files have been processed? This is crucial to ensure that any lingering ...

Restrict mxgraph cell dragging to the bounds of the canvas width

I am dealing with a situation where there are multiple vertex cells in a graph and I am utilizing the JavaScript library mxGraph. The issue arises when I drag a cell from the edge of the canvas, causing it to extend beyond the canvas boundaries. I am seeki ...

Why is it that one function does not hold off on execution until Promise.all() is resolved in another function?

I am currently working on a form that allows users to upload files seamlessly. <form @submit.prevent="sendForm" enctype="multipart/form-data"> <input multiple ref="PostFiles" name="PostFiles" type="file" @change="selectFile('add')"> ...

tips for choosing a specific dropdown menu item

I'm having an issue with a function that I want to apply to all my dropdown lists. The problem arises when I try to select an option from the second dropdown list - instead of displaying the correct value, it shows the value from the first group in th ...

What is the best way to access specific information about the top card in a Trello list?

Is there a way for me to retrieve the name, label, and due date of the top cards in a Trello list on my board and then send it through Discord using my bot? I would greatly appreciate any guidance on how to achieve this. ...

Tips for concealing the Google Chrome status bar from appearing on a webpage

I have been intrigued by the rise of Progressive Web Apps (PWAs) and I am eager to dive into understanding them better. One common feature I have noticed in PWAs is the ability to hide the browser chrome, including the URL bar, back button, search fields, ...

What is the best way to add custom text to the URL input field of the CKEditor image/link dialog?

Hey everyone, I've been working with CKEditor 4 on my project and I'm facing a challenge. I need to insert a string into the URL textfield in the image or link dialog window using JavaScript/jQuery. Here's where I'm stuck: https://i.ss ...

Angular - ng-repeat failing to update when nested array is modified

Utilizing ng-repeat to render data fetched via a GET request that returns an array. HTML <div ng-controller="candidateCtrl" > <div class="table-responsive"> <table class="table table-striped"> <thead> ...

What is the best way to handle errors that occur asynchronously without using promises in order to respond to those specific errors?

I have searched for answers but none seem to directly address my specific question. My current usage involves the pattern shown below: class A { getLocation() { return Promise.reject(2222222) } async a() { try ...

Utilizing ng-options within an ng-repeat to filter out previously chosen options

Facing a simple problem and seeking a solution. I am using ng-repeat to dynamically create select boxes with ng-options displaying the same values. The ng-repeat is used to iterate through model options. <div data-ng-repeat="condition in model.condit ...

How can you access the index of an object in Vue.js when one of its properties has been modified

Here's the Vue component code I'm working with: data: function () { return { products: [ { product_id: '', price: ''}, { product_id: '', price: ''}, ], ...

Incorporate Ruby's embedded helpers with jQuery for advanced functionality

How do I properly add a ruby helper to iterate through an active record response? I attempted to do so with the following code (.html or .append): $( ".result" ).html('<%= @products.each do |product| %><label>product</label><% e ...