Skip to content

Commit

Permalink
Merge pull request #44 from SoopSASM/feature/group-chart-node-connection
Browse files Browse the repository at this point in the history
[modify] connect chart node with group node
  • Loading branch information
lea-hwang authored Oct 2, 2022
2 parents 62f0ff7 + 4e1d018 commit 91c8654
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 74 deletions.
155 changes: 127 additions & 28 deletions dashboard/nodes/soop_chart.html
Original file line number Diff line number Diff line change
@@ -1,24 +1,109 @@
<script type="text/javascript">
const chartPositionSelector = "#node-input-widgetX, #node-input-widgetY, #node-input-width, #node-input-height";
function getGroupGrid(nodeId) {
const groupId = $("#node-input-group").val();
const groupNode = RED.nodes.node(groupId);
groupNode._def.reflectEdit(groupId, nodeId);
return groupNode.groupState;
}
function getXYWH() {
const x = parseInt($("#node-input-widgetX").val());
const y = parseInt($("#node-input-widgetY").val());
const w = parseInt($("#node-input-width").val());
const h = parseInt($("#node-input-height").val());
return { x, y, w, h };
}
// Validate the widget to place on (x, y, w, h).
function validateXYWH(arr) {
const { x, y, w, h } = getXYWH();
// If x, y, w, h is under or over idx of arr -> return false
if (x < 0 || y < 0 || w <= 0 || h <= 0 || w > 12 || x + w > arr[0].length || y + h > arr.length) {
return false;
}
// If the space is alredy filled, return false
for (let i = x; i < x + w; i++) {
for (let j = y; j < y + h; j++) {
if (arr[j][i]) {
return false;
}
}
}
return true;
}
// Create a table with array
function newTable(arr) {
const row = arr.length;
const col = arr[0].length;
// Append a row for column header(1,2,....)
$("#group-table>tbody").append('<tr id="col-header"></tr>');
$("#col-header").append("<th></th>");
for (let j = 0; j < col; j++) {
$("#col-header").append(`<th scope="col">${j}</th>`);
}
// Append group row and col
for (let i = 0; i < row; i++) {
// append row
$("#group-table>tbody").append(`<tr id="row${i}"></tr>`);
// Append a col for row header(1,2,...)
$(`#row${i}`).append(`<th scope="row" class="row-header">${i}</th>`);
// Append col
for (let j = 0; j < col; j++) {
const tag = `<td id="col${j}" class="col ${arr[i][j] ? "filled" : "empty"}" ></td>`;
$(`#row${i}`).append(tag);
}
}
// Table Design
$(".col").css("border", "dotted black 1px");
$(".col").css("width", "20px");
$(".col").css("height", "20px");
$(".filled").css("background-color", "#DEDEDE");
$(".empty").css("background-color", "#FFFFFF");
$("th").css("border", "none");
}
// Remove color for new node and return the original color for filled or empty space
function removeColor(w, h) {
for (let i = 0; i < w; i++) {
for (let j = 0; j < h; j++) {
$(`#row${j}>#col${i}`).removeClass("new-node");
}
}
$(".filled").css("background-color", "#DEDEDE");
$(".empty").css("background-color", "#FFFFFF");
}
// Add color for new node
function addColor() {
const { x, y, w, h } = getXYWH();
for (let i = x; i < x + w; i++) {
for (let j = y; j < y + h; j++) {
$(`#row${j}>#col${i}`).addClass("new-node");
}
}
$(".new-node").css("background-color", "#D9E5FF");
}
// Add new node on group grid
function addNewNode(arr) {
// Remove 'new-node' class in every row-col
const { x, y, w, h } = getXYWH();
removeColor(arr[0].length, arr.length);
// if (x, y, w, h) is ok, then put. or error.
if (validateXYWH(arr)) {
addColor();
$(chartPositionSelector).removeClass("input-error");
} else {
$(chartPositionSelector).addClass("input-error");
console.log(`You can not put a node on (${y}, ${x})`);
}
}
RED.nodes.registerType("soop_chart", {
category: "soop-dashboard",
color: "rgb(100, 189, 27)", // 이후 수정되어야할 부분
color: "#1153FC",
defaults: {
group: { type: "soop_group", required: true },
width: {
value: 0,
validate: function (value) {
const width = value || 0;
const currentGroup = $("#node-input-group").val() || this.group;
const groupNode = RED.nodes.node(currentGroup);
const valid = !groupNode || +width <= +groupNode.width;
$("#node-input-size").toggleClass("input-error", !valid);
return valid;
},
},
height: { value: 0 },
width: { value: 1, validate: RED.validators.number(), required: true },
height: { value: 1, validate: RED.validators.number(), required: true },
widgetX: { value: 0, validate: RED.validators.number(), required: true },
widgetY: { value: 0, validate: RED.validators.number(), required: true },
label: { value: "chart_name" },
title: { value: "chart_name" },
chartType: { value: "line" },
xAxisFormat: { value: "HH:mm:ss" },
customValue: { value: "" },
Expand Down Expand Up @@ -48,26 +133,31 @@
return `${this.chartType} chart data`;
},
label: function () {
return this.name || (~this.label.indexOf("{{") ? null : this.label) || "new_chart";
return this.name || (~this.title.indexOf("{{") ? null : this.title) || "new_chart";
},
labelStyle: function () {
return this.name ? "node_label_italic" : "";
},
oneditprepare: function () {
// 이후 삭제
$("#node-input-size").elementSizer({
width: "#node-input-width",
height: "#node-input-height",
group: "#node-input-group",
});
$.fn.groupTable = function (arr) {
$(this).append('<table border="1" id="group-table"><tbody></tbody></table>');
newTable(arr);
$(chartPositionSelector).on("change", () => addNewNode(arr));
};
$("#node-input-group-table").groupTable(getGroupGrid(this.id));

if (!$("#node-input-widgetX").val()) {
$("#node-input-widgetX").val(0);
}
if (!$("#node-input-widgetY").val()) {
$("#node-input-widgetY").val(0);
}

if (!$("#node-input-width").val()) {
$("#node-input-width").val(1);
}
if (!$("#node-input-height").val()) {
$("#node-input-height").val(1);
}
if (!$("#node-input-chartType").val()) {
$("#node-input-chartType").val("line");
}
Expand Down Expand Up @@ -121,14 +211,23 @@
<input type="text" id="node-input-group" />
</div>
<div class="form-row">
<label for="node-input-size"><i class="fa fa-object-group"></i> Size</label>
<input type="hidden" id="node-input-width" />
<input type="hidden" id="node-input-height" />
<button class="editor-button" id="node-input-size"></button>
<label for="node-input-group-table"><i class="fa fa-table"></i> Group table</label>
<div id="node-input-group-table" style="width:70%; display: inline-block;">
<div style="margin-bottom:10px">
<label for="node-input-widgetX" style="width:auto;">x</label>
<input type="text" id="node-input-widgetX" value="0" style="width:30px; margin-right:10px;" />
<label for="node-input-widgetY" style="width:auto;">y </label>
<input type="text" id="node-input-widgetY" value="0" style="width:30px; margin-right:10px;" />
<label for="node-input-width" style="width:auto;">w</label>
<input type="text" id="node-input-width" value="1" style="width:30px; margin-right:10px;" />
<label for="node-input-height" style="width:auto;">h</label>
<input type="text" id="node-input-height" value="1" style="width:30px; margin-right:10px;" />
</div>
</div>
</div>
<div class="form-row">
<label for="node-input-label"><i class="fa fa-i-cursor"></i> Label</label>
<input type="text" id="node-input-label" />
<label for="node-input-title"><i class="fa fa-i-cursor"></i> Label</label>
<input type="text" id="node-input-title" />
</div>
<div class="form-row">
<label for="node-input-chartType"><i class="fa fa-line-chart"></i> Type</label>
Expand Down
49 changes: 3 additions & 46 deletions dashboard/nodes/soop_chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,65 +5,22 @@ module.exports = function (RED) {
const node = this;
RED.nodes.createNode(node, config);

// const group = RED.nodes.getNode(config.group);
// if (!group) {
// node.error('Group is undefined.')
// return;
// }
// var tab = RED.nodes.getNode(group.config.tab);
// if (!tab) {
// node.error('Tab is undefined.')
// return;
// }
const group = "";
const chartType = config.chartType;
let state = {
// nodeId: node.id,
node_id: node.id,
nodeType: "chart",
group: group,
// tab: tab,
size: [
// parseInt(config.height || group.config.width / 2 + 1 || 4),
// parseInt(config.width || group.config.width || 6),
parseInt(4),
parseInt(6),
parseInt(config.widgetX),
parseInt(config.widgetY),
],
// label: config.label,
title: config.label,
chartType: config.chartType,
legend: config.legend === "true" ? true : false,
blankLabel: config.blankLabel,
isTimeSeries: config.isTimeSeries,
};

if (chartType === "line" || chartType === "bar") {
state = Object.assign(state, {
xAxisFormat: config.xAxisFormat,
yMin: config.yMin ? parseInt(config.yMin) : "",
yMax: config.yMax ? parseInt(config.yMax) : "",
customValue: config.xAxisFormat === "custom" ? config.customValue : "",
});
}
// send state to dashboard
dashboard.emitState(state, config.isTimeSeries);
node.on("input", function (msg, done) {
if (isNaN(msg.payload)) {
node.error("Payload is not a number.");
return;
}
dashboard.emitState(
{
node_id: node.id,
nodeId: node.id,
data: {
[msg.label]: {
value: parseInt(msg.payload),
value: +msg.payload,
},
},
},
config.isTimeSeries,
true,
);
// done
if (done) done();
Expand Down

0 comments on commit 91c8654

Please sign in to comment.