tilelayout - resize event is not working for the first time.

1 Answer 83 Views
TileLayout
Steven
Top achievements
Rank 1
Steven asked on 23 Jul 2024, 04:46 PM

In below code, i dynamically loading telerik charts, and the resize of the Charts is not working for the first time. from second time its resizing as expected. For second time also i added some custom logic to fetch the width. I tried multiple ways, like debounce, observer the tilelayout. 

<div id="reports-container"></div>
<script>
    $(document).ready(function () {
        fetchReports();

        function fetchReports() {
            var loginId = @Model.CurrentUserId;
            $.ajax({
                url: '/api/Dashboard/ListDashboardItemByProfile',
                type: 'POST',
                data: { LoginId: loginId },
                success: function (data) {
                    displayReports(data);
                },
                error: function (e) {
                    error_handler(e);
                }
            });
        }

        function displayReports(reports) {
            var container = $('#reports-container');
            container.empty(); // Clear any existing reports

            var tileLayout = $('<div></div>')
                .attr('id', 'tilelayout')
                .attr('name', 'tilelayout')
                .addClass('k-widget k-tilelayout')
                .css({
                    'display': 'grid',
                    'grid-template-columns': 'repeat(6, 1fr)', // Ensure each column takes equal space
                    'grid-auto-rows': 'minmax(0, 185px)', // Ensure each row has a minimum height
                    'gap': '16px',
                    'padding': '16px'
                });

            container.append(tileLayout);

            reports.forEach(function (report) {
                var tileContainer = $('<div></div>')
                    .addClass('k-tilelayout-item k-card')
                    .attr('id', 'tile-container-' + report.ReportId)
                    .attr('data-profiledetailid', report.ProfileDetailId)
                    .css({
                        'grid-column-end': 'span ' + report.ColumnSpan,
                        'grid-row-end': 'span ' + report.RowSpan,
                        'order': report.ReportSequence,
                        'display': 'inline-flex',
                        'width': '100%', // Ensure tiles take full width within the grid column
                        'height': '100%' // Ensure tiles take full height within the grid row
                    });

                var tileHeader = $('<div></div>')
                    .addClass('k-tilelayout-item-header k-card-header k-cursor-grab')
                    .text(report.AltReportName);

                tileContainer.append(tileHeader);

                var tileBody = $('<div></div>')
                    .addClass('k-tilelayout-item-body k-card-body');

                tileContainer.append(tileBody);
                tileLayout.append(tileContainer);

                loadChart(report, tileBody); // Pass tileBody to loadChart function
            });

            initializeTileLayout();
        }

        function initializeTileLayout() {
            var computedWidthList = [];
            var resizeObserver;

            function handleResize(container, computedWidth, computedHeight) {
                var parentWidth = container.parent().width();
                var columnWidth = parentWidth / 6;
                var rowHeight = 225; // Adjust rowHeight if needed

                computedWidthList.push(computedWidth);
                console.log(computedWidthList);

                if (computedWidthList.length > 3) {
                    var lastcomputedWidth = computedWidthList[computedWidthList.length - 1];
                    var beforeLastcomputedWidth = computedWidthList[computedWidthList.length - 2];
                    var beforeBeforeLastcomputedWidth = computedWidthList[computedWidthList.length - 3];

                    if (beforeLastcomputedWidth == 0) {
                        var lastcomputedWidth = computedWidthList[computedWidthList.length - 1];
                        var beforeLastcomputedWidth = computedWidthList[computedWidthList.length - 3];
                        var beforeBeforeLastcomputedWidth = computedWidthList[computedWidthList.length - 4];
                    }

                    if (beforeBeforeLastcomputedWidth < beforeLastcomputedWidth && lastcomputedWidth < beforeLastcomputedWidth) {
                        computedWidth = beforeLastcomputedWidth;
                    } else if (beforeBeforeLastcomputedWidth > beforeLastcomputedWidth && lastcomputedWidth < beforeLastcomputedWidth) {
                        computedWidth = beforeLastcomputedWidth;
                    }
                }

                // Calculate the new column and row spans
                var newColumnSpan = Math.max(1, Math.round(computedWidth / columnWidth));
                var newRowSpan = Math.max(1, Math.round(computedHeight / rowHeight));

                // Update grid-column-end and grid-row-end styles
                container.css('grid-column-end', 'span ' + newColumnSpan);
                container.css('grid-row-end', 'span ' + newRowSpan);

                // Update data attributes for future calculations
                container.attr('data-colspan', newColumnSpan);
                container.attr('data-rowspan', newRowSpan);

                // Trigger chart resize if chart exists
                var chartContainer = container.find(".k-chart");
                if (chartContainer.length) {
                    chartContainer.data("kendoChart").resize();
                }
            }

            // Initialize the Kendo TileLayout
            $("#tilelayout").kendoTileLayout({
                columns: 6,
                gap: {
                    columns: 16,
                    rows: 16
                },
                containers: $(".k-tilelayout-item"),
                draggable: true,
                resizable: true,
                reorderable: true,
                resize: function (e) {
                    var resizedElement = e.container;
                    var resizedWidth = resizedElement.width();
                    var container = e.container;
                    console.log(resizedWidth);
                    if (!container || container.length === 0) {
                        console.error("Container not found");
                        return;
                    }

                    var containerElement = container[0];

                    // Disconnect previous observer if exists
                    if (resizeObserver) {
                        resizeObserver.disconnect();
                    }

                    // Create a new ResizeObserver to observe size changes during resize
                    resizeObserver = new ResizeObserver(entries => {
                        for (let entry of entries) {
                            const computedWidth = entry.contentRect.width;
                            const computedHeight = entry.contentRect.height;
                            handleResize(container, computedWidth, computedHeight);
                        }
                    });

                    // Observe the container element during resize
                    resizeObserver.observe(containerElement);
                },
                reorder: function (e) {
                    var container = $(e.container[0]);
                    if (container) {
                        var tileId = container.attr('id').replace('tile-container-', '');
                        var newIndex = e.newIndex;

                        // Update the order property based on the new index
                        container.css('order', newIndex); // Adjust for 1-based indexing
                        // Optionally, you may update this order value in your data model as well
                    }
                }
            });

        }




        function loadChart(report, containerElement) {
            var reportContainer = $('<div></div>')
                .attr('id', 'report-container-' + report.ReportId)
                .css({
                    'border': '1px solid #ddd',
                    'padding': '10px',
                    'margin': '5px',
                    'width': '100%',
                    'height': '100%'
                });

            containerElement.append(reportContainer);

            // Check if the report needs a chart or a gauge
            if (report.Type === "Bar" && report.ReportName == "Summary By Task") {
                loadSummaryByTask(report, reportContainer);
            } else if (report.Type === "Bar" && report.ReportName == "Summary By Employee") {
                loadSummaryByEmployee(report, reportContainer);
            } else if (report.Type === "Bar" && report.ReportName == "Summary By Site") {
                loadSummaryBySite(report, reportContainer);
            } else if (report.Type === "ArcGauge" && report.ReportName == "Long Duration Assignments") {
                loadLongDuration(report, reportContainer);
            } else if (report.Type === "Line" && report.ReportName == "Utilization By Site") {
                loadUtilizationBySite(report, reportContainer);
            } else if (report.Type === "Line" && report.ReportName == "Lines Per Hour by Site") {
                loadLinesPerHourbySite(report, reportContainer);
            } else if (report.Type === "Line" && report.ReportName == "Productivity By Site") {
                loadProductivityBySite(report, reportContainer);
            } else if (report.Type === "ArcGauge" && report.ReportName == "Error Audit Summary Report") {
                loadErrorAudit(report, reportContainer);
            }
        }

        function loadSummaryBySite(report, containerElement) {
            if (report.Duration == null) {
                report.Duration = 0;
            }
            $.post('/api/Dashboard/GetLabelsForReport', { reportName: report.ReportName })
                .done(function (labelsResponse) {
                    var labels = labelsResponse;

                    $.post('/api/Dashboard/GetDataForReport', { reportName: report.ReportName, siteId: report.SiteId, startDateId: report.StartDateId, endDateId: report.EndDateId, loginId: @Model.CurrentUserId, activityId: report.ActivityId, duration: report.Duration, frequencyId: report.FrequencyId, errorTypeId: report.ErrorTypeId })
                        .done(function (dataResponse) {
                            var data = dataResponse;

                            var chartElement = $('<div></div>')
                                .attr('id', 'chart-container-' + report.ReportId)
                                .css({
                                    'width': 'auto',
                                    'height': '400px'
                                });

                            containerElement.append(chartElement);

                            chartElement.kendoChart({
                                title: {
                                    text: ""
                                },
                                legend: {
                                    position: "top"
                                },
                                series: [{
                                    name: "Performance",
                                    data: data.map(d => d.Performance),
                                    type: "column",
                                    axis: "performance"
                                }],
                                categoryAxis: {
                                    categories: data.map(d => d.SiteName),
                                    labels: {
                                        rotation: -45,
                                        template: "#: value #"
                                    },
                                    title: {
                                        text: "SiteName"
                                    }
                                },
                                valueAxes: [{
                                    name: "performance",
                                    title: {
                                        text: "Performance"
                                    }
                                }],
                                tooltip: {
                                    visible: true,
                                    format: "{0}"
                                }
                            });

                            // Save the chart instance for resizing
                            chartElement.data("kendoChart").resize();
                        })
                        .fail(function () {
                            alert("Error loading chart data.");
                        });
                })
                .fail(function () {
                    alert("Error loading chart labels.");
                });
        }
</script>

1 Answer, 1 is accepted

Sort by
0
Martin
Telerik team
answered on 26 Jul 2024, 12:47 PM

Hello, Steven,

Could you please share a runnable Dojo example that reproduces the issue? I will be happy to investigate and provide further details.

Thank you for the cooperation. Looking forward to your reply.

Regards,
Martin
Progress Telerik

Do you have a stake in the designеr-developer collaboration process? If so, take our survey to share your perspective and become part of this global research. You’ll be among the first to know once the results are out.
-> Start The State of Designer-Developer Collaboration Survey 2024

Tags
TileLayout
Asked by
Steven
Top achievements
Rank 1
Answers by
Martin
Telerik team
Share this question
or