mirror of
https://github.com/UnickSoft/graphonline.git
synced 2026-10-11 19:14:18 +00:00
242 lines
6.9 KiB
JavaScript
242 lines
6.9 KiB
JavaScript
doInclude ([
|
|
include ("features/base_handler/index.js")
|
|
])
|
|
|
|
/**
|
|
* Save/Load graph from Incidence matrix.
|
|
*
|
|
*/
|
|
function ShowIncidenceMatrix(app)
|
|
{
|
|
BaseHandler.apply(this, arguments);
|
|
this.message = "";
|
|
}
|
|
|
|
// inheritance.
|
|
ShowIncidenceMatrix.prototype = Object.create(BaseHandler.prototype);
|
|
// First selected.
|
|
ShowIncidenceMatrix.prototype.firstObject = null;
|
|
// Path
|
|
ShowIncidenceMatrix.prototype.pathObjects = null;
|
|
|
|
ShowIncidenceMatrix.prototype.show = function()
|
|
{
|
|
var handler = this;
|
|
var dialogButtons = {};
|
|
let edgeNames = this.app.graph.edges.map(function(edge) { return edge.GetUpText(); });
|
|
let edgeEnumSelect = $("#incidenceEdgeEnumeration");
|
|
let edgeNamesDialog = $("#incidenceEdgeNamesDialog");
|
|
let edgeNamesList = $("#incidenceEdgeNamesList");
|
|
let currentColumns = [];
|
|
let currentColumnWidths = [];
|
|
let matrixIsValid = false;
|
|
let edgeEnumValue = this.app.currentEnumEdgesType || "";
|
|
if (edgeEnumValue === "Custom")
|
|
{
|
|
edgeEnumValue = "";
|
|
}
|
|
let selectedEdgeEnumValue = edgeEnumValue;
|
|
edgeEnumSelect.find("option:not(:first)").remove();
|
|
this.app.GetEnumVerticesList().forEach(function(item) {
|
|
if (item.value !== "Custom")
|
|
{
|
|
edgeEnumSelect.append($("<option>", { value: item.value, text: item.text }));
|
|
}
|
|
});
|
|
edgeEnumSelect.val(edgeEnumValue);
|
|
$("#IncidenceMatrixField").off("keyup change input");
|
|
|
|
dialogButtons[g_save] = function() {
|
|
let matrix = ta.val();
|
|
let rows = {};
|
|
let columns = {};
|
|
let validIncidenceMatrix = handler.app.TestIncidenceMatrix(matrix, rows, columns);
|
|
|
|
handler.app.PushToStack("IncidenceMatrixChanged");
|
|
handler.app.SetIncidenceMatrixSmart(matrix);
|
|
if (validIncidenceMatrix)
|
|
{
|
|
handler.app.SetEnumEdgesType(selectedEdgeEnumValue);
|
|
handler.app.graph.edges.forEach(function(edge, edgeIndex) {
|
|
edge.SetUpText(edgeNames[edgeIndex] || "");
|
|
});
|
|
handler.app.redrawGraph();
|
|
}
|
|
$( this ).dialog( "close" );
|
|
};
|
|
dialogButtons[g_cancel] = function() {
|
|
$( this ).dialog( "close" );
|
|
};
|
|
|
|
let ta = $("#IncidenceMatrixField");
|
|
let topWrap = $("#incidenceMatrix_top_text");
|
|
let sideWrap = $("#incidenceMatrix_side_text");
|
|
let incidenceMatrix = this.app.GetIncidenceMatrix();
|
|
|
|
ta.on("scroll", function() {
|
|
topWrap.scrollLeft(ta.scrollLeft());
|
|
sideWrap.scrollTop(ta.scrollTop());
|
|
});
|
|
|
|
$( "#IncidenceMatrixField" ).val(incidenceMatrix.trimEnd());
|
|
ta.focus()[0].setSelectionRange(0, 0);
|
|
|
|
$( "#BadIncidenceMatrixFormatMessage" ).hide();
|
|
|
|
/* Make side and top text */
|
|
let sideText = "";
|
|
for (let i = 0; i < this.app.graph.vertices.length; i++)
|
|
{
|
|
/* Each vertex name max 3 symbols */
|
|
sideText += this.app.graph.vertices[i].mainText.toString().slice(0, 3) + "\n";
|
|
}
|
|
$("#incidenceMatrix_side_text_text").html(sideText + "\n");
|
|
|
|
let topText = $("#incidenceMatrix_top_text_text");
|
|
let renderEdgeNames = function(columns) {
|
|
topText.empty();
|
|
let columnCount = columns.length > 0 ? columns[0].length : 0;
|
|
for (let edgeIndex = 0; edgeIndex < columnCount; edgeIndex++)
|
|
{
|
|
let edgeName = (edgeNames[edgeIndex] || "").slice(0, 2);
|
|
let columnWidth = Math.max(1, edgeName.length, currentColumnWidths[edgeIndex] || 0);
|
|
for (let rowIndex = 0; rowIndex < columns.length; rowIndex++)
|
|
{
|
|
columnWidth = Math.max(columnWidth, String(columns[rowIndex][edgeIndex]).trim().length);
|
|
}
|
|
topText.append(document.createTextNode(edgeName.slice(0, columnWidth).padStart(columnWidth, " ")));
|
|
if (edgeIndex < columnCount - 1)
|
|
{
|
|
topText.append(document.createTextNode(" "));
|
|
}
|
|
}
|
|
};
|
|
let getMatrixColumnWidths = function(matrix, columnCount) {
|
|
let widths = Array(columnCount).fill(1);
|
|
let rows = matrix.split(/\r?\n/).filter(function(row) { return row.trim().length > 0; });
|
|
rows.forEach(function(row) {
|
|
let cells = row.split(",");
|
|
if (cells.length !== columnCount)
|
|
{
|
|
return;
|
|
}
|
|
cells.forEach(function(cell, columnIndex) {
|
|
let cellWidth = cell.length;
|
|
if (columnIndex > 0 && cell.startsWith(" "))
|
|
{
|
|
cellWidth--;
|
|
}
|
|
widths[columnIndex] = Math.max(widths[columnIndex], cellWidth);
|
|
});
|
|
});
|
|
return widths;
|
|
};
|
|
let getEdgeEnumType = function(value) {
|
|
return handler.app.enumVerticesTextList.find(function(enumType) {
|
|
return enumType.GetValue() === value && value !== "Custom";
|
|
});
|
|
};
|
|
let applyEdgeEnumeration = function(value) {
|
|
if (!matrixIsValid)
|
|
{
|
|
return;
|
|
}
|
|
selectedEdgeEnumValue = value;
|
|
let enumType = getEdgeEnumType(value);
|
|
for (let edgeIndex = 0; edgeIndex < edgeNames.length; edgeIndex++)
|
|
{
|
|
edgeNames[edgeIndex] = enumType ? enumType.GetVertexText(edgeIndex).toString() : "";
|
|
}
|
|
renderEdgeNames(currentColumns);
|
|
};
|
|
|
|
edgeEnumSelect.off("change").on("change", function() {
|
|
applyEdgeEnumeration($(this).val());
|
|
});
|
|
|
|
$("#editIncidenceEdgeNames").off("click").on("click", function() {
|
|
if (!matrixIsValid)
|
|
{
|
|
return;
|
|
}
|
|
edgeNamesList.val(edgeNames.join("\n"));
|
|
edgeNamesDialog.dialog("open");
|
|
});
|
|
|
|
edgeNamesDialog.dialog({
|
|
autoOpen: false,
|
|
modal: true,
|
|
resizable: false,
|
|
width: "auto",
|
|
title: $("#EdgeLabel").text().trim(),
|
|
buttons: {
|
|
[g_save]: function() {
|
|
let editedNames = edgeNamesList.val().split(/\r?\n/);
|
|
edgeNames = Array.from({ length: edgeNames.length }, function(_, index) {
|
|
return editedNames[index] || "";
|
|
});
|
|
renderEdgeNames(currentColumns);
|
|
$(this).dialog("close");
|
|
},
|
|
[g_cancel]: function() {
|
|
$(this).dialog("close");
|
|
}
|
|
},
|
|
dialogClass: 'EdgeDialog'
|
|
});
|
|
|
|
let updateMatrixState = function() {
|
|
let rows = {};
|
|
let columns = {};
|
|
let isValid = handler.app.TestIncidenceMatrix(ta.val(), rows, columns);
|
|
if (isValid)
|
|
{
|
|
let columnCount = columns.cols.length > 0 ? columns.cols[0].length : 0;
|
|
currentColumns = columns.cols;
|
|
currentColumnWidths = getMatrixColumnWidths(ta.val(), columnCount);
|
|
let enumType = getEdgeEnumType(selectedEdgeEnumValue);
|
|
if (columnCount < edgeNames.length)
|
|
{
|
|
edgeNames.length = columnCount;
|
|
}
|
|
else
|
|
{
|
|
for (let edgeIndex = edgeNames.length; edgeIndex < columnCount; edgeIndex++)
|
|
{
|
|
edgeNames.push(enumType ? enumType.GetVertexText(edgeIndex).toString() : "");
|
|
}
|
|
}
|
|
matrixIsValid = true;
|
|
edgeEnumSelect.prop("disabled", false);
|
|
$("#editIncidenceEdgeNames").prop("disabled", false);
|
|
$("#BadIncidenceMatrixFormatMessage").hide();
|
|
renderEdgeNames(columns.cols);
|
|
}
|
|
else
|
|
{
|
|
matrixIsValid = false;
|
|
edgeEnumSelect.prop("disabled", true);
|
|
$("#editIncidenceEdgeNames").prop("disabled", true);
|
|
$("#BadIncidenceMatrixFormatMessage").show();
|
|
}
|
|
};
|
|
|
|
ta.on("input", updateMatrixState);
|
|
updateMatrixState();
|
|
|
|
$( "#incidenceMatrix" ).dialog({
|
|
resizable: false,
|
|
height: "auto",
|
|
width: "auto",
|
|
modal: true,
|
|
title: g_incidenceMatrixText,
|
|
buttons: dialogButtons,
|
|
dialogClass: 'EdgeDialog',
|
|
open: function(event, ui) {
|
|
/* Set width for side text */
|
|
topWrap.width(ta.width());
|
|
$("#BadIncidenceMatrixFormatMessage").width(ta.width());
|
|
}
|
|
});
|
|
}
|