Searle
Searle

Reputation: 361

D3 timezone offset shifting to previous day

Details

Problems

Desired Solution

Chart Initialization Code

function createStackedTimeSeriesChart(chartName, data, margins, tableName, ajaxPath, filterType, timeColumn, statuses, document_types, showLegend, percentage) {

    if(typeof(data) == 'undefined') {
        $('#' + chartName).parent().text('no data found');
        return;
    }

    if(data.length == 0) {
        $('#' + chartName).parent().text('no data found');
        return;
    }

    try {

        var maxValue = data[0]['values'][0]['x'];
        var minValue = maxValue;
        for(var i = 0; i < data.length; i++) {
            for(var v = 0; v < data[i]['values'].length; v++) {
                if(data[i]['values'][v]['x'] > maxValue) maxValue = data[i]['values'][v]['x'];
                if(data[i]['values'][v]['x'] < minValue) minValue = data[i]['values'][v]['x'];
                data[i]['values'][v]['x'] = new Date(data[i]['values'][v]['x']);
            }
        }

        var chart;
        nv.addGraph(function() {
            chart = nv.models.stackedAreaWithFocusChart()
                .useInteractiveGuideline(true)
                .x(function(d) { return d['x'] })
                .y(function(d) { return d['y'] })
                .controlLabels({stacked: "Stacked", expanded: "Expanded"})
                .duration(300)
                .color(function(d){return getChartColorByValue(d)})
                .showControls(false)
                .showLegend(showLegend)
                .clipEdge(false);

            var chart_wrapper = new Chart(chartName, chart, tableName, ajaxPath, data, filterType, timeColumn, statuses, document_types);
            chart_wrapper.oldest_date = moment(maxValue);
            chart_wrapper.dataTable.percentage = percentage;

            chart.interactiveLayer.tooltip.contentGenerator(tooltipContentGenerator(chart_wrapper));

            var extentPeriod = chart_wrapper.getCurrentYearSpan();
            chart.brushExtent([extentPeriod.begDate, extentPeriod.endDate]);

            chart.xAxis.tickFormat(function(d) { return d3.time.format('%d/%m/%Y') (new Date(d)) });
            chart.x2Axis.tickFormat(function(d) { return d3.time.format('%d/%m/%Y') (new Date(d)) });
            chart.xAxis.axisLabel("date");
            chart.yAxis.tickFormat(d3.format(',.0f'));
            chart.y2Axis.tickFormat(d3.format(',.4f'));

            chart.legend.vers('furious');

            chart.legend.margin(margins);

            atleastOnePoint = false;

            d3.select('#' + chartName)
                .datum(data)
                .transition().duration(1000)
                .call(chart)
                .each('start', function() {
                    setTimeout(function() {
                        d3.selectAll('#' + chartName + ' *').each(function() {
                            if(this.__transition__)
                                this.__transition__.duration = 1;
                        })
                    }, 0)
                });

            nv.utils.windowResize(chart.update);

            charts_array[chartName] = chart_wrapper;
            chart.update();

            chart.dispatch.on('renderEnd', function(e) { chart_wrapper.refreshDataTable(); });

            return chart;
        });

    } catch(e) {
        $('#' + chartName).parent().text(e);
    }

}

Upvotes: 1

Views: 457

Answers (1)

Searle
Searle

Reputation: 361

I've resolved my issue by moving away from a TZ aware API, and instead switching to date strings.

  • The server converts to the desired TZ (EST) and passes the results as date strings.
  • The client primarily uses moment JS, creating objects from the date strings w/ a local TZ. The time is meaningless, and I only use the date.
  • The moment objects are converted to JS date objects for NVD3 w/ local TZ set.
  • To get date only brush extents, I convert to moment and then round the beginning date to next day if less than beginning of day. The end date I drop to floor.
  • When making a call to the server with the new date range, I convert to date string (which happens to have always been in EST).

This solution turned out to be simpler to follow than what I was previously attempting to do.

Upvotes: 1

Related Questions