1

I am trying to dynamically (on_click event) add a new row to an array loaded from a CSV file using d3. The first row has been recognized as headers.

However, the new row data does not update the array correctly?

Date,Mcode,Weight,Reps,Points
2017/06/01,HIPABD,160.0,25,66
2017/06/02,STRETCH,,10,10
2017/06/03,TWISTS,25.0,50,20
2017/06/04,SBENDS,25.0,50,20

Following is the relevant code snippits. Using a row converter to format the date and numeric columns.

I use an on_click event to add the new row.

//Function for converting CSV values from strings to Dates and numbers
        var rowConverter = function(d) {
            return {
                Date:    parseTime(d.Date),
                Mcode:             d.Mcode,              // No Conversion
                Weight:            parseFloat(d.Weight), // convert to floating point
                Reps:              parseFloat(d.Reps),   // convert to floating point
                Points:            parseFloat(d.Points)  // convert to floating point
                    };
                                       }

            // load dataset from csv file
            d3.csv("small_points_data.csv", rowConverter, function(error, csvdata) {
                if (error) {console.log(error);} // error detected, no data loaded
                 else {console.log(csvdata);}   // no error detected, data loaded
                       dataset = csvdata;       // once loaded, copy data to dataset variable


                //On click, update with new data
                d3.select("p")
                    .on("click", function() {

                        //Add one new value to dataset
                        dataset.push([2017/07/22,"SHLPRESS",55.0,10,78]);

Following is the output from the console when inspecting the structure and contents of the array.

First is the original array as loaded from the CSV file; this is fine. Expanded are the last row (3), and the header array

Second is the array after the on_click is executed adding the new row. Expanded are the original last row (3), the new last tow (4), and the headers array.

dataset
(4) [{…}, {…}, {…}, {…}, columns: Array(5)]
0: {Date: Thu Jun 01 2017 00:00:00 GMT-0500 (Central Daylight Time), Mcode: "HIPABD", Weight: 160, Reps: 25, Points: 66}
1: {Date: Fri Jun 02 2017 00:00:00 GMT-0500 (Central Daylight Time), Mcode: "STRETCH", Weight: NaN, Reps: 10, Points: 10}
2: {Date: Sat Jun 03 2017 00:00:00 GMT-0500 (Central Daylight Time), Mcode: "TWISTS", Weight: 25, Reps: 50, Points: 20}

3:
Date: Sun Jun 04 2017 00:00:00 GMT-0500 (Central Daylight Time) {}
Mcode: "SBENDS"
Points: 20
Reps: 50
Weight: 25
__proto__: Object

columns: Array(5)
0: "Date"
1: "Mcode"
2: "Weight"
3: "Reps"
4: "Points"
length: 5
__proto__: Array(0)
length: 4
__proto__: Array(0)



*** after new row added ****

dataset
(5) [{…}, {…}, {…}, {…}, Array(5), columns: Array(5)]
0: {Date: Thu Jun 01 2017 00:00:00 GMT-0500 (Central Daylight Time), Mcode: "HIPABD", Weight: 160, Reps: 25, Points: 66}
1: {Date: Fri Jun 02 2017 00:00:00 GMT-0500 (Central Daylight Time), Mcode: "STRETCH", Weight: NaN, Reps: 10, Points: 10}
2: {Date: Sat Jun 03 2017 00:00:00 GMT-0500 (Central Daylight Time), Mcode: "TWISTS", Weight: 25, Reps: 50, Points: 20}

3:
Date: Sun Jun 04 2017 00:00:00 GMT-0500 (Central Daylight Time) {}
Mcode: "SBENDS"
Points: 20
Reps: 50
Weight: 25
__proto__: Object

4: Array(5)
0: 13.0974025974026
1: "SHLPRESS"
2: 55
3: 10
4: 78
length: 5
__proto__: Array(0)

columns: Array(5)
0: "Date"
1: "Mcode"
2: "Weight"
3: "Reps"
4: "Points"
length: 5
__proto__: Array(0)



**** this is the new row with nothing expanded ****

(5) [{…}, {…}, {…}, {…}, Array(5), columns: Array(5)]
0: {Date: Thu Jun 01 2017, Mcode: "HIPABD", Weight: 160, Reps: 25, Points: 66}
1: {Date: Fri Jun 02 2017 00:00:00 GMT-0500 (Central Daylight Time), Mcode: "STRETCH", Weight: NaN, Reps: 10, Points: 10}
2: {Date: Sat Jun 03 2017 00:00:00 GMT-0500 (Central Daylight Time), Mcode: "TWISTS", Weight: 25, Reps: 50, Points: 20}
3: {Date: Sun Jun 04 2017 00:00:00 GMT-0500 (Central Daylight Time), Mcode: "SBENDS", Weight: 25, Reps: 50, Points: 20}
4: (5) [13.0974025974026, "SHLPRESS", 55, 10, 78]
columns: (5) ["Date", "Mcode", "Weight", "Reps", "Points"]
length: 5
__proto__: Array(0)



There seems to be a number of problems with the new row (4):

1) why does it say Array(5) when row (3) doesn't?

2) the values of the new row(4) don't show the column names like row(3).

3) The date (first column) wasn't converted to date format but treated as an equation.

Question:

What changes to my code do I need to make in order for the new dynamically added row to look and work like the original rows loaded from the CSV file?

The last console view of the dataset with nothing expanded makes it easy to see the differences between the original three rows loaded from the CSV file, and the fourth row added dynamically.

thanks for any help and suggestions.

1
  • Could you make a jsfiddle/block for this? Commented Dec 7, 2019 at 17:41

1 Answer 1

0

Once d3.csv has finished parsing the CSV and you are inside the callback there is no rows or columns anymore: forget about the CSV structure you had, now you have just a JavaScript array of objects.

Therefore, the solution is pushing the new row as an object, with the correspondent keys.

For instance, this is an example using d3.csvParse, because I can't use d3.csv in a Stack Overflow snippet:

var csv = `Date,Mcode,Weight,Reps,Points
2017/06/01,HIPABD,160.0,25,66
2017/06/02,STRETCH,,10,10
2017/06/03,TWISTS,25.0,50,20
2017/06/04,SBENDS,25.0,50,20`;

var parseTime = d3.timeParse("%Y/%m/%d")

var rowConverter = function(d) {
  return {
    Date: parseTime(d.Date),
    Mcode: d.Mcode,
    Weight: parseFloat(d.Weight),
    Reps: parseFloat(d.Reps),
    Points: parseFloat(d.Points)
  };
}

var data = d3.csvParse(csv, rowConverter);

d3.select("p")
  .on("click", function() {
    data.push({
      Date: parseTime("2017/07/22"),
      Mcode: "SHLPRESS",
      Weight: 55.0,
      Reps: 10,
      Points: 78
    });
    console.log(data)
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<p>Click me</p>

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

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.