mirror of
https://github.com/UnickSoft/graphonline.git
synced 2025-07-01 23:36:00 +00:00
Merge branch 'master' of https://github.com/UnickSoft/graphonline
This commit is contained in:
commit
a3ac8b8fe5
@ -240,6 +240,20 @@
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
#CanvasMessage
|
||||
{
|
||||
position: absolute;
|
||||
right: 48px;
|
||||
z-index: 10;
|
||||
-webkit-touch-callout: none; /* iOS Safari */
|
||||
-webkit-user-select: none; /* Safari */
|
||||
-khtml-user-select: none; /* Konqueror HTML */
|
||||
-moz-user-select: none; /* Firefox */
|
||||
-ms-user-select: none; /* Internet Explorer/Edge */
|
||||
user-select: none; /* Non-prefixed version, currently
|
||||
supported by Chrome and Opera */
|
||||
}
|
||||
|
||||
.MarginLeft
|
||||
{
|
||||
margin-right: 32px !important;
|
||||
@ -326,3 +340,18 @@
|
||||
min-width: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.InlineStyle
|
||||
{
|
||||
display:inline;
|
||||
}
|
||||
|
||||
.PaddingRight
|
||||
{
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
#NewEdgeAction
|
||||
{
|
||||
padding-top: 8px;
|
||||
}
|
@ -165,4 +165,12 @@
|
||||
$g_lang["alpha"] = "Opacity";
|
||||
|
||||
$g_lang["background_style"] = "Background color";
|
||||
|
||||
$g_lang["adjacency_matrix_multigraph_description"] = "Multigraph matrix contains weight of minimum edges between vertices.";
|
||||
|
||||
$g_lang["graph_is_multi_message"] = "Multigraph does not support all algorithms";
|
||||
$g_lang["graph_is_general_message"] = "";
|
||||
|
||||
$g_lang["replace_edge"] = "replace current";
|
||||
$g_lang["add_edge"] = "add (multigraph)";
|
||||
?>
|
||||
|
@ -168,4 +168,12 @@
|
||||
$g_lang["alpha"] = "Прозрачность";
|
||||
|
||||
$g_lang["background_style"] = "Цвет фона";
|
||||
|
||||
$g_lang["adjacency_matrix_multigraph_description"] = "Для мультиграфа матрица содержит значения минимальных дуг между вершинами.";
|
||||
|
||||
$g_lang["replace_edge"] = "заменить текущую";
|
||||
$g_lang["add_edge"] = "добавить (мультиграф)";
|
||||
|
||||
$g_lang["graph_is_multi_message"] = "Мультиграф не поддерживает все алгоритмы";
|
||||
$g_lang["graph_is_general_message"] = "";
|
||||
?>
|
||||
|
@ -135,7 +135,11 @@ BaseAlgorithm.prototype.getPriority = function()
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Algorithm support multi graph
|
||||
BaseAlgorithm.prototype.IsSupportMultiGraph = function()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default handler.
|
||||
|
@ -79,6 +79,8 @@ Application.prototype.redrawGraph = function()
|
||||
if (!this.isTimerRender)
|
||||
{
|
||||
this._redrawGraph();
|
||||
|
||||
this.GraphTypeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@ -417,9 +419,9 @@ Application.prototype.AddNewVertex = function(vertex)
|
||||
return this.graph.AddNewVertex(vertex);
|
||||
}
|
||||
|
||||
Application.prototype.AddNewEdge = function(edge)
|
||||
Application.prototype.AddNewEdge = function(edge, replaceIfExists)
|
||||
{
|
||||
return this.graph.AddNewEdge(edge);
|
||||
return this.graph.AddNewEdge(edge, replaceIfExists);
|
||||
}
|
||||
|
||||
Application.prototype.CreateNewGraph = function(x, y)
|
||||
@ -439,20 +441,35 @@ Application.prototype.CreateNewGraphEx = function(x, y, vertexEnume)
|
||||
return this.graph.AddNewVertex(new BaseVertex(x, y, vertexEnume));
|
||||
}
|
||||
|
||||
Application.prototype.CreateNewArc = function(graph1, graph2, isDirect, weight)
|
||||
Application.prototype.CreateNewArc = function(graph1, graph2, isDirect, weight, replaceIfExist)
|
||||
{
|
||||
var edge = this.AddNewEdge(new BaseEdge(graph1, graph2, isDirect, weight));
|
||||
|
||||
// Make cruvled for pair.
|
||||
var edge = this.AddNewEdge(new BaseEdge(graph1, graph2, isDirect, weight), replaceIfExist);
|
||||
|
||||
var edgeObject = this.graph.edges[edge];
|
||||
if (edgeObject.hasPair)
|
||||
var hasPair = this.graph.hasPair(edgeObject);
|
||||
var neighbourEdges = this.graph.getNeighbourEdges(edgeObject);
|
||||
|
||||
if (hasPair)
|
||||
{
|
||||
if (edgeObject.model.default)
|
||||
edgeObject.model.type = EdgeModels.cruvled;
|
||||
|
||||
var pairEdge = this.FindEdge(graph2.id, graph1.id);
|
||||
var pairEdge = this.graph.FindPairFor(edgeObject);
|
||||
if (pairEdge.model.default)
|
||||
pairEdge.model.type = EdgeModels.cruvled;
|
||||
{
|
||||
pairEdge.model.type = EdgeModels.cruvled;
|
||||
if (pairEdge.vertex1 == edgeObject.vertex1 && pairEdge.vertex2 == edgeObject.vertex2)
|
||||
pairEdge.model.curvedValue = -pairEdge.model.curvedValue;
|
||||
}
|
||||
}
|
||||
else if (neighbourEdges.length >= 2)
|
||||
{
|
||||
var cruvled = this.GetAvalibleCruvledValue(neighbourEdges, edgeObject);
|
||||
if (edgeObject.model.default)
|
||||
{
|
||||
edgeObject.model.type = EdgeModels.cruvled;
|
||||
edgeObject.model.curvedValue = cruvled;
|
||||
}
|
||||
}
|
||||
|
||||
return edge;
|
||||
@ -462,16 +479,18 @@ Application.prototype.DeleteEdge = function(edgeObject)
|
||||
{
|
||||
var vertex1 = edgeObject.vertex1;
|
||||
var vertex2 = edgeObject.vertex2;
|
||||
var hasPair = edgeObject.hasPair;
|
||||
|
||||
var hasPair = this.graph.hasPair(edgeObject);
|
||||
|
||||
this.graph.DeleteEdge(edgeObject);
|
||||
|
||||
// Make line for pair.
|
||||
if (hasPair)
|
||||
{
|
||||
var edgeObject = this.FindEdge(vertex2.id, vertex1.id);
|
||||
if (edgeObject.model.default)
|
||||
edgeObject.model.type = EdgeModels.line;
|
||||
var pairEdges = this.FindAllEdges(vertex2.id, vertex1.id);
|
||||
|
||||
if (pairEdges.length == 1 && pairEdges[0].model.default)
|
||||
pairEdges[0].model.type = EdgeModels.line;
|
||||
}
|
||||
}
|
||||
|
||||
@ -508,6 +527,16 @@ Application.prototype.FindEdge = function(id1, id2)
|
||||
return this.graph.FindEdge(id1, id2);
|
||||
}
|
||||
|
||||
Application.prototype.FindEdgeAny = function(id1, id2)
|
||||
{
|
||||
return this.graph.FindEdgeAny(id1, id2);
|
||||
}
|
||||
|
||||
Application.prototype.FindAllEdges = function(id1, id2)
|
||||
{
|
||||
return this.graph.FindAllEdges(id1, id2);
|
||||
}
|
||||
|
||||
Application.prototype.FindPath = function(graph1, graph2)
|
||||
{
|
||||
var creator = new GraphMLCreater(this.graph.vertices, this.graph.edges);
|
||||
@ -1501,3 +1530,39 @@ Application.prototype.ResetBackgroundStyle = function ()
|
||||
this.isBackgroundCommonStyleCustom = false;
|
||||
}
|
||||
|
||||
Application.prototype.GetAvalibleCruvledValue = function(neighbourEdges, originalEdge)
|
||||
{
|
||||
var values = [];
|
||||
|
||||
for (var i = 0; i < neighbourEdges.length; i ++)
|
||||
{
|
||||
var edge = neighbourEdges[i];
|
||||
var sameDirection = (originalEdge.vertex1.id == edge.vertex1.id);
|
||||
if (edge.model.type == EdgeModels.cruvled)
|
||||
{
|
||||
values[(sameDirection ? edge.model.curvedValue : -edge.model.curvedValue)] = true;
|
||||
}
|
||||
}
|
||||
|
||||
var changeValue = DefaultHandler.prototype.curvedValue;
|
||||
var defaultValue = 0.0;
|
||||
var maxSearch = 10;
|
||||
|
||||
for (var i = 1; i < maxSearch; i ++)
|
||||
{
|
||||
value = i * changeValue;
|
||||
if (!values.hasOwnProperty(value))
|
||||
return value;
|
||||
|
||||
value = - i * changeValue;
|
||||
if (!values.hasOwnProperty(value))
|
||||
return value;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
Application.prototype.GraphTypeChanged = function()
|
||||
{
|
||||
$("#CanvasMessage").text(this.graph.isMulti() ? g_GrapsIsMultiMessage : g_GrapsIsGeneralMessage);
|
||||
}
|
@ -14,8 +14,6 @@ function BaseEdge(vertex1, vertex2, isDirect, weight)
|
||||
this.isDirect = isDirect;
|
||||
this.weight = 0;
|
||||
this.text = "";
|
||||
// For direct graph, has pair edge or not.
|
||||
this.hasPair = false;
|
||||
this.useWeight = false;
|
||||
this.id = 0;
|
||||
this.model = new EdgeModel();
|
||||
@ -32,7 +30,6 @@ BaseEdge.prototype.SaveToXML = function ()
|
||||
"isDirect=\"" + this.isDirect + "\" " +
|
||||
"weight=\"" + this.weight + "\" " +
|
||||
"useWeight=\"" + this.useWeight + "\" " +
|
||||
"hasPair=\"" + this.hasPair + "\" " +
|
||||
"id=\"" + this.id + "\" " +
|
||||
"text=\"" + this.text + "\" " +
|
||||
"arrayStyleStart=\"" + this.arrayStyleStart + "\" " +
|
||||
@ -99,33 +96,7 @@ BaseEdge.prototype.HitTest = function (pos)
|
||||
|
||||
BaseEdge.prototype.GetEdgePositionsShift = function()
|
||||
{
|
||||
var pairShift = this.vertex1.model.diameter * 0.25;
|
||||
var shift = (this.hasPair ? pairShift : 0);
|
||||
|
||||
if (shift == 0 || this.model.type == EdgeModels.cruvled)
|
||||
{
|
||||
return this.GetEdgePositions();
|
||||
}
|
||||
else
|
||||
{
|
||||
var position1 = this.vertex1.position;
|
||||
var position2 = this.vertex2.position;
|
||||
var diameter1 = this.vertex1.model.diameter;
|
||||
var diameter2 = this.vertex2.model.diameter;
|
||||
|
||||
var direction = position1.subtract(position2);
|
||||
direction.normalize(1.0);
|
||||
var normal = direction.normal();
|
||||
direction = direction.multiply(0.5);
|
||||
position1 = position1.subtract(normal.multiply(shift));
|
||||
position2 = position2.subtract(normal.multiply(shift));
|
||||
diameter1 = Math.sqrt(diameter1 * diameter1 - shift * shift);
|
||||
diameter2 = Math.sqrt(diameter2 * diameter2 - shift * shift);
|
||||
var res = [];
|
||||
res.push(position1.subtract(direction.multiply(diameter1)));
|
||||
res.push(position2.subtract(direction.multiply(-diameter2)));
|
||||
return res;
|
||||
}
|
||||
return this.GetEdgePositions();
|
||||
}
|
||||
|
||||
BaseEdge.prototype.GetEdgePositions = function()
|
||||
|
@ -163,7 +163,7 @@ BaseEdgeDrawer.prototype.Draw = function(baseEdge, arcStyle)
|
||||
|
||||
if (baseEdge.GetText().length > 0)
|
||||
{
|
||||
this.DrawWeight(positions[0], positions[1], baseEdge.GetText(), arcStyle, baseEdge.hasPair);
|
||||
this.DrawWeight(positions[0], positions[1], baseEdge.GetText(), arcStyle, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -274,7 +274,7 @@ BaseEdgeDrawer.prototype.GetTextCenterPoint = function (position1, position2, ha
|
||||
}
|
||||
|
||||
var textShift = Math.min(12 / position1.subtract(position2).length(), 0.4);
|
||||
var centerPoint = Point.interpolate(position1, position2, 0.5 + (hasPair ? textShift : 0));
|
||||
var centerPoint = Point.interpolate(position1, position2, 0.5);
|
||||
if (position1.equals(position2))
|
||||
{
|
||||
centerPoint.y = centerPoint.y - Math.cos(arcStyle.loopShiftAngel) * arcStyle.sizeOfLoop * 2;
|
||||
|
@ -419,7 +419,7 @@ ConnectionGraphHandler.prototype.firstObject = null;
|
||||
|
||||
ConnectionGraphHandler.prototype.AddNewEdge = function(selectedObject, isDirect)
|
||||
{
|
||||
this.app.CreateNewArc(this.firstObject, selectedObject, isDirect, document.getElementById('EdgeWeight').value);
|
||||
this.app.CreateNewArc(this.firstObject, selectedObject, isDirect, document.getElementById('EdgeWeight').value, $("#RadiosReplaceEdge").prop("checked"));
|
||||
this.SelectFirst();
|
||||
this.app.NeedRedraw();
|
||||
}
|
||||
@ -431,6 +431,26 @@ ConnectionGraphHandler.prototype.SelectVertex = function(selectedObject)
|
||||
var direct = false;
|
||||
var handler = this;
|
||||
var dialogButtons = {};
|
||||
|
||||
if (!this.app.graph.isMulti())
|
||||
{
|
||||
var hasEdge = this.app.graph.FindEdgeAny(this.firstObject.id, selectedObject.id);
|
||||
var hasReverseEdge = this.app.graph.FindEdgeAny(selectedObject.id, this.firstObject.id);
|
||||
|
||||
if (hasEdge == null && hasReverseEdge == null)
|
||||
{
|
||||
$("#RadiosReplaceEdge").prop("checked", true);
|
||||
$("#NewEdgeAction" ).hide();
|
||||
}
|
||||
else
|
||||
$( "#NewEdgeAction" ).show();
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#RadiosAddEdge").prop("checked", true);
|
||||
$("#NewEdgeAction" ).hide();
|
||||
}
|
||||
|
||||
dialogButtons[g_orintEdge] = function() {
|
||||
handler.AddNewEdge(selectedObject, true);
|
||||
$( this ).dialog( "close" );
|
||||
@ -635,7 +655,12 @@ ShowAdjacencyMatrix.prototype.show = function()
|
||||
|
||||
$( "#AdjacencyMatrixField" ).val(this.app.GetAdjacencyMatrix());
|
||||
$( "#BadMatrixFormatMessage" ).hide();
|
||||
|
||||
|
||||
if (this.app.graph.isMulti())
|
||||
$( "#AdjacencyMatrixMultiGraphDesc").show();
|
||||
else
|
||||
$( "#AdjacencyMatrixMultiGraphDesc").hide();
|
||||
|
||||
$( "#adjacencyMatrix" ).dialog({
|
||||
resizable: false,
|
||||
height: "auto",
|
||||
|
161
script/Graph.js
161
script/Graph.js
@ -16,6 +16,8 @@ function Graph()
|
||||
this.uidEdge = 10000;
|
||||
// Has direction edge.
|
||||
this.hasDirect = false;
|
||||
// Is graph multi
|
||||
this.isMultiGraph = false;
|
||||
};
|
||||
|
||||
// infinity
|
||||
@ -37,43 +39,33 @@ Graph.prototype.AddNewEdgeSafe = function(graph1, graph2, isDirect, weight)
|
||||
return this.AddNewEdge(new BaseEdge(graph1, graph2, isDirect, weight));
|
||||
}
|
||||
|
||||
Graph.prototype.AddNewEdge = function(edge)
|
||||
Graph.prototype.AddNewEdge = function(edge, replaceIfExists)
|
||||
{
|
||||
edge.id = this.uidEdge;
|
||||
this.uidEdge = this.uidEdge + 1;
|
||||
|
||||
var edge1 = this.FindEdge(edge.vertex1.id, edge.vertex2.id);
|
||||
var edgeRevert = this.FindEdge(edge.vertex2.id, edge.vertex1.id);
|
||||
var edge1 = this.FindEdgeAny(edge.vertex1.id, edge.vertex2.id);
|
||||
var edgeRevert = this.FindEdgeAny(edge.vertex2.id, edge.vertex1.id);
|
||||
if (!edge.isDirect)
|
||||
{
|
||||
if (edge1 != null)
|
||||
{
|
||||
if (edge1 != null && replaceIfExists)
|
||||
this.DeleteEdge(edge1);
|
||||
}
|
||||
if (edgeRevert != null)
|
||||
{
|
||||
if (edgeRevert != null && replaceIfExists)
|
||||
this.DeleteEdge(edgeRevert);
|
||||
}
|
||||
|
||||
this.edges.push(edge);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (edge1 != null)
|
||||
{
|
||||
if (edge1 != null && replaceIfExists)
|
||||
this.DeleteEdge(edge1);
|
||||
}
|
||||
if (edgeRevert != null && !edgeRevert.isDirect)
|
||||
{
|
||||
if (edgeRevert != null && !edgeRevert.isDirect && replaceIfExists)
|
||||
this.DeleteEdge(edgeRevert);
|
||||
}
|
||||
else if (edgeRevert != null)
|
||||
{
|
||||
edgeRevert.hasPair = true;
|
||||
edge.hasPair = true;
|
||||
}
|
||||
|
||||
this.edges.push(edge);
|
||||
}
|
||||
|
||||
this.isMultiGraph = this.checkMutiGraph();
|
||||
|
||||
return this.edges.length - 1;
|
||||
}
|
||||
@ -84,16 +76,12 @@ Graph.prototype.DeleteEdge = function(edgeObject)
|
||||
var index = this.edges.indexOf(edgeObject);
|
||||
if (index > -1)
|
||||
{
|
||||
var edgeRevert = this.FindEdge(edgeObject.vertex2.id, edgeObject.vertex1.id);
|
||||
if (edgeRevert != null && edgeRevert.isDirect)
|
||||
{
|
||||
edgeRevert.hasPair = false;
|
||||
}
|
||||
this.edges.splice(index, 1);
|
||||
}
|
||||
|
||||
this.isMultiGraph = this.checkMutiGraph();
|
||||
}
|
||||
|
||||
|
||||
Graph.prototype.DeleteVertex = function(vertexObject)
|
||||
{
|
||||
var index = this.vertices.indexOf(vertexObject);
|
||||
@ -126,7 +114,13 @@ Graph.prototype.FindVertex = function(id)
|
||||
return res;
|
||||
}
|
||||
|
||||
// depricated
|
||||
Graph.prototype.FindEdge = function(id1, id2)
|
||||
{
|
||||
return this.FindEdgeAny(id1, id2);
|
||||
}
|
||||
|
||||
Graph.prototype.FindEdgeAny = function(id1, id2)
|
||||
{
|
||||
var res = null;
|
||||
for (var i = 0; i < this.edges.length; i++)
|
||||
@ -142,6 +136,43 @@ Graph.prototype.FindEdge = function(id1, id2)
|
||||
return res;
|
||||
}
|
||||
|
||||
Graph.prototype.FindEdgeMin = function(id1, id2)
|
||||
{
|
||||
var res = null;
|
||||
var minWeight = this.infinity;
|
||||
for (var i = 0; i < this.edges.length; i++)
|
||||
{
|
||||
var edge = this.edges[i];
|
||||
if ((edge.vertex1.id == id1 && edge.vertex2.id == id2)
|
||||
|| (!edge.isDirect && edge.vertex1.id == id2 && edge.vertex2.id == id1))
|
||||
{
|
||||
if (edge.weight < minWeight)
|
||||
{
|
||||
res = edge;
|
||||
minWeight = edge.weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Graph.prototype.FindAllEdges = function(id1, id2)
|
||||
{
|
||||
var res = [];
|
||||
for (var i = 0; i < this.edges.length; i++)
|
||||
{
|
||||
var edge = this.edges[i];
|
||||
if ((edge.vertex1.id == id1 && edge.vertex2.id == id2)
|
||||
|| (!edge.isDirect && edge.vertex1.id == id2 && edge.vertex2.id == id1))
|
||||
{
|
||||
res.push(edge);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Graph.prototype.GetAdjacencyMatrixStr = function ()
|
||||
{
|
||||
var matrix = "";
|
||||
@ -149,7 +180,7 @@ Graph.prototype.GetAdjacencyMatrixStr = function ()
|
||||
{
|
||||
for (var j = 0; j < this.vertices.length; j++)
|
||||
{
|
||||
var edge = this.FindEdge (this.vertices[i].id, this.vertices[j].id);
|
||||
var edge = this.FindEdgeMin (this.vertices[i].id, this.vertices[j].id);
|
||||
if (edge != null)
|
||||
{
|
||||
matrix += edge.weight;
|
||||
@ -182,7 +213,7 @@ Graph.prototype.GetAdjacencyMatrix = function ()
|
||||
for (var j = 0; j < this.vertices.length; j ++)
|
||||
{
|
||||
var v2 = this.vertices[j];
|
||||
var edge = this.FindEdge(v1.id, v2.id);
|
||||
var edge = this.FindEdgeMin(v1.id, v2.id);
|
||||
if (edge != null)
|
||||
{
|
||||
matrix[i][j] = edge.GetWeight();
|
||||
@ -845,6 +876,8 @@ Graph.prototype.LoadFromXML = function (xmlText, additionalData)
|
||||
{
|
||||
additionalData["data"] = $additional.attr('data');
|
||||
}
|
||||
|
||||
this.isMultiGraph = this.checkMutiGraph();
|
||||
}
|
||||
|
||||
Graph.prototype.hasDirectEdge = function ()
|
||||
@ -910,3 +943,75 @@ Graph.prototype.getGraphBBox = function (viewportSize)
|
||||
|
||||
return new Rect(pointMin, pointMax);
|
||||
}
|
||||
|
||||
Graph.prototype.hasPair = function (edge)
|
||||
{
|
||||
return this.FindPairFor(edge) != null;
|
||||
}
|
||||
|
||||
Graph.prototype.FindPairFor = function (edge)
|
||||
{
|
||||
var res = this.getNeighbourEdges(edge);
|
||||
|
||||
return res.length == 1 ? res[0] : null;
|
||||
}
|
||||
|
||||
Graph.prototype.getNeighbourEdges = function (edge)
|
||||
{
|
||||
var res = [];
|
||||
|
||||
for (var i = 0; i < this.edges.length; i++)
|
||||
{
|
||||
var curEdge = this.edges[i];
|
||||
if (curEdge == edge)
|
||||
continue;
|
||||
|
||||
if ((curEdge.vertex1.id == edge.vertex1.id &&
|
||||
curEdge.vertex2.id == edge.vertex2.id) ||
|
||||
(curEdge.vertex1.id == edge.vertex2.id &&
|
||||
curEdge.vertex2.id == edge.vertex1.id))
|
||||
{
|
||||
res.push(curEdge);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Graph.prototype.checkMutiGraph = function ()
|
||||
{
|
||||
var res = false;
|
||||
|
||||
var start = {};
|
||||
|
||||
for (var i = 0; i < this.edges.length; i++)
|
||||
{
|
||||
var edge = this.edges[i];
|
||||
if (start.hasOwnProperty(edge.vertex1.id) &&
|
||||
start[edge.vertex1.id] == edge.vertex2.id)
|
||||
{
|
||||
res = true;
|
||||
break;
|
||||
}
|
||||
|
||||
start[edge.vertex1.id] = edge.vertex2.id;
|
||||
if (!edge.isDirect)
|
||||
{
|
||||
if (start.hasOwnProperty(edge.vertex2.id) &&
|
||||
start[edge.vertex2.id] == edge.vertex1.id)
|
||||
{
|
||||
res = true;
|
||||
break;
|
||||
}
|
||||
|
||||
start[edge.vertex2.id] = edge.vertex1.id;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Graph.prototype.isMulti = function ()
|
||||
{
|
||||
return this.isMultiGraph;
|
||||
}
|
||||
|
@ -126,6 +126,21 @@ function createAlgorithmMenu()
|
||||
application.SetHandlerMode(this.id);
|
||||
}
|
||||
|
||||
var eventData = {};
|
||||
eventData.index = i;
|
||||
eventData.object = clone;
|
||||
eventData.algorithm = algorithm;
|
||||
|
||||
$("#openAlgorithmList").bind('click', eventData, function (_eventData) {
|
||||
var data = _eventData.data;
|
||||
var algorithm = g_Algorithms[g_AlgorithmIds.indexOf(data.algorithm.id)](application.graph, application);
|
||||
|
||||
if (application.graph.isMulti() && !algorithm.IsSupportMultiGraph())
|
||||
$(data.object).hide();
|
||||
else
|
||||
$(data.object).show();
|
||||
});
|
||||
|
||||
list.appendChild(clone);
|
||||
index++;
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ BFSAlgorithm.prototype.bfs = function(vertex, vertexArray, edgeArray)
|
||||
for (var i = 0; i < this.graph.vertices.length; i ++)
|
||||
{
|
||||
var nextVertex = this.graph.vertices[i];
|
||||
var edge = this.graph.FindEdge(vertex.id, nextVertex.id);
|
||||
var edge = this.graph.FindEdgeAny(vertex.id, nextVertex.id);
|
||||
if (edge && !vertexArray.includes(nextVertex))
|
||||
{
|
||||
edgeArray.push(edge);
|
||||
@ -104,6 +104,12 @@ BFSAlgorithm.prototype.bfs = function(vertex, vertexArray, edgeArray)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Algorithm support multi graph
|
||||
BFSAlgorithm.prototype.IsSupportMultiGraph = function()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Factory for connected components.
|
||||
function CreateBFSAlgorithm(graph, app)
|
||||
{
|
||||
|
@ -369,6 +369,12 @@ Coloring.prototype.getPriority = function()
|
||||
return -9.0;
|
||||
}
|
||||
|
||||
// Algorithm support multi graph
|
||||
Coloring.prototype.IsSupportMultiGraph = function()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Factory for connected components.
|
||||
function CreateColoring(graph, app)
|
||||
|
@ -76,7 +76,7 @@ FindConnectedComponentNew.prototype.calculate = function(fillUpText = false)
|
||||
for (j = 0; j < connectedVertex[stackElement.id].length; j++)
|
||||
{
|
||||
var nextVertex = connectedVertex[stackElement.id][j];
|
||||
var connectedEdge = this.graph.FindEdge(stackElement.id, nextVertex.id);
|
||||
var connectedEdge = this.graph.FindEdgeAny(stackElement.id, nextVertex.id);
|
||||
if (stack.indexOf(nextVertex) < 0)
|
||||
{
|
||||
stack.push(nextVertex);
|
||||
@ -113,6 +113,12 @@ FindConnectedComponentNew.prototype.getPriority = function()
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Algorithm support multi graph
|
||||
FindConnectedComponentNew.prototype.IsSupportMultiGraph = function()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Factory for connected components.
|
||||
function CreateConnectedComponetsNew(graph, app)
|
||||
|
@ -91,7 +91,7 @@ DFSAlgorithm.prototype.dfs = function(vertex, vertexArray, edgeArray)
|
||||
for (var i = 0; i < this.graph.vertices.length; i ++)
|
||||
{
|
||||
var nextVertex = this.graph.vertices[i];
|
||||
var edge = this.graph.FindEdge(vertex.id, nextVertex.id);
|
||||
var edge = this.graph.FindEdgeAny(vertex.id, nextVertex.id);
|
||||
if (edge && !vertexArray.includes(nextVertex))
|
||||
{
|
||||
edgeArray.push(edge);
|
||||
@ -103,6 +103,12 @@ DFSAlgorithm.prototype.dfs = function(vertex, vertexArray, edgeArray)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Algorithm support multi graph
|
||||
DFSAlgorithm.prototype.IsSupportMultiGraph = function()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Factory for connected components.
|
||||
function CreateDFSAlgorithm(graph, app)
|
||||
{
|
||||
|
@ -103,7 +103,7 @@ FloidAlgorithm.prototype.resultMatrix = function()
|
||||
for (var j = 0; j < this.graph.vertices.length; j ++)
|
||||
{
|
||||
var v2 = this.graph.vertices[j];
|
||||
var edge = this.graph.FindEdge(v1.id, v2.id);
|
||||
var edge = this.graph.FindEdgeMin(v1.id, v2.id);
|
||||
if (edge != null)
|
||||
{
|
||||
this.matrix[i][j] = edge.GetWeight();
|
||||
|
@ -159,6 +159,11 @@ GraphReorder.prototype.getPriority = function()
|
||||
return -8.5;
|
||||
}
|
||||
|
||||
// Algorithm support multi graph
|
||||
GraphReorder.prototype.IsSupportMultiGraph = function()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Factory for connected components.
|
||||
function CreateAlgorithmGraphReorder(graph, app)
|
||||
|
@ -104,7 +104,7 @@ MinimumSpanningTree.prototype.resultStartedFrom = function(vertex, connectedVert
|
||||
for (j = 0; j < connectedVertex[element.id].length; j++)
|
||||
{
|
||||
var connectedElement = connectedVertex[element.id][j];
|
||||
var connectedEdge = this.graph.FindEdge(element.id, connectedElement.id);
|
||||
var connectedEdge = this.graph.FindEdgeMin(element.id, connectedElement.id);
|
||||
if (inTree.indexOf(connectedElement) < 0)
|
||||
{
|
||||
if (minEdge == null || minEdge.weight > connectedEdge.weight)
|
||||
|
@ -182,7 +182,6 @@ ModernGraphStyle.prototype.getObjectSelectedGroup = function(object)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Factory for connected components.
|
||||
function CreateAlgorithmModernGraphStyle(graph, app)
|
||||
{
|
||||
|
@ -183,7 +183,7 @@ RadiusAndDiameter.prototype.getPathByMatrix = function(adjacencyMatrix, minPathM
|
||||
if (minPathMatrix[i][finishNode] == length - adjacencyMatrix[startNode][i] && i != startNode)
|
||||
{
|
||||
res.push(vertices[startNode]);
|
||||
res.push(this.graph.FindEdge(vertices[startNode].id, vertices[i].id));
|
||||
res.push(this.graph.FindEdgeMin(vertices[startNode].id, vertices[i].id));
|
||||
|
||||
length -= adjacencyMatrix[startNode][i];
|
||||
startNode = i;
|
||||
@ -193,7 +193,7 @@ RadiusAndDiameter.prototype.getPathByMatrix = function(adjacencyMatrix, minPathM
|
||||
}
|
||||
|
||||
res.push(vertices[startNode]);
|
||||
res.push(this.graph.FindEdge(vertices[startNode].id, vertices[finishNode].id));
|
||||
res.push(this.graph.FindEdgeMin(vertices[startNode].id, vertices[finishNode].id));
|
||||
res.push(vertices[finishNode]);
|
||||
|
||||
return res;
|
||||
|
@ -104,6 +104,9 @@ var g_vertexDraw = "Vertex draw style";
|
||||
var g_edgeDraw = "Edge draw style";
|
||||
var g_backgroundStyle = "Bacgkround style";
|
||||
|
||||
var g_GrapsIsMultiMessage = "Graph is multigraph";
|
||||
var g_GrapsIsGeneralMessage = "";
|
||||
|
||||
function loadTexts()
|
||||
{
|
||||
g_textsSelectAndMove = document.getElementById("SelectAndMoveObject").innerHTML;
|
||||
@ -208,4 +211,7 @@ function loadTexts()
|
||||
g_edgeDraw = document.getElementById("edgeDrawStyle").innerHTML;
|
||||
|
||||
g_backgroundStyle = document.getElementById("backgroundStyle").innerHTML;
|
||||
|
||||
g_GrapsIsMultiMessage = document.getElementById("graphIsMultiMessage").innerHTML;
|
||||
g_GrapsIsGeneralMessage = document.getElementById("graphIsGeneralMessage").innerHTML;
|
||||
}
|
||||
|
20
tpl/home.php
20
tpl/home.php
@ -150,6 +150,7 @@
|
||||
</section>
|
||||
|
||||
<section id="canvasSection">
|
||||
<span id="CanvasMessage"></span>
|
||||
<button type="button" class="btn btn-default btn-sm hidden-phone" id="Fullscreen"><span class="glyphicon glyphicon-resize-full fa-fw" id="FullscreenIcon"></span></button>
|
||||
<canvas id="canvas"><?= L('browser_no_support')?></canvas>
|
||||
<div id="developerTools" class="well well-sm">
|
||||
@ -221,6 +222,20 @@
|
||||
<span onClick="document.getElementById('EdgeWeight').value='7'; document.getElementById('EdgeWeightSlider').value=7;" style="cursor: pointer" class="defaultWeigth">7</span>
|
||||
<span onClick="document.getElementById('EdgeWeight').value='11'; document.getElementById('EdgeWeightSlider').value=11;" style="cursor: pointer" class="defaultWeigth">11</span>
|
||||
</div>
|
||||
<div id="NewEdgeAction">
|
||||
<div class="InlineStyle PaddingRight">
|
||||
<input class="form-check-input" type="radio" name="NewEdgeActionValue" id="RadiosReplaceEdge" value="replace" checked>
|
||||
<label for="RadiosReplaceEdge">
|
||||
<?= L('replace_edge')?>
|
||||
</label>
|
||||
</div>
|
||||
<div class="InlineStyle PaddingRight">
|
||||
<input class="form-check-input" type="radio" name="NewEdgeActionValue" id="RadiosAddEdge" value="add">
|
||||
<label for="RadiosAddEdge" id="RadiosAddEdgeLabel">
|
||||
<?= L('add_edge')?>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
@ -248,6 +263,7 @@
|
||||
<form>
|
||||
<fieldset>
|
||||
<p><?= L('adjacency_matrix_description')?></p>
|
||||
<p id="AdjacencyMatrixMultiGraphDesc"><?= L('adjacency_matrix_multigraph_description')?></p>
|
||||
<textarea name="adjacencyMatrixField" id="AdjacencyMatrixField" wrap="off"></textarea>
|
||||
<p id="BadMatrixFormatMessage"><?= L('adjacency_matrix_bad_format')?></p>
|
||||
</fieldset>
|
||||
@ -551,7 +567,9 @@
|
||||
<p id="edgeDrawStyle" class="translation"><?= L('edge_draw_style')?></p>
|
||||
<p id="backgroundStyle" class="translation"><?= L('background_style')?></p>
|
||||
|
||||
|
||||
<p id="graphIsMultiMessage" class="translation"><?= L('graph_is_multi_message')?></p>
|
||||
<p id="graphIsGeneralMessage" class="translation"><?= L('graph_is_general_message')?></p>
|
||||
|
||||
</section>
|
||||
<!--
|
||||
<script>
|
||||
|
Loading…
x
Reference in New Issue
Block a user