dc.jscrossfilter

plot individual aspects of a javascript crossfilter dimension (quantity vs time using d3 and crossfilter)


I am trying to plot a line graph of some quantity, in this case, "bananas", vs Time using D3 and crossfilter. The dimension aspect of the plot does not seem to reflect the dimension values that I am inputting, though is possible that this is a conceptual issue with crossfilter, as I am new to using it. below is the script that I am using and the output plot, as you can see the y-axis runs 0-6 and there are 11 unique inputs for banana and time. Other examples that I have looked at for this type of plot appear to plot the equivalent to the quantity aspect of bananas (which runs from 8 to 668 in this case), so I was hoping for some clarity on what exactly is on my Y-axis and how to re-write my code such that it is actually plotting the number of bananas consumed as a function of time.

    //declare new variable, chart and select the dc chart type 
    var chart =     new dc.LineChart("#lineChart");
//insert the data you wish to plot 
     var data1 = [ 
     {"bananas": 22.28876521596685, "Timestamp":'2021-01-19 17:06:50.239197'},
     {"bananas": 25.8395210863092,  "Timestamp": '2021-01-19 17:16:52.181954'},
     {"bananas": 23.11122495696,  "Timestamp": '2021-01-20 17:21:52.181954'},
      {"bananas": 28.8395210863092,  "Timestamp": '2021-01-21 17:26:52.181954'},
      {"bananas": 38.32323232232,  "Timestamp": '2021-01-21 17:26:52.181954'},
      {"bananas": 248.8395210863092,  "Timestamp": '2021-01-21 17:26:52.181954'},
      {"bananas": 8.122345566789, "Timestamp": '2021-01-21 17:26:52.181954'},
      {"bananas": 9.8395210863092,  "Timestamp": '2021-01-21 17:26:52.181954'},
      {"bananas": 58.86904272742, "Timestamp": '2021-01-21 17:26:52.181954'},
      {"bananas": 668.642100932,  "Timestamp": '2021-01-22 17:26:52.181954'},
      {"bananas": 68.8395210863092,  "Timestamp": '2021-01-21 18:26:52.181954'},
     ];

// convert the timestamp data into something that js can understand 
    data1.forEach(function (d) {
        d.Timestamp = new Date(d.Timestamp);
    }); 
    //log the updated values to the console (troubleshooting)
    console.log(data1)


    // set crossfilter with first dataset
    var xfilter = crossfilter(data1),
   // var all = xfilter.groupAll();

        //Define the Dimensions 
            bananasDim = xfilter.dimension(function (d){return +d.bananas;})
            console.log(bananasDim.top(Infinity)) 
            //this prints out the entire data1 json in the console 
            TimeDim = xfilter.dimension(function (d){return d.Timestamp;});     
            
       //Define the Group elements 
         bananasGroup= bananasDim.group()
         TimeGroup=TimeDim.group()
         console.log(bananasGroup)
         console.log(TimeGroup)

    function render_plots(){
 
         chart
            .width(768)
            .height(480)
            .x(d3.scaleTime().domain([0,200])) //this defines a range of 0 to 200
            // but we use elasticX so its not really relevant 
            .curve(d3.curveLinear)
            .renderArea(true)
            .brushOn(false)
            .renderDataPoints(true)
            .clipPadding(10)
            .elasticX(true)
            .elasticY(true)
            .dimension(bananasDim)
            .group(TimeGroup);

        dc.renderAll();
    }

    render_plots();

Bananas Vs Time Plot


Solution

  • Thanks for including a complete working example with your question.

    That looks like a plot of counts by time. If you want to sum the bananas, you could use

         TimeGroup=TimeDim.group().reduceSum(d => d.bananas)
    

    Additionally, for a specific chart, the group should usually be instantiated from the same dimension:

            .dimension(TimeDim)
    

    This is because the group will be used for fetching the data and the dimension will be used for filtering.

    You will probably also want to set the resolution so that times which are not exactly the same will aggregate. For example you could do:

            TimeDim = xfilter.dimension(function (d){return d3.timeHour(d.Timestamp);});     
          // ...
          chart
            .xUnits(d3.timeHours)
    

    to round to hours (similar for days).

    screenshot with bananas/hour

    demo fiddle