You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

132 lines
5.0 KiB

/* Copyright 2018 Onestein
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
odoo.define('web_timeline.TimelineCanvas', function (require) {
"use strict";
var Widget = require('web.Widget');
/**
* Used to draw stuff on upon the timeline view.
*/
var TimelineCanvas = Widget.extend({
template: 'TimelineView.Canvas',
/**
* Clears all drawings (svg elements) from the canvas.
*/
clear: function () {
this.$el.find(' > :not(defs)').remove();
},
/**
* Gets the path from one point to another.
*
* @param {Number} coordx1
* @param {Number} coordy1
* @param {Number} coordx2
* @param {Number} coordy2
* @param {Number} width1
* @param {Number} height1
* @param {Number} width2
* @param {Number} height2
* @param {Number} widthMarker The marker's width of the polyline
* @param {Number} breakAt The space between the line turns
* @returns {Array} Each item represents a coordinate
*/
get_polyline_points: function (coordx1, coordy1, coordx2, coordy2,
width1, height1, width2, height2,
widthMarker, breakAt) {
var halfHeight1 = height1 / 2;
var halfHeight2 = height2 / 2;
var x1 = coordx1 - widthMarker;
var y1 = coordy1 + halfHeight1;
var x2 = coordx2 + width2;
var y2 = coordy2 + halfHeight2;
var xDiff = x1 - x2;
var yDiff = y1 - y2;
var threshold = breakAt + widthMarker;
var spaceY = halfHeight2 + 6;
var points = [[x1, y1]];
if (y1 !== y2) {
if (xDiff > threshold) {
points.push([x1 - breakAt, y1]);
points.push([x1 - breakAt, y1 - yDiff]);
} else if (xDiff <= threshold) {
var yDiffSpace = yDiff > 0 ? spaceY : -spaceY;
points.push([x1 - breakAt, y1]);
points.push([x1 - breakAt, y2 + yDiffSpace]);
points.push([x2 + breakAt, y2 + yDiffSpace]);
points.push([x2 + breakAt, y2]);
}
} else if(x1 < x2) {
points.push([x1 - breakAt, y1]);
points.push([x1 - breakAt, y1 + spaceY]);
points.push([x2 + breakAt, y2 + spaceY]);
points.push([x2 + breakAt, y2]);
}
points.push([x2, y2]);
return points;
},
/**
* Draws an arrow.
*
* @param {HTMLElement} from Element to draw the arrow from
* @param {HTMLElement} to Element to draw the arrow to
* @param {String} color Color of the line
* @param {Number} width Width of the line
* @returns {HTMLElement} The created SVG polyline
*/
draw_arrow: function (from, to, color, width) {
return this.draw_line(from, to, color, width, '#arrowhead', 10, 12);
},
/**
* Draws a line.
*
* @param {HTMLElement} from Element to draw the line from
* @param {HTMLElement} to Element to draw the line to
* @param {String} color Color of the line
* @param {Number} width Width of the line
* @param {String} markerStart Start marker of the line
* @param {Number} widthMarker The marker's width of the polyline
* @param {Number} breakLineAt The space between the line turns
* @returns {HTMLElement} The created SVG polyline
*/
draw_line: function (from, to, color, width, markerStart, widthMarker, breakLineAt) {
var x1 = from.offsetLeft,
y1 = from.offsetTop + from.parentElement.offsetTop,
x2 = to.offsetLeft,
y2 = to.offsetTop + to.parentElement.offsetTop,
width1 = from.clientWidth,
height1 = from.clientHeight,
width2 = to.clientWidth,
height2 = to.clientHeight;
var points = this.get_polyline_points(
x1, y1, x2, y2, width1, height1, width2, height2, widthMarker, breakLineAt
);
var polyline_points = _.map(points, function(point) {
return point.join(',');
}).join();
var line = document.createElementNS(
'http://www.w3.org/2000/svg', 'polyline'
);
line.setAttribute('points', polyline_points);
line.setAttribute('stroke', color || '#000');
line.setAttribute('stroke-width', width || 1);
line.setAttribute('fill', 'none');
if (markerStart) {
line.setAttribute('marker-start', 'url(' + markerStart + ')');
}
this.$el.append(line);
return line;
},
});
return TimelineCanvas;
});