1
0
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:
lana-k
2024-12-10 21:41:07 +01:00
parent 637d8d26dd
commit eee67763b5
5 changed files with 67 additions and 74 deletions

View File

@@ -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

View File

@@ -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
})
}

View File

@@ -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>

View File

@@ -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(

View File

@@ -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 })
},