user4029967
user4029967

Reputation:

Highcharts- show all days even if there are no values

I am using PHP and MySQL to get total amount of orders made on each day during a selected time period and then save them in a *.csv file using PHP. I generate the chart from csv file and everything is ok but I would need to include days with no orders made as well. *.csv file content is something like that:

1,05-01
1,05-02
2,05-04
1,05-06

So on the chart they appear as 1 order made on 1st of May, 1 order made on 2nd of May and then 3rd of May is skipped- I need to show it on the chart with value 0. Can it be done with jQuery/highcharts (I don't have much experience with javascript) or should I edit the PHP to create file with those values, like this:

1,05-01
1,05-02
0,05-03
2,05-04
0,05-05
1,05-06

I use the following PHP code to save the file:

$result = mysqli_query($con,"$query");
        $fp = fopen('data/temp.csv', 'w');
        if ($fp && $result) {
            while ($row = $result->fetch_array(MYSQLI_NUM)) {
                fputcsv($fp, array_values($row));
            }
        }

And the following script to generate the chart:

var myCategories = [];
var myData = [];
var myChart;

$(document).ready(function() {
    var options = {
    chart: {
        renderTo: 'chart-container',
        defaultSeriesType: 'column'
    },
    title: {
        text: 'Orders received in selected days'
    },
    xAxis: {
        title: {text: 'Date'},
        categories: []
    },
    yAxis: {
        title: {
            text: 'Orders'
        }
    },
    series: []
    };
    $.get('data/temp.csv', function(data) {
        var lines = data.split('\n').slice(0, -1); //generated csv file has \n after last entry so there is always an empty line I have to delete
        $.each(lines, function(lineNo, line) {
            var items = line.split(',');
            myCategories.push(items[1]);
            myData.push(parseInt(items[0]));
        });
        options.xAxis.categories = myCategories;
        options.series = [{ data: myData }];
        myChart = new Highcharts.Chart(options);
    });
});

Upvotes: 0

Views: 398

Answers (1)

user4029967
user4029967

Reputation:

Only solution I found was to create some crazy query on MySQL side (I preffer to handle that logic in PHP) it seems this cannot be done with HighCharts, so in the end I modified my PHP code a little bit to add some extra loops. If someone is interested it now looks like this:

$result2 = mysqli_query($con,"$query2");
$fp = fopen('data/temp.csv', 'w');
$dayCompare=date("n-d", strtotime($theDay));    //I know which day is the first one selected so I save it as variable #theDay
while ($row = mysqli_fetch_array($result2)) {
    if ($row['Date'] !== $dayCompare){
        while ($row['Date'] !== $dayCompare){ //This "while" keeps on looping till the date from database matches the day
            fputcsv($fp, array('0,'.$dayCompare));
            $theDay= date("Y/m/d", strtotime($theDay . "+1 day"));
            $dayCompare=date("n-d", strtotime($theDay));
        }
    } //Rest of the code is to be executed when dates match
    fputcsv($fp, array($row['Orders'].",".$row['Date']));
    $theDay= date("Y/m/d", strtotime($theDay . "+1 day"));
    $dayCompare=date("n-d", strtotime($theDay));
}
for ($theDay; $theDay <= $lastDay; strtotime($theDay . "+1 day")) { //I added a "for" loop to fill in the empty days if the day of last order is earlier than the last day selected/current day.
    fputcsv($fp, array('0,'.$dayCompare));
    $theDay= date("Y/m/d", strtotime($theDay . "+1 day"));
    $dayCompare=date("n-d", strtotime($theDay));
}

This produces sample output:

"1,5-01"
"1,5-02"
"0,5-03"
"2,5-04"
"0,5-05"
"1,5-06"

The only problem that it gives me now the data is saved in the *.csv file with quotes, but I solved it by modifying the *.js file with my script changing this part:

$.each(lines, function(lineNo, line) {
    var items = line.split(',');
    myCategories.push(items[1]);
    myData.push(parseInt(items[0]));
});

To this:

    $.each(lines, function(lineNo, line) {
        var items = line.split(',');
        myCategories.push(items[1].replace(/"/g,""));
        myData.push(parseInt(items[0].replace(/"/g,"")));
    });

Thanks to trimming the quote marks the output is as expected. Variables with dates are still quite elaborated but it seems it has to be like that since PHP has problems recognizing short dates when it is about doing math equations, and I also hope to modify that triple loop someday but this will have to wait at least till next deployment.

In the end I added one more loop to loop through the empty days when the last day selected is later than the day of last order, for example if 9th of May was selected and last order was on 7th there will be 2 lines added with 0 values for 8th and 9th.

Upvotes: 2

Related Questions