Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

plot with year-independent date axis - JS

The data that should be plotted by chart.js is available in a postgres table in a structure like this:

date        season  cum_sum
2021-12-23  2022    11
2022-01-01  2022    19
2022-01-04  2022    20
2022-01-05  2022    40 
2022-03-01  2022    43
2022-12-01  2023    3
2022-12-02  2023    7
2022-12-10  2023    11
2022-12-23  2023    17
2023-01-01  2023    19
2023-01-05  2023    30

My idea is to provide this data as JSON by PHP. How can I plot (line or dot plot) this data with an x-axis from december to march, without a year, so the value for 1st January is at the same x-position? For each season I need an own line or color of dots.

Here my try: get_data.php

$sql = "...";
$rows = queryDatabase($sql);
$chartData = array();

foreach ($rows as $row) {
    // extract the month and day from the date string
    $date = strtotime($row['date']);
    $month = date('m', $date);
    $day = date('d', $date);

    // add the data to the chartData array
    $chartData[$row['season']][] = array($month . '/' . $day, $row['cum_sum']);
}

// encode the chartData array as JSON and output it
echo json_encode($chartData);

creates data like this:

{"2022":[["01\/03","6.5"],["01\/03","6.5"],["01\/04","11.0"],["05\/12","887.7"]],"2023":[["12\/05","2.5"],["12\/05","2.5"],["12\/06","10.0"],["12\/06","10.0"],...

make_chart.php

<script>
        $( document ).ready(function() {
            // retrieve data from PHP as JSON object using fetch API
            fetch('./inc/get_data.php')
            .then(response => response.json())
            .then(data  => {
                // create chart
                var ctx = document.getElementById('myChart').getContext('2d');
                var chart = new Chart(ctx, {
                type: 'line',
                data: {
                    datasets: [{
                        label: 'Season 2022',
                        data: data.filter(d => d['2022'] ),
                        borderColor: 'blue',
                        fill: false
                        }, {
                        label: 'Season 2023',
                        data: data.filter(d => d['2023'] ),
                        borderColor: 'red',
                        fill: false
                    }]
                },
                options: {
                    scales: {
                    xAxes: [{
                        type: 'category',
                        ticks: {
                        callback: function(value, index, values) {
                            return value.replace(/-\d{2}/, '');
                        }
                        }
                    }],
                    yAxes: [{
                        ticks: {
                        beginAtZero: true
                        }
                    }]
                    }
                }
                });
            })
            .catch(error => console.error(error));
        });

</script>

Getting TypeError: data.filter is not a function (EDIT:solved in #1)

EDIT: The x-axis is not chronological. Days of the season 2023, that were not part of the season 2022, are plotted at the end of the x-axis. E.g.: data_2022 = ["01-03", 5], ["01-10", 15] data_2023 = ["01-03", 10], ["01-05",20] --> 01/05 is plotted on the end of the x-axis

enter image description here

like image 504
erik-stengel Avatar asked Feb 19 '26 13:02

erik-stengel


1 Answers

datais is not an array but an object, hence it has no filter function. You could create the data of individual datasets as follows:

const baseData = {"2022":[["01\/02","6.5"],["01\/03","6.5"],["01\/04","11.0"],["05\/12","887.7"]],"2023":[["12\/05","2.5"],["12\/05","2.5"],["12\/06","10.0"],["12\/06","10.0"]]};

const data = baseData['2022'].map(arr => ({ x: arr[0], y: parseFloat(arr[1])}));
console.log(data );

You can also create all datasets dynamically, similar to what was proposed in this answer: https://stackoverflow.com/a/75635274/2358409.

like image 105
uminder Avatar answered Feb 22 '26 01:02

uminder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!