제가진자 프론트를 거의몰라서 너무힘들럿슮,,,



원하는것 : 

이런식으로 {학습명: 로그}로 들어오는 데이터를 그래프로 보여주기


실제구현한것

이런식으로 그래프로 만들어줘줬음


문제사항:

보다싶이 차트가 너무 존만하게나옴

responsive라는 arguments를 true로주면 상황에 맞게 최대로 채워주는걸로 알고있는데


responsive: false로 준 상태


responsive: true로 준 상태



responsive True로 준 순간 갑자기 얘내 크기가 0이되어버림 

?



그래서 공식문서에 나오는 그대로도 해보고(https://github.com/chartjs/Chart.js/issues/882, https://www.chartjs.org/docs/latest/configuration/responsive.html)

스택오버플로우에 arguments 더 추가해서 한게있길래 그걸로도해보고(그게현재)

버전도 2.9.7, 3.0.0, 이렇게 바꿔보고해도 아예안됨,,


오늘 하루 이걸ㄹ로날린거같은데 진자 모르겟어서 질문드림,,,부탁드림니다,,감사합니다,,,.


밑에는 구현코드


<!DOCTYPE html>

<html lang="en">

<head>

    <!--suppress JSUnresolvedLibraryURL -->

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"

            integrity="-"

            crossorigin="anonymous" referrerpolicy="no-referrer"></script>

    <!--suppress JSUnresolvedLibraryURL -->

    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.1/js/bootstrap.bundle.min.js"

            integrity="-"

            crossorigin="anonymous" referrerpolicy="no-referrer"></script>

    <!--suppress JSUnresolvedLibraryURL -->

    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"

            integrity="-"

            crossorigin="anonymous" referrerpolicy="no-referrer"></script>

    <style>

        td {

            border-bottom: 2px solid rgb(0, 13, 255);

        }

        .chart-container {

            position: relative;

            resize: both;

            overflow: hidden;

            width: 100%;

            height: 100%;

        }

    </style>

    <meta charset="UTF-8">

    <title>Current Training Logs</title>

</head>

<body>

<table style="margin-left:auto;margin-right:auto;width:100%;table-layout: fixed">

    <thead>

        <tr>

            <td colspan="420" style="text-align: center; vertical-align: center; font-size: 30px; font-weight: bold">

                Current Training Logs

            </td>

        </tr>

    </thead>

    <tbody id="chartBody">

    </tbody>

</table>


<!-- JS Belows -->

<script>

    function insertRow(key, data) {

        // Create the row where the chart will be inserted

        const to_split = Object.entries(data[0].logs);

        const middle = to_split.length / 2

        const train_log = Object.fromEntries(to_split.slice(0, middle));

        const valid_log = Object.fromEntries(to_split.slice(middle, data[0].logs.length));

        const names = Object.keys(train_log);

        const names_valid = Object.keys(valid_log);

        const width_per = 100 / names.length;

        const width_span = 420 / names.length;


        let tr = document.createElement("tr"),

            docFrag = new DocumentFragment();

        tr.id = key;

        tr.style.height = "500px";


        // Create the chart for the training/validation log ex. 1: loss/val_loss, 2: accuracy/val_accuracy

        for (let i = 0; i < Object.keys(train_log).length; i++) {

            // Create the td and Empty canvas

            let td = document.createElement("td");

            td.setAttribute('colspan', width_span);

            let div = document.createElement("div");

            div.classList.add("chart-container");

            let canvas = document.createElement("canvas");

            canvas.id = key + '_' + names[i];

            const config = {

                type: 'line',

                data: {},

                options: {

                    plugins: {

                        title: {

                            display: true,

                            text: key + ' - ' + names[i]

                        },

                    },

                    responsive: true,

                    maintainAspectRatio: false,

                    tooltips: {

                        mode: 'index',

                        intersect: false,

                    },

                    hover: {

                        mode: 'nearest',

                        intersect: true

                    },

                    scales: {

                        x: {

                            display: true,

                            scaleLabel: {

                                display: true,

                                labelString: 'Epoch'

                            }

                        },

                        y: {

                            display: true,

                            scaleLabel: {

                                display: true,

                                labelString: 'Value'

                            }

                        }

                    }

                }

            }


            // Insert Actual Data into the Chart

            config.data.labels = data.map((d) => d.epoch);

            config.data.datasets = [{

                label: 'Train',

                backgroundColor: 'rgba(243,82,88,0.85)',

                borderColor: 'rgba(243,82,88,0.85)',

                data: data.map((d) => d.logs[names[i]]),

                fill: false,

            }, {

                label: 'Valid',

                fill: false,

                backgroundColor: 'rgb(99,219,255)',

                borderColor: 'rgb(99,219,255)',

                data: data.map((d) => d.logs[names_valid[i]]),

            }];


            const Context = canvas.getContext('2d');

            const chart = new Chart(Context, config);


            // Join all the elements together

            div.appendChild(canvas);

            td.appendChild(div);

            tr.appendChild(td);

        }

        docFrag.appendChild(tr);

        return docFrag;

    }

    function deleteRow(key) {

        // Delete the row if key is not in the data

        document.getElementById("chartBody").removeChild(document.getElementById(key));

    }


    function updateChart(key, data) {

        // Update chart if data's length and chart's dataset length is not same

        const to_split = Object.entries(data[0].logs);

        const middle = to_split.length / 2

        const train_log = Object.fromEntries(to_split.slice(0, middle));

        const valid_log = Object.fromEntries(to_split.slice(middle, data[0].logs.length));

        const names = Object.keys(train_log);

        const names_valid = Object.keys(valid_log);

        const n_current = data.length;

        const n_chart = Chart.getChart(key + '_' + names[0]).data.datasets[0].data.length;

        const n_update = n_current - n_chart;


        if (n_update !== 0) {

            for (let i = 0; i < names.length; i++) {

                const chart = Chart.getChart(key + '_' + names[i]);

                chart.data.labels = data.map((d) => d.epoch);

                chart.data.datasets[0].data = data.map((d) => d.logs[names[i]]);

                chart.data.datasets[1].data = data.map((d) => d.logs[names_valid[i]]);

                chart.update();

            }

        }

    }

</script>

<script>

    $(document).ready(function () {

        const source = new EventSource("/trainlog/data");

        let keys = []; // key and keys means train_name

        source.onmessage = function (event) {

            const data = JSON.parse(event.data);

            const data_keys = Object.keys(data);

            const new_keys = data_keys.filter(key => !keys.includes(key));

            const deleted_keys = keys.filter(key => !data_keys.includes(key));


            // Delete old Charts

            deleted_keys.forEach(key => {

                deleteRow(key);

                keys = keys.filter(k => k !== key);

            });


            // Update Charts

            keys.forEach(key => {

                updateChart(key, data[key]);

            })


            // Add new Charts

            new_keys.forEach(key => {

                document.getElementById("chartBody").appendChild(insertRow(key, data[key]));

                keys.push(key);

            });

        }

    });

</script>

</body>

</html>