mirror of
https://github.com/UnickSoft/graphonline.git
synced 2026-04-07 16:26:17 +00:00
Add dialog to select original graph or autosaved graph.
Refactor graph styles holding objects. Small style fixes.
This commit is contained in:
274
script/features/graph_preview/index.js
Normal file
274
script/features/graph_preview/index.js
Normal file
@@ -0,0 +1,274 @@
|
||||
/**
|
||||
* Preview element for graph
|
||||
*
|
||||
*/
|
||||
function GraphPreview(graph, style, canvas, positionUpdateCallback)
|
||||
{
|
||||
this.graph = graph;
|
||||
this.style = style;
|
||||
this.canvas = canvas;
|
||||
this.canvasScale = 1.0;
|
||||
this.canvasPosition = new Point(0, 0);
|
||||
this.prevMousePos = null;
|
||||
this.positionUpdateCallback = positionUpdateCallback;
|
||||
this.AutoAdjustViewport();
|
||||
|
||||
let canvasParent = canvas.parentNode;
|
||||
let zoomPlusArray = canvasParent.getElementsByClassName("zoom-plus");
|
||||
let preview = this;
|
||||
let one_scale = 1.2;
|
||||
let zoomFunc = function(real_scale)
|
||||
{
|
||||
let oldRealW = preview.getRealWidth();
|
||||
let oldRealH = preview.getRealHeight();
|
||||
preview.canvasScale = preview.canvasScale * real_scale;
|
||||
let realW = preview.getRealWidth();
|
||||
let realH = preview.getRealHeight();
|
||||
preview.canvasPosition = preview.canvasPosition.add(new Point((- oldRealW + realW) / 2, (- oldRealH + realH) / 2));
|
||||
preview.redraw();
|
||||
preview.callPositionUpdateCallback();
|
||||
};
|
||||
|
||||
if (zoomPlusArray.length > 0)
|
||||
{
|
||||
this.zoomPlusButton = zoomPlusArray[0];
|
||||
this.zoomPlusButton.onclick = function()
|
||||
{
|
||||
zoomFunc(one_scale);
|
||||
};
|
||||
}
|
||||
let zoomMinusArray = canvasParent.getElementsByClassName("zoom-minus");
|
||||
if (zoomMinusArray.length > 0)
|
||||
{
|
||||
this.zoomMinusButton = zoomMinusArray[0];
|
||||
this.zoomMinusButton.onclick = function()
|
||||
{
|
||||
zoomFunc(1.0 / one_scale);
|
||||
};
|
||||
}
|
||||
|
||||
this.canvas.onmousemove = function (e)
|
||||
{
|
||||
return preview.CanvasOnMouseMove(e);
|
||||
}
|
||||
|
||||
this.canvas.onmousedown = function (e)
|
||||
{
|
||||
return preview.CanvasOnMouseDown(e);
|
||||
}
|
||||
|
||||
this.canvas.onmouseup = function (e)
|
||||
{
|
||||
return preview.CanvasOnMouseUp(e);
|
||||
}
|
||||
|
||||
this.canvas.onwheel = function (e)
|
||||
{
|
||||
var e = window.event || e; // old IE support
|
||||
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
|
||||
if (delta > 0)
|
||||
{
|
||||
zoomFunc(one_scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
zoomFunc(1.0 / one_scale);
|
||||
}
|
||||
}
|
||||
|
||||
this.canvas.removeEventListener("touchstart", touchHandler, true);
|
||||
this.canvas.removeEventListener("touchmove", touchHandler, true);
|
||||
this.canvas.removeEventListener("touchend", touchHandler, true);
|
||||
this.canvas.removeEventListener("touchcancel", touchHandler, true);
|
||||
|
||||
this.canvas.addEventListener("touchstart", touchHandler, true);
|
||||
this.canvas.addEventListener("touchmove", touchHandler, true);
|
||||
this.canvas.addEventListener("touchend", touchHandler, true);
|
||||
this.canvas.addEventListener("touchcancel", touchHandler, true);
|
||||
|
||||
this.redraw();
|
||||
// Redraw one, because graph may have background.
|
||||
setTimeout(
|
||||
function()
|
||||
{
|
||||
this.redraw();
|
||||
}.bind(this),
|
||||
1000);
|
||||
}
|
||||
|
||||
GraphPreview.prototype.redraw = function()
|
||||
{
|
||||
const ctx = this.canvas.getContext("2d");
|
||||
|
||||
ctx.save();
|
||||
|
||||
ctx.scale(this.canvasScale, this.canvasScale);
|
||||
ctx.translate(this.canvasPosition.x, this.canvasPosition.y);
|
||||
|
||||
this.redrawGraph(ctx, this.canvasPosition);
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
GraphPreview.prototype.getRealWidth = function ()
|
||||
{
|
||||
return this.canvas.width / this.canvasScale;
|
||||
}
|
||||
|
||||
GraphPreview.prototype.getRealHeight = function ()
|
||||
{
|
||||
return this.canvas.height / this.canvasScale;
|
||||
}
|
||||
|
||||
GraphPreview.prototype.redrawGraph = function(context, backgroundPosition)
|
||||
{
|
||||
var backgroundDrawer = new BaseBackgroundDrawer(context);
|
||||
|
||||
backgroundDrawer.Draw(
|
||||
this.style.backgroundCommonStyle,
|
||||
Math.max(this.canvas.width, this.getRealWidth()),
|
||||
Math.max(this.canvas.height, this.getRealHeight()),
|
||||
backgroundPosition,
|
||||
this.canvasScale);
|
||||
|
||||
// Update edge styles
|
||||
for (i = 0; i < this.graph.edges.length; i ++)
|
||||
{
|
||||
let edge = this.graph.edges[i];
|
||||
var currentStyle = null;
|
||||
if (edge.hasOwnStyleFor(0))
|
||||
currentStyle = edge.getStyleFor(0);
|
||||
else
|
||||
currentStyle = this.style.edgeCommonStyle;
|
||||
|
||||
edge.currentStyle = currentStyle;
|
||||
}
|
||||
|
||||
// Upadte current vertexs styles
|
||||
for (i = 0; i < this.graph.vertices.length; i ++)
|
||||
{
|
||||
var currentStyle = null;
|
||||
let vetrex = this.graph.vertices[i];
|
||||
if (vetrex.hasOwnStyleFor(0))
|
||||
currentStyle = vetrex.getStyleFor(0);
|
||||
else
|
||||
currentStyle = this.style.vertexCommonStyle;
|
||||
|
||||
this.graph.vertices[i].currentStyle = currentStyle;
|
||||
}
|
||||
|
||||
for (i = 0; i < this.graph.edges.length; i ++)
|
||||
{
|
||||
let edge = this.graph.edges[i];
|
||||
var arcDrawer = this.GetBaseArcDrawer(context, edge);
|
||||
arcDrawer.Draw(edge, edge.currentStyle.GetStyle({}, edge));
|
||||
}
|
||||
|
||||
var graphDrawer = new BaseVertexDrawer(context);
|
||||
for (i = 0; i < this.graph.vertices.length; i ++)
|
||||
{
|
||||
let vertex = this.graph.vertices[i];
|
||||
graphDrawer.Draw(this.graph.vertices[i], vertex.currentStyle.GetStyle({}, vertex));
|
||||
}
|
||||
}
|
||||
|
||||
GraphPreview.prototype.GetBaseArcDrawer = function(context, edge)
|
||||
{
|
||||
var arcDrawer = new BaseEdgeDrawer(context);
|
||||
|
||||
if (edge.model.type == EdgeModels.curve)
|
||||
{
|
||||
var curvedArcDrawer = new CurvedArcDrawer(context, edge.model);
|
||||
|
||||
arcDrawer = new BaseEdgeDrawer(context,
|
||||
{
|
||||
drawArc : curvedArcDrawer,
|
||||
startArrowDirection : curvedArcDrawer,
|
||||
finishArrowDirection : curvedArcDrawer,
|
||||
textCenterObject : curvedArcDrawer,
|
||||
getPointOnArc : curvedArcDrawer
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return arcDrawer;
|
||||
}
|
||||
|
||||
GraphPreview.prototype.AutoAdjustViewport = function()
|
||||
{
|
||||
graphBBox = this.graph.getGraphBBox();
|
||||
bboxCenter = graphBBox.center();
|
||||
bboxSize = graphBBox.size();
|
||||
|
||||
if (bboxSize.length() > 0)
|
||||
{
|
||||
// Setup size
|
||||
if (bboxSize.x > this.getRealWidth() || bboxSize.y > this.getRealHeight())
|
||||
{
|
||||
this.canvasScale = Math.min(this.getRealWidth() / bboxSize.x, this.getRealHeight() / bboxSize.y);
|
||||
}
|
||||
|
||||
// Setup position.
|
||||
if (graphBBox.minPoint.x < 0.0 || graphBBox.minPoint.y < 0.0 ||
|
||||
graphBBox.maxPoint.x > this.getRealWidth() || graphBBox.maxPoint.y > this.getRealHeight())
|
||||
{
|
||||
// Move center.
|
||||
this.canvasPosition = graphBBox.minPoint.inverse();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GraphPreview.prototype.CanvasOnMouseMove = function(e)
|
||||
{
|
||||
if (this.prevMousePos == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// X,Y position.
|
||||
var pos = this.getMousePos(this.canvas, e);
|
||||
|
||||
let newPos = (new Point(pos.x, pos.y)).subtract(this.prevMousePos).multiply(this.canvasScale);
|
||||
this.canvasPosition = this.canvasPosition.add(newPos.multiply(1 / this.canvasScale));
|
||||
|
||||
this.redraw();
|
||||
this.callPositionUpdateCallback();
|
||||
}
|
||||
|
||||
GraphPreview.prototype.CanvasOnMouseDown = function(e)
|
||||
{
|
||||
// Skip non left button.
|
||||
if(e.which !== 1) return;
|
||||
|
||||
var pos = this.getMousePos(this.canvas, e); /// provide this canvas and event
|
||||
|
||||
this.prevMousePos = pos;
|
||||
}
|
||||
|
||||
GraphPreview.prototype.CanvasOnMouseUp = function(e)
|
||||
{
|
||||
// Skip non left button.
|
||||
if(e.which !== 1) return;
|
||||
|
||||
this.prevMousePos = null;
|
||||
}
|
||||
|
||||
GraphPreview.prototype.getMousePos = function(canvas, e)
|
||||
{
|
||||
/// getBoundingClientRect is supported in most browsers and gives you
|
||||
/// the absolute geometry of an element
|
||||
var rect = canvas.getBoundingClientRect();
|
||||
|
||||
/// as mouse event coords are relative to document you need to
|
||||
/// subtract the element's left and top position:
|
||||
return new Point((e.clientX - rect.left) / this.canvasScale - this.canvasPosition.x,
|
||||
(e.clientY - rect.top) / this.canvasScale - this.canvasPosition.y);
|
||||
}
|
||||
|
||||
GraphPreview.prototype.callPositionUpdateCallback = function()
|
||||
{
|
||||
if (this.positionUpdateCallback != null)
|
||||
{
|
||||
this.positionUpdateCallback(this.canvasPosition, this.canvasScale);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user