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>