2

D3 Drag Drop Example

I am working through the Drag Drop Example an would like to read in data from a csv.

I would like to reformat the returned data from my csv file into a needed format. In a drag and drop scenario, the dragged element has a value from Array[3] and is dropped on an element with r1val(n). When those values match an event occurs. I would like to find a way to set the values of the first column as key as shown in the Object below.

file.csv:

  col1,col2,col3,col4
  r1val1,r1val2,r1val3,r1val4
  r2val1,r2val2,r2val3,r2val4
  ....

needed format:

  var colSet = {
  r1val1 : ["r1val2","r1val3","r1val4"],
  r2val1 : ["r2val2","r2val2","r2val2"],
  ...
  } 

console.log of needed format:

Object
  r1val1: Array[3]
  r2val1: Array[3]
  ...
__proto__: Object

My target is this function:

var DragDropManager = {
    dragged: null,
    droppable: null,
    draggedMatchesTarget: function() {
        if (!this.droppable) return false;
        return (colSet[this.droppable].indexOf(this.dragged) >= 0);
    }
}
2
  • stackoverflow.com/questions/23762822/… You can parse with jquery but that might not be best. Commented Aug 7, 2015 at 16:44
  • @DotDotBeep - I have included the function where the object is needed. Commented Aug 7, 2015 at 16:58

3 Answers 3

1

This generates a d3.map instead of a JavaScript object, but should work for your situation (you can still access elements like an object with obj[key]):

d3.csv('test.csv',function(error,rows){

    var obj = d3.map(rows, function(d){
      return d.col1;
    });
    obj.forEach(function(k,v){
      this[k] = [v.col2, v.col3, v.col4];
    });

    console.log(obj);
  });

Example here.

At this point, we are both overthinking it, how about:

d3.csv('test.csv', function(error, rows) {
  var obj = {};
  rows.forEach(function(d){
    obj[d.col1] = [d.col2, d.col3, d.col4];
  });
  console.log(obj);
});

Updated example.

Sign up to request clarification or add additional context in comments.

2 Comments

Mark I have used d3.map, so far it did not work, I will try again. The function in my 'UPDATE' does create the correct format, but once per row. I have a merge function for objects that works, now I have to figure out how to use it with a loop.
@EdDie, see new answer. We are both getting too fancy :)
0
d3.csv("data/language.csv", function(error, data) {


//reformatting data array content stripping 'key' and 'value'


var refData = data.map(function(d){ 
var rObj = {};
rObj[d.col1] = d.col3;
return rObj;
});


// function that merges Objects
function merge(target, source) {      
    /* Merges two (or more) objects,
   giving the last one precedence */   
if ( typeof target !== 'object' ) {
    target = {};
}   
for (var property in source) {      
    if ( source.hasOwnProperty(property) ) {          
        var sourceProperty = source[ property ];         
        if ( typeof sourceProperty === 'object' ) {
            target[ property ] = util.merge( target[ property ],    sourceProperty );
            continue;
        }        
        target[ property ] = sourceProperty;          
    }     
}    
for (var a = 2, l = arguments.length; a < l; a++) {
    merge(target, arguments[a]);
}   
return target;
};


//loops through the refData creating dwarfSet
for (i = 0; i < refData.length; i++) {
var dwarfSet = merge(refData[0],refData[i]);
};

This code actually produces the desired Object. I am not entirely happy with the loop function as it produces one dwarfSet per row, and not one overall.

Suggestions for improvement are very welcome.

Comments

0

I think this can be done simply with:

var obj = d3.nest()
  .key(function(d) { return d.r1val1; })
  .entries(data);

http://learnjsdata.com/group_data.html

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.