0

I am new to D3.js and need some help. I currently have some json data that kind of looks like this, there are multiple instances within the data where a variety of course titles and atendances appear but i just used two to show as an example ... (there are more fields but these are the one that are key to the question.

{
"Course_title": "Adv Mech Eng",
"Attendance_record": 0.89,
"Last_attendance": "2018-10-19 09:00:00.000",
},
{
 "Course_title": "Comp Sci",
 "Attendance_record": 0.50,
 "Last_attendance": "2018-10-19 15:59:59.999"
 }

I wanted to know how do i filter or manipulate the data, such that it gives me the mean attendance for each individual course title, within the last like 30 days for instance.

d3.json('attendance_data.json', function(data) {
var avg_data = d3.nest()
    .key(function (d) {
        return d.Course_title
    })
    .rollup(function (v) {
        return d3.mean(v, function (d) {
            return d.Attendance_record;
        });
    })
    .entries(data);
console.log(JSON.stringify(avg_data));
return avg_data;

I have no idea how to do the date element however, but i have tried the above code as a part implementation, and i cant seem to use it so i can input it into my d3 chart code.

Please can someone help, as i am new to d3 and have been stuck on it now for a few days.

hawks
  • 49
  • 5

1 Answers1

0

You could use d3.utcParse to read a date parameter. There is also option filter to mine courses by date.

The code to retrieve the date 30 days ago is from another SO post: how-to-get-30-days-prior-to-current-date

Here is an example:

d3.json('attendance_data.json', function(data) {

  //Date today and 30 days ago
  var dateToday = new Date()
  var date30daysAgo = new Date(new Date().setDate(dateToday.getDate()-30))

  // Parser to "Last_attendance"
  var parserDate = d3.utcParse("%Y-%m-%d %H:%M:%S.%L")

  //Courses occurring in the last 30 days
  var selectedCourses = data.filter(function(d){
    return parserDate(d.Last_attendance) > new Date(date30daysAgo);
  })

  var avg_data = d3.nest()
    .key(function (d) {
      return d.Course_title //group by couse title
    })
    .rollup(function (courses) {
      return d3.mean(courses, function (d) {
        return d.Attendance_record;//mean of attendance
      });
    })
    .entries(selectedCourses);

 
  console.log(JSON.stringify(avg_data));

})
<script src="https://d3js.org/d3.v4.min.js"></script>
anbrito
  • 76
  • 3
  • I am trying to create a circular packing graph from this which shows the attendance for a particular course title, so to call the data into the graph could i saying something like `avg_data.Course_title` and `avg_data.Attendance_record`. – hawks Jun 27 '20 at 18:54
  • Hi, would you like to filter a specific course? In this case, you could filter ```avg_data``` or add a new condition in the first filter. For instance, ```var courseName = "Adv Mech Eng"; var course = avg_data.filter(function(d){return d.key == courseName;})[0]``` . So, you could use ```course.key```and ```course.value``` – anbrito Jun 27 '20 at 19:37
  • yeah i need a average attendance value for each specific course and i have 48 different courses. sorry i may be asking stupid questions but i am new and getting quite confused with it at times. @anbrito – hawks Jun 27 '20 at 20:02
  • For example, the output from ```avg_data``` is ```[{"key":"Adv Mech Eng","value":50.445},{"key":"Comp Sci","value":0.4}]```. Iterating this variable, we have the mean per course: ```avg_data.forEach(function(avg){console.log(avg.key + " - " + avg.value)})``` How is the output format you are looking for? – anbrito Jun 27 '20 at 20:28
  • I need it such that i can call in the code below the average attendance of a course in the `.attr("r", function(d){ return size(d.Attendance_record)})` and course name in `.style("fill", function(d){ return color(d.Course_title)})` These are some of the attributes i need to create the circles that will visualise the data `var node = svg.append("g") .selectAll("circle") .data(data) .enter() .append("circle")` – hawks Jun 27 '20 at 20:36
  • I think you need to replace ```data``` --> ```avg_data```, ```d.Attendance_record``` --> ```d.value```, and ```d.Course_title``` --> ```d.key``` It works? – anbrito Jun 27 '20 at 20:51
  • Do i not need to do that `forEach` iteration? I am going to try it tomorrow morning hopefully that should work, thank you so much for the help. would it be cool if i ask more questions if i have any issues? – hawks Jun 27 '20 at 20:55
  • Sure, your questions are welcome. We do not need a forEach after to filter avg_data, I think you need something like [https://www.d3indepth.com/datajoins/](https://www.d3indepth.com/datajoins) – anbrito Jun 27 '20 at 21:18
  • when i looked at the console log of the avg data it is returning empty array there is no data there i am not sure why – hawks Jun 28 '20 at 12:14
  • Are there courses dated up to 30 days ago? In the example, the dates refer to 2018. – anbrito Jun 28 '20 at 15:22
  • It was my mistake i used the wrong operand for the date check sorry. But everything is working as i wanted thank you so much i really appreciate the help – hawks Jun 28 '20 at 15:58