mirror of
https://github.com/lana-k/sqliteviz.git
synced 2025-12-07 18:48:55 +08:00
Compare commits
7 Commits
0.17.0
...
310a939109
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
310a939109 | ||
|
|
bb9ba08902 | ||
|
|
c7c727ff78 | ||
|
|
8669a6a9e5 | ||
|
|
c1cc5bb95e | ||
|
|
9c55e76a41 | ||
|
|
70a9edf57e |
684
package-lock.json
generated
684
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sqliteviz",
|
"name": "sqliteviz",
|
||||||
"version": "0.17.0",
|
"version": "0.18.0",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
49
src/components/svg/html.vue
Normal file
49
src/components/svg/html.vue
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<svg
|
||||||
|
width="19"
|
||||||
|
height="18"
|
||||||
|
viewBox="0 0 19 18"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M5.1626 10.0745L7.56641 10.8831V12.2322L3.68164 10.6501V9.4812L7.56641
|
||||||
|
7.89917V9.2439L5.1626 10.0745ZM8.99023 13.3H7.93994L10.124 6.35229H11.1787L8.99023
|
||||||
|
13.3ZM14.1099 10.0613L11.7192 9.24829V7.90356L15.582 9.4856V10.6545L11.7192
|
||||||
|
12.2366V10.8918L14.1099 10.0613Z"
|
||||||
|
fill="#A2B1C6"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M2.17041 0.0637207H16.2185V1.56372H2.17041V9.30354H0.67041V1.56372C0.67041 0.73872
|
||||||
|
1.34541 0.0637207 2.17041 0.0637207Z"
|
||||||
|
fill="#A2B1C6"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M17.1704 0.0637207H15.3052V1.56372H17.1704V9.84163H18.6704V1.56372C18.6704 0.73872
|
||||||
|
17.9954 0.0637207 17.1704 0.0637207Z"
|
||||||
|
fill="#A2B1C6"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M2.17041 17.1098H15.8754V15.6098H2.17041V8.78486H0.67041V15.6098C0.67041 16.4348
|
||||||
|
1.34541 17.1098 2.17041 17.1098Z"
|
||||||
|
fill="#A2B1C6"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M17.1704 17.1098H15.3052V15.6098H17.1704V8.55939H18.6704V15.6098C18.6704 16.4348
|
||||||
|
17.9954 17.1098 17.1704 17.1098Z"
|
||||||
|
fill="#A2B1C6"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M18.1197 4.13787H1.76172V3.03787H18.1197V4.13787Z"
|
||||||
|
fill="#A2B1C6"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'HtmlIcon'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import dereference from 'react-chart-editor/lib/lib/dereference'
|
import dereference from 'react-chart-editor/lib/lib/dereference'
|
||||||
import plotly from 'plotly.js'
|
import plotly from 'plotly.js'
|
||||||
|
import { nanoid } from 'nanoid'
|
||||||
|
|
||||||
export function getOptionsFromDataSources (dataSources) {
|
export function getOptionsFromDataSources (dataSources) {
|
||||||
if (!dataSources) {
|
if (!dataSources) {
|
||||||
@@ -33,8 +34,43 @@ export async function getImageDataUrl (element, type) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getChartData (element) {
|
||||||
|
const chartElement = element.querySelector('.js-plotly-plot')
|
||||||
|
return {
|
||||||
|
data: chartElement.data,
|
||||||
|
layout: chartElement.layout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getHtml (options) {
|
||||||
|
const chartId = nanoid()
|
||||||
|
return `
|
||||||
|
<script src="https://cdn.plot.ly/plotly-latest.js" charset="UTF-8"></script>
|
||||||
|
<div id="${chartId}"></div>
|
||||||
|
<script>
|
||||||
|
const el = document.getElementById("${chartId}")
|
||||||
|
|
||||||
|
let timeout
|
||||||
|
function debounceResize() {
|
||||||
|
clearTimeout(timeout)
|
||||||
|
timeout = setTimeout(() => {
|
||||||
|
var r = el.getBoundingClientRect()
|
||||||
|
Plotly.relayout(el, {width: r.width, height: r.height})
|
||||||
|
}, 200)
|
||||||
|
}
|
||||||
|
|
||||||
|
const resizeObserver = new ResizeObserver(debounceResize)
|
||||||
|
resizeObserver.observe(el)
|
||||||
|
|
||||||
|
Plotly.newPlot(el, ${JSON.stringify(options.data)}, ${JSON.stringify(options.layout)})
|
||||||
|
</script>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getOptionsFromDataSources,
|
getOptionsFromDataSources,
|
||||||
getOptionsForSave,
|
getOptionsForSave,
|
||||||
getImageDataUrl
|
getImageDataUrl,
|
||||||
|
getHtml,
|
||||||
|
getChartData
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export default {
|
|||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
// https://github.com/plotly/plotly.js/issues/4555
|
// https://github.com/plotly/plotly.js/issues/4555
|
||||||
plotly.setPlotConfig ({
|
plotly.setPlotConfig({
|
||||||
notifyOnLogging: 1
|
notifyOnLogging: 1
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -105,6 +105,13 @@ export default {
|
|||||||
fIo.downloadFromUrl(url, 'chart')
|
fIo.downloadFromUrl(url, 'chart')
|
||||||
},
|
},
|
||||||
|
|
||||||
|
saveAsHtml () {
|
||||||
|
fIo.exportToFile(
|
||||||
|
chartHelper.getHtml(this.state),
|
||||||
|
'chart.html',
|
||||||
|
'text/html'
|
||||||
|
)
|
||||||
|
},
|
||||||
async prepareCopy (type = 'png') {
|
async prepareCopy (type = 'png') {
|
||||||
return await chartHelper.getImageDataUrl(this.$refs.plotlyEditor.$el, type)
|
return await chartHelper.getImageDataUrl(this.$refs.plotlyEditor.$el, type)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import $ from 'jquery'
|
|||||||
import 'pivottable'
|
import 'pivottable'
|
||||||
import 'pivottable/dist/pivot.css'
|
import 'pivottable/dist/pivot.css'
|
||||||
import PivotUi from './PivotUi'
|
import PivotUi from './PivotUi'
|
||||||
import { getPivotCanvas } from './pivotHelper'
|
import pivotHelper from './pivotHelper'
|
||||||
import Chart from '@/views/Main/Workspace/Tabs/Tab/DataView/Chart'
|
import Chart from '@/views/Main/Workspace/Tabs/Tab/DataView/Chart'
|
||||||
import chartHelper from '@/lib/chartHelper'
|
import chartHelper from '@/lib/chartHelper'
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
@@ -169,7 +169,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
const source = this.viewStandartChart
|
const source = this.viewStandartChart
|
||||||
? await chartHelper.getImageDataUrl(this.$refs.pivotOutput, 'png')
|
? await chartHelper.getImageDataUrl(this.$refs.pivotOutput, 'png')
|
||||||
: (await getPivotCanvas(this.$refs.pivotOutput)).toDataURL('image/png')
|
: (await pivotHelper.getPivotCanvas(this.$refs.pivotOutput)).toDataURL('image/png')
|
||||||
|
|
||||||
this.$emit('loadingImageCompleted')
|
this.$emit('loadingImageCompleted')
|
||||||
fIo.downloadFromUrl(source, 'pivot')
|
fIo.downloadFromUrl(source, 'pivot')
|
||||||
@@ -182,7 +182,7 @@ export default {
|
|||||||
} else if (this.viewStandartChart) {
|
} else if (this.viewStandartChart) {
|
||||||
return await chartHelper.getImageDataUrl(this.$refs.pivotOutput, 'png')
|
return await chartHelper.getImageDataUrl(this.$refs.pivotOutput, 'png')
|
||||||
} else {
|
} else {
|
||||||
return await getPivotCanvas(this.$refs.pivotOutput)
|
return await pivotHelper.getPivotCanvas(this.$refs.pivotOutput)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -193,6 +193,25 @@ export default {
|
|||||||
const url = await chartHelper.getImageDataUrl(this.$refs.pivotOutput, 'svg')
|
const url = await chartHelper.getImageDataUrl(this.$refs.pivotOutput, 'svg')
|
||||||
fIo.downloadFromUrl(url, 'pivot')
|
fIo.downloadFromUrl(url, 'pivot')
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
saveAsHtml () {
|
||||||
|
if (this.viewCustomChart) {
|
||||||
|
this.pivotOptions.rendererOptions.customChartComponent.saveAsHtml()
|
||||||
|
} else if (this.viewStandartChart) {
|
||||||
|
const chartState = chartHelper.getChartData(this.$refs.pivotOutput)
|
||||||
|
fIo.exportToFile(
|
||||||
|
chartHelper.getHtml(chartState),
|
||||||
|
'chart.html',
|
||||||
|
'text/html'
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
fIo.exportToFile(
|
||||||
|
pivotHelper.getPivotHtml(this.$refs.pivotOutput),
|
||||||
|
'pivot.html',
|
||||||
|
'text/html'
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,3 +81,40 @@ export async function getPivotCanvas (pivotOutput) {
|
|||||||
const tableElement = pivotOutput.querySelector('.pvtTable')
|
const tableElement = pivotOutput.querySelector('.pvtTable')
|
||||||
return await html2canvas(tableElement, { logging: false })
|
return await html2canvas(tableElement, { logging: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getPivotHtml (pivotOutput) {
|
||||||
|
return `
|
||||||
|
<style>
|
||||||
|
table.pvtTable {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: left;
|
||||||
|
border-collapse: collapse;
|
||||||
|
min-width: 100%;
|
||||||
|
}
|
||||||
|
table.pvtTable .pvtColLabel {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
table.pvtTable .pvtTotalLabel {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
table.pvtTable tbody tr td {
|
||||||
|
color: #506784;
|
||||||
|
border: 1px solid #DFE8F3;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
table.pvtTable thead tr th,
|
||||||
|
table.pvtTable tbody tr th {
|
||||||
|
background-color: #506784;
|
||||||
|
color: #fff;
|
||||||
|
border: 1px solid #DFE8F3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
${pivotOutput.outerHTML}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
getPivotCanvas,
|
||||||
|
getPivotHtml
|
||||||
|
}
|
||||||
|
|||||||
@@ -51,6 +51,13 @@
|
|||||||
<export-to-svg-icon />
|
<export-to-svg-icon />
|
||||||
</icon-button>
|
</icon-button>
|
||||||
|
|
||||||
|
<icon-button
|
||||||
|
tooltip="Save as HTML"
|
||||||
|
tooltip-position="top-left"
|
||||||
|
@click="saveAsHtml"
|
||||||
|
>
|
||||||
|
<HtmlIcon />
|
||||||
|
</icon-button>
|
||||||
<icon-button
|
<icon-button
|
||||||
:loading="copyingImage"
|
:loading="copyingImage"
|
||||||
tooltip="Copy visualisation to clipboard"
|
tooltip="Copy visualisation to clipboard"
|
||||||
@@ -81,6 +88,7 @@ import SideToolBar from '../SideToolBar'
|
|||||||
import IconButton from '@/components/IconButton'
|
import IconButton from '@/components/IconButton'
|
||||||
import ChartIcon from '@/components/svg/chart'
|
import ChartIcon from '@/components/svg/chart'
|
||||||
import PivotIcon from '@/components/svg/pivot'
|
import PivotIcon from '@/components/svg/pivot'
|
||||||
|
import HtmlIcon from '@/components/svg/html'
|
||||||
import ExportToSvgIcon from '@/components/svg/exportToSvg'
|
import ExportToSvgIcon from '@/components/svg/exportToSvg'
|
||||||
import PngIcon from '@/components/svg/png'
|
import PngIcon from '@/components/svg/png'
|
||||||
import ClipboardIcon from '@/components/svg/clipboard'
|
import ClipboardIcon from '@/components/svg/clipboard'
|
||||||
@@ -100,6 +108,7 @@ export default {
|
|||||||
PivotIcon,
|
PivotIcon,
|
||||||
ExportToSvgIcon,
|
ExportToSvgIcon,
|
||||||
PngIcon,
|
PngIcon,
|
||||||
|
HtmlIcon,
|
||||||
ClipboardIcon,
|
ClipboardIcon,
|
||||||
loadingDialog
|
loadingDialog
|
||||||
},
|
},
|
||||||
@@ -177,6 +186,9 @@ export default {
|
|||||||
|
|
||||||
saveAsSvg () {
|
saveAsSvg () {
|
||||||
this.$refs.viewComponent.saveAsSvg()
|
this.$refs.viewComponent.saveAsSvg()
|
||||||
|
},
|
||||||
|
saveAsHtml () {
|
||||||
|
this.$refs.viewComponent.saveAsHtml()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,40 @@ describe('chartHelper.js', () => {
|
|||||||
expect(/^data:image\/png/.test(url)).to.equal(true)
|
expect(/^data:image\/png/.test(url)).to.equal(true)
|
||||||
|
|
||||||
url = await chartHelper.getImageDataUrl(element, 'svg')
|
url = await chartHelper.getImageDataUrl(element, 'svg')
|
||||||
console.log()
|
|
||||||
expect(/^data:image\/svg\+xml/.test(url)).to.equal(true)
|
expect(/^data:image\/svg\+xml/.test(url)).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('getChartData returns plotly data and layout from element', async () => {
|
||||||
|
const element = document.createElement('div')
|
||||||
|
const child = document.createElement('div')
|
||||||
|
element.append(child)
|
||||||
|
child.classList.add('js-plotly-plot')
|
||||||
|
child.data = 'plotly data'
|
||||||
|
child.layout = 'plotly layout'
|
||||||
|
|
||||||
|
const chartData = chartHelper.getChartData(element)
|
||||||
|
expect(chartData).to.eql({
|
||||||
|
data: 'plotly data',
|
||||||
|
layout: 'plotly layout'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('getHtml returns valid html', async () => {
|
||||||
|
const options = {
|
||||||
|
data: 'plotly data',
|
||||||
|
layout: 'plotly layout'
|
||||||
|
}
|
||||||
|
|
||||||
|
const html = chartHelper.getHtml(options)
|
||||||
|
const doc = document.createElement('div')
|
||||||
|
doc.innerHTML = html
|
||||||
|
|
||||||
|
expect(doc.innerHTML).to.equal(html)
|
||||||
|
expect(doc.children).to.have.lengthOf(3)
|
||||||
|
expect(doc.children[0].src).to.includes('plotly-latest.js')
|
||||||
|
expect(doc.children[1].id).to.have.lengthOf(21)
|
||||||
|
expect(doc.children[2].innerHTML).to.includes(doc.children[1].id)
|
||||||
|
expect(doc.children[2].innerHTML)
|
||||||
|
.to.includes('Plotly.newPlot(el, "plotly data", "plotly layout"')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -59,6 +59,31 @@ describe('DataView.vue', () => {
|
|||||||
expect(pivot.saveAsSvg.calledOnce).to.equal(true)
|
expect(pivot.saveAsSvg.calledOnce).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('method saveAsHtml calls the same method of the current view component', async () => {
|
||||||
|
const wrapper = mount(DataView)
|
||||||
|
|
||||||
|
// Find chart and spy the method
|
||||||
|
const chart = wrapper.findComponent({ name: 'Chart' }).vm
|
||||||
|
sinon.spy(chart, 'saveAsHtml')
|
||||||
|
|
||||||
|
// Export to html
|
||||||
|
const htmlBtn = createWrapper(wrapper.findComponent({ name: 'htmlIcon' }).vm.$parent)
|
||||||
|
await htmlBtn.trigger('click')
|
||||||
|
expect(chart.saveAsHtml.calledOnce).to.equal(true)
|
||||||
|
|
||||||
|
// Switch to pivot
|
||||||
|
const pivotBtn = createWrapper(wrapper.findComponent({ name: 'pivotIcon' }).vm.$parent)
|
||||||
|
await pivotBtn.trigger('click')
|
||||||
|
|
||||||
|
// Find pivot and spy the method
|
||||||
|
const pivot = wrapper.findComponent({ name: 'pivot' }).vm
|
||||||
|
sinon.spy(pivot, 'saveAsHtml')
|
||||||
|
|
||||||
|
// Export to svg
|
||||||
|
await htmlBtn.trigger('click')
|
||||||
|
expect(pivot.saveAsHtml.calledOnce).to.equal(true)
|
||||||
|
})
|
||||||
|
|
||||||
it('shows alert when ClipboardItem is not supported', async () => {
|
it('shows alert when ClipboardItem is not supported', async () => {
|
||||||
const ClipboardItem = window.ClipboardItem
|
const ClipboardItem = window.ClipboardItem
|
||||||
delete window.ClipboardItem
|
delete window.ClipboardItem
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import chartHelper from '@/lib/chartHelper'
|
|||||||
import fIo from '@/lib/utils/fileIo'
|
import fIo from '@/lib/utils/fileIo'
|
||||||
import $ from 'jquery'
|
import $ from 'jquery'
|
||||||
import sinon from 'sinon'
|
import sinon from 'sinon'
|
||||||
|
import pivotHelper from '@/views/Main/Workspace/Tabs/Tab/DataView/Pivot/pivotHelper'
|
||||||
|
|
||||||
describe('Pivot.vue', () => {
|
describe('Pivot.vue', () => {
|
||||||
let container
|
let container
|
||||||
@@ -271,6 +272,41 @@ describe('Pivot.vue', () => {
|
|||||||
expect(chartComponent.saveAsSvg.called).to.equal(true)
|
expect(chartComponent.saveAsSvg.called).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('saveAsHtml calls chart method if renderer is Custom Chart', async () => {
|
||||||
|
const wrapper = mount(Pivot, {
|
||||||
|
propsData: {
|
||||||
|
dataSources: {
|
||||||
|
item: ['foo', 'bar', 'bar', 'bar'],
|
||||||
|
year: [2021, 2021, 2020, 2020]
|
||||||
|
},
|
||||||
|
initOptions: {
|
||||||
|
rows: ['item'],
|
||||||
|
cols: ['year'],
|
||||||
|
colOrder: 'key_a_to_z',
|
||||||
|
rowOrder: 'key_a_to_z',
|
||||||
|
aggregatorName: 'Count',
|
||||||
|
vals: [],
|
||||||
|
renderer: $.pivotUtilities.renderers['Custom chart'],
|
||||||
|
rendererName: 'Custom chart',
|
||||||
|
rendererOptions: {
|
||||||
|
customChartOptions: {
|
||||||
|
data: [],
|
||||||
|
layout: {},
|
||||||
|
frames: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
attachTo: container
|
||||||
|
})
|
||||||
|
|
||||||
|
const chartComponent = wrapper.vm.pivotOptions.rendererOptions.customChartComponent
|
||||||
|
sinon.stub(chartComponent, 'saveAsHtml')
|
||||||
|
|
||||||
|
await wrapper.vm.saveAsHtml()
|
||||||
|
expect(chartComponent.saveAsHtml.called).to.equal(true)
|
||||||
|
})
|
||||||
|
|
||||||
it('saveAsPng calls chart method if renderer is Custom Chart', async () => {
|
it('saveAsPng calls chart method if renderer is Custom Chart', async () => {
|
||||||
const wrapper = mount(Pivot, {
|
const wrapper = mount(Pivot, {
|
||||||
propsData: {
|
propsData: {
|
||||||
@@ -333,6 +369,66 @@ describe('Pivot.vue', () => {
|
|||||||
expect(chartHelper.getImageDataUrl.calledOnce).to.equal(true)
|
expect(chartHelper.getImageDataUrl.calledOnce).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('saveAsHtml - standart chart', async () => {
|
||||||
|
sinon.spy(chartHelper, 'getChartData')
|
||||||
|
sinon.spy(chartHelper, 'getHtml')
|
||||||
|
|
||||||
|
const wrapper = mount(Pivot, {
|
||||||
|
propsData: {
|
||||||
|
dataSources: {
|
||||||
|
item: ['foo', 'bar', 'bar', 'bar'],
|
||||||
|
year: [2021, 2021, 2020, 2020]
|
||||||
|
},
|
||||||
|
initOptions: {
|
||||||
|
rows: ['item'],
|
||||||
|
cols: ['year'],
|
||||||
|
colOrder: 'key_a_to_z',
|
||||||
|
rowOrder: 'key_a_to_z',
|
||||||
|
aggregatorName: 'Count',
|
||||||
|
vals: [],
|
||||||
|
renderer: $.pivotUtilities.renderers['Bar Chart'],
|
||||||
|
rendererName: 'Bar Chart'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
attachTo: container
|
||||||
|
})
|
||||||
|
|
||||||
|
await wrapper.vm.saveAsHtml()
|
||||||
|
expect(chartHelper.getChartData.calledOnce).to.equal(true)
|
||||||
|
const chartData = await chartHelper.getChartData.returnValues[0]
|
||||||
|
expect(chartHelper.getHtml.calledOnceWith(chartData)).to.equal(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('saveAsHtml - table', async () => {
|
||||||
|
sinon.stub(pivotHelper, 'getPivotHtml')
|
||||||
|
sinon.stub(fIo, 'exportToFile')
|
||||||
|
|
||||||
|
const wrapper = mount(Pivot, {
|
||||||
|
propsData: {
|
||||||
|
dataSources: {
|
||||||
|
item: ['foo', 'bar', 'bar', 'bar'],
|
||||||
|
year: [2021, 2021, 2020, 2020]
|
||||||
|
},
|
||||||
|
initOptions: {
|
||||||
|
rows: ['item'],
|
||||||
|
cols: ['year'],
|
||||||
|
colOrder: 'key_a_to_z',
|
||||||
|
rowOrder: 'key_a_to_z',
|
||||||
|
aggregatorName: 'Count',
|
||||||
|
vals: [],
|
||||||
|
renderer: $.pivotUtilities.renderers.Table,
|
||||||
|
rendererName: 'Table'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
attachTo: container
|
||||||
|
})
|
||||||
|
|
||||||
|
await wrapper.vm.saveAsHtml()
|
||||||
|
expect(pivotHelper.getPivotHtml.calledOnce).to.equal(true)
|
||||||
|
const html = pivotHelper.getPivotHtml.returnValues[0]
|
||||||
|
expect(fIo.exportToFile.calledOnceWith(html, 'pivot.html', 'text/html')).to.equal(true)
|
||||||
|
})
|
||||||
|
|
||||||
it('saveAsPng - standart chart', async () => {
|
it('saveAsPng - standart chart', async () => {
|
||||||
sinon.stub(chartHelper, 'getImageDataUrl').returns('standat chart data url')
|
sinon.stub(chartHelper, 'getImageDataUrl').returns('standat chart data url')
|
||||||
sinon.stub(fIo, 'downloadFromUrl')
|
sinon.stub(fIo, 'downloadFromUrl')
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { expect } from 'chai'
|
import { expect } from 'chai'
|
||||||
import { _getDataSources, getPivotCanvas }
|
import { _getDataSources, getPivotCanvas, getPivotHtml }
|
||||||
from '@/views/Main/Workspace/Tabs/Tab/DataView/Pivot/pivotHelper'
|
from '@/views/Main/Workspace/Tabs/Tab/DataView/Pivot/pivotHelper'
|
||||||
|
|
||||||
describe('pivotHelper.js', () => {
|
describe('pivotHelper.js', () => {
|
||||||
@@ -63,4 +63,19 @@ describe('pivotHelper.js', () => {
|
|||||||
|
|
||||||
expect(await getPivotCanvas(pivotOutput)).to.be.instanceof(HTMLCanvasElement)
|
expect(await getPivotCanvas(pivotOutput)).to.be.instanceof(HTMLCanvasElement)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('getPivotHtml returns html with styles', async () => {
|
||||||
|
const pivotOutput = document.createElement('div')
|
||||||
|
pivotOutput.append('test')
|
||||||
|
|
||||||
|
const html = getPivotHtml(pivotOutput)
|
||||||
|
const doc = document.createElement('div')
|
||||||
|
doc.innerHTML = html
|
||||||
|
|
||||||
|
expect(doc.innerHTML).to.equal(html)
|
||||||
|
expect(doc.children).to.have.lengthOf(2)
|
||||||
|
expect(doc.children[0].tagName).to.equal('STYLE')
|
||||||
|
expect(doc.children[1].tagName).to.equal('DIV')
|
||||||
|
expect(doc.children[1].innerHTML).to.equal('test')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user