mirror of
https://github.com/UnickSoft/graphonline.git
synced 2025-07-04 00:36:45 +00:00
Added max flow algorithm.
This commit is contained in:
parent
e14bf77af6
commit
c1c0d55075
@ -118,4 +118,12 @@
|
|||||||
$g_lang["checkToSave"] = "Check to save";
|
$g_lang["checkToSave"] = "Check to save";
|
||||||
$g_lang["showDistMatrix"] = "Show distance matrix";
|
$g_lang["showDistMatrix"] = "Show distance matrix";
|
||||||
$g_lang["distMatrixText"] = "Distance matrix";
|
$g_lang["distMatrixText"] = "Distance matrix";
|
||||||
|
|
||||||
|
$g_lang["selectStartVertexForMaxFlow"] = "Select source vertex of maximum flow";
|
||||||
|
$g_lang["selectFinishVertexForMaxFlow"] = "Select sink vertex of maximum flow";
|
||||||
|
$g_lang["maxFlowResult"] = "Maximum flow from %2 to %3 is %1";
|
||||||
|
$g_lang["flowNotExists"] = "Flow from %1 to %2 does not exists";
|
||||||
|
|
||||||
|
$g_lang["sourceVertex"] = "Source";
|
||||||
|
$g_lang["sinkVertex"] = "Sink";
|
||||||
?>
|
?>
|
||||||
|
@ -121,4 +121,12 @@
|
|||||||
$g_lang["checkToSave"] = "Нажмите для сохранения";
|
$g_lang["checkToSave"] = "Нажмите для сохранения";
|
||||||
$g_lang["showDistMatrix"] = "Показать матрицу расстояний";
|
$g_lang["showDistMatrix"] = "Показать матрицу расстояний";
|
||||||
$g_lang["distMatrixText"] = "Матрица расстояний";
|
$g_lang["distMatrixText"] = "Матрица расстояний";
|
||||||
|
|
||||||
|
$g_lang["selectStartVertexForMaxFlow"] = "Выделите исток максимального потока";
|
||||||
|
$g_lang["selectFinishVertexForMaxFlow"] = "Выделите сток максимального потока";
|
||||||
|
$g_lang["maxFlowResult"] = "Максимальный поток из %2 в %3 равен %1";
|
||||||
|
$g_lang["flowNotExists"] = "Поток из %1 в %2 не существует";
|
||||||
|
|
||||||
|
$g_lang["sourceVertex"] = "Исток";
|
||||||
|
$g_lang["sinkVertex"] = "Сток";
|
||||||
?>
|
?>
|
||||||
|
@ -212,7 +212,17 @@ BaseAlgorithmEx.prototype.CalculateAlgorithm = function(queryString, resultCallb
|
|||||||
$edges.each(function(){
|
$edges.each(function(){
|
||||||
var source = $(this).attr('source');
|
var source = $(this).attr('source');
|
||||||
var target = $(this).attr('target');
|
var target = $(this).attr('target');
|
||||||
pathObjects.push(graph.FindEdge(source, target));
|
var edge = graph.FindEdge(source, target);
|
||||||
|
pathObjects.push(edge);
|
||||||
|
|
||||||
|
$data = $(this).find("data");
|
||||||
|
$data.each(function(){
|
||||||
|
if (!properties[edge.id])
|
||||||
|
{
|
||||||
|
properties[edge.id] = {};
|
||||||
|
}
|
||||||
|
properties[edge.id][$(this).attr('key')] = $(this).text();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(result);
|
console.log(result);
|
||||||
|
@ -1005,7 +1005,7 @@ Application.prototype.GetFindPathReport = function ()
|
|||||||
return this.findPathReport;
|
return this.findPathReport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
Application.prototype.CalculateAlgorithm = function(queryString, callbackObject)
|
Application.prototype.CalculateAlgorithm = function(queryString, callbackObject)
|
||||||
{
|
{
|
||||||
var app = this;
|
var app = this;
|
||||||
@ -1068,7 +1068,18 @@ Application.prototype.CalculateAlgorithm = function(queryString, callbackObject)
|
|||||||
$edges.each(function(){
|
$edges.each(function(){
|
||||||
var source = $(this).attr('source');
|
var source = $(this).attr('source');
|
||||||
var target = $(this).attr('target');
|
var target = $(this).attr('target');
|
||||||
pathObjects.push(app.FindEdge(source, target));
|
var edge = app.FindEdge(source, target);
|
||||||
|
pathObjects.push(edge);
|
||||||
|
|
||||||
|
$data = $(this).find("data");
|
||||||
|
$data.each(function(){
|
||||||
|
if (!properties[edge.id])
|
||||||
|
{
|
||||||
|
properties[edge.id] = {};
|
||||||
|
}
|
||||||
|
properties[edge.id][$(this).attr('key')] = $(this).text();
|
||||||
|
console.log("Data edge " + $(this).text());
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(result);
|
console.log(result);
|
||||||
@ -1078,6 +1089,7 @@ Application.prototype.CalculateAlgorithm = function(queryString, callbackObject)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
Application.prototype.GetRealWidth = function ()
|
Application.prototype.GetRealWidth = function ()
|
||||||
{
|
{
|
||||||
|
@ -10,6 +10,7 @@ function BaseEdge(vertex1, vertex2, isDirect, weight, useWeight)
|
|||||||
this.vertex2 = vertex2;
|
this.vertex2 = vertex2;
|
||||||
this.isDirect = isDirect;
|
this.isDirect = isDirect;
|
||||||
this.weight = Number(weight);
|
this.weight = Number(weight);
|
||||||
|
this.text = "";
|
||||||
// For direct graph, has pair edge or not.
|
// For direct graph, has pair edge or not.
|
||||||
this.hasPair = false;
|
this.hasPair = false;
|
||||||
this.useWeight = useWeight;
|
this.useWeight = useWeight;
|
||||||
@ -27,6 +28,7 @@ BaseEdge.prototype.SaveToXML = function ()
|
|||||||
"useWeight=\"" + this.useWeight + "\" " +
|
"useWeight=\"" + this.useWeight + "\" " +
|
||||||
"hasPair=\"" + this.hasPair + "\" " +
|
"hasPair=\"" + this.hasPair + "\" " +
|
||||||
"id=\"" + this.id + "\" " +
|
"id=\"" + this.id + "\" " +
|
||||||
|
"text=\"" + this.text + "\" " +
|
||||||
"></edge>";
|
"></edge>";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,6 +43,7 @@ BaseEdge.prototype.LoadFromXML = function (xml, graph)
|
|||||||
this.hasPair = xml.attr('hasPair') == "true";
|
this.hasPair = xml.attr('hasPair') == "true";
|
||||||
this.useWeight = xml.attr('useWeight') == "true";
|
this.useWeight = xml.attr('useWeight') == "true";
|
||||||
this.id = parseInt(xml.attr('id'));
|
this.id = parseInt(xml.attr('id'));
|
||||||
|
this.text = xml.attr("text") == null ? "" : xml.attr("text");
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseEdge.prototype.GetPixelLength = function ()
|
BaseEdge.prototype.GetPixelLength = function ()
|
||||||
@ -59,3 +62,8 @@ BaseEdge.prototype.GetWeight = function ()
|
|||||||
{
|
{
|
||||||
return this.useWeight ? this.weight : 1;
|
return this.useWeight ? this.weight : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BaseEdge.prototype.GetText = function ()
|
||||||
|
{
|
||||||
|
return this.text.length > 0 ? this.text : (this.useWeight ? this.weight.toString() : "");
|
||||||
|
}
|
@ -95,9 +95,9 @@ BaseEdgeDrawer.prototype.Draw = function(baseEdge, arcStyle)
|
|||||||
var positions = this.GetArcPositions(baseEdge.vertex1.position, baseEdge.vertex2.position, baseEdge.vertex1.model.diameter);
|
var positions = this.GetArcPositions(baseEdge.vertex1.position, baseEdge.vertex2.position, baseEdge.vertex1.model.diameter);
|
||||||
|
|
||||||
this.DrawArc (positions[0], positions[1], arcStyle);
|
this.DrawArc (positions[0], positions[1], arcStyle);
|
||||||
if (baseEdge.useWeight)
|
if (baseEdge.GetText().length > 0)
|
||||||
{
|
{
|
||||||
this.DrawWeight(positions[0], positions[1], baseEdge.weight, arcStyle, baseEdge.hasPair);
|
this.DrawWeight(positions[0], positions[1], baseEdge.GetText(), arcStyle, baseEdge.hasPair);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,9 +226,9 @@ DirectArcDrawer.prototype.Draw = function(baseEdge, arcStyle)
|
|||||||
this.context.lineWidth = 0;
|
this.context.lineWidth = 0;
|
||||||
this.DrawArrow(positions[0], positions[1], length, width);
|
this.DrawArrow(positions[0], positions[1], length, width);
|
||||||
|
|
||||||
if (baseEdge.useWeight)
|
if (baseEdge.GetText().length > 0)
|
||||||
{
|
{
|
||||||
baseDrawer.DrawWeight(positions[0], positions[1], baseEdge.weight, arcStyle, baseEdge.hasPair);
|
baseDrawer.DrawWeight(positions[0], positions[1], baseEdge.GetText(), arcStyle, baseEdge.hasPair);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +52,9 @@ var g_shortReport = "Short report";
|
|||||||
var g_hasEulerianLoop = "Graph has Eulerian Loop";
|
var g_hasEulerianLoop = "Graph has Eulerian Loop";
|
||||||
var g_hasNotEulerianLoop = "Graph has not Eulerian Loop";
|
var g_hasNotEulerianLoop = "Graph has not Eulerian Loop";
|
||||||
|
|
||||||
|
var g_hasEulerianPath = "Graph has Eulerian Path";
|
||||||
|
var g_hasNotEulerianPath = "Graph has not Eulerian Path";
|
||||||
|
|
||||||
var g_processing = "Processing...";
|
var g_processing = "Processing...";
|
||||||
|
|
||||||
var g_customEnumVertex = "Custom";
|
var g_customEnumVertex = "Custom";
|
||||||
@ -66,6 +69,22 @@ var g_editWeight = "Edit weight";
|
|||||||
|
|
||||||
var g_noWeight = "No weight";
|
var g_noWeight = "No weight";
|
||||||
var g_groupRename = "Group rename";
|
var g_groupRename = "Group rename";
|
||||||
|
var g_vote = "Vote";
|
||||||
|
|
||||||
|
var g_recommendAlgorithm = "Recommend algorithm";
|
||||||
|
|
||||||
|
var g_graphOfMinDist = "Graph of minimal distances.";
|
||||||
|
var g_checkToSave = "Check to save";
|
||||||
|
var g_showDistMatrix = "Show Distance matrix";
|
||||||
|
var g_minDistMatrixText = "Minimal distances matrix";
|
||||||
|
|
||||||
|
var g_selectStartVertexForMaxFlow = "Select source vertex for max flow";
|
||||||
|
var g_selectFinishVertexForMaxFlow = "Select sink vertex for max flow";
|
||||||
|
var g_maxFlowResult = "Maximum flow from %2 to %3 is %1";
|
||||||
|
var g_flowNotExists = "Flow from %1 to %2 does not exists";
|
||||||
|
|
||||||
|
var g_sourceVertex = "Source";
|
||||||
|
var g_sinkVertex = "Sink";
|
||||||
|
|
||||||
function loadTexts()
|
function loadTexts()
|
||||||
{
|
{
|
||||||
@ -133,6 +152,25 @@ function loadTexts()
|
|||||||
|
|
||||||
g_noWeight = document.getElementById("noWeight").innerHTML;
|
g_noWeight = document.getElementById("noWeight").innerHTML;
|
||||||
g_groupRename = document.getElementById("groupeRenameText").innerHTML;
|
g_groupRename = document.getElementById("groupeRenameText").innerHTML;
|
||||||
|
g_vote = document.getElementById("voteText").innerHTML;
|
||||||
|
|
||||||
|
g_recommendAlgorithm = document.getElementById("recommend_algorithm").innerHTML;
|
||||||
|
|
||||||
|
g_hasEulerianPath = document.getElementById("hasEulerianPath").innerHTML;
|
||||||
|
g_hasNotEulerianPath = document.getElementById("hasNotEulerianPath").innerHTML;
|
||||||
|
|
||||||
|
g_graphOfMinDist = document.getElementById("graphOfMinDist").innerHTML;
|
||||||
|
g_checkToSave = document.getElementById("checkToSave").innerHTML;
|
||||||
|
g_showDistMatrix = document.getElementById("showDistMatrix").innerHTML;
|
||||||
|
g_minDistMatrixText = document.getElementById("distMatrixText").innerHTML;
|
||||||
|
|
||||||
|
g_selectStartVertexForMaxFlow = document.getElementById("selectStartVertexForMaxFlow").innerHTML;
|
||||||
|
g_selectFinishVertexForMaxFlow = document.getElementById("selectFinishVertexForMaxFlow").innerHTML;
|
||||||
|
g_maxFlowResult = document.getElementById("maxFlowResult").innerHTML;
|
||||||
|
g_flowNotExists = document.getElementById("flowNotExists").innerHTML;
|
||||||
|
|
||||||
|
g_sourceVertex = document.getElementById("sourceVertex").innerHTML;
|
||||||
|
g_sinkVertex = document.getElementById("sinkVertex").innerHTML;
|
||||||
}
|
}
|
||||||
function Point(x, y){
|
function Point(x, y){
|
||||||
this.x = x || 0;
|
this.x = x || 0;
|
||||||
@ -298,10 +336,10 @@ function BaseVertex(x, y, vertexEnumType)
|
|||||||
this.mainText = "";
|
this.mainText = "";
|
||||||
this.upText = "";
|
this.upText = "";
|
||||||
this.vertexEnumType = vertexEnumType;
|
this.vertexEnumType = vertexEnumType;
|
||||||
|
this.model = new VertexModel();
|
||||||
};
|
};
|
||||||
|
|
||||||
BaseVertex.prototype.position = new Point(0, 0);
|
BaseVertex.prototype.position = new Point(0, 0);
|
||||||
BaseVertex.prototype.model = new VertexModel();
|
|
||||||
|
|
||||||
BaseVertex.prototype.SaveToXML = function ()
|
BaseVertex.prototype.SaveToXML = function ()
|
||||||
{
|
{
|
||||||
@ -345,14 +383,14 @@ function BaseEdge(vertex1, vertex2, isDirect, weight, useWeight)
|
|||||||
this.vertex2 = vertex2;
|
this.vertex2 = vertex2;
|
||||||
this.isDirect = isDirect;
|
this.isDirect = isDirect;
|
||||||
this.weight = Number(weight);
|
this.weight = Number(weight);
|
||||||
|
this.text = "";
|
||||||
// For direct graph, has pair edge or not.
|
// For direct graph, has pair edge or not.
|
||||||
this.hasPair = false;
|
this.hasPair = false;
|
||||||
this.useWeight = useWeight;
|
this.useWeight = useWeight;
|
||||||
this.id = 0;
|
this.id = 0;
|
||||||
|
this.model = new EdgeModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseEdge.prototype.model = new EdgeModel();
|
|
||||||
|
|
||||||
BaseEdge.prototype.SaveToXML = function ()
|
BaseEdge.prototype.SaveToXML = function ()
|
||||||
{
|
{
|
||||||
return "<edge " +
|
return "<edge " +
|
||||||
@ -363,6 +401,7 @@ BaseEdge.prototype.SaveToXML = function ()
|
|||||||
"useWeight=\"" + this.useWeight + "\" " +
|
"useWeight=\"" + this.useWeight + "\" " +
|
||||||
"hasPair=\"" + this.hasPair + "\" " +
|
"hasPair=\"" + this.hasPair + "\" " +
|
||||||
"id=\"" + this.id + "\" " +
|
"id=\"" + this.id + "\" " +
|
||||||
|
"text=\"" + this.text + "\" " +
|
||||||
"></edge>";
|
"></edge>";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,6 +416,7 @@ BaseEdge.prototype.LoadFromXML = function (xml, graph)
|
|||||||
this.hasPair = xml.attr('hasPair') == "true";
|
this.hasPair = xml.attr('hasPair') == "true";
|
||||||
this.useWeight = xml.attr('useWeight') == "true";
|
this.useWeight = xml.attr('useWeight') == "true";
|
||||||
this.id = parseInt(xml.attr('id'));
|
this.id = parseInt(xml.attr('id'));
|
||||||
|
this.text = xml.attr("text") == null ? "" : xml.attr("text");
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseEdge.prototype.GetPixelLength = function ()
|
BaseEdge.prototype.GetPixelLength = function ()
|
||||||
@ -390,7 +430,16 @@ BaseEdge.prototype.GetPixelLength = function ()
|
|||||||
return Point.distance(this.vertex1.position, this.vertex2.position);
|
return Point.distance(this.vertex1.position, this.vertex2.position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
|
BaseEdge.prototype.GetWeight = function ()
|
||||||
|
{
|
||||||
|
return this.useWeight ? this.weight : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseEdge.prototype.GetText = function ()
|
||||||
|
{
|
||||||
|
return this.text.length > 0 ? this.text : (this.useWeight ? this.weight.toString() : "");
|
||||||
|
}/**
|
||||||
* Graph drawer.
|
* Graph drawer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -624,9 +673,9 @@ BaseEdgeDrawer.prototype.Draw = function(baseEdge, arcStyle)
|
|||||||
var positions = this.GetArcPositions(baseEdge.vertex1.position, baseEdge.vertex2.position, baseEdge.vertex1.model.diameter);
|
var positions = this.GetArcPositions(baseEdge.vertex1.position, baseEdge.vertex2.position, baseEdge.vertex1.model.diameter);
|
||||||
|
|
||||||
this.DrawArc (positions[0], positions[1], arcStyle);
|
this.DrawArc (positions[0], positions[1], arcStyle);
|
||||||
if (baseEdge.useWeight)
|
if (baseEdge.GetText().length > 0)
|
||||||
{
|
{
|
||||||
this.DrawWeight(positions[0], positions[1], baseEdge.weight, arcStyle, baseEdge.hasPair);
|
this.DrawWeight(positions[0], positions[1], baseEdge.GetText(), arcStyle, baseEdge.hasPair);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -636,6 +685,7 @@ BaseEdgeDrawer.prototype.SetupStyle = function(baseEdge, arcStyle)
|
|||||||
this.context.lineWidth = baseEdge.model.width;
|
this.context.lineWidth = baseEdge.model.width;
|
||||||
this.context.strokeStyle = arcStyle.strokeStyle;
|
this.context.strokeStyle = arcStyle.strokeStyle;
|
||||||
this.context.fillStyle = arcStyle.fillStyle;
|
this.context.fillStyle = arcStyle.fillStyle;
|
||||||
|
this.sizeOfLoop = baseEdge.vertex1.model.diameter / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseEdgeDrawer.prototype.DrawArc = function(position1, position2, arcStyle)
|
BaseEdgeDrawer.prototype.DrawArc = function(position1, position2, arcStyle)
|
||||||
@ -686,23 +736,23 @@ BaseEdgeDrawer.prototype.DrawWeight = function(position1, position2, text, arcSt
|
|||||||
this.context.fillText(text, centerPoint.x - widthText / 2, centerPoint.y);
|
this.context.fillText(text, centerPoint.x - widthText / 2, centerPoint.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseEdgeDrawer.prototype.GetArcPositions = function(position1, position2, diameter)
|
BaseEdgeDrawer.prototype.GetArcPositions = function(position1, position2, diameter1, diameter2)
|
||||||
{
|
{
|
||||||
var direction = position1.subtract(position2);
|
var direction = position1.subtract(position2);
|
||||||
direction.normalize(1.0);
|
direction.normalize(1.0);
|
||||||
direction = direction.multiply(0.5);
|
direction = direction.multiply(0.5);
|
||||||
|
|
||||||
var res = [];
|
var res = [];
|
||||||
res.push(position1.subtract(direction.multiply(diameter)));
|
res.push(position1.subtract(direction.multiply(diameter1)));
|
||||||
res.push(position2.subtract(direction.multiply(-diameter)));
|
res.push(position2.subtract(direction.multiply(-diameter2)));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseEdgeDrawer.prototype.GetArcPositionsShift = function(position1, position2, diameter, shift)
|
BaseEdgeDrawer.prototype.GetArcPositionsShift = function(position1, position2, diameter1, diameter2, shift)
|
||||||
{
|
{
|
||||||
if (shift == 0)
|
if (shift == 0)
|
||||||
{
|
{
|
||||||
return this.GetArcPositions(position1, position2, diameter);
|
return this.GetArcPositions(position1, position2, diameter1, diameter2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -712,10 +762,11 @@ BaseEdgeDrawer.prototype.GetArcPositionsShift = function(position1, position2, d
|
|||||||
direction = direction.multiply(0.5);
|
direction = direction.multiply(0.5);
|
||||||
position1 = position1.subtract(normal.multiply(shift));
|
position1 = position1.subtract(normal.multiply(shift));
|
||||||
position2 = position2.subtract(normal.multiply(shift));
|
position2 = position2.subtract(normal.multiply(shift));
|
||||||
diameter = Math.sqrt(diameter * diameter - shift * shift);
|
diameter1 = Math.sqrt(diameter1 * diameter1 - shift * shift);
|
||||||
|
diameter2 = Math.sqrt(diameter2 * diameter2 - shift * shift);
|
||||||
var res = [];
|
var res = [];
|
||||||
res.push(position1.subtract(direction.multiply(diameter)));
|
res.push(position1.subtract(direction.multiply(diameter1)));
|
||||||
res.push(position2.subtract(direction.multiply(-diameter)));
|
res.push(position2.subtract(direction.multiply(-diameter2)));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -745,7 +796,7 @@ DirectArcDrawer.prototype.Draw = function(baseEdge, arcStyle)
|
|||||||
var realShift = (baseEdge.hasPair ? pairShift : 0);
|
var realShift = (baseEdge.hasPair ? pairShift : 0);
|
||||||
direction.normalize(1.0);
|
direction.normalize(1.0);
|
||||||
var positions = this.GetArcPositionsShift(baseEdge.vertex1.position,
|
var positions = this.GetArcPositionsShift(baseEdge.vertex1.position,
|
||||||
baseEdge.vertex2.position, baseEdge.vertex1.model.diameter, realShift);
|
baseEdge.vertex2.position, baseEdge.vertex1.model.diameter, baseEdge.vertex2.model.diameter, realShift);
|
||||||
|
|
||||||
baseDrawer.DrawArc (positions[0], positions[1].subtract(direction.multiply(-length / 2)), arcStyle);
|
baseDrawer.DrawArc (positions[0], positions[1].subtract(direction.multiply(-length / 2)), arcStyle);
|
||||||
|
|
||||||
@ -753,9 +804,9 @@ DirectArcDrawer.prototype.Draw = function(baseEdge, arcStyle)
|
|||||||
this.context.lineWidth = 0;
|
this.context.lineWidth = 0;
|
||||||
this.DrawArrow(positions[0], positions[1], length, width);
|
this.DrawArrow(positions[0], positions[1], length, width);
|
||||||
|
|
||||||
if (baseEdge.useWeight)
|
if (baseEdge.GetText().length > 0)
|
||||||
{
|
{
|
||||||
baseDrawer.DrawWeight(positions[0], positions[1], baseEdge.weight, arcStyle, baseEdge.hasPair);
|
baseDrawer.DrawWeight(positions[0], positions[1], baseEdge.GetText(), arcStyle, baseEdge.hasPair);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -806,7 +857,7 @@ ProgressArcDrawer.prototype.Draw = function(baseEdge, arcStyle)
|
|||||||
var pairShift = baseEdge.vertex1.model.diameter * 0.25;
|
var pairShift = baseEdge.vertex1.model.diameter * 0.25;
|
||||||
var realShift = (baseEdge.hasPair ? pairShift : 0);
|
var realShift = (baseEdge.hasPair ? pairShift : 0);
|
||||||
var positions = this.GetArcPositionsShift(baseEdge.vertex1.position,
|
var positions = this.GetArcPositionsShift(baseEdge.vertex1.position,
|
||||||
baseEdge.vertex2.position, baseEdge.vertex1.model.diameter, realShift);
|
baseEdge.vertex2.position, baseEdge.vertex1.model.diameter, baseEdge.vertex2.model.diameter, realShift);
|
||||||
var progressSize = 10;
|
var progressSize = 10;
|
||||||
|
|
||||||
if (positions[0].equals(positions[1]))
|
if (positions[0].equals(positions[1]))
|
||||||
@ -949,6 +1000,17 @@ BaseAlgorithm.prototype.needRestoreUpText = function()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @return true, if you change resotry graph after use.
|
||||||
|
BaseAlgorithm.prototype.wantRestore = function()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calls this method if wantRestore return true.
|
||||||
|
BaseAlgorithm.prototype.restore = function()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// @return 0, if object is not selected, in other case return groupe of selection.
|
// @return 0, if object is not selected, in other case return groupe of selection.
|
||||||
BaseAlgorithm.prototype.getObjectSelectedGroup = function(object)
|
BaseAlgorithm.prototype.getObjectSelectedGroup = function(object)
|
||||||
{
|
{
|
||||||
@ -958,6 +1020,13 @@ BaseAlgorithm.prototype.getObjectSelectedGroup = function(object)
|
|||||||
// This methos is called, when messages was updated on html page.
|
// This methos is called, when messages was updated on html page.
|
||||||
BaseAlgorithm.prototype.messageWasChanged = function() {}
|
BaseAlgorithm.prototype.messageWasChanged = function() {}
|
||||||
|
|
||||||
|
// Algorithm priority in menu
|
||||||
|
BaseAlgorithm.prototype.getPriority = function()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default handler.
|
* Default handler.
|
||||||
@ -1034,7 +1103,17 @@ BaseAlgorithmEx.prototype.CalculateAlgorithm = function(queryString, resultCallb
|
|||||||
$edges.each(function(){
|
$edges.each(function(){
|
||||||
var source = $(this).attr('source');
|
var source = $(this).attr('source');
|
||||||
var target = $(this).attr('target');
|
var target = $(this).attr('target');
|
||||||
pathObjects.push(graph.FindEdge(source, target));
|
var edge = graph.FindEdge(source, target);
|
||||||
|
pathObjects.push(edge);
|
||||||
|
|
||||||
|
$data = $(this).find("data");
|
||||||
|
$data.each(function(){
|
||||||
|
if (!properties[edge.id])
|
||||||
|
{
|
||||||
|
properties[edge.id] = {};
|
||||||
|
}
|
||||||
|
properties[edge.id][$(this).attr('key')] = $(this).text();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(result);
|
console.log(result);
|
||||||
@ -1699,10 +1778,10 @@ SavedDialogGraphImageHandler.prototype.pathObjects = null;
|
|||||||
// Objects.
|
// Objects.
|
||||||
SavedDialogGraphImageHandler.prototype.objects = null;
|
SavedDialogGraphImageHandler.prototype.objects = null;
|
||||||
|
|
||||||
SavedDialogGraphImageHandler.prototype.show = function(object)
|
SavedDialogGraphImageHandler.prototype.show = function(object, isFull = false)
|
||||||
|
{
|
||||||
|
var showDialogCallback = function ()
|
||||||
{
|
{
|
||||||
var imageName = this.app.SaveGraphImageOnDisk();
|
|
||||||
|
|
||||||
var dialogButtons = {};
|
var dialogButtons = {};
|
||||||
|
|
||||||
dialogButtons[g_close] = function() {
|
dialogButtons[g_close] = function() {
|
||||||
@ -1711,7 +1790,9 @@ SavedDialogGraphImageHandler.prototype.show = function(object)
|
|||||||
|
|
||||||
var fileLocation = "tmp/saved/" + imageName.substr(0, 2) + "/"+ imageName + ".png"
|
var fileLocation = "tmp/saved/" + imageName.substr(0, 2) + "/"+ imageName + ".png"
|
||||||
|
|
||||||
|
document.getElementById("showSavedImageGraph").src = "/" + fileLocation;
|
||||||
|
document.getElementById("showSavedImageGraphRef").href = "/" + fileLocation;
|
||||||
|
//document.getElementById("showSavedImageGraph").src = document.getElementById("showSavedImageGraph").src.replace(/tmp\/saved\/([A-Za-z]*)\/([A-Za-z]*).png/g, fileLocation);
|
||||||
document.getElementById("ShareSavedImageGraph").innerHTML =
|
document.getElementById("ShareSavedImageGraph").innerHTML =
|
||||||
document.getElementById("ShareSavedImageGraph").innerHTML.replace(/tmp\/saved\/([A-Za-z]*)\/([A-Za-z]*).png/g, fileLocation);
|
document.getElementById("ShareSavedImageGraph").innerHTML.replace(/tmp\/saved\/([A-Za-z]*)\/([A-Za-z]*).png/g, fileLocation);
|
||||||
|
|
||||||
@ -1730,6 +1811,9 @@ SavedDialogGraphImageHandler.prototype.show = function(object)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var imageName = isFull ? this.app.SaveFullGraphImageOnDisk(showDialogCallback) : this.app.SaveGraphImageOnDisk(showDialogCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Algorithm Graph handler.
|
* Algorithm Graph handler.
|
||||||
@ -1805,6 +1889,11 @@ AlgorithmGraphHandler.prototype.RestoreAll = function()
|
|||||||
{
|
{
|
||||||
this.RestoreUpText();
|
this.RestoreUpText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.algorithm.wantRestore())
|
||||||
|
{
|
||||||
|
this.algorithm.restore();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AlgorithmGraphHandler.prototype.SaveUpText = function()
|
AlgorithmGraphHandler.prototype.SaveUpText = function()
|
||||||
@ -1849,6 +1938,11 @@ AlgorithmGraphHandler.prototype.InitControls = function()
|
|||||||
this.algorithm.messageWasChanged();
|
this.algorithm.messageWasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AlgorithmGraphHandler.prototype.GetMessage = function()
|
||||||
|
{
|
||||||
|
return this.algorithm.getMessage(g_language);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Groupe rename vertices.
|
* Groupe rename vertices.
|
||||||
@ -1982,6 +2076,8 @@ function Graph()
|
|||||||
this.hasDirect = false;
|
this.hasDirect = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// infinity
|
||||||
|
Graph.prototype.infinity = 1E8;
|
||||||
|
|
||||||
Graph.prototype.AddNewVertex = function(vertex)
|
Graph.prototype.AddNewVertex = function(vertex)
|
||||||
{
|
{
|
||||||
@ -2110,7 +2206,7 @@ Graph.prototype.FindEdge = function(id1, id2)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Graph.prototype.GetAdjacencyMatrix = function ()
|
Graph.prototype.GetAdjacencyMatrixStr = function ()
|
||||||
{
|
{
|
||||||
var matrix = "";
|
var matrix = "";
|
||||||
for (var i = 0; i < this.vertices.length; i++)
|
for (var i = 0; i < this.vertices.length; i++)
|
||||||
@ -2139,6 +2235,32 @@ Graph.prototype.GetAdjacencyMatrix = function ()
|
|||||||
return matrix;
|
return matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Graph.prototype.GetAdjacencyMatrix = function ()
|
||||||
|
{
|
||||||
|
var matrix = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < this.vertices.length; i ++)
|
||||||
|
{
|
||||||
|
matrix.push([]);
|
||||||
|
var v1 = this.vertices[i];
|
||||||
|
for (var j = 0; j < this.vertices.length; j ++)
|
||||||
|
{
|
||||||
|
var v2 = this.vertices[j];
|
||||||
|
var edge = this.FindEdge(v1.id, v2.id);
|
||||||
|
if (edge != null)
|
||||||
|
{
|
||||||
|
matrix[i][j] = edge.GetWeight();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
matrix[i][j] = this.infinity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return matrix;
|
||||||
|
}
|
||||||
|
|
||||||
Graph.prototype.TestAdjacencyMatrix = function (matrix, rowsObj, colsObj, separator = ",")
|
Graph.prototype.TestAdjacencyMatrix = function (matrix, rowsObj, colsObj, separator = ",")
|
||||||
{
|
{
|
||||||
var bGoodFormat = true;
|
var bGoodFormat = true;
|
||||||
@ -3128,6 +3250,26 @@ Application.prototype._redrawGraph = function()
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Application.prototype._OffscreenRedrawGraph = function()
|
||||||
|
{
|
||||||
|
var bbox = this.graph.getGraphBBox();
|
||||||
|
var canvas = document.createElement('canvas');
|
||||||
|
canvas.width = bbox.size().x;
|
||||||
|
canvas.height = bbox.size().y;
|
||||||
|
var context = canvas.getContext('2d');
|
||||||
|
|
||||||
|
context.save();
|
||||||
|
context.clearRect(0, 0, Math.max(this.canvas.width, this.GetRealWidth()), Math.max(this.canvas.height, this.GetRealHeight()));
|
||||||
|
context.translate(bbox.minPoint.inverse().x, bbox.minPoint.inverse().y);
|
||||||
|
|
||||||
|
this.RedrawEdges(context);
|
||||||
|
this.RedrawNodes(context);
|
||||||
|
|
||||||
|
context.restore();
|
||||||
|
|
||||||
|
return canvas;
|
||||||
|
}
|
||||||
|
|
||||||
Application.prototype.updateRenderPathLength = function()
|
Application.prototype.updateRenderPathLength = function()
|
||||||
{
|
{
|
||||||
this.renderPathLength = 0;
|
this.renderPathLength = 0;
|
||||||
@ -3459,10 +3601,13 @@ Application.prototype.FindPath = function(graph1, graph2)
|
|||||||
|
|
||||||
Application.prototype.SetHandlerMode = function(mode)
|
Application.prototype.SetHandlerMode = function(mode)
|
||||||
{
|
{
|
||||||
if (this.handler)
|
var manipolationHandlers = ["default", "addGraph", "addArc", "delete", "findPath", "connectedComponent", "eulerianLoop"];
|
||||||
|
|
||||||
|
if (this.handler && (g_AlgorithmIds.indexOf(mode) >= 0 || manipolationHandlers.indexOf(mode) >= 0))
|
||||||
{
|
{
|
||||||
this.handler.RestoreAll();
|
this.handler.RestoreAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == "default")
|
if (mode == "default")
|
||||||
{
|
{
|
||||||
this.handler = new DefaultHandler(this);
|
this.handler = new DefaultHandler(this);
|
||||||
@ -3512,6 +3657,11 @@ Application.prototype.SetHandlerMode = function(mode)
|
|||||||
var savedDialogGraphImageHandler = new SavedDialogGraphImageHandler(this);
|
var savedDialogGraphImageHandler = new SavedDialogGraphImageHandler(this);
|
||||||
savedDialogGraphImageHandler.show();
|
savedDialogGraphImageHandler.show();
|
||||||
}
|
}
|
||||||
|
else if (mode == "saveDialogFullImage")
|
||||||
|
{
|
||||||
|
var savedDialogGraphImageHandler = new SavedDialogGraphImageHandler(this);
|
||||||
|
savedDialogGraphImageHandler.show(null, true);
|
||||||
|
}
|
||||||
else if (mode == "eulerianLoop")
|
else if (mode == "eulerianLoop")
|
||||||
{
|
{
|
||||||
this.handler = new EulerianLoopGraphHandler(this);
|
this.handler = new EulerianLoopGraphHandler(this);
|
||||||
@ -3640,7 +3790,7 @@ Application.prototype.GetStatus = function()
|
|||||||
|
|
||||||
Application.prototype.GetAdjacencyMatrix = function ()
|
Application.prototype.GetAdjacencyMatrix = function ()
|
||||||
{
|
{
|
||||||
return this.graph.GetAdjacencyMatrix();
|
return this.graph.GetAdjacencyMatrixStr();
|
||||||
}
|
}
|
||||||
|
|
||||||
Application.prototype.TestAdjacencyMatrix = function (matrix, rowsObj, colsObj, separator = ",")
|
Application.prototype.TestAdjacencyMatrix = function (matrix, rowsObj, colsObj, separator = ",")
|
||||||
@ -3762,7 +3912,7 @@ Application.prototype.SaveGraphOnDisk = function ()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Application.prototype.SaveGraphImageOnDisk = function ()
|
Application.prototype.SaveGraphImageOnDisk = function (showDialogCallback)
|
||||||
{
|
{
|
||||||
var imageName = this.GetNewGraphName();
|
var imageName = this.GetNewGraphName();
|
||||||
|
|
||||||
@ -3794,7 +3944,39 @@ Application.prototype.SaveGraphImageOnDisk = function ()
|
|||||||
data: {
|
data: {
|
||||||
base64data : imageBase64Data
|
base64data : imageBase64Data
|
||||||
},
|
},
|
||||||
dataType: "text"
|
dataType: "text",
|
||||||
|
success: function(data){
|
||||||
|
showDialogCallback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return imageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
Application.prototype.SaveFullGraphImageOnDisk = function (showDialogCallback)
|
||||||
|
{
|
||||||
|
var imageName = this.GetNewGraphName();
|
||||||
|
|
||||||
|
this.stopRenderTimer();
|
||||||
|
var canvas = this._OffscreenRedrawGraph();
|
||||||
|
|
||||||
|
var bbox = this.graph.getGraphBBox();
|
||||||
|
|
||||||
|
var rectParams = "";
|
||||||
|
rectParams = "&x=0" + "&y=0" + "&width=" + bbox.size().x + "&height=" + bbox.size().y;
|
||||||
|
|
||||||
|
var imageBase64Data = canvas.toDataURL();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/cgi-bin/saveImage.php?name=" + imageName + rectParams,
|
||||||
|
data: {
|
||||||
|
base64data : imageBase64Data
|
||||||
|
},
|
||||||
|
dataType: "text",
|
||||||
|
success: function(data){
|
||||||
|
showDialogCallback();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return imageName;
|
return imageName;
|
||||||
@ -3942,7 +4124,7 @@ Application.prototype.GetFindPathReport = function ()
|
|||||||
return this.findPathReport;
|
return this.findPathReport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
Application.prototype.CalculateAlgorithm = function(queryString, callbackObject)
|
Application.prototype.CalculateAlgorithm = function(queryString, callbackObject)
|
||||||
{
|
{
|
||||||
var app = this;
|
var app = this;
|
||||||
@ -4005,7 +4187,18 @@ Application.prototype.CalculateAlgorithm = function(queryString, callbackObject)
|
|||||||
$edges.each(function(){
|
$edges.each(function(){
|
||||||
var source = $(this).attr('source');
|
var source = $(this).attr('source');
|
||||||
var target = $(this).attr('target');
|
var target = $(this).attr('target');
|
||||||
pathObjects.push(app.FindEdge(source, target));
|
var edge = app.FindEdge(source, target);
|
||||||
|
pathObjects.push(edge);
|
||||||
|
|
||||||
|
$data = $(this).find("data");
|
||||||
|
$data.each(function(){
|
||||||
|
if (!properties[edge.id])
|
||||||
|
{
|
||||||
|
properties[edge.id] = {};
|
||||||
|
}
|
||||||
|
properties[edge.id][$(this).attr('key')] = $(this).text();
|
||||||
|
console.log("Data edge " + $(this).text());
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(result);
|
console.log(result);
|
||||||
@ -4015,6 +4208,7 @@ Application.prototype.CalculateAlgorithm = function(queryString, callbackObject)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
Application.prototype.GetRealWidth = function ()
|
Application.prototype.GetRealWidth = function ()
|
||||||
{
|
{
|
||||||
@ -4073,9 +4267,14 @@ Application.prototype.getAlgorithmNames = function()
|
|||||||
oneFactory = factory(this.graph);
|
oneFactory = factory(this.graph);
|
||||||
obj.name = oneFactory.getName(g_language);
|
obj.name = oneFactory.getName(g_language);
|
||||||
obj.id = oneFactory.getId();
|
obj.id = oneFactory.getId();
|
||||||
|
obj.priority = oneFactory.getPriority();
|
||||||
res.push(obj);
|
res.push(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res.sort(function (a, b) {
|
||||||
|
return a.priority - b.priority;
|
||||||
|
});
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4123,8 +4322,8 @@ var userAction = function(str)
|
|||||||
{
|
{
|
||||||
if (typeof window.yaCounter25827098 !== "undefined")
|
if (typeof window.yaCounter25827098 !== "undefined")
|
||||||
{
|
{
|
||||||
console.log(str);
|
console.log(g_language + "/" + str);
|
||||||
window.yaCounter25827098.hit("http://" + window.location.hostname + "/UserAction#" + str);
|
window.yaCounter25827098.hit("http://" + window.location.hostname + (g_language != "ru" ? "/" + g_language : "") + "/UserAction#" + str);
|
||||||
}
|
}
|
||||||
else if (!waitCounter)
|
else if (!waitCounter)
|
||||||
{
|
{
|
||||||
@ -4278,6 +4477,29 @@ function postLoadPage()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCharCode(event) {
|
||||||
|
if (event.which == null) { // IE
|
||||||
|
return event.keyCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.which != 0 && event.charCode != 0) { // все кроме IE
|
||||||
|
return event.which; // остальные
|
||||||
|
}
|
||||||
|
|
||||||
|
return null; // спец. символ
|
||||||
|
}
|
||||||
|
|
||||||
|
function getChar(event) {
|
||||||
|
return String.fromCharCode(getCharCode(event)); // остальные
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectHandler(buttonName, handlerName)
|
||||||
|
{
|
||||||
|
userAction(buttonName + "_shortcut");
|
||||||
|
restButtons (buttonName);
|
||||||
|
application.SetHandlerMode(handlerName);
|
||||||
|
}
|
||||||
|
|
||||||
document.onkeypress = function (e)
|
document.onkeypress = function (e)
|
||||||
{
|
{
|
||||||
if (event.defaultPrevented
|
if (event.defaultPrevented
|
||||||
@ -4288,50 +4510,65 @@ function postLoadPage()
|
|||||||
|| ($('#saveDialog').hasClass('ui-dialog-content') && $('#saveDialog').dialog('isOpen'))
|
|| ($('#saveDialog').hasClass('ui-dialog-content') && $('#saveDialog').dialog('isOpen'))
|
||||||
|| ($('#saveImageDialog').hasClass('ui-dialog-content') && $('#saveImageDialog').dialog('isOpen'))
|
|| ($('#saveImageDialog').hasClass('ui-dialog-content') && $('#saveImageDialog').dialog('isOpen'))
|
||||||
|| ($('#GroupRenameDialog').hasClass('ui-dialog-content') && $('#GroupRenameDialog').dialog('isOpen'))
|
|| ($('#GroupRenameDialog').hasClass('ui-dialog-content') && $('#GroupRenameDialog').dialog('isOpen'))
|
||||||
|| $('#developerTools').css("display") != "none")
|
|| $('#developerTools').css("display") != "none"
|
||||||
|
|| ($('#NeedAlgorithm').hasClass('ui-dialog-content') && $('#NeedAlgorithm').dialog('isOpen')))
|
||||||
{
|
{
|
||||||
console.log("prevent");
|
console.log("prevent");
|
||||||
return; // Should do nothing if the default action has been cancelled
|
return; // Should do nothing if the default action has been cancelled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var key = 0;
|
var key = getChar(event);
|
||||||
|
var code = getCharCode(event);
|
||||||
if(window.event)
|
console.log(key + " code=" + code);
|
||||||
{
|
|
||||||
key = event.keyCode;
|
|
||||||
}
|
|
||||||
else if(event.which)
|
|
||||||
{
|
|
||||||
key = event.which;
|
|
||||||
}
|
|
||||||
console.log(key);
|
|
||||||
|
|
||||||
var moveValue = 10;
|
var moveValue = 10;
|
||||||
if (key == 61 || key == 43) // +
|
if (code == 61 || code == 43) // +
|
||||||
{
|
{
|
||||||
application.multCanvasScale(1.5);
|
application.multCanvasScale(1.5);
|
||||||
}
|
}
|
||||||
else if (key == 45) // -
|
else if (code == 45) // -
|
||||||
{
|
{
|
||||||
application.multCanvasScale(1 / 1.5);
|
application.multCanvasScale(1 / 1.5);
|
||||||
}
|
}
|
||||||
else if (key == 119 || key == 1094) // up
|
else if (key == 'w' || key == 'ц') // up
|
||||||
{
|
{
|
||||||
application.onCanvasMove(new Point(0, moveValue));
|
application.onCanvasMove(new Point(0, moveValue));
|
||||||
}
|
}
|
||||||
else if (key == 115 || key == 1099) // down
|
else if (key == 's' || key == 'ы') // down
|
||||||
{
|
{
|
||||||
application.onCanvasMove(new Point(0, -moveValue));
|
application.onCanvasMove(new Point(0, -moveValue));
|
||||||
}
|
}
|
||||||
else if (key == 97 || key == 1092) // left
|
else if (key == 'a' || key == 'ф') // left
|
||||||
{
|
{
|
||||||
application.onCanvasMove(new Point(moveValue, 0));
|
application.onCanvasMove(new Point(moveValue, 0));
|
||||||
}
|
}
|
||||||
else if (key == 100 || key == 1074) // right
|
else if (key == 'd' || key == 'в') // right
|
||||||
{
|
{
|
||||||
application.onCanvasMove(new Point(-moveValue, 0));
|
application.onCanvasMove(new Point(-moveValue, 0));
|
||||||
}
|
}
|
||||||
|
else if (key == 'v' || key == 'м') // vertex
|
||||||
|
{
|
||||||
|
selectHandler('AddGraph', 'addGraph');
|
||||||
|
}
|
||||||
|
else if (key == 'e' || key == 'у') // edge
|
||||||
|
{
|
||||||
|
selectHandler('ConnectGraphs', 'addArc');
|
||||||
|
}
|
||||||
|
else if (key == 'r' || key == 'к') // delete
|
||||||
|
{
|
||||||
|
selectHandler('DeleteObject', 'delete');
|
||||||
|
}
|
||||||
|
else if (key == 'n' || key == 'т') // new
|
||||||
|
{
|
||||||
|
userAction('NewGraph_shortcut');
|
||||||
|
application.SetHandlerMode("deleteAll");
|
||||||
|
application.SetDefaultTransformations();
|
||||||
|
}
|
||||||
|
else if (key == 'm' || key == 'ь') // move
|
||||||
|
{
|
||||||
|
selectHandler('Default', 'default');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('ShowAdjacencyMatrix').onclick = function ()
|
document.getElementById('ShowAdjacencyMatrix').onclick = function ()
|
||||||
@ -4412,6 +4649,12 @@ function postLoadPage()
|
|||||||
application.SetHandlerMode("saveDialogImage");
|
application.SetHandlerMode("saveDialogImage");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.getElementById('SaveFullGraphImage').onclick = function ()
|
||||||
|
{
|
||||||
|
userAction(this.id);
|
||||||
|
application.SetHandlerMode("saveDialogFullImage");
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById('Zoom100').onclick = function ()
|
document.getElementById('Zoom100').onclick = function ()
|
||||||
{
|
{
|
||||||
userAction(this.id);
|
userAction(this.id);
|
||||||
@ -4510,6 +4753,40 @@ function postLoadPage()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (document.getElementById('VoteButton') !== null)
|
||||||
|
document.getElementById('VoteButton').onclick = function ()
|
||||||
|
{
|
||||||
|
var dialogButtons = {};
|
||||||
|
|
||||||
|
for (var i = 0; i < 6 && document.getElementById('vote' + i) !== null; i++)
|
||||||
|
{
|
||||||
|
document.getElementById('vote' + i)["voteIndex"] = i;
|
||||||
|
document.getElementById('vote' + i).onclick = function ()
|
||||||
|
{
|
||||||
|
console.log("Vote" + this["voteIndex"]);
|
||||||
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: "/cgi-bin/vote.php?index=" + this["voteIndex"],
|
||||||
|
dataType: "text"
|
||||||
|
});
|
||||||
|
$("#voteDialog").dialog('close');
|
||||||
|
$("#VoteButton").hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogButtons[g_close] = function() {
|
||||||
|
$( this ).dialog( "close" );
|
||||||
|
};
|
||||||
|
|
||||||
|
$( "#voteDialog" ).dialog({
|
||||||
|
resizable: false,
|
||||||
|
title: g_vote,
|
||||||
|
width: 400,
|
||||||
|
modal: true,
|
||||||
|
dialogClass: 'EdgeDialog',
|
||||||
|
buttons: dialogButtons,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Get algorithms list and load it.
|
// Get algorithms list and load it.
|
||||||
|
185
script/plugins/MaxFlow.js
Normal file
185
script/plugins/MaxFlow.js
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
/**
|
||||||
|
* Find short path.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function FindMaxFlow(graph, app)
|
||||||
|
{
|
||||||
|
BaseAlgorithmEx.apply(this, arguments);
|
||||||
|
this.message = g_selectStartVertexForMaxFlow;
|
||||||
|
this.selectedObjects = {};
|
||||||
|
this.selectedEdges = [];
|
||||||
|
this.resetUpText = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// inheritance.
|
||||||
|
FindMaxFlow.prototype = Object.create(BaseAlgorithmEx.prototype);
|
||||||
|
// First selected.
|
||||||
|
FindMaxFlow.prototype.firstObject = null;
|
||||||
|
// Second selected.
|
||||||
|
FindMaxFlow.prototype.secondObject = null;
|
||||||
|
// Path
|
||||||
|
FindMaxFlow.prototype.selectedEdges = null;
|
||||||
|
|
||||||
|
|
||||||
|
FindMaxFlow.prototype.getName = function(local)
|
||||||
|
{
|
||||||
|
return local == "ru" ? "Поиск максимального потока" : "Find Maximum flow";
|
||||||
|
}
|
||||||
|
|
||||||
|
FindMaxFlow.prototype.getId = function()
|
||||||
|
{
|
||||||
|
return "OlegSh.FindMaxFlow";
|
||||||
|
}
|
||||||
|
|
||||||
|
// @return message for user.
|
||||||
|
FindMaxFlow.prototype.getMessage = function(local)
|
||||||
|
{
|
||||||
|
return this.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
FindMaxFlow.prototype.result = function(resultCallback)
|
||||||
|
{
|
||||||
|
if (this.firstObject && this.secondObject)
|
||||||
|
{
|
||||||
|
this.outResultCallback = function (result ) { resultCallback(result); };
|
||||||
|
self = this;
|
||||||
|
this.CalculateAlgorithm("mfpr=cgiInput&source=" + this.firstObject.id + "&drain=" + this.secondObject.id + "&report=xml", function (pathObjects, properties, results)
|
||||||
|
{
|
||||||
|
self.resultCallback(pathObjects, properties, results);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
FindMaxFlow.prototype.resultCallback = function(pathObjects, properties, results)
|
||||||
|
{
|
||||||
|
var outputResult = {};
|
||||||
|
outputResult["version"] = 1;
|
||||||
|
|
||||||
|
this.pathObjects = pathObjects;
|
||||||
|
this.properties = properties;
|
||||||
|
|
||||||
|
var bFound = results.length > 0 && results[0].value < 1E5 && (results[0].type == 1 || results[0].type == 2) && results[0].value * 1 > 0.0;
|
||||||
|
|
||||||
|
if (bFound)
|
||||||
|
{
|
||||||
|
this.selectedObjects = {};
|
||||||
|
|
||||||
|
for (var i = 0; i < pathObjects.length; i++)
|
||||||
|
{
|
||||||
|
if (pathObjects[i] instanceof BaseEdge)
|
||||||
|
{
|
||||||
|
this.selectedObjects[pathObjects[i].id] = 1;
|
||||||
|
if (pathObjects[i].useWeight)
|
||||||
|
{
|
||||||
|
pathObjects[i].text = properties[pathObjects[i].id]["flowValue"] + " / " + pathObjects[i].GetWeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.selectedEdges = pathObjects;
|
||||||
|
|
||||||
|
this.message = g_maxFlowResult.replace("%1", (results[0].value * 1).toString()).replace("%2", this.firstObject.mainText).replace("%3", this.secondObject.mainText);
|
||||||
|
|
||||||
|
this.selectedObjects[this.secondObject.id] = 3;
|
||||||
|
this.selectedObjects[this.firstObject.id] = 1;
|
||||||
|
|
||||||
|
this.secondObject.upText = g_sinkVertex;
|
||||||
|
this.resetUpText.push(this.secondObject);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.message = g_flowNotExists.toString().replace("%1", this.firstObject.mainText).replace("%2", this.secondObject.mainText);
|
||||||
|
}
|
||||||
|
this.secondObject = null;
|
||||||
|
this.firstObject = null;
|
||||||
|
|
||||||
|
this.outResultCallback(outputResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
FindMaxFlow.prototype.selectVertex = function(vertex)
|
||||||
|
{
|
||||||
|
this.pathObjects = null;
|
||||||
|
this.shortDist = null;
|
||||||
|
|
||||||
|
if (this.firstObject)
|
||||||
|
{
|
||||||
|
this.message = g_processing;
|
||||||
|
this.secondObject = vertex;
|
||||||
|
this.selectedObjects = [];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.restore();
|
||||||
|
|
||||||
|
this.firstObject = vertex;
|
||||||
|
this.secondObject = null;
|
||||||
|
this.selectedObjects = {};
|
||||||
|
this.message = g_selectFinishVertexForMaxFlow;
|
||||||
|
this.firstObject.upText = g_sourceVertex;
|
||||||
|
this.resetUpText.push(this.firstObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FindMaxFlow.prototype.deselectAll = function()
|
||||||
|
{
|
||||||
|
this.firstObject = null;
|
||||||
|
this.secondObject = null;
|
||||||
|
this.selectedObjects = {};
|
||||||
|
this.message = g_selectStartVertexForMaxFlow;
|
||||||
|
this.restore();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FindMaxFlow.prototype.instance = function()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FindMaxFlow.prototype.getObjectSelectedGroup = function(object)
|
||||||
|
{
|
||||||
|
return (object.id in this.selectedObjects) ? this.selectedObjects[object.id] : ((object == this.firstObject || object == object.secondObject) ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
FindMaxFlow.prototype.getPriority = function()
|
||||||
|
{
|
||||||
|
return -9.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @return true, if you change resotry graph after use.
|
||||||
|
BaseAlgorithm.prototype.wantRestore = function()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calls this method if wantRestore return true.
|
||||||
|
BaseAlgorithm.prototype.restore = function()
|
||||||
|
{
|
||||||
|
if (this.selectedEdges != null)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < this.selectedEdges.length; i++)
|
||||||
|
{
|
||||||
|
if (this.selectedEdges[i] instanceof BaseEdge)
|
||||||
|
{
|
||||||
|
this.selectedEdges[i].text = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < this.resetUpText.length; i++)
|
||||||
|
{
|
||||||
|
this.resetUpText[i].upText = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Factory for connected components.
|
||||||
|
function CreateFindMaxFlow(graph, app)
|
||||||
|
{
|
||||||
|
return new FindMaxFlow(graph, app)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gerister connected component.
|
||||||
|
RegisterAlgorithm (CreateFindMaxFlow);
|
@ -78,6 +78,14 @@ var g_checkToSave = "Check to save";
|
|||||||
var g_showDistMatrix = "Show Distance matrix";
|
var g_showDistMatrix = "Show Distance matrix";
|
||||||
var g_minDistMatrixText = "Minimal distances matrix";
|
var g_minDistMatrixText = "Minimal distances matrix";
|
||||||
|
|
||||||
|
var g_selectStartVertexForMaxFlow = "Select source vertex for max flow";
|
||||||
|
var g_selectFinishVertexForMaxFlow = "Select sink vertex for max flow";
|
||||||
|
var g_maxFlowResult = "Maximum flow from %2 to %3 is %1";
|
||||||
|
var g_flowNotExists = "Flow from %1 to %2 does not exists";
|
||||||
|
|
||||||
|
var g_sourceVertex = "Source";
|
||||||
|
var g_sinkVertex = "Sink";
|
||||||
|
|
||||||
function loadTexts()
|
function loadTexts()
|
||||||
{
|
{
|
||||||
g_textsSelectAndMove = document.getElementById("SelectAndMoveObject").innerHTML;
|
g_textsSelectAndMove = document.getElementById("SelectAndMoveObject").innerHTML;
|
||||||
@ -155,4 +163,12 @@ function loadTexts()
|
|||||||
g_checkToSave = document.getElementById("checkToSave").innerHTML;
|
g_checkToSave = document.getElementById("checkToSave").innerHTML;
|
||||||
g_showDistMatrix = document.getElementById("showDistMatrix").innerHTML;
|
g_showDistMatrix = document.getElementById("showDistMatrix").innerHTML;
|
||||||
g_minDistMatrixText = document.getElementById("distMatrixText").innerHTML;
|
g_minDistMatrixText = document.getElementById("distMatrixText").innerHTML;
|
||||||
|
|
||||||
|
g_selectStartVertexForMaxFlow = document.getElementById("selectStartVertexForMaxFlow").innerHTML;
|
||||||
|
g_selectFinishVertexForMaxFlow = document.getElementById("selectFinishVertexForMaxFlow").innerHTML;
|
||||||
|
g_maxFlowResult = document.getElementById("maxFlowResult").innerHTML;
|
||||||
|
g_flowNotExists = document.getElementById("flowNotExists").innerHTML;
|
||||||
|
|
||||||
|
g_sourceVertex = document.getElementById("sourceVertex").innerHTML;
|
||||||
|
g_sinkVertex = document.getElementById("sinkVertex").innerHTML;
|
||||||
}
|
}
|
||||||
|
@ -398,6 +398,14 @@
|
|||||||
<p id="checkToSave" class="translation"><?= L('checkToSave')?></p>
|
<p id="checkToSave" class="translation"><?= L('checkToSave')?></p>
|
||||||
<p id="showDistMatrix" class="translation"><?= L('showDistMatrix')?></p>
|
<p id="showDistMatrix" class="translation"><?= L('showDistMatrix')?></p>
|
||||||
<p id="distMatrixText" class="translation"><?= L('distMatrixText')?></p>
|
<p id="distMatrixText" class="translation"><?= L('distMatrixText')?></p>
|
||||||
|
|
||||||
|
<p id="selectStartVertexForMaxFlow" class="translation"><?= L('selectStartVertexForMaxFlow')?></p>
|
||||||
|
<p id="selectFinishVertexForMaxFlow" class="translation"><?= L('selectFinishVertexForMaxFlow')?></p>
|
||||||
|
<p id="maxFlowResult" class="translation"><?= L('maxFlowResult')?></p>
|
||||||
|
<p id="flowNotExists" class="translation"><?= L('flowNotExists')?></p>
|
||||||
|
|
||||||
|
<p id="sourceVertex" class="translation"><?= L('sourceVertex')?></p>
|
||||||
|
<p id="sinkVertex" class="translation"><?= L('sinkVertex')?></p>
|
||||||
</section>
|
</section>
|
||||||
<!--
|
<!--
|
||||||
<script>
|
<script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user