dc.js Show filtered count of objects

Viewed 112

I'm new to dc.js. and i havent found a solution to my problem.

I have an array of objects like this

[{
 devicename: "device1",
 operatingSystem: "android",
 complainceState: "complaint"
 ...
},
{
 devicename: "device2",
 operatingSystem: "android",
 complainceState: "noncomplaint"
 ...
},
...]

Now i'm using a numberDisplay to try and show the amount of objects where complaincestate="complaint"
But it seems to show the amount of different values eg. 2 because there is "non complaint" and "complaint". What should i do to solve?

const complaincy = ndx.dimension((d: any) => d.complianceState)
      const complaincyGroup = complaincy.group()

      numberDisplay
      .formatNumber(d3.format(".1s"))
      .dimension(complaincy)
      .group(complaincyGroup)

this is the code i wrote. I've tried using .filter but it doesn't seem to work like i tought it would.

If anyone could point me to the right direction or link an article it would be greatly appreciated!

EDIT: Here is some more context to my problem.

I currently have 2 charts and 1 number counter.enter image description here

This is the full code for dc.js


var deviceChart = dc.pieChart("#devices")
    var numberRowChart = dc.rowChart("#complaincy")
    var numberDisplay = dc.numberDisplay("#complaincyNumber")

this.tenantService.getDevicesD3(this.selectedTenant).then(data => {
      const ndx = crossfilter(data);

      //devices by os doughnut chart
      const deviceDimension = ndx.dimension((d:any) => d.operatingSystem);
      const deviceGroup = deviceDimension.group();

      deviceChart.ordinalColors(["#00a2ed","#3DDC84"]);
      deviceChart
      .radius(100)
      .width(160)
      .height(160)
      .dimension(deviceDimension)
      .group(deviceGroup)
      .innerRadius(50)
      .label((d) => "")
      .legend(dc.htmlLegend().container("#deviceLegend").highlightSelected(true))
      

      //non complaint number counter
      const complaincy = ndx.dimension((d: any) => d.complianceState)
      const complaincyGroup = complaincy.group()
      
      numberDisplay
      .formatNumber(d3.format(".1s"))
      .dimension(complaincy)

      //{
      //   value: () => complaincyGroup.all()
      //  .filter(({key}) => key == ‘complaint’)[0]
      //}
      // This solution suggested by gordon returns the following error in 
      //   console. ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'value' of undefined
      .group(complaincyGroup);
      


      //number row chart
      numberRowChart
      .dimension(complaincy)
      .group(complaincyGroup)

      dc.renderAll();
      dc.redrawAll();

    })
1 Answers

The behavior is documented at the top of the NumberDisplay documentation:

If the group is a groupAll then its .value() will be displayed. This is the recommended usage.

However, if it is given an ordinary group, the numberDisplay will show the last bin's value, after sorting with the ordering function. numberDisplay defaults the ordering function to sorting by value, so this will display the largest value if the values are numeric.

I guess you are seeing the last bin’s value.

Probably the easiest way to do what you want is to create a fake groupAll that returns only the element you want:

numberDisplay.group({
    value: () => complaincyGroup.all()
       .filter(({key}) => key == ‘complaint’)[0]})

Note: there is a misspelling in your code; if you spell your accessor like this

  const complaincy = ndx.dimension(d => d.complainceState)

then it works.

Example fiddle.

Related