Skip to content

Commit

Permalink
Add resizing per chart
Browse files Browse the repository at this point in the history
Signed-off-by: felix.gateru <felix.gateru@gmail.com>
  • Loading branch information
felixgateru committed Mar 6, 2024
1 parent 25f1b72 commit 19eca79
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 111 deletions.
4 changes: 2 additions & 2 deletions cmd/ui/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ const envPrefixGoogle = "MG_GOOGLE_"

type config struct {
LogLevel string `env:"MG_UI_LOG_LEVEL" envDefault:"debug"`
Port string `env:"MG_UI_PORT" envDefault:"9095"`
Port string `env:"MG_UI_PORT" envDefault:"9097"`
InstanceID string `env:"MG_UI_INSTANCE_ID" envDefault:""`
HTTPAdapterURL string `env:"MG_HTTP_ADAPTER_URL" envDefault:"http://localhost:8008"`
ReaderURL string `env:"MG_READER_URL" envDefault:"http://localhost:9007"`
ThingsURL string `env:"MG_THINGS_URL" envDefault:"http://localhost:9000"`
UsersURL string `env:"MG_USERS_URL" envDefault:"http://localhost:9002"`
HostURL string `env:"MG_UI_HOST_URL" envDefault:"http://localhost:9095"`
HostURL string `env:"MG_UI_HOST_URL" envDefault:"http://localhost:9097"`
BootstrapURL string `env:"MG_BOOTSTRAP_URL" envDefault:"http://localhost:9013"`
DomainsURL string `env:"MG_DOMAINS_URL" envDefault:"http://localhost:8189"`
InvitationsURL string `env:"MG_INVITATIONS_URL" envDefault:"http://localhost:9020"`
Expand Down
11 changes: 4 additions & 7 deletions ui/web/static/css/dashboards.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,12 @@ SPDX-License-Identifier: Apache-2.0 */
}

.grid-editable {
position: relative;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
grid-gap: 1rem;
padding: 1rem;

background-size: calc(18rem + 50px) calc(18rem + 50px);
background-size: calc(10rem + 10px) calc(10rem + 10px);
background-image: linear-gradient(to right, lightgrey 1px, transparent 1px),
linear-gradient(to bottom, lightgrey 1px, transparent 1px);

min-width: 100%;
min-height: 50vh;
}

.item {
Expand Down
105 changes: 105 additions & 0 deletions ui/web/static/js/charts.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class Echart extends Chart {
};
this.Content = this.#generateContent();
}

#generateContent() {
return `
<div class="item-content" id="${this.ID}" style="width: ${this.Style.width}; height: ${this.Style.height};">
Expand Down Expand Up @@ -1835,6 +1836,13 @@ class Widget {
this.widgetID = widgetID;
this.config = new chartTypes[this.chartData.Type](chartData, widgetID);
this.element = this.#createWidgetElement();
this.resizeObserver = this.initResizeObserver();
this.resizeObserver.observe(this.element);
this.previousSizes = new Map();
this.previousChartSize = {
width: 400,
height: 400,
};
}

#createWidgetElement() {
Expand All @@ -1861,4 +1869,101 @@ class Widget {
});
return newItem;
}

initResizeObserver() {
const resizeObserver = new ResizeObserver((entries) => {
for (let entry of entries) {
const { target } = entry;
const previousSize = previousSizes.get(target) || {
width: target.clientWidth,
height: target.clientHeight,
};
const contentEl = target.querySelector(".item-content");
const gridRightPosition = target.parentNode.getBoundingClientRect().right;
const widgetRightPosition = target.getBoundingClientRect().right;
const isOverflowing = widgetRightPosition > gridRightPosition;
if (isOverflowing) {
target.style.maxWidth = target.clientWidth + "px";
target.style.maxHeight = target.clientHeight + "px";
} else {
target.style.maxWidth = "none";
target.style.maxHeight = "none";
}

if (widgetRightPosition < gridRightPosition - 5) {
// Calculate the change in width and height
var widthChange = target.clientWidth - previousSize.width;
var heightChange = target.clientHeight - previousSize.height;
var itemContentWidth =
parseInt(window.getComputedStyle(contentEl).getPropertyValue("width")) + widthChange;
var itemContentHeight =
parseInt(window.getComputedStyle(contentEl).getPropertyValue("height")) + heightChange;

// Update the previous size for the next callback
previousSizes.set(target, {
width: target.clientWidth,
height: target.clientHeight,
});

target.style.width = target.clientWidth + "px";
target.style.height = target.clientHeight + "px";

contentEl.style.width = itemContentWidth + "px";
contentEl.style.height = itemContentHeight + "px";

// Resize apache echarts chart
const chart = echarts.getInstanceByDom(contentEl);
if (chart) {
chart.resize({
width: itemContentWidth,
height: itemContentHeight,
});
} else {
const cardDiv = target.querySelector(".widgetcard");
const h5Elem = cardDiv.querySelector("h5");
const cardBody = cardDiv.querySelector(".card-body");
const cardFooter = cardDiv.querySelector(".card-footer");

if (entry.contentBoxSize) {
// The standard makes contentBoxSize an array...
if (entry.contentBoxSize[0]) {
h5Elem.style.fontSize =
Math.max(1, entry.contentBoxSize[0].inlineSize / 300) + "rem";
if (cardBody) {
cardBody.style.fontSize =
Math.max(1.5, entry.contentBoxSize[0].inlineSize / 300) + "rem";
}
if (cardFooter) {
cardFooter.style.fontSize =
Math.max(1, entry.contentBoxSize[0].inlineSize / 600) + "rem";
}
} else {
// ...but old versions of Firefox treat it as a single item
h5Elem.style.fontSize = Math.max(1, entry.contentBoxSize.inlineSize / 300) + "rem";
if (cardBody) {
cardBody.style.fontSize =
Math.max(1.5, entry.contentBoxSize.inlineSize / 300) + "rem";
}
if (cardFooter) {
cardFooter.style.fontSize =
Math.max(1, entry.contentBoxSize.inlineSize / 600) + "rem";
}
}
} else {
h5Elem.style.fontSize = `${Math.max(1, entry.contentRect.width / 300)}rem`;
if (cardBody) {
cardBody.style.fontSize = `${Math.max(1.5, entry.contentRect.width / 300)}rem`;
}
if (cardFooter) {
cardFooter.style.fontSize = `${Math.max(1, entry.contentRect.width / 600)}rem`;
}
}
}
// grid.refreshItems();
// grid.layout(true);
}
}
});
return resizeObserver;
}
}
106 changes: 5 additions & 101 deletions ui/web/static/js/dashboard.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
const gridClass = ".grid";
const editableGridClass = ".grid-editable";
var grid = initGrid(layout);
const gridSize = 50;

Expand All @@ -15,7 +16,7 @@ function cancelEdit() {
function addWidget(chartData, widgetID) {
let newItem = new Widget(chartData, widgetID);
grid.add(newItem.element);
resizeObserver.observe(newItem.element);
// resizeObserver.observe(newItem.element);
}

function removeGridItem(item) {
Expand Down Expand Up @@ -136,6 +137,8 @@ function loadLayout(savedLayout) {
// widgets around the canvas
function editableCanvas() {
removeNoWidgetPlaceholder();
let ltgrid = document.querySelector(".grid");
ltgrid.classList.add("grid-editable");
try {
if (grid) {
grid.destroy(true);
Expand Down Expand Up @@ -169,7 +172,7 @@ function editableCanvas() {
height: widgetSize.height,
});
grid.add(newItem, { layout: true });
resizeObserver.observe(newItem);
// resizeObserver.observe(newItem);
});
grid.layout();
}
Expand All @@ -186,105 +189,6 @@ function editableCanvas() {
return grid;
}

const previousSizes = new Map();

const resizeObserver = new ResizeObserver((entries) => {
for (let entry of entries) {
const { target } = entry;

let snappedWidth = Math.round(target.clientWidth / gridSize) * gridSize;
let snappedHeight = Math.round(target.clientHeight / gridSize) * gridSize;

const previousSize = previousSizes.get(target) || {
width: snappedWidth,
height: snappedHeight,
};
const contentEl = target.querySelector(".item-content");
const gridRightPosition = target.parentNode.getBoundingClientRect().right;
const widgetRightPosition = target.getBoundingClientRect().right;
const isOverflowing = widgetRightPosition > gridRightPosition;
if (isOverflowing) {
target.style.maxWidth = target.clientWidth + "px";
target.style.maxHeight = target.clientHeight + "px";
} else {
target.style.maxWidth = "none";
target.style.maxHeight = "none";
}

if (widgetRightPosition < gridRightPosition - gridSize) {
// Calculate the change in width and height
var widthChange = snappedWidth - previousSize.width;
var heightChange = snappedHeight - previousSize.height;
var itemContentWidth =
parseInt(window.getComputedStyle(contentEl).getPropertyValue("width")) + widthChange;
var itemContentHeight =
parseInt(window.getComputedStyle(contentEl).getPropertyValue("height")) + heightChange;

// Update the previous size for the next callback
previousSizes.set(target, {
width: snappedWidth,
height: snappedHeight,
});

target.style.width = snappedWidth + "px";
target.style.height = snappedHeight + "px";

contentEl.style.width = itemContentWidth + "px";
contentEl.style.height = itemContentHeight + "px";

// Resize apache echarts chart
const chart = echarts.getInstanceByDom(contentEl);
if (chart) {
chart.resize({
width: itemContentWidth,
height: itemContentHeight,
});
} else {
const cardDiv = target.querySelector(".widgetcard");
const h5Elem = cardDiv.querySelector("h5");
const cardBody = cardDiv.querySelector(".card-body");
const cardFooter = cardDiv.querySelector(".card-footer");

if (entry.contentBoxSize) {
// The standard makes contentBoxSize an array...
if (entry.contentBoxSize[0]) {
h5Elem.style.fontSize = Math.max(1, entry.contentBoxSize[0].inlineSize / 300) + "rem";
if (cardBody) {
cardBody.style.fontSize =
Math.max(1.5, entry.contentBoxSize[0].inlineSize / 300) + "rem";
}
if (cardFooter) {
cardFooter.style.fontSize =
Math.max(1, entry.contentBoxSize[0].inlineSize / 600) + "rem";
}
} else {
// ...but old versions of Firefox treat it as a single item
h5Elem.style.fontSize = Math.max(1, entry.contentBoxSize.inlineSize / 300) + "rem";
if (cardBody) {
cardBody.style.fontSize =
Math.max(1.5, entry.contentBoxSize.inlineSize / 300) + "rem";
}
if (cardFooter) {
cardFooter.style.fontSize =
Math.max(1, entry.contentBoxSize.inlineSize / 600) + "rem";
}
}
} else {
h5Elem.style.fontSize = `${Math.max(1, entry.contentRect.width / 300)}rem`;
if (cardBody) {
cardBody.style.fontSize = `${Math.max(1.5, entry.contentRect.width / 300)}rem`;
}
if (cardFooter) {
cardFooter.style.fontSize = `${Math.max(1, entry.contentRect.width / 600)}rem`;
}
}
}
grid.refreshItems();
grid.layout(true);
}
}
});

// No widget placeholder
function showNoWidgetPlaceholder() {
const noWidgetPlaceholder = document.querySelector(".no-widget-placeholder");
Expand Down
1 change: 0 additions & 1 deletion ui/web/templates/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
<div class="row bg-white dashboard-canvas ">
<div class="no-widget-placeholder row align-items-center"></div>
<div class="grid"></div>
<div class="grid-editable"></div>
</div>

<!-- Off canvas containing the chart widgets -->
Expand Down

0 comments on commit 19eca79

Please sign in to comment.