Search code examples
d3.jschartsscatter-plotdc.jsaxis-labels

Changing number values for text on Y Axis label for dc.js ScatterPlot


I have a scatter plot that charts unique events per date on my X axis and when they happened on each day, by the second, on the Y axis.

To accomplish this I took the date data that I use for the X axis, and ran it through a function that would output the exact second of the day in which the event happened (0 to 86400). In that sense, my Y axis goes from 0 seconds to 86400 seconds.

This allowed me to represent each even uniquely as a dot on my chart down to the second.

I'm pretty happy with the outcome of my chart:

Scatter plot image

The only issue is my Y label goes from 0 to 86400. I would like to change the text to a familiar HH AM/PM format, perhaps something along the lines of "0 to 23, where ie: if (y value = 3600) return "1 AM".

My scatterplot looks like this:

scatterPlot
        .width(window.innerWidth-100)
        .height(window.innerHeight/2)
        .x(d3.time.scale().domain([minDate, maxDate]))
        .brushOn(false)
        .mouseZoomable(true)
        // .title(function (d) {
        //     return "Event: " + d['text'];
        // })
        .clipPadding(5)
        .yAxisLabel("Hour of the day")
        .elasticY(true)
        .dimension(eventsByDateAndHourDim)
        .group(eventsByDateAndHourGroup);

I tried to do this:

scatterPlot.yAxis().tickFormat(function (d) {
    if (domain = 43200)
        return "12 PM";
})

But that only changes all labels to "12 PM". I'm not sure how to refer to the actual value of my Y domain.

I tried using the group "if (eventsByDateAndHourGroup = 43200)..." but that didn't work either.


Solution

  • The parameter to the function passed to the tickFormat() method is the Y coordinate which needs to be formatted.

    So you should be able to do something like

    scatterPlot.yAxis().tickFormat(function (d) {
        var hour = Math.floor(d/3600),
            pm = hour > 11;
        if(pm) hour -= 12; 
        if(hour === 0) hour = 12; 
        return String(hour) + (pm ? ' PM' : ' AM');
    });
    

    Or you can use d3.time.format.utc for a more robust, elegant solution:

    var hourFormat = d3.time.format.utc('%I %p');
    scatterPlot.yAxis().tickFormat(function (d) {
        var date = new Date(d*1000);
        return hourFormat(date);
    });
    

    This is somewhat less efficient, because Date objects are slow, but it probably doesn't matter for processing a dozen ticks.