angulartypescriptd3.jsdc.jscrossfilter

dc charts look different when building Angular App in production mode


I'm currently working on an application that is using d3, dc, and crossfilter to render some charts.

I was working on making the Y scale only showing inter numbers without a decimal point.

This is working when I run my application in development mode with 'ng serve'.

enter image description here

But when I build my app in production mode the Y scale is not the same.

enter image description here

Really the only thing different here is using "ng serve" or "ng build --prod".

The code that sets the ticks is

  /* grpProductType is a crossfilter.Group*/
  const maxY = d3.max(d3.values(grpProductType))(1)[0]?.value;

  if (maxY < 7) {

    /* dcStepsByProductType is a dc.BarChart*/
    dcStepsByProductType.yAxis().ticks(maxY);

  }

I have managed to narrow down what is causing the problem to a certain point. The problem is dependant on the property the angular.json file under:

projects => [app name] => architect => build => configurations => production => optimization => scripts

If this flag is true then the logic error occurs, if false then the app runs fine.

The logs when printing out when the value is true (with error) are enter image description here

When the value is false (working correctly) then the logs are enter image description here

It seems the return value from invoking the 'all' function is the difference.

My question is what could be possible reasons for this?


Solution

  • Your code and your debug output specify

    d3.values(grpProductType)
    

    but it looks like grpProductType is a crossfilter group object, so this produces an array of the methods of the object:

    d3.values debug

    Then your code proceeds to compute the maximum of these functions, and then calls that function with a parameter 1, takes the first element of the resulting array, and reads its field value if any:

    const maxY = d3.max(d3.values(grpProductType))(1)[0]?.value;
    

    I think this must be autocomplete-driven software development, because the intention is inscrutable to me. It probably works in develop mode because the maximum of the functions is .top() (by name?) but in optimized prod mode the functions have shorter nonsense names, so you call a different function.

    Anyway, it's a crossfilter group object, so you should directly call .all() to retrieve the bins. This will return an array of {key,value} objects, so a better way to calculate maxY is:

    const maxY = d3.max(grpProductType.all(), d => d.value);
    

    Or if you prefer to use .top():

    const maxY = grpProductType.top(1)[0].value;