0

I have an object that contains multiple datasets objects that can contain an array of items or multiple arrays within this object. Without knowing whether it is a multiple object array, how can I pass it to function, that is expecting to 'forEach' depending on the amount of the arrays?

To make it more clear see data within storage:

var storage = {
  dataset1: {
    labels: ["Mon", "Tue", "Wed"],
     storageDatasets: [{                   // two objects here
        data: [2, 4, 5, 6, 10]
      },
      {
        data: [200, 100, 300, 600]
      }
    ]
  },
  dataset2: {
    labels: ["Mon", "Tue", "Wed"],
    storageDatasets: [{                  // one object here
      data: [200, 100, 300, 600]
    }]
  }
};

with above I am trying to pass them as parameters:

$(".change").click(function() {
  var temp = $(this).text();
  addChartData(myChart, storage[temp].labels, storage[temp].storageDatasets.data);        // how to get last parameter correctly, based on the amount of data objects?
});

and process using this function:

function addChartData(chart, labels, data) {
  chart.data.labels = labels;
  chart.data.datasets.forEach(dataset => {
    dataset.data = data;
  });
  chart.update();
}

The problem is with the amount of data objects within storageDatasets in var storage. Some will have multiple, some one. How can I loop through them to pass them as argument so addChartData function will run correctly.

var config = {
  type: 'line',
  data: {
    labels: ["January", "February", "March", "April", "May", "June", "July"],
    datasets: [{
      label: "My First dataset",
      data: [65, 0, 80, 81, 56, 85, 40],
      fill: false
    }]
  }
};

var storage = {
  dataset1: {
    labels: ["Mon", "Tue", "Wed"],
    storageDatasets: [{
        data: [2, 4, 5, 6, 10]
      },
      {
        data: [200, 100, 300, 600]
      }
    ]
  },
  dataset2: {
    labels: ["Mon", "Tue", "Wed"],
    storageDatasets: [{
      data: [200, 100, 300, 600]
    }]
  }
};

function addChartData(chart, labels, data) {
  chart.data.labels = labels;
  chart.data.datasets.forEach(dataset => {
    dataset.data = data;
  });
  chart.update();
}


var ctx = document.getElementById("myChart").getContext("2d");
var myChart = new Chart(ctx, config);


$(".change").click(function() {
  var temp = $(this).text();
  addChartData(myChart, storage[temp].labels, storage[temp].storageDatasets.data);

  console.log(temp);

});
.chart-container {
  height: 300px;
  width: 500px;
  position: relative;
}

canvas {
  position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js"></script>
<div> <button class="change">dataset1</button></div>
<div> <button class="change">dataset2</button></div>

<div class="chart-container">
  <canvas id="myChart"></canvas>
</div>

4
  • What does dataset.data need? for example, it needs this: [2, 4, 5, 6, 10, 200, 100, 300, 600] <--- Concatenation. Commented Mar 19, 2018 at 15:52
  • 1
    Pass storageDatasets to your function instead, and have it iterate through each child data object. Commented Mar 19, 2018 at 15:53
  • @DanielBeck shall I store it in another temp var? Commented Mar 19, 2018 at 15:55
  • No. I'll post an answer explaining in more detail. Commented Mar 19, 2018 at 15:57

2 Answers 2

1

Instead of dealing with a variable number of parameters, it may be easier to pass the whole of storageDatasets to your function as a single param:

$(".change").click(function() {
  var temp = $(this).text();
  addChartData(
      myChart, 
      storage[temp].labels, 
      storage[temp].storageDatasets
  );
});

function addChartData(chart, labels, datasets) {
  chart.labels = labels;
  chart.datasets = datasets; // per comments below, this is a direct assignment, no iteration necessary
  chart.update();
}

But if you needed to merge two datasets into one, for example, then you would need to iterate through storageDatasets:

function addChartData(chart, labels, datasets) {
  chart.labels = labels;
  chart.datasets = [{data:[]}];
  datasets.forEach(set=> {
    chart.datasets[0].data = chart.datasets[0].data.concat(set.data);
  })
  // chart.datasets now contains a single object containing concatenated data from all the datasets passed in
  chart.update();
}
Sign up to request clarification or add additional context in comments.

13 Comments

It does not seem to work for me. I am guessing it is the naming confusion. Therefore I would like to stick to storageDatasets when passing the argument. Function addChartData changes the labels and data (it is already iterating through 'datasets' of current chart). How to marry both of them? Iterate through storageDataset and place into iterated datasets of current chart? Bear in mind, I do not need to loop through labels as there won`t be more than one set of them.
To make it clearer I added extra dataset to original chart. Basically it is replacing multiple datasets of current chart to, sometimes multiple and sometimes not, datasets. codepen.io/anon/pen/Wzoqor?editors=1111
I have to admit that your repeated use of the same variable names for different purposes has me lost as to what you're trying to do. Given the input from storage.dataset1, what is the desired contents of chart.data.datasets?
I do apologise... It was not wise to use same or very close naming, especially when chart js uses some of them already... clicking on dataset1 should replace original chart.data.datasets to storage[dataset1].storageDatasets. Hence function addChartData is already iterating through chart.data.datasets and finds 2 (see var config).
Now I'm even more confused -- if chart.data.datasets is supposed to end up identical to storage[foo].storageDatasets, why are you iterating through it at all, instead of just assigning it directly?
|
0

Javascript has a built in object called arguments... It is avavilable in every function...It is actually a list.... So you can loop through it to get you job done....

function name (arg1,arg2,.....) {
    for (var i=0;i<arguments.length;i++) {
        //You can access each argument as argument[i]
    }
}

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.