mirror of
https://github.com/UnickSoft/graphonline.git
synced 2025-07-04 00:36:45 +00:00
Add new shapes for vertexes.
This commit is contained in:
parent
2172acb28f
commit
b60e70c089
@ -151,17 +151,26 @@ BaseEdge.prototype.GetEdgePositionsShift = function()
|
|||||||
|
|
||||||
BaseEdge.prototype.GetEdgePositions = function()
|
BaseEdge.prototype.GetEdgePositions = function()
|
||||||
{
|
{
|
||||||
|
var res = [];
|
||||||
|
|
||||||
|
if (this.vertex1 == this.vertex2)
|
||||||
|
{
|
||||||
|
res.push(this.vertex1.position);
|
||||||
|
res.push(this.vertex2.position);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
var position1 = this.vertex1.position;
|
var position1 = this.vertex1.position;
|
||||||
var position2 = this.vertex2.position;
|
var position2 = this.vertex2.position;
|
||||||
var diameter1 = this.vertex1.model.diameter + parseInt(this.vertex1.currentStyle.lineWidth);
|
var diameter1 = this.vertex1.model.diameter + parseInt(this.vertex1.currentStyle.GetStyle({}).lineWidth);
|
||||||
var diameter2 = this.vertex2.model.diameter + parseInt(this.vertex2.currentStyle.lineWidth);
|
var diameter2 = this.vertex2.model.diameter + parseInt(this.vertex2.currentStyle.GetStyle({}).lineWidth);
|
||||||
|
|
||||||
var direction = position1.subtract(position2);
|
var direction = position1.subtract(position2);
|
||||||
|
|
||||||
var direction1 = direction;
|
var direction1 = direction;
|
||||||
var direction2 = direction;
|
var direction2 = direction;
|
||||||
var d1 = diameter1;
|
var d1 = diameter1;
|
||||||
var d2 = -diameter2;
|
var d2 = diameter2;
|
||||||
|
|
||||||
if (this.model.type == EdgeModels.cruvled)
|
if (this.model.type == EdgeModels.cruvled)
|
||||||
{
|
{
|
||||||
@ -174,15 +183,47 @@ BaseEdge.prototype.GetEdgePositions = function()
|
|||||||
|
|
||||||
d2 = diameter2;
|
d2 = diameter2;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
direction2 = direction2.multiply(-1);
|
||||||
|
}
|
||||||
|
|
||||||
direction1.normalize(1.0);
|
direction1.normalize(1.0);
|
||||||
direction1 = direction1.multiply(0.5);
|
|
||||||
direction2.normalize(1.0);
|
direction2.normalize(1.0);
|
||||||
direction2 = direction2.multiply(0.5);
|
|
||||||
|
|
||||||
var res = [];
|
var vertexes = [];
|
||||||
res.push(position1.subtract(direction1.multiply(d1)));
|
vertexes.push({vertex : this.vertex1, direction : direction1, position : position1, diameter : d1});
|
||||||
res.push(position2.subtract(direction2.multiply(d2)));
|
vertexes.push({vertex : this.vertex2, direction : direction2, position : position2, diameter : d2});
|
||||||
|
|
||||||
|
vertexes.forEach(function(data)
|
||||||
|
{
|
||||||
|
var shape = data.vertex.currentStyle.GetStyle({}).shape;
|
||||||
|
if (shape == VertexCircleShape)
|
||||||
|
{
|
||||||
|
var direction = data.direction.multiply(0.5);
|
||||||
|
|
||||||
|
res.push(data.position.subtract(direction.multiply(data.diameter)));
|
||||||
|
}
|
||||||
|
else if (shape == VertexSquareShape || shape == VertexTriangleShape)
|
||||||
|
{
|
||||||
|
var lineFinish1 = data.direction.multiply(-1).multiply(1000.0);
|
||||||
|
|
||||||
|
var pointsVertex1 = shape == VertexSquareShape ? GetSquarePoints(data.diameter) : GetTrianglePoints(data.diameter);
|
||||||
|
pointsVertex1.push(pointsVertex1[0]);
|
||||||
|
|
||||||
|
for (var i = 0; i < pointsVertex1.length - 1; i ++)
|
||||||
|
{
|
||||||
|
var hitText = Point.hitTest(new Point(0, 0), lineFinish1, pointsVertex1[i], pointsVertex1[i + 1]);
|
||||||
|
if (hitText != null)
|
||||||
|
{
|
||||||
|
res.push(data.position.add(hitText));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,3 +77,46 @@ BaseVertex.prototype.IsUndefinedPosition = function ()
|
|||||||
{
|
{
|
||||||
return this.hasUndefinedPosition;
|
return this.hasUndefinedPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BaseVertex.prototype.HitTest = function (pos)
|
||||||
|
{
|
||||||
|
var shape = this.hasOwnProperty('currentStyle') ? this.currentStyle.GetStyle({}).shape : VertexCircleShape;
|
||||||
|
var width = this.hasOwnProperty('currentStyle') ? this.currentStyle.GetStyle({}).lineWidth : 0;
|
||||||
|
|
||||||
|
if (shape == VertexCircleShape)
|
||||||
|
{
|
||||||
|
return this.position.distance(pos) < this.model.diameter / 2.0 + width;
|
||||||
|
}
|
||||||
|
else if (shape == VertexSquareShape || shape == VertexTriangleShape)
|
||||||
|
{
|
||||||
|
var relativPos = (new Point(pos.x, pos.y)).subtract(this.position);
|
||||||
|
var lineFinish1 = relativPos.add(new Point(1000, 0));
|
||||||
|
var lineFinish2 = relativPos.add(new Point(-1000, 0));
|
||||||
|
|
||||||
|
var pointsVertex1 = shape == VertexSquareShape ? GetSquarePoints(this.model.diameter + width) : GetTrianglePoints(this.model.diameter + width);
|
||||||
|
pointsVertex1.push(pointsVertex1[0]);
|
||||||
|
|
||||||
|
var hitNumber1 = 0;
|
||||||
|
var hitNumber2 = 0;
|
||||||
|
|
||||||
|
console.log("Points");
|
||||||
|
for (var i = 0; i < pointsVertex1.length - 1; i ++)
|
||||||
|
{
|
||||||
|
console.log(pointsVertex1[i] + " " + pointsVertex1[i + 1]);
|
||||||
|
var hitTest = Point.hitTest(relativPos, lineFinish1, pointsVertex1[i], pointsVertex1[i + 1]);
|
||||||
|
if (hitTest != null)
|
||||||
|
{
|
||||||
|
hitNumber1++;
|
||||||
|
}
|
||||||
|
hitTest = Point.hitTest(relativPos, lineFinish2, pointsVertex1[i], pointsVertex1[i + 1]);
|
||||||
|
if (hitTest != null)
|
||||||
|
{
|
||||||
|
hitNumber2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hitNumber1 == 1 && hitNumber2 == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
@ -4,6 +4,41 @@
|
|||||||
|
|
||||||
// Test graph: http://localhost:8080/?graph=oimDPgsdgiAjWGBHZZcst
|
// Test graph: http://localhost:8080/?graph=oimDPgsdgiAjWGBHZZcst
|
||||||
|
|
||||||
|
|
||||||
|
// Vertex shape
|
||||||
|
const VertexCircleShape = 0,
|
||||||
|
VertexSquareShape = 1,
|
||||||
|
VertexTriangleShape = 2;
|
||||||
|
|
||||||
|
function GetSquarePoints(diameter)
|
||||||
|
{
|
||||||
|
var res = [];
|
||||||
|
|
||||||
|
var a = diameter;
|
||||||
|
res.push(new Point(-a / 2, - a / 2));
|
||||||
|
res.push(new Point(a / 2, -a / 2));
|
||||||
|
res.push(new Point(a / 2, a / 2));
|
||||||
|
res.push(new Point(-a / 2, a / 2));
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetTrianglePoints(diameter)
|
||||||
|
{
|
||||||
|
var res = [];
|
||||||
|
|
||||||
|
var effectiveDiameter = diameter * 1.5;
|
||||||
|
var upOffset = effectiveDiameter / 2;
|
||||||
|
var downOffset = effectiveDiameter / 4;
|
||||||
|
var lrOffset = effectiveDiameter * 3 / (Math.sqrt(3) * 4);
|
||||||
|
|
||||||
|
res.push(new Point(0, - upOffset));
|
||||||
|
res.push(new Point(lrOffset, downOffset));
|
||||||
|
res.push(new Point(- lrOffset, downOffset));
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
function BaseVertexStyle()
|
function BaseVertexStyle()
|
||||||
{
|
{
|
||||||
this.baseStyles = [];
|
this.baseStyles = [];
|
||||||
@ -24,7 +59,10 @@ BaseVertexStyle.prototype.GetStyle = function (baseStyle)
|
|||||||
baseStyle.fillStyle = this.fillStyle;
|
baseStyle.fillStyle = this.fillStyle;
|
||||||
if (this.hasOwnProperty('mainTextColor'))
|
if (this.hasOwnProperty('mainTextColor'))
|
||||||
baseStyle.mainTextColor = this.mainTextColor;
|
baseStyle.mainTextColor = this.mainTextColor;
|
||||||
|
if (this.hasOwnProperty('shape'))
|
||||||
|
baseStyle.shape = this.shape;
|
||||||
|
|
||||||
|
baseStyle.lineWidth = parseInt(baseStyle.lineWidth);
|
||||||
return baseStyle;
|
return baseStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,6 +80,7 @@ function CommonVertexStyle()
|
|||||||
this.strokeStyle = '#c7b7c7';
|
this.strokeStyle = '#c7b7c7';
|
||||||
this.fillStyle = '#68aeba';
|
this.fillStyle = '#68aeba';
|
||||||
this.mainTextColor = '#f0d543';
|
this.mainTextColor = '#f0d543';
|
||||||
|
this.shape = VertexCircleShape;//VertexSquareShape;
|
||||||
|
|
||||||
this.baseStyles = [];
|
this.baseStyles = [];
|
||||||
}
|
}
|
||||||
@ -219,7 +258,10 @@ BaseVertexDrawer.prototype.Draw = function(baseGraph, graphStyle)
|
|||||||
{
|
{
|
||||||
this.SetupStyle(graphStyle);
|
this.SetupStyle(graphStyle);
|
||||||
this.DrawShape(baseGraph);
|
this.DrawShape(baseGraph);
|
||||||
|
|
||||||
|
if (this.currentStyle.lineWidth != 0)
|
||||||
this.context.stroke();
|
this.context.stroke();
|
||||||
|
|
||||||
this.context.fill();
|
this.context.fill();
|
||||||
|
|
||||||
this.DrawCenterText(baseGraph.position, baseGraph.mainText, graphStyle.mainTextColor, graphStyle.fillStyle, true, true, 16);
|
this.DrawCenterText(baseGraph.position, baseGraph.mainText, graphStyle.mainTextColor, graphStyle.fillStyle, true, true, 16);
|
||||||
@ -236,6 +278,7 @@ BaseVertexDrawer.prototype.Draw = function(baseGraph, graphStyle)
|
|||||||
|
|
||||||
BaseVertexDrawer.prototype.SetupStyle = function(style)
|
BaseVertexDrawer.prototype.SetupStyle = function(style)
|
||||||
{
|
{
|
||||||
|
this.currentStyle = style;
|
||||||
this.context.lineWidth = style.lineWidth;
|
this.context.lineWidth = style.lineWidth;
|
||||||
this.context.strokeStyle = style.strokeStyle;
|
this.context.strokeStyle = style.strokeStyle;
|
||||||
this.context.fillStyle = style.fillStyle;
|
this.context.fillStyle = style.fillStyle;
|
||||||
@ -244,7 +287,35 @@ BaseVertexDrawer.prototype.SetupStyle = function(style)
|
|||||||
BaseVertexDrawer.prototype.DrawShape = function(baseGraph)
|
BaseVertexDrawer.prototype.DrawShape = function(baseGraph)
|
||||||
{
|
{
|
||||||
this.context.beginPath();
|
this.context.beginPath();
|
||||||
|
if (this.currentStyle.shape == VertexCircleShape)
|
||||||
|
{
|
||||||
this.context.arc(baseGraph.position.x, baseGraph.position.y, baseGraph.model.diameter / 2.0, 0, 2 * Math.PI);
|
this.context.arc(baseGraph.position.x, baseGraph.position.y, baseGraph.model.diameter / 2.0, 0, 2 * Math.PI);
|
||||||
|
}
|
||||||
|
else if (this.currentStyle.shape == VertexSquareShape)
|
||||||
|
{
|
||||||
|
var points = GetSquarePoints(baseGraph.model.diameter);
|
||||||
|
|
||||||
|
this.context.moveTo(baseGraph.position.x + points[points.length - 1].x, baseGraph.position.y + points[points.length - 1].y);
|
||||||
|
|
||||||
|
var context = this.context;
|
||||||
|
|
||||||
|
points.forEach(function(point) {
|
||||||
|
context.lineTo(baseGraph.position.x + point.x, baseGraph.position.y + point.y);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (this.currentStyle.shape == VertexTriangleShape)
|
||||||
|
{
|
||||||
|
var points = GetTrianglePoints(baseGraph.model.diameter)
|
||||||
|
|
||||||
|
this.context.moveTo(baseGraph.position.x + points[points.length - 1].x, baseGraph.position.y + points[points.length - 1].y);
|
||||||
|
|
||||||
|
var context = this.context;
|
||||||
|
|
||||||
|
points.forEach(function(point) {
|
||||||
|
context.lineTo(baseGraph.position.x + point.x, baseGraph.position.y + point.y);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.context.closePath();
|
this.context.closePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ BaseHandler.prototype.GetSelectedGraph = function(pos)
|
|||||||
var res = null;
|
var res = null;
|
||||||
for (var i = 0; i < this.app.graph.vertices.length; i ++)
|
for (var i = 0; i < this.app.graph.vertices.length; i ++)
|
||||||
{
|
{
|
||||||
if (this.app.graph.vertices[i].position.distance(pos) < this.app.graph.vertices[i].model.diameter / 2.0)
|
if (this.app.graph.vertices[i].HitTest(pos))
|
||||||
{
|
{
|
||||||
// Select last of them.
|
// Select last of them.
|
||||||
res = this.app.graph.vertices[i];
|
res = this.app.graph.vertices[i];
|
||||||
@ -1376,7 +1376,7 @@ SetupVertexStyle.prototype.show = function(index)
|
|||||||
style.mainTextColor = $( "#vertexTextColor" ).val();
|
style.mainTextColor = $( "#vertexTextColor" ).val();
|
||||||
|
|
||||||
if (fullStyle.lineWidth != $( "#vertexStrokeSize" ).val())
|
if (fullStyle.lineWidth != $( "#vertexStrokeSize" ).val())
|
||||||
style.lineWidth = $( "#vertexStrokeSize" ).val();
|
style.lineWidth = parseInt($( "#vertexStrokeSize" ).val());
|
||||||
|
|
||||||
var canvas = document.getElementById( "VertexPreview" );
|
var canvas = document.getElementById( "VertexPreview" );
|
||||||
var context = canvas.getContext('2d');
|
var context = canvas.getContext('2d');
|
||||||
|
@ -96,6 +96,11 @@ Point.prototype.inverse = function()
|
|||||||
return new Point(-this.x, -this.y);
|
return new Point(-this.x, -this.y);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Point.prototype.cross = function(point)
|
||||||
|
{
|
||||||
|
return this.x * point.y - this.y * point.x;
|
||||||
|
};
|
||||||
|
|
||||||
Point.interpolate = function(pt1, pt2, f){
|
Point.interpolate = function(pt1, pt2, f){
|
||||||
return new Point(pt1.x * (1.0 - f) + pt2.x * f, pt1.y * (1.0 - f) + pt2.y * f);
|
return new Point(pt1.x * (1.0 - f) + pt2.x * f, pt1.y * (1.0 - f) + pt2.y * f);
|
||||||
};
|
};
|
||||||
@ -116,6 +121,63 @@ Point.toString = function(){
|
|||||||
return x + " " + y;
|
return x + " " + y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Point.projection = function (point, line1, line2)
|
||||||
|
{
|
||||||
|
var x = line2.y - line1.y;
|
||||||
|
var y = line1.x - line2.x;
|
||||||
|
var l = (line1.cross(line2) + line1.cross(point) + line2.cross(point))/(x*(line2.y - line1.y) + y*(line1.x - line2.x));
|
||||||
|
var res = new Point(point.x + x * l, point.y + y * l);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point.hitTest = function (pt11, pt12, pt21, pt22)
|
||||||
|
{
|
||||||
|
var res = null;
|
||||||
|
var n = 0.0;
|
||||||
|
|
||||||
|
var x1 = pt11.x;
|
||||||
|
var y1 = pt11.y;
|
||||||
|
var x2 = pt12.x;
|
||||||
|
var y2 = pt12.y;
|
||||||
|
var x3 = pt21.x;
|
||||||
|
var y3 = pt21.y;
|
||||||
|
var x4 = pt22.x;
|
||||||
|
var y4 = pt22.y;
|
||||||
|
|
||||||
|
if (y2 - y1 != 0.0)
|
||||||
|
{ // a(y)
|
||||||
|
var q = (x2 - x1) / (y1 - y2);
|
||||||
|
var sn = (x3 - x4) + (y3 - y4) * q;
|
||||||
|
if (sn == 0.0)
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
} // c(x) + c(y)*q
|
||||||
|
|
||||||
|
var fn = (x3 - x1) + (y3 - y1) * q; // b(x) + b(y)*q
|
||||||
|
n = fn / sn;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((y3 - y4) == 0.0)
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
} // b(y)
|
||||||
|
n = (y3 - y1) / (y3 - y4); // c(y)/b(y)
|
||||||
|
}
|
||||||
|
|
||||||
|
// x3 + (-b(x))*n && y3 +(-b(y))*n
|
||||||
|
res = new Point(x3 + (x4 - x3) * n, y3 + (y4 - y3) * n);
|
||||||
|
|
||||||
|
var epsilon = 1E-5;
|
||||||
|
if (! (res.x >= Math.min(x1, x2) - epsilon && res.x >= Math.min(x3, x4) - epsilon && res.x <= Math.max(x1, x2) + epsilon && res.x <= Math.max(x3, x4) + epsilon &&
|
||||||
|
res.y >= Math.min(y1, y2) - epsilon && res.y >= Math.min(y3, y4) - epsilon && res.y <= Math.max(y1, y2) + epsilon && res.y <= Math.max(y3, y4) + epsilon))
|
||||||
|
{
|
||||||
|
res = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
function Rect(minPoint, maxPoint){
|
function Rect(minPoint, maxPoint){
|
||||||
this.minPoint = minPoint;
|
this.minPoint = minPoint;
|
||||||
this.maxPoint = maxPoint;
|
this.maxPoint = maxPoint;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user