Skip to content

Commit

Permalink
git issue 1395. Implement svg ellipse rendering. (#1405)
Browse files Browse the repository at this point in the history
  • Loading branch information
turner authored Oct 19, 2021
1 parent b7a6285 commit c8fd9fc
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 12 deletions.
76 changes: 76 additions & 0 deletions dev/interact/svg-ellipse.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">

<title>SVG demo</title>


</head>

<body>

<div id="igv-centering-container">
<div id='igv-app-container'></div>
</div>

<div id='igv-draw-svg-button-container'>
<button id='igv-draw-svg-button' type="button">
<label>Draw SVG</label>
</button>
</div>

<div id="igv-svg-container">
</div>

</body>

<script type="module">

import $ from '../../js/vendor/jquery-3.3.1.slim.js'
import igv from '../../js'

(async () => {

const config =
{
genome: "hg38",
locus: "chr2:65,489,209-65,795,733",
tracks:
[
{
url: "https://s3.amazonaws.com/igv.org.demo/GSM1872886_GM12878_CTCF_PET.bedpe.txt",
type: "interact",
format: "bedpe",
name: "CTCF PET - proportional",
arcType: "proportional",
color: "rgb(0,200,0)",
logScale: true,
showBlocks: true,
max: 80,
visibilityWindow: 10000000
},
{
url: "https://s3.amazonaws.com/igv.org.demo/GSM1872886_GM12878_CTCF_PET.bedpe.txt",
type: "interact",
format: "bedpe",
name: "CTCF PET - nested",
arcType: "nested",
arcOrientation: false,
color: "blue",
showBlocks: true,
alpha: 0.15,
visibilityWindow: 10000000
}
]
};

const browser = await igv.createBrowser(document.getElementById('igv-app-container'), config)

$('#igv-draw-svg-button').on('click', () => browser.saveSVGtoFile({ $container: $('#igv-svg-container') }))


})()

</script>
</html>
30 changes: 28 additions & 2 deletions js/canvas2svg.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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:
Expand Down
29 changes: 19 additions & 10 deletions js/feature/interactionTrack.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)"});

Expand Down Expand Up @@ -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;
Expand All @@ -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};
Expand Down

0 comments on commit c8fd9fc

Please sign in to comment.