Skip to content

Commit

Permalink
Downloading working, fixes #24
Browse files Browse the repository at this point in the history
  • Loading branch information
keller-mark committed Feb 24, 2019
1 parent b141085 commit f7212fe
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 27 deletions.
36 changes: 32 additions & 4 deletions examples-src/App.vue
Expand Up @@ -10,11 +10,20 @@
<PlotContainer
:pWidth="500"
:pHeight="300"
:pMarginTop="10"
:pMarginTop="120"
:pMarginLeft="120"
:pMarginRight="10"
:pMarginRight="120"
:pMarginBottom="100"
ref="ScatterPlotContainer"
>
<Axis
slot="axisTop"
variable="vue_x"
side="top"
:tickRotation="0"
:getScale="getScale"
:getStack="getStack"
/>
<Axis
slot="axisLeft"
variable="vue_y"
Expand All @@ -35,6 +44,14 @@
:getScale="getScale"
:clickHandler="exampleClickHandler"
/>
<Axis
slot="axisRight"
variable="vue_y"
side="right"
:tickRotation="-35"
:getScale="getScale"
:getStack="getStack"
/>
<Axis
slot="axisBottom"
variable="vue_x"
Expand All @@ -45,6 +62,8 @@
/>
</PlotContainer>

<button @click="exampleDownload">Download Plot</button>

<h3>&lt;StackedBarPlot/&gt;</h3>
<PlotContainer
:pWidth="800"
Expand Down Expand Up @@ -850,10 +869,8 @@
:getStack="getStack"
/>
</PlotContainer>




<div class="stack-wrapper" v-show="showStack">
<h3>&lt;Stack/&gt;</h3>
<Stack :getStack="getStack" />
Expand Down Expand Up @@ -1299,6 +1316,17 @@ export default {
},
countBarPlotFilterFunction(val) {
return (val > 1);
},
exampleDownload() {
this.$refs.ScatterPlotContainer.download("test")
.then((uri) => {
const downloadAnchorNode = document.createElement('a');
downloadAnchorNode.setAttribute("href", uri);
downloadAnchorNode.setAttribute("download", "vueplotlib_download_demo.png");
document.body.appendChild(downloadAnchorNode); // required for firefox
downloadAnchorNode.click();
downloadAnchorNode.remove();
});
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "vue-declarative-plots",
"version": "1.2.32",
"version": "1.2.33",
"private": false,
"scripts": {
"serve": "vue-cli-service serve --open ./examples-src/index.js",
Expand Down
100 changes: 98 additions & 2 deletions src/components/PlotContainer.vue
@@ -1,4 +1,6 @@
<script>
import { getRetinaRatio } from './../helpers.js';
/**
* Function that takes in array of VNodes and adds props from a provided props object.
* @private
Expand All @@ -22,6 +24,27 @@ const addProp = function(slotArray, newProps) {
}
return [];
}
/**
* Given a canvas context, x and y offsets, and an image URI, render the image to the context.
* @private
* @param {Context} ctx The canvas context.
* @param {string} uri The image data URI.
* @param {int} x The x offset.
* @param {int} y The y offset.
*/
const renderToContext = function(ctx, uri, x, y, width, height) {
return new Promise((resolve, reject) => {
var img = new Image;
img.onload = () => {
ctx.drawImage(img, x, y, width, height);
resolve();
};
img.src = uri;
});
};
/**
* This component is a container for axis and plot components,
* which passes its props to its children and imposes styles.
Expand Down Expand Up @@ -109,10 +132,83 @@ export default {
);
let classes = ['vdp-plot-container'];
let styles = {
width: (this.pMarginLeft + this.pWidth + this.pMarginRight) + 'px',
height: (this.pMarginTop + this.pHeight + this.pMarginBottom) + 'px'
width: this.fullWidth + 'px',
height: this.fullHeight + 'px'
};
return h('div', { class: classes, style: styles }, children);
},
computed: {
fullWidth() {
return this.pMarginLeft + this.pWidth + this.pMarginRight;
},
fullHeight() {
return this.pMarginTop + this.pHeight + this.pMarginBottom;
}
},
methods: {
renderToContext(ctx, x, y, uri) {
var img = new Image;
img.onload = () => {
ctx.drawImage(img, x, y); // Or at whatever offset you like
};
img.src = uri;
},
download() {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const ratio = getRetinaRatio(ctx);
const scaledWidth = this.fullWidth * ratio;
const scaledHeight = this.fullHeight * ratio;
canvas.width = scaledWidth;
canvas.height = scaledHeight;
ctx.scale(ratio, ratio);
const renderAxisToContext = (axisType) => {
if(this.$slots[axisType].length > 0) {
return this.$slots[axisType][0].componentInstance.downloadAxis()
.then((uri) => {
console.log(uri);
const x = this.$slots[axisType][0].componentInstance.computedLeft;
const y = this.$slots[axisType][0].componentInstance.computedTop;
const width = this.$slots[axisType][0].componentInstance.computedWidth;
const height = this.$slots[axisType][0].componentInstance.computedHeight;
return renderToContext(ctx, uri, x, y, width, height);
});
}
return Promise.resolve();
};
const renderPlotToContext = () => {
if(this.$slots.plot.length > 0) {
return this.$slots.plot[0].componentInstance.downloadPlot()
.then((uri) => {
console.log(uri);
const x = this.pMarginLeft;
const y = this.pMarginTop;
const width = this.pWidth;
const height = this.pHeight;
return renderToContext(ctx, uri, x, y, width, height);
});
}
return Promise.resolve();
};
const renderPromises = [];
renderPromises.push(renderAxisToContext("axisTop"));
renderPromises.push(renderAxisToContext("axisLeft"));
renderPromises.push(renderPlotToContext());
renderPromises.push(renderAxisToContext("axisRight"));
renderPromises.push(renderAxisToContext("axisBottom"));
return new Promise((resolve, reject) => {
Promise.all(renderPromises).then(() => {
const uri = canvas.toDataURL("image/png");
resolve(uri);
});
});
}
}
}
</script>
Expand Down
24 changes: 16 additions & 8 deletions src/components/axes/Axis.vue
Expand Up @@ -17,7 +17,7 @@ import { axisTop as d3_axisTop, axisLeft as d3_axisLeft, axisRight as d3_axisRig
import { brushX as d3_brushX, brushY as d3_brushY } from 'd3-brush';
import { event as d3_event } from 'd3';
import { saveSvgAsPng } from 'save-svg-as-png';
import { svgAsPngUri } from 'save-svg-as-png';
import AbstractScale from './../../scales/AbstractScale.js';
import HistoryEvent from './../../history/HistoryEvent.js';
Expand Down Expand Up @@ -133,7 +133,7 @@ export default {
if(this._side === SIDES.BOTTOM || this._side === SIDES.TOP) {
return this.pMarginLeft + this.pWidth + this.pMarginRight;
} else if(this._side === SIDES.LEFT) {
return this.pMarginLeft;
return this.pMarginLeft + 1;
} else if(this._side === SIDES.RIGHT) {
return this.pMarginRight;
}
Expand All @@ -142,7 +142,7 @@ export default {
if(this._side === SIDES.LEFT || this._side === SIDES.RIGHT) {
return this.pMarginTop + this.pHeight + this.pMarginBottom;
} else if(this._side === SIDES.TOP) {
return this.pMarginTop;
return this.pMarginTop + 1;
} else if(this._side === SIDES.BOTTOM) {
return this.pMarginBottom;
}
Expand All @@ -161,7 +161,7 @@ export default {
},
computedTranslateX: function() {
if(this._side === SIDES.LEFT) {
return this.pMarginLeft - 1;
return this.pMarginLeft;
} else if(this._side === SIDES.BOTTOM || this._side === SIDES.TOP) {
return this.pMarginLeft;
}
Expand All @@ -173,9 +173,11 @@ export default {
} else if(this._side === SIDES.RIGHT) {
return this.pMarginTop;
} else if(this._side === SIDES.TOP) {
return this.pMarginTop - 1;
return this.pMarginTop;
} else if(this._side === SIDES.BOTTOM) {
return 0;
}
return 0;
}
},
watch: {
Expand Down Expand Up @@ -684,6 +686,7 @@ export default {
const labelText = containerLabel.append("text")
.style("text-anchor", "middle")
.style("font-family", "Avenir")
.text(varScale.name);
const labelTextBbox = labelText.node().getBBox();
Expand Down Expand Up @@ -722,8 +725,13 @@ export default {
},
downloadAxis() {
let node = d3_select(this.axisSelector).select("svg").node();
saveSvgAsPng(node, this.axisElemID + ".png");
const node = d3_select(this.axisSelector).select("svg").node();
return new Promise((resolve, reject) => {
svgAsPngUri(node, {}, (uri) => {
resolve(uri);
});
});
}
}
}
Expand Down
10 changes: 7 additions & 3 deletions src/components/axes/DendrogramAxis.vue
Expand Up @@ -14,7 +14,7 @@
import { select as d3_select } from 'd3-selection';
import { cluster as d3_cluster, hierarchy as d3_hierarchy } from 'd3-hierarchy';
import { saveSvgAsPng } from 'save-svg-as-png';
import { svgAsPngUri } from 'save-svg-as-png';
import AbstractScale from './../../scales/AbstractScale.js';
import DataContainer from './../../data/DataContainer.js';
Expand Down Expand Up @@ -338,8 +338,12 @@ export default {
},
downloadAxis() {
let node = d3_select(this.axisSelector).select("svg").node();
saveSvgAsPng(node, this.axisElemID + ".png");
const node = d3_select(this.axisSelector).select("svg").node();
return new Promise((resolve, reject) => {
svgAsPngUri(node, {}, (uri) => {
resolve(uri);
});
});
}
}
}
Expand Down
18 changes: 11 additions & 7 deletions src/components/axes/GenomeAxis.vue
Expand Up @@ -40,7 +40,7 @@ import { select as d3_select } from 'd3-selection';
import { axisTop as d3_axisTop, axisLeft as d3_axisLeft, axisRight as d3_axisRight, axisBottom as d3_axisBottom } from 'd3-axis';
import { zip as d3_zip } from 'd3-array';
import { saveSvgAsPng } from 'save-svg-as-png';
import { svgAsPngUri } from 'save-svg-as-png';
import GenomeScale from './../../scales/GenomeScale.js';
import HistoryEvent from './../../history/HistoryEvent.js';
Expand Down Expand Up @@ -132,7 +132,7 @@ export default {
if(this._side === SIDES.BOTTOM || this._side === SIDES.TOP) {
return this.pMarginLeft + this.pWidth + this.pMarginRight;
} else if(this._side === SIDES.LEFT) {
return this.pMarginLeft;
return this.pMarginLeft + 1;
} else if(this._side === SIDES.RIGHT) {
return this.pMarginRight;
}
Expand All @@ -141,7 +141,7 @@ export default {
if(this._side === SIDES.LEFT || this._side === SIDES.RIGHT) {
return this.pMarginTop + this.pHeight + this.pMarginBottom;
} else if(this._side === SIDES.TOP) {
return this.pMarginTop;
return this.pMarginTop + 1;
} else if(this._side === SIDES.BOTTOM) {
return this.pMarginBottom;
}
Expand All @@ -160,7 +160,7 @@ export default {
},
computedTranslateX: function() {
if(this._side === SIDES.LEFT) {
return this.pMarginLeft - 1;
return this.pMarginLeft;
} else if(this._side === SIDES.BOTTOM || this._side === SIDES.TOP) {
return this.pMarginLeft;
}
Expand All @@ -172,7 +172,7 @@ export default {
} else if(this._side === SIDES.RIGHT) {
return this.pMarginTop;
} else if(this._side === SIDES.TOP) {
return this.pMarginTop - 1;
return this.pMarginTop;
}
return 0;
},
Expand Down Expand Up @@ -504,8 +504,12 @@ export default {
},
downloadAxis() {
let node = d3_select(this.axisSelector).select("svg").node();
saveSvgAsPng(node, this.axisElemID + ".png");
const node = d3_select(this.axisSelector).select("svg").node();
return new Promise((resolve, reject) => {
svgAsPngUri(node, {}, (uri) => {
resolve(uri);
});
});
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/components/plots/mixin.js
Expand Up @@ -109,8 +109,10 @@ export default {
// stub
},
downloadPlot: function() {
let image = document.getElementById(this.plotElemID).toDataURL("image/png");
document.write('<img src="'+image+'"/>');
const uri = document.getElementById(this.plotElemID).toDataURL("image/png");
return new Promise((resolve, reject) => {
resolve(uri);
});
}
}
}

0 comments on commit f7212fe

Please sign in to comment.