Robin
Robin

Reputation: 35

Google Chart ticks not displaying at all

I have a problem with the vaxis.ticks option in google charts.

My code does work and the chart is correct, but the strings in the ticks array are ignored and the initial numbers are displaying. No errors or warnings.

I cant seem to find a solution for this problem.

$.ajax({
    url: '/api/chart/eta/lane/45',
    dataType: 'json'
}).done(function (response) {
    var array = [];
    var ticks = [];
    array.push(['Time', 'line 1', 'line 2', 'line 3', 'line 4']);
    $.each(response, function (key, row) {
        array.push([new Date(row[0]), row[1], row[2], row[3], row[4]]);
        if(row[1])
            ticks.push({v: row[1], f: secondsToTime(row[1])});
        if(row[2])
            ticks.push({v: row[2], f: secondsToTime(row[2])});
        if(row[3])
            ticks.push({v: row[3], f: secondsToTime(row[3])});
        if(row[4])
            ticks.push({v: row[4], f: secondsToTime(row[4])});
    });
    google.charts.load('current', {'packages': ['line']});
    google.charts.setOnLoadCallback(drawChart);
    function drawChart() {

        var datatable = google.visualization.arrayToDataTable(array);

        var options = {
            width: 1000,
            height: 800,
            legend: {position: 'none'},
            hAxis: {
                format: 'd.M.yyyy H:mm'
            },
            vAxis: {
                title: "Δ ETA",
                ticks: ticks
            }
        };

        var container = document.getElementById('chart');
        var chart = new google.charts.Line(container);

        chart.draw(datatable, google.charts.Line.convertOptions(options));
    }
});

function secondsToTime(seconds) {
    var isNegative = false;
    if(seconds < 0) {
        seconds = Math.abs(seconds);
        isNegative = true;
    }
    return (isNegative ? '-' : '') + Math.floor(seconds / 3600) + ':' + Math.floor((seconds%3600) / 60);
}

Example AJAX response:

[
    ["2018-07-25 17:09:24",311,4490,null,-10994],
    ["2018-07-25 17:16:20",364,4543,null,-11047],
    ["2018-07-25 17:19:29",412,4591,null,-11095],
    ["2018-07-25 17:21:25",528,4707,null,-11211],
    ["2018-07-25 17:21:43",546,4725,null,-11229],
    ["2018-07-25 17:22:01",564,4743,null,-11247],
    ["2018-07-25 17:22:18",581,4760,null,-11264],
    ["2018-07-25 17:22:38",601,4780,null,-11284],
    ["2018-07-25 17:22:57",620,4799,null,-11303],
    ["2018-07-25 17:23:17",640,4819,null,-11323],
    ["2018-07-25 17:23:36",659,null,5573,-11342],
    ["2018-07-25 17:23:56",616,null,5530,-11299],
    ["2018-07-25 17:28:02",862,null,5776,-11545]
]

Result

Upvotes: 1

Views: 2659

Answers (1)

WhiteHat
WhiteHat

Reputation: 61212

you're using a Material chart vs. a Classic chart

there are several options that are not supported by Material charts,
see --> Tracking Issue for Material Chart Feature Parity

this includes --> {hAxis,vAxis,hAxes.*,vAxes.*}.ticks


Material = packages: ['line'] -- google.charts.Line

Classic = packages: ['corechart'] -- google.visualization.LineChart

if you switch to Classic, there is an option to make the chart similar to Material

theme: 'material'

using Classic the ticks will appear, however, there also needs to be enough room to display the ticks

with the example data, the scale of the y-axis is so large, there won't be enough room to display them all

see following working snippet...

google.charts.load('current', {
    packages: ['corechart']
}).then(getData);

function getData() {
    $.ajax({
        url: '/api/chart/eta/lane/45',
        dataType: 'json'
    }).done(drawChart).fail(function () {
        drawChart([
            ["2018-07-25 17:09:24",311,4490,null,-10994],
            ["2018-07-25 17:16:20",364,4543,null,-11047],
            ["2018-07-25 17:19:29",412,4591,null,-11095],
            ["2018-07-25 17:21:25",528,4707,null,-11211],
            ["2018-07-25 17:21:43",546,4725,null,-11229],
            ["2018-07-25 17:22:01",564,4743,null,-11247],
            ["2018-07-25 17:22:18",581,4760,null,-11264],
            ["2018-07-25 17:22:38",601,4780,null,-11284],
            ["2018-07-25 17:22:57",620,4799,null,-11303],
            ["2018-07-25 17:23:17",640,4819,null,-11323],
            ["2018-07-25 17:23:36",659,null,5573,-11342],
            ["2018-07-25 17:23:56",616,null,5530,-11299],
            ["2018-07-25 17:28:02",862,null,5776,-11545]
        ]);
    });
}

function drawChart(response) {
    var array = [];
    var ticks = [];
    array.push(['Time', 'line 1', 'line 2', 'line 3', 'line 4']);
    $.each(response, function (key, row) {
        array.push([new Date(row[0]), row[1], row[2], row[3], row[4]]);
        if(row[1])
            ticks.push({v: row[1], f: secondsToTime(row[1])});
        if(row[2])
            ticks.push({v: row[2], f: secondsToTime(row[2])});
        if(row[3])
            ticks.push({v: row[3], f: secondsToTime(row[3])});
        if(row[4])
            ticks.push({v: row[4], f: secondsToTime(row[4])});
    });

    var datatable = google.visualization.arrayToDataTable(array);

    var options = {
        theme: 'material',
        width: 1000,
        height: 800,
        legend: {position: 'none'},
        hAxis: {
            format: 'd.M.yyyy H:mm'
        },
        vAxis: {
            title: "? ETA",
            ticks: ticks
        }
    };

    var container = document.getElementById('chart');
    var chart = new google.visualization.LineChart(container);

    chart.draw(datatable, options);
}

function secondsToTime(seconds) {
    var isNegative = false;
    if(seconds < 0) {
        seconds = Math.abs(seconds);
        isNegative = true;
    }
    return (isNegative ? '-' : '') + Math.floor(seconds / 3600) + ':' + Math.floor((seconds%3600) / 60);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>


note: recommend loading google charts first, before getting the data
google charts only needs to be loaded once per page load, not per chart to be drawn
by default, google.charts.load will wait for the page to load, so it can be used in place of $(document).ready or other similar functions
a setup similar to above will allow you to draw multiple charts or make multiple ajax calls,
while only loading google charts once...

Upvotes: 1

Related Questions