Question

I've been fighting this problem for most of the day now, so I figure I'd ask here...

I'm creating a plot using highcharts, and I want to use a datetime xAxis. The label I wish to show on this axis is a calculated value, relative to a set of specific dates. So I use a labels.formatter function which have access to the previous and the last dates, and relative to these dates I do some logics.

The logic is that if this.value (from within the formatter) is before the last one, the axis should show months since previous ones, if this.value == last it should show 0 and if this.value > last it should show months since last.

I have some helper functions that are called in my code, they have been used in many occasions and work as they should.

Below is the implementation of my label formatter for the xAxis.

gVars.reportAddedResistance.MonthSinceUsed = new Array();    

this.highchart.options.xAxis.labels.formatter = function() {
    var mbDec;
    var mod;
    var result;
    var returnValue = null;
    var isSet;
    var previous = new Date(self.data.plotConf.previousDrydockDate);
    var last = new Date(self.data.plotConf.lastDrydockDate);
    var val = new Date(this.value);

    if(val.getTime() < last.getTime()) {
      // BEFORE LAST DRYDOCK
      mbDec = Utils.monthsBetweenDecimal(previous, val);
      mod = mbDec % 1;
      if(mod <= (1 / 30.4375)) {
        result = Math.round(mbDec);
        isSet = gVars.reportAddedResistance.MonthSinceUsed.indexOf(result);
        if(isSet == -1) {
          gVars.reportAddedResistance.MonthSinceUsed.push(result);
          //console.log('',"LESS Returning "+result+" Used: "+gVars.reportAddedResistance.MonthSinceUsed);
          returnValue = result;
        }
      }
    }
    else if(val.getTime() == last.getTime()){
      // AT LAST DRYDOCK
      var result = 0;
      isSet = gVars.reportAddedResistance.MonthSinceUsed.indexOf(result);
      if(isSet == -1) {
        gVars.reportAddedResistance.MonthSinceUsed.push(result);
        //console.log('',"EVEN Returning "+result+" Used: "+gVars.reportAddedResistance.MonthSinceUsed);
        returnValue = result;
      }
    }
    else if(val.getTime() > last.getTime()){
      // AFTER LAST DRYDOCK
      mbDec = Utils.monthsBetweenDecimal(last, val);
      mod = mbDec % 1;
      if(mod <= (1 / 30.4375)) {
        result = Math.round(mbDec);
        isSet = gVars.reportAddedResistance.MonthSinceUsed.indexOf(result);
        if(isSet == -1) {
          gVars.reportAddedResistance.MonthSinceUsed.push(result);
          //console.log('',"MORE Returning "+result+" Used: "+gVars.reportAddedResistance.MonthSinceUsed);
          returnValue = result;
        }
      }
    }
    return returnValue;
  };

The value of previous is (from console.log):

Date {Tue Jun 15 2010 02:00:00 GMT+0200 (Romance Daylight Time)}

The value of last is (from console.log):

Date {Sat Jun 15 2013 02:00:00 GMT+0200 (Romance Daylight Time)}

If I enable the console.log output I get this output, which to me indicates that the logics and date comparisons is working as expected:

LESS Returning 31 Used: 31
LESS Returning 32 Used: 31,32
LESS Returning 33 Used: 31,32,33
LESS Returning 34 Used: 31,32,33,34
LESS Returning 35 Used: 31,32,33,34,35
EVEN Returning 0 Used: 31,32,33,34,35,0
MORE Returning 1 Used: 31,32,33,34,35,0,1
MORE Returning 2 Used: 31,32,33,34,35,0,1,2
MORE Returning 3 Used: 31,32,33,34,35,0,1,2,3
MORE Returning 4 Used: 31,32,33,34,35,0,1,2,3,4
MORE Returning 5 Used: 31,32,33,34,35,0,1,2,3,4,5
MORE Returning 6 Used: 31,32,33,34,35,0,1,2,3,4,5,6
MORE Returning 7 Used: 31,32,33,34,35,0,1,2,3,4,5,6,7
MORE Returning 8 Used: 31,32,33,34,35,0,1,2,3,4,5,6,7,8

My problem is, that the returned values are not displayed on my plot. If I change the formatter function to just return this.value it displays them all, without any problems, but for some reason I cannot identify the return values (as seen in the above console.log output) is not shown.

My xAxis is configured like this:

xAxis: {
type : 'datetime',
dateTimeLabelFormats: {
  day: '%Y-%m-%d',
  week: '%Y-%m-%d',
  month: '%Y-%m-%d',
  year: '%Y-%m'
},
startOnTick : false,
tickInterval : 24 * 3600 * 1000 * 1, // 1 day
title : {
  text : 'Months relative to drydockings',
  style : {
    fontSize : '9pt',
    fontFamily : 'Arial'
  }
},
labels : {
  maxStaggerLines : 1,
  style : {
    fontSize : '7pt',
    fontFamily : 'Arial'
  }
}

},

I'm stuck - PLEASE HELP!!! :-)

EDIT: I'm using Highcharts JS v3.0.7 (2013-10-24)

Was it helpful?

Solution

The solution to my problem was to add this to the formatter:

    if(this.isFirst) {
      gVars.noOfSeriesCalled++;
    }
    if(gVars.noOfSeriesCalled == this.axis.series.length) {
        // The stuff thats posted above
    }
    else {
      return null;
    }

I think its an error in the library that I have to use a global variable to keep track of how many iterations I've been through.

The correct implementation, as seen from my perspective, would be that the formatting function were called once for each tick in the xAxis, regardless of how many series are added to the plot.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top