diff --git a/dev/interact/svg-ellipse.html b/dev/interact/svg-ellipse.html
new file mode 100644
index 000000000..bca5b19b3
--- /dev/null
+++ b/dev/interact/svg-ellipse.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+ SVG demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/js/canvas2svg.js b/js/canvas2svg.js
index 259fa3756..8ea8099e7 100644
--- a/js/canvas2svg.js
+++ b/js/canvas2svg.js
@@ -82,7 +82,7 @@ function getDominantBaseline(textBaseline) {
function normalize(vector) {
var len = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1]);
return [vector[0] / len, vector[1] / len];
-};
+}
function intersectRect(rect1, rect2) {
@@ -910,7 +910,7 @@ class ctx {
x += width;
width = -width;
}
- // See if rect instersects current viewbox
+ // See if rect intersects current viewbox
var r2 = {
x: x,
y: y,
@@ -953,6 +953,32 @@ class ctx {
this.__applyStyleToCurrentElement("stroke");
};
+ // stroke ellipse
+ strokeEllipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW) {
+ this.__ellipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW, 'stroke')
+ }
+
+ // fill ellipse
+ fillEllipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW) {
+ this.__ellipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW, 'fill')
+ }
+
+ // ellipse helper
+ __ellipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW, style) {
+
+ const config =
+ {
+ cx,
+ cy,
+ rx,
+ ry
+ }
+ const element = this.__createElement('ellipse', config, true)
+ const parent = this.__closestGroupOrSvg()
+ parent.appendChild(element)
+ this.__currentElement = element
+ this.__applyStyleToCurrentElement(style)
+ }
/**
* Clear entire canvas:
diff --git a/js/feature/interactionTrack.js b/js/feature/interactionTrack.js
index 2e1c14105..0ed758be3 100644
--- a/js/feature/interactionTrack.js
+++ b/js/feature/interactionTrack.js
@@ -264,10 +264,10 @@ class InteractionTrack extends TrackBase {
const xScale = bpPerPixel;
// SVG output for proportional arcs are currently not supported because "ellipse" is not implemented
- if(typeof ctx.ellipse !== 'function') {
- Alert.presentAlert("SVG output of proportional arcs is currently not supported.")
- return;
- }
+ // if(typeof ctx.ellipse !== 'function') {
+ // Alert.presentAlert("SVG output of proportional arcs is currently not supported.")
+ // return;
+ // }
IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"});
@@ -310,9 +310,14 @@ class InteractionTrack extends TrackBase {
const color = feature.color || this.color;
ctx.strokeStyle = color;
ctx.lineWidth = feature.thickness || this.thickness || 1;
- ctx.beginPath();
- ctx.ellipse(xc, y, radiusX, radiusY, 0, 0, Math.PI, counterClockwise);
- ctx.stroke();
+
+ if (true === ctx.isSVG) {
+ ctx.strokeEllipse(xc, y, radiusX, radiusY, 0, 0, Math.PI, counterClockwise)
+ } else {
+ ctx.beginPath()
+ ctx.ellipse(xc, y, radiusX, radiusY, 0, 0, Math.PI, counterClockwise)
+ ctx.stroke()
+ }
if (this.showBlocks && feature.chr !== 'all') {
ctx.fillStyle = color;
@@ -326,9 +331,13 @@ class InteractionTrack extends TrackBase {
}
if (this.alpha) {
- const alphaColor = getAlphaColor(color, this.alpha);
- ctx.fillStyle = alphaColor;
- ctx.fill();
+ ctx.fillStyle = getAlphaColor(color, this.alpha)
+ if (true === ctx.isSVG) {
+ ctx.fillEllipse(xc, y, radiusX, radiusY, 0, 0, Math.PI, counterClockwise)
+ } else {
+ ctx.fill()
+ }
+
}
feature.drawState = {xc, yc: y, radiusX, radiusY};