mirror of
https://github.com/lana-k/sqliteviz.git
synced 2025-12-06 18:18:53 +08:00
plotly in pivot
This commit is contained in:
@@ -3,7 +3,9 @@
|
||||
<div class="warning chart-warning" v-show="!dataSources && visible">
|
||||
There is no data to build a chart. Run your SQL query and make sure the result is not empty.
|
||||
</div>
|
||||
<div class="chart" :style="{ height: !dataSources ? 'calc(100% - 40px)' : '100%' }">
|
||||
<PlotlyEditor
|
||||
v-show="visible"
|
||||
:data="state.data"
|
||||
:layout="state.layout"
|
||||
:frames="state.frames"
|
||||
@@ -14,13 +16,12 @@
|
||||
:useResizeHandler="useResizeHandler"
|
||||
:debug="true"
|
||||
:advancedTraceTypeSelector="true"
|
||||
class="chart"
|
||||
ref="plotlyEditor"
|
||||
:style="{ height: !dataSources ? 'calc(100% - 40px)' : '100%' }"
|
||||
@update="update"
|
||||
@render="onRender"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -105,11 +106,10 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleResize () {
|
||||
async handleResize () {
|
||||
this.visible = false
|
||||
this.$nextTick(() => {
|
||||
await this.$nextTick()
|
||||
this.visible = true
|
||||
})
|
||||
},
|
||||
onRender (data, layout, frames) {
|
||||
// TODO: check changes and enable Save button if needed
|
||||
|
||||
@@ -140,13 +140,11 @@ import $ from 'jquery'
|
||||
import Multiselect from 'vue-multiselect'
|
||||
import PivotSortBtn from './PivotSortBtn'
|
||||
import { renderers, aggregators, zeroValAggregators, twoValAggregators } from '../pivotHelper'
|
||||
import Chart from '@/views/Main/Workspace/Tabs/Tab/DataView/Chart'
|
||||
import { createApp } from 'vue'
|
||||
|
||||
export default {
|
||||
name: 'pivotUi',
|
||||
props: ['keyNames', 'modelValue'],
|
||||
emits: ['loadingCustomChartImageCompleted', 'update:modelValue', 'update'],
|
||||
emits: ['update:modelValue', 'update'],
|
||||
components: {
|
||||
Multiselect,
|
||||
PivotSortBtn
|
||||
@@ -163,13 +161,7 @@ export default {
|
||||
val1: (this.modelValue && this.modelValue.vals && this.modelValue.vals[0]) || '',
|
||||
val2: (this.modelValue && this.modelValue.vals && this.modelValue.vals[1]) || '',
|
||||
colOrder: (this.modelValue && this.modelValue.colOrder) || 'key_a_to_z',
|
||||
rowOrder: (this.modelValue && this.modelValue.rowOrder) || 'key_a_to_z',
|
||||
customChartComponent:
|
||||
(
|
||||
this.modelValue &&
|
||||
this.modelValue.rendererOptions &&
|
||||
this.modelValue.rendererOptions.customChartComponent
|
||||
) || createApp(Chart)
|
||||
rowOrder: (this.modelValue && this.modelValue.rowOrder) || 'key_a_to_z'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -223,12 +215,6 @@ export default {
|
||||
this.returnValue()
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.customChartComponent.onUpdate = () => { this.$emit('update') }
|
||||
this.customChartComponent.onLoadingImageCompleted = () => {
|
||||
this.$emit('loadingCustomChartImageCompleted')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
returnValue () {
|
||||
const vals = []
|
||||
@@ -245,11 +231,6 @@ export default {
|
||||
aggregatorName: this.aggregator.name,
|
||||
renderer: this.renderer.fun,
|
||||
rendererName: this.renderer.name,
|
||||
rendererOptions: this.renderer.name !== 'Custom chart'
|
||||
? undefined
|
||||
: {
|
||||
customChartComponent: this.customChartComponent
|
||||
},
|
||||
vals
|
||||
})
|
||||
}
|
||||
|
||||
@@ -7,14 +7,24 @@
|
||||
:key-names="columns"
|
||||
v-model="pivotOptions"
|
||||
@update="$emit('update')"
|
||||
@loadingCustomChartImageCompleted="$emit('loadingImageCompleted')"
|
||||
/>
|
||||
<div ref="pivotOutput" class="pivot-output"/>
|
||||
<div
|
||||
ref="customChartOutput"
|
||||
v-show="viewCustomChart"
|
||||
class="custom-chart-output"
|
||||
>
|
||||
<chart
|
||||
ref="customChart"
|
||||
v-bind="customChartComponentProps"
|
||||
@update="$emit('update')"
|
||||
@onLoadingImageCompleted="$emit('loadingImageCompleted')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { createApp } from 'vue'
|
||||
import fIo from '@/lib/utils/fileIo'
|
||||
import $ from 'jquery'
|
||||
import 'pivottable'
|
||||
@@ -35,7 +45,8 @@ export default {
|
||||
'update:importToPngEnabled'
|
||||
],
|
||||
components: {
|
||||
PivotUi
|
||||
PivotUi,
|
||||
Chart
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
@@ -50,8 +61,7 @@ export default {
|
||||
aggregator: $.pivotUtilities.aggregators.Count(),
|
||||
vals: [],
|
||||
rendererName: 'Table',
|
||||
renderer: $.pivotUtilities.renderers.Table,
|
||||
rendererOptions: undefined
|
||||
renderer: $.pivotUtilities.renderers.Table
|
||||
}
|
||||
: {
|
||||
rows: this.initOptions.rows,
|
||||
@@ -64,15 +74,11 @@ export default {
|
||||
](this.initOptions.vals),
|
||||
vals: this.initOptions.vals,
|
||||
rendererName: this.initOptions.rendererName,
|
||||
renderer: $.pivotUtilities.renderers[this.initOptions.rendererName],
|
||||
rendererOptions: !this.initOptions.rendererOptions
|
||||
? undefined
|
||||
: {
|
||||
customChartComponent: createApp(Chart, {
|
||||
initOptions: this.initOptions
|
||||
.rendererOptions.customChartOptions
|
||||
})
|
||||
}
|
||||
renderer: $.pivotUtilities.renderers[this.initOptions.rendererName]
|
||||
},
|
||||
customChartComponentProps: {
|
||||
initOptions: this.initOptions?.rendererOptions?.customChartOptions,
|
||||
forPivot: true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -115,13 +121,13 @@ export default {
|
||||
},
|
||||
mounted () {
|
||||
this.show()
|
||||
// We need to detect resizing because plotly doesn't resize when resixe its container
|
||||
// We need to detect resizing because plotly doesn't resize when resize its container
|
||||
// but it resize on window.resize (we will trigger it manualy in order to make plotly resize)
|
||||
this.resizeObserver = new ResizeObserver(this.handleResize)
|
||||
this.resizeObserver.observe(this.$refs.pivotOutput)
|
||||
this.resizeObserver.observe(this.$refs.customChartOutput)
|
||||
},
|
||||
beforeUnmount () {
|
||||
this.resizeObserver.unobserve(this.$refs.pivotOutput)
|
||||
this.resizeObserver.unobserve(this.$refs.customChartOutput)
|
||||
},
|
||||
methods: {
|
||||
handleResize () {
|
||||
@@ -149,6 +155,12 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.viewCustomChart) {
|
||||
options.rendererOptions = {
|
||||
getCustomComponentsProps: () => this.customChartComponentProps
|
||||
}
|
||||
}
|
||||
|
||||
$(this.$refs.pivotOutput).pivot(
|
||||
function (callback) {
|
||||
const rowCount = !this.dataSources ? 0 : this.dataSources[this.columns[0]].length
|
||||
@@ -172,7 +184,7 @@ export default {
|
||||
getOptionsForSave () {
|
||||
const options = { ...this.pivotOptions }
|
||||
if (options.rendererOptions) {
|
||||
const chartComponent = this.pivotOptions.rendererOptions.customChartComponent
|
||||
const chartComponent = this.$refs.customChart
|
||||
options.rendererOptions = {
|
||||
customChartOptions: chartComponent.getOptionsForSave()
|
||||
}
|
||||
@@ -183,7 +195,7 @@ export default {
|
||||
|
||||
async saveAsPng () {
|
||||
if (this.viewCustomChart) {
|
||||
this.pivotOptions.rendererOptions.customChartComponent.saveAsPng()
|
||||
this.$refs.customChart.saveAsPng()
|
||||
} else {
|
||||
const source = this.viewStandartChart
|
||||
? await chartHelper.getImageDataUrl(this.$refs.pivotOutput, 'png')
|
||||
@@ -196,7 +208,7 @@ export default {
|
||||
|
||||
async prepareCopy () {
|
||||
if (this.viewCustomChart) {
|
||||
return await this.pivotOptions.rendererOptions.customChartComponent.prepareCopy()
|
||||
return await this.$refs.customChart.prepareCopy()
|
||||
}
|
||||
if (this.viewStandartChart) {
|
||||
return await chartHelper.getImageDataUrl(this.$refs.pivotOutput, 'png')
|
||||
@@ -206,7 +218,7 @@ export default {
|
||||
|
||||
async saveAsSvg () {
|
||||
if (this.viewCustomChart) {
|
||||
this.pivotOptions.rendererOptions.customChartComponent.saveAsSvg()
|
||||
this.$refs.customChart.saveAsSvg()
|
||||
} else if (this.viewStandartChart) {
|
||||
const url = await chartHelper.getImageDataUrl(this.$refs.pivotOutput, 'svg')
|
||||
fIo.downloadFromUrl(url, 'pivot')
|
||||
@@ -215,7 +227,7 @@ export default {
|
||||
|
||||
saveAsHtml () {
|
||||
if (this.viewCustomChart) {
|
||||
this.pivotOptions.rendererOptions.customChartComponent.saveAsHtml()
|
||||
this.$refs.customChart.saveAsHtml()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -246,7 +258,8 @@ export default {
|
||||
background-color: var(--color-white);
|
||||
}
|
||||
|
||||
.pivot-output {
|
||||
.pivot-output,
|
||||
.custom-chart-output {
|
||||
flex-grow: 1;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
@@ -288,4 +301,7 @@ export default {
|
||||
.pivot-output :deep(textarea:focus-visible) {
|
||||
outline: none;
|
||||
}
|
||||
.pivot-output:empty {
|
||||
flex-grow: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -50,14 +50,9 @@ export function _getDataSources (pivotData) {
|
||||
}
|
||||
|
||||
function customChartRenderer (data, options) {
|
||||
options.customChartComponent.dataSources = _getDataSources(data)
|
||||
options.customChartComponent.forPivot = true
|
||||
|
||||
const container = document.createElement('div')
|
||||
|
||||
options.customChartComponent.mount(container)
|
||||
|
||||
return $(container)
|
||||
const propsRef = options.getCustomComponentsProps()
|
||||
propsRef.dataSources = _getDataSources(data)
|
||||
return null
|
||||
}
|
||||
|
||||
$.extend(
|
||||
|
||||
@@ -131,6 +131,7 @@ export default {
|
||||
const fromPosition = this.tab.layout[from]
|
||||
this.tab.layout[from] = this.tab.layout[to]
|
||||
this.tab.layout[to] = fromPosition
|
||||
window.dispatchEvent(new Event('resize'))
|
||||
|
||||
events.send('inquiry.panel', null, { panel: to })
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user