mirror of
https://github.com/lana-k/sqliteviz.git
synced 2025-12-06 18:18:53 +08:00
copy png to clipboard #50
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import dereference from 'react-chart-editor/lib/lib/dereference'
|
||||
import plotly from 'plotly.js'
|
||||
|
||||
export function getOptionsFromDataSources (dataSources) {
|
||||
if (!dataSources) {
|
||||
@@ -23,7 +24,17 @@ export function getOptionsForSave (state, dataSources) {
|
||||
return stateCopy
|
||||
}
|
||||
|
||||
export async function getImageDataUrl (element, type) {
|
||||
const chartElement = element.querySelector('.js-plotly-plot')
|
||||
return await plotly.toImage(chartElement, {
|
||||
format: type,
|
||||
width: null,
|
||||
height: null
|
||||
})
|
||||
}
|
||||
|
||||
export default {
|
||||
getOptionsFromDataSources,
|
||||
getOptionsForSave
|
||||
getOptionsForSave,
|
||||
getImageDataUrl
|
||||
}
|
||||
@@ -1,8 +1,30 @@
|
||||
import Lib from 'plotly.js/src/lib'
|
||||
import dataUrlToBlob from 'dataurl-to-blob'
|
||||
|
||||
async function _copyBlob(blob) {
|
||||
await navigator.clipboard.write([
|
||||
new ClipboardItem({
|
||||
[blob.type]: blob
|
||||
})
|
||||
])
|
||||
}
|
||||
|
||||
export default {
|
||||
async copyCsv (str) {
|
||||
await navigator.clipboard.writeText(str)
|
||||
Lib.notifier('CSV copied to clipboard successfully', 'long')
|
||||
},
|
||||
|
||||
async copyCanvas (canvas, type) {
|
||||
canvas.toBlob(async (blob) => {
|
||||
await _copyBlob(blob)
|
||||
Lib.notifier('Image copied to clipboard successfully', 'long')
|
||||
}, 'image/png', 1)
|
||||
},
|
||||
|
||||
async copyFromDataUrl (url) {
|
||||
const blob = dataUrlToBlob(url)
|
||||
await _copyBlob(blob)
|
||||
Lib.notifier('Image copied to clipboard successfully', 'long')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,9 +28,10 @@ import plotly from 'plotly.js'
|
||||
import 'react-chart-editor/lib/react-chart-editor.min.css'
|
||||
|
||||
import PlotlyEditor from 'react-chart-editor'
|
||||
import chartHelper from './chartHelper'
|
||||
import chartHelper from '@/lib/chartHelper'
|
||||
import dereference from 'react-chart-editor/lib/lib/dereference'
|
||||
import fIo from '@/lib/utils/fileIo'
|
||||
import cIo from '@/lib/utils/clipboardIo'
|
||||
|
||||
export default {
|
||||
name: 'Chart',
|
||||
@@ -89,10 +90,13 @@ export default {
|
||||
return chartHelper.getOptionsForSave(this.state, this.dataSources)
|
||||
},
|
||||
async saveAsPng () {
|
||||
const chartElement = this.$refs.plotlyEditor.$el.querySelector('.js-plotly-plot')
|
||||
const url = await plotly.toImage(chartElement, { format: 'png', width: null, height: null })
|
||||
const url = await chartHelper.getImageDataUrl(this.$refs.plotlyEditor.$el, 'png')
|
||||
this.$emit('loadingImageCompleted')
|
||||
fIo.downloadFromUrl(url, 'chart')
|
||||
},
|
||||
async copyPngToClipboard () {
|
||||
const url = await chartHelper.getImageDataUrl(this.$refs.plotlyEditor.$el, 'png')
|
||||
cIo.copyFromDataUrl(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
import $ from 'jquery'
|
||||
import Multiselect from 'vue-multiselect'
|
||||
import PivotSortBtn from './PivotSortBtn'
|
||||
import { renderers, aggregators, zeroValAggregators, twoValAggregators } from './pivotHelper'
|
||||
import { renderers, aggregators, zeroValAggregators, twoValAggregators } from '../pivotHelper'
|
||||
import Chart from '@/views/Main/Workspace/Tabs/Tab/DataView/Chart'
|
||||
import Vue from 'vue'
|
||||
const ChartClass = Vue.extend(Chart)
|
||||
|
||||
@@ -14,14 +14,15 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import html2canvas from 'html2canvas'
|
||||
import plotly from 'plotly.js'
|
||||
import fIo from '@/lib/utils/fileIo'
|
||||
import cIo from '@/lib/utils/clipboardIo'
|
||||
import $ from 'jquery'
|
||||
import 'pivottable'
|
||||
import 'pivottable/dist/pivot.css'
|
||||
import PivotUi from './PivotUi'
|
||||
import { getPivotCanvas } from './pivotHelper'
|
||||
import Chart from '@/views/Main/Workspace/Tabs/Tab/DataView/Chart'
|
||||
import chartHelper from '@/lib/chartHelper'
|
||||
import Vue from 'vue'
|
||||
const ChartClass = Vue.extend(Chart)
|
||||
|
||||
@@ -156,21 +157,27 @@ export default {
|
||||
if (this.pivotOptions.rendererName === 'Custom chart') {
|
||||
this.pivotOptions.rendererOptions.customChartComponent.saveAsPng()
|
||||
} else if (this.pivotOptions.rendererName in $.pivotUtilities.plotly_renderers) {
|
||||
const chartElement = this.$refs.pivotOutput.querySelector('.js-plotly-plot')
|
||||
const url = await plotly.toImage(chartElement, {
|
||||
format: 'png',
|
||||
width: null,
|
||||
height: null
|
||||
})
|
||||
const url = await chartHelper.getImageDataUrl(this.$refs.pivotOutput, 'png')
|
||||
this.$emit('loadingImageCompleted')
|
||||
fIo.downloadFromUrl(url, 'pivot')
|
||||
} else {
|
||||
const tableElement = this.$refs.pivotOutput.querySelector('.pvtTable')
|
||||
const canvas = await html2canvas(tableElement)
|
||||
const canvas = await getPivotCanvas(this.$refs.pivotOutput)
|
||||
this.$emit('loadingImageCompleted')
|
||||
fIo.downloadFromUrl(canvas.toDataURL('image/png'), 'pivot', 'image/png')
|
||||
}
|
||||
}
|
||||
},
|
||||
async copyPngToClipboard () {
|
||||
if (this.pivotOptions.rendererName === 'Custom chart') {
|
||||
this.pivotOptions.rendererOptions.customChartComponent.copyPngToClipboard()
|
||||
} else if (this.pivotOptions.rendererName in $.pivotUtilities.plotly_renderers) {
|
||||
const url = await chartHelper.getImageDataUrl(this.$refs.pivotOutput, 'png')
|
||||
cIo.copyFromDataUrl(url)
|
||||
} else {
|
||||
const canvas = await getPivotCanvas(this.$refs.pivotOutput)
|
||||
cIo.copyCanvas(canvas)
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -2,6 +2,7 @@ import $ from 'jquery'
|
||||
import 'pivottable'
|
||||
import 'pivottable/dist/export_renderers.js'
|
||||
import 'pivottable/dist/plotly_renderers.js'
|
||||
import html2canvas from 'html2canvas'
|
||||
|
||||
export const zeroValAggregators = [
|
||||
'Count',
|
||||
@@ -75,3 +76,8 @@ export const aggregators = Object.keys($.pivotUtilities.aggregators).map(key =>
|
||||
fun: $.pivotUtilities.aggregators[key]
|
||||
}
|
||||
})
|
||||
|
||||
export async function getPivotCanvas (pivotOutput) {
|
||||
const tableElement = pivotOutput.querySelector('.pvtTable')
|
||||
return await html2canvas(tableElement)
|
||||
}
|
||||
@@ -40,6 +40,14 @@
|
||||
>
|
||||
<png-icon />
|
||||
</icon-button>
|
||||
|
||||
<icon-button
|
||||
tooltip="Copy visualisation to clipboard"
|
||||
tooltip-position="top-left"
|
||||
@click="copyToClipboard"
|
||||
>
|
||||
<clipboard-icon/>
|
||||
</icon-button>
|
||||
</side-tool-bar>
|
||||
</div>
|
||||
</template>
|
||||
@@ -52,6 +60,7 @@ import IconButton from '@/components/IconButton'
|
||||
import ChartIcon from '@/components/svg/chart'
|
||||
import PivotIcon from '@/components/svg/pivot'
|
||||
import PngIcon from '@/components/svg/png'
|
||||
import ClipboardIcon from '@/components/svg/clipboard'
|
||||
|
||||
export default {
|
||||
name: 'DataView',
|
||||
@@ -63,7 +72,8 @@ export default {
|
||||
IconButton,
|
||||
ChartIcon,
|
||||
PivotIcon,
|
||||
PngIcon
|
||||
PngIcon,
|
||||
ClipboardIcon
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
@@ -95,6 +105,9 @@ export default {
|
||||
},
|
||||
getOptionsForSave () {
|
||||
return this.$refs.viewComponent.getOptionsForSave()
|
||||
},
|
||||
copyToClipboard () {
|
||||
this.$refs.viewComponent.copyPngToClipboard()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user