What are some ways to streamline this D3 script?

My CSV data displays pass rates by organisation for different years:

org,org_cat,2004_passed,2004_total,2005_passed,2005_total,2006_passed,2006_total
GSK,industry,35,100,45,100,55,100

I am using D3 and aiming to create a dictionary of organisations structured as follows:

data = {
 'GSK': {
     'org_cat': 'industry',
     'data': [
        { 'year': 2004, 'passed': 35, 'total': 100 },
        { 'year': 2005, 'passed': 45, 'total': 100 },
        { 'year': 2006, 'passed': 55, 'total': 100 }
     ]
  ]
}

The process seems clear except for the messy code handling the year columns:

var data = {};
allData.forEach(function(d) {
  data[d.org] = {
    'category': d.org_cat,
    'data': []
  };
  for (var k in d) {
    var temp = {};
    for (var k in d) {
      if (patt.test(k)) {
        var res = k.split("_");
        if (res[0] in temp) {
          temp[res[0]][res[1]] = +d[k];
        } else {
          temp[res[0]] = {};
          temp[res[0]][res[1]] = +d[k];
        }
      }
    }
    var tempArr = [];
    for (var y in temp) {
      var tempDict = {};
      tempDict.year = y;
      tempDict.passed = temp[y].passed;
      tempDict.total = temp[y].total;
      tempArr.push(tempDict);
    }
    // TODO: sort by year in case the keys got shuffled
    data[d.org].data = tempArr;
  }
});

Is there a simpler way to clean up this complex code?

We can assume each row represents a unique organisation.

Answer №1

There's no need for D3 in this scenario, as your code doesn't utilize it either. Below is an approach I would take, which might not be the most straightforward method, but it could still benefit you:

Check out the Jsfiddle example here: https://jsfiddle.net/thatOneGuy/dnvheznk/1/

In my implementation, I converted the data to JSON for JSFiddle usage. However, since you are already familiar with looping through CSV, simply update line 14 as follows:

for (var i = 0; i < data.length; i++) { //loop through data array (this allows scalability for larger arrays) 

You can modify it like this:

allData.forEach(function(d, i) { //make sure to add 'i' for indexing

The fully commented code with converted JSON data is provided below:

var data = [{ //data set converted to JSON for easier use
  "org": "GSK",
  "org_cat": "industry",
  "2004_passed": 35,
  "2004_total": 100,
  "2005_passed": 45,
  "2005_total": 100,
  "2006_passed": 55,
  "2006_total": 100
}];

var newData = {}; //new data container

for (var i = 0; i < data.length; i++) { //loop through data array (this is so you can use this on a bigger sized array)
  var thisObj = {}; //create empty object
  thisObj.org_cat = data[i].org_cat; //set org_cat
  thisObj.data = []; //initialize data array to populate later

  for (var key in data[i]) { //iterate through data[i]
    if (key != 'org' && key != 'org_cat') { //ensure the key is neither 'org' nor 'org_cat'
      var thisData = {}; //initialize data object
      var thisYear = key.toString().substring(0, 4); //extract year using substring

      thisData.year = thisYear; //assign year
      thisData.passed = data[i][thisYear + '_passed']; //assign passed value for this year
      thisData.total = data[i][thisYear + '_total']; //assign total value for this year

      thisObj.data.push(thisData); //add current data object to the data array
    }
  }

  var uniqueDates = []; //store unique items from the data array
  for (var j = 0; j < thisObj.data.length; j++) { //iterate over the data array created earlier
    if (uniqueDates.indexOf(thisObj.data[j].year) < 0) { //if the current year is not included in the unique array
      uniqueDates.push(thisObj.data[j].year); //add it
    } else {
      thisObj.data.splice(j--, 1); //remove duplicate data
    }
  }

  newData[data[i].org] = thisObj; //associate the data of the current organization with the object created above
}

console.log('newData', newData) //output new data

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

Updating the chosen option using jQuery

Is there a way to change the currently selected option using jQuery? <select name="nameSelect" id="idSelect"> <option value="0">Text0</option> <option value="1">Text1</option> <option value="2" selected>Text ...

Tips on serving a static file from a location other than the public or view directories following middleware in Express JS

I am organizing my files in a specific way. Inside the folder api-docs, I have an index.html file along with some CSS and JS files. My goal is to display the API documentation only for authenticated users. Since I am using Jade for views in this proje ...

Tips for fixing the "Uncaught TypeError: Cannot access property 'get' of undefined" error in Vue.JS 2

Here is my component: methods: { reloadMessage() { setTimeout(function () { this.$http.get(window.BaseUrl + '/message/inbox'); }, 1500); } } And here are my routes: Route::group(['prefix' => &ap ...

The rule "react/jsx-sort-props" does not have a valid configuration

I've been attempting to organize props names alphabetically using the eslint-plugin-react plugin but I keep encountering this error: [Error ] .eslintrc.json: Configuration for rule "react/jsx-sort-props" is invalid: Value {"callbacksLast":true,"shorth ...

Is it possible to utilize the node package ssh2 within a web browser environment?

I am working on a project for school where I am creating an SFTP client directly in my browser. I have successfully implemented the node package ssh2 and it works perfectly when running the code in the terminal. I can connect to the server, read directorie ...

What is the best way to recover past messages from a channel?

I am working on a bot that is supposed to be able to retrieve all messages from a specific server and channel upon request. I attempted to use the channel.messages.cache.array() method, but it only returned an empty array []. How can I efficiently fetch ...

Persistent vertical menu dropdown that remains expanded on sub menu pages

I am struggling to understand how to keep my menu sub items open when on the active page. Although I have tried similar solutions, I have not been successful in implementing them. I apologize if this question has been asked before. My approach involves usi ...

The array is present both before and after the res.json() call, however it appears empty in the response

When using Express to send a json response with res.json(), I am experiencing an issue where the value of records in the object sent via res.json() is empty. My code snippet looks like this: stats.activities(params).then(res => { processActivities ...

Charts created using Google VisualizationORThe visual representations

My chart is currently not displaying at 100% width as I intended. I would like the chart to span from the beginning to the end of the container. https://i.stack.imgur.com/Xjw6g.png Here's my code snippet: test.controller('testCtrl', [&apo ...

What is the best way to display three unique maps simultaneously on separate views?

In this scenario, I have incorporated three separate divs and my goal is to integrate three maps into them. The javascript function that controls this process is as follows: function initialize() { var map_canvas1 = document.getElementById('map_canva ...

Generate a new tree structure using the identifiers of list items within an unorganized list

Attempting to convert the id's of li's in a nested unordered list into valid JSON. For example, consider the following list. To be clear, the goal is not to create the UL list itself, but rather the JSON from the li id's <ul class="lis ...

What is the proper way to reference a computed symbol that has been inherited as a function in an extended class

As a newcomer to Typescript, my understanding of the code might be lacking. I am currently working with the Klasa framework, which is built on top of Discord bot framework using Discord.js. The framework recently introduced plugin functionality and there a ...

Display a substitute image if there is no internet connection available to load the Google Map Canvas

I have a WebApp that runs locally, but it's possible that users may not always have access to 3G/WiFi when using the app. This means that the Google Map will not load without an internet connection since it requires the web API. In order to provide a ...

The button component in my React application is not functioning as expected, despite utilizing the useState and useEffect hooks

I'm having trouble with my Button not working, even though I am using useState and useEffect Check out the code below: import React, { useState, useEffect } from "react"; // import Timeout from "await-timeout"; import ...

Using Jquery to target an element within the same DOM element and apply changes

My website platform doesn't assign any IDs or classes to the menus it generates, and uses nested lists for submenus. To make the submenus expand upon clicking, I created a jQuery script: $(function () { $(".wrapper ul li").click(function () { ...

Is there a way to track when the Angular DTOptionsBuilder ajax call is complete and trigger a callback function?

Working with angular datatables, I have the following code: beforeSend:

success callback causes the table on the page not to populate with the data. How can I implement a callback that triggers once the ajax is done without interfering with the nor ...

In TypeScript, it can be challenging to determine the equality between a value and an enum

I am encountering an issue with my simple code: enum Color { BLUE, RED } class Brush { color: Color constructor(values) { this.color = values.color } } let JSON_RESPONSE = `{"color": "BLUE"}` let brush = new Brush(JSON.parse(JSON ...

"Patience is key when waiting for an AJAX response within a jQuery loop

I've been facing difficulties in making this work using the $.Deferred object. Here is a simplified version of the code setup. g_plans = []; $(function(){ // Need to utilize a custom ajax function that returns a promise object var pageLoadPro ...

The appearance of an unforeseen * symbol caused a

Having issues with this particular line of code, import * as posenet from '@tensorflow-models/posenet' The error 'Uncaught SyntaxError: Unexpected token *' keeps popping up, I have the latest version of Chrome installed and I've ...

After integrating Redux into React, the map(item) function is unable to send "item" as props to a JSX component

Currently, I am working on integrating Redux into my React application. As part of this process, I have developed four actions to manage the "items" in my application. The initial three actions, namely GET_ITEMS, DELETE_ITEM, and ADD_ITEM, function seamles ...