Skip to content

Commit 248354d

Browse files
committed
Merge brach 'main' into demo
2 parents 00637b4 + 709971b commit 248354d

17 files changed

Lines changed: 927 additions & 842 deletions

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vvplot",
3-
"version": "0.0.1",
3+
"version": "0.1.1",
44
"license": "MIT",
55
"files": [
66
"dist"
@@ -15,6 +15,8 @@
1515
"imports": {
1616
"#base/*": "./src/*"
1717
},
18+
"homepage": "https://fan-ix.github.io/vvplot/",
19+
"repository": "https://github.com/Fan-iX/vvplot/",
1820
"exports": {
1921
".": "./dist/index.js",
2022
"./components": "./dist/components.js",

src/components/Plot.vue

Lines changed: 126 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup>
2-
import { computed, watch, Fragment, useAttrs, useSlots, useTemplateRef, onMounted, reactive } from 'vue'
2+
import { computed, watch, Fragment, useAttrs, useSlots, useTemplateRef, onMounted, reactive, provide } from 'vue'
33
import { reactiveComputed, useElementSize } from '@vueuse/core'
44
import { baseParse } from '@vue/compiler-core'
55
import { theme_base, theme_default, themeBuild, themeMerge, themePreprocess } from '../js/theme'
@@ -22,26 +22,23 @@ function _isPropTruthy(v) {
2222
return v === "" || Boolean(v)
2323
}
2424

25-
const emit = defineEmits(['resize'])
25+
const emit = defineEmits(['resize', 'rangechange', 'select', 'update:range', 'update:rangePreview'])
2626
const {
2727
data: $data, scales: $scales, aes: $aes,
2828
expandAdd: $expandAdd, expandMult: $expandMult, extend: $extend,
29-
levels: $levels, range: $range, minRange: $minRange,
29+
levels: $levels, range: $range, minRange: $minRange, rangePreview: $rangePreview,
3030
axes: $axes, theme: $theme, action: $action, reverse: $reverse,
3131
flip, clip, resize, legendTeleport
3232
} = defineProps({
3333
data: Array, scales: Object, aes: Object,
3434
expandAdd: Object, expandMult: Object, extend: Object,
35-
levels: Object, range: Object, minRange: Object,
35+
levels: Object, range: Object, minRange: Object, rangePreview: Object,
3636
axes: [Object, Array], theme: [Object, Array], action: [Object, Array], reverse: Object,
3737
flip: Boolean, clip: { type: Boolean, default: true }, resize: null,
3838
legendTeleport: null,
3939
})
40-
const activeSelection = defineModel('activeSelection')
41-
const translateH = defineModel('translateH')
42-
const translateV = defineModel('translateV')
43-
const transcaleH = defineModel('transcaleH')
44-
const transcaleV = defineModel('transcaleV')
40+
const selectionPreview = defineModel('selectionPreview', { default: () => ({}) })
41+
const selectionPreviewTheme = defineModel('selectionPreviewTheme', { default: () => ({}) })
4542
const transition = defineModel('transition')
4643

4744
function expandFragment(componentList) {
@@ -119,13 +116,6 @@ const vBind = computed(() => {
119116
wrapper[key] = $attrs[key]
120117
}
121118
}
122-
for (let ori of ['x', 'y']) {
123-
for (let bound of ['min', 'max']) {
124-
if (primaryAxis?.[ori]?.[`onUpdate:${bound}`]) {
125-
plot[`onUpdate:${ori}${bound}`] = primaryAxis?.[ori]?.[`onUpdate:${bound}`]
126-
}
127-
}
128-
}
129119
return { plot, wrapper }
130120
})
131121

@@ -143,15 +133,36 @@ const primaryAxis = reactiveComputed(() => {
143133
y: yAxes.find(c => _isPropTruthy(c.primary)) ?? yAxes.find(c => c.primary == null && !_isPropTruthy(c.secondary))
144134
}
145135
})
136+
137+
const primaryAxisConfig = {
138+
levels: reactive({}),
139+
extend: reactive({}),
140+
['min-range']: reactive({}),
141+
['expand-add']: reactive({}),
142+
['expand-mult']: reactive({}),
143+
boundary: reactive({}),
144+
reverse: reactive({}),
145+
min: reactive({}),
146+
max: reactive({}),
147+
['min-preview']: reactive({}),
148+
['max-preview']: reactive({}),
149+
}
150+
151+
watch(primaryAxis, v => {
152+
for (let ori of ['x', 'y']) {
153+
for (let key in primaryAxisConfig) {
154+
primaryAxisConfig[key][ori] = v?.[ori]?.[key]
155+
}
156+
}
157+
}, { immediate: true })
158+
146159
const actionBoundary = reactiveComputed(() => {
147160
let boundary = {}
148161
for (let ori of ['x', 'y']) {
149-
let bound = primaryAxis[ori]?.boundary
150-
if (bound) {
151-
boundary[ori] = {
152-
min: bound.min ?? bound[0],
153-
max: bound.max ?? bound[1]
154-
}
162+
let bound = primaryAxisConfig.boundary[ori]
163+
boundary[ori] = {
164+
min: bound?.min ?? bound?.[0],
165+
max: bound?.max ?? bound?.[1]
155166
}
156167
}
157168
return boundary
@@ -165,8 +176,8 @@ const schema = computed(() => {
165176
return {
166177
data: $data,
167178
aes: $aes,
168-
extendX: primaryAxis?.x?.extend ?? $extend?.x ?? 0,
169-
extendY: primaryAxis?.y?.extend ?? $extend?.y ?? 0
179+
extendX: primaryAxisConfig.extend.x ?? $extend?.x ?? 0,
180+
extendY: primaryAxisConfig.extend.y ?? $extend?.y ?? 0
170181
}
171182
})
172183
/* layers
@@ -205,22 +216,18 @@ const levels = computed(() => (({ x, y, ...etc }) => etc)($levels ?? {}))
205216
const coordLevels = computed(() => {
206217
let levels = {}
207218
for (let ori of ['x', 'y']) {
208-
if (primaryAxis[ori]) {
209-
let ax = primaryAxis[ori]
210-
levels[ori] = ax.levels ?? $levels?.[ori]
211-
}
219+
levels[ori] = primaryAxisConfig.levels[ori] ?? $levels?.[ori]
212220
}
213221
return levels
214222
})
215223

216-
const range = computed(() => {
224+
const coordRange = computed(() => {
217225
let result = {}
218226
for (let ori of ['x', 'y']) {
219-
let ax = primaryAxis[ori]
220-
let min = ax?.min ?? ax?.limits?.min ?? ax?.limits?.[0]
221-
let max = ax?.max ?? ax?.limits?.max ?? ax?.limits?.[1]
222-
result[ori + "min"] = isFinite(min) && !Number.isNaN(min) ? min : $range?.[ori + "min"]
223-
result[ori + "max"] = isFinite(max) && !Number.isNaN(max) ? max : $range?.[ori + "max"]
227+
let min = primaryAxisConfig.min[ori] ?? $range?.[ori + "min"]
228+
let max = primaryAxisConfig.max[ori] ?? $range?.[ori + "max"]
229+
result[ori + "min"] = isFinite(min) && !Number.isNaN(min) ? min : null
230+
result[ori + "max"] = isFinite(max) && !Number.isNaN(max) ? max : null
224231
let level = coordLevels.value[ori]
225232
if (level != null) {
226233
result[ori + "min"] = (result[ori + "min"] ?? 0) - 0.5
@@ -230,31 +237,96 @@ const range = computed(() => {
230237
return result
231238
})
232239

240+
const coordRangePreview = computed(() => {
241+
let result = {}
242+
for (let ori of ['x', 'y']) {
243+
let min = primaryAxisConfig['min-preview'][ori] ?? $rangePreview?.[ori + "min"]
244+
let max = primaryAxisConfig['max-preview'][ori] ?? $rangePreview?.[ori + "max"]
245+
result[ori + "min"] = isFinite(min) && !Number.isNaN(min) ? min : null
246+
result[ori + "max"] = isFinite(max) && !Number.isNaN(max) ? max : null
247+
}
248+
return result
249+
})
250+
const rangeUpdate = reactiveComputed(() => {
251+
return {
252+
xmin: primaryAxis?.x?.["onUpdate:min"],
253+
xmax: primaryAxis?.x?.["onUpdate:max"],
254+
ymin: primaryAxis?.y?.["onUpdate:min"],
255+
ymax: primaryAxis?.y?.["onUpdate:max"],
256+
}
257+
})
258+
const rangePreviewUpdate = reactiveComputed(() => {
259+
return {
260+
xmin: primaryAxis?.x?.["onUpdate:minPreview"],
261+
xmax: primaryAxis?.x?.["onUpdate:maxPreview"],
262+
ymin: primaryAxis?.y?.["onUpdate:minPreview"],
263+
ymax: primaryAxis?.y?.["onUpdate:maxPreview"],
264+
}
265+
})
266+
267+
const range = reactive({}), rangePreview = reactive({})
268+
watch(coordRange, (newRange, oldRange) => {
269+
if (newRange?.xmin !== oldRange?.xmin)
270+
range.xmin = newRange.xmin
271+
if (newRange?.xmax !== oldRange?.xmax)
272+
range.xmax = newRange.xmax
273+
if (newRange?.ymin !== oldRange?.ymin)
274+
range.ymin = newRange.ymin
275+
if (newRange?.ymax !== oldRange?.ymax)
276+
range.ymax = newRange.ymax
277+
}, { immediate: true })
278+
watch(coordRangePreview, (newRange, oldRange) => {
279+
if (newRange?.xmin !== oldRange?.xmin)
280+
rangePreview.xmin = newRange.xmin
281+
if (newRange?.xmax !== oldRange?.xmax)
282+
rangePreview.xmax = newRange.xmax
283+
if (newRange?.ymin !== oldRange?.ymin)
284+
rangePreview.ymin = newRange.ymin
285+
if (newRange?.ymax !== oldRange?.ymax)
286+
rangePreview.ymax = newRange.ymax
287+
}, { immediate: true })
288+
289+
watch(() => range, (newRange, oldRange) => {
290+
for (let key in rangeUpdate) {
291+
rangeUpdate[key]?.(newRange[key])
292+
}
293+
emit('rangechange', { ...newRange }, { ...oldRange })
294+
emit('update:range', { ...newRange })
295+
}, { deep: true })
296+
watch(() => rangePreview, (newRange) => {
297+
for (let key in rangePreviewUpdate) {
298+
rangePreviewUpdate[key]?.(newRange[key])
299+
}
300+
emit('update:rangePreview', { ...newRange })
301+
}, { deep: true })
302+
provide('range', range)
303+
provide('rangePreview', rangePreview)
304+
233305
const minRange = computed(() => ({
234-
x: primaryAxis?.x?.['min-range'] ?? $minRange?.x ?? 0,
235-
y: primaryAxis?.y?.['min-range'] ?? $minRange?.y ?? 0,
306+
x: primaryAxisConfig["min-range"].x ?? $minRange?.x ?? 0,
307+
y: primaryAxisConfig["min-range"].y ?? $minRange?.y ?? 0,
236308
}))
237309
const expandAdd = computed(() => {
238-
let x = primaryAxis?.x?.['expand-add'] ?? $expandAdd?.x ?? 0,
239-
y = primaryAxis?.y?.['expand-add'] ?? $expandAdd?.y ?? 0
310+
let x = primaryAxisConfig['expand-add'].x ?? $expandAdd?.x ?? 0,
311+
y = primaryAxisConfig['expand-add'].y ?? $expandAdd?.y ?? 0
240312
if (Array.isArray(x)) x = { min: x[0], max: x[1] }
241313
else if (typeof x == 'number') x = { min: x, max: x }
242314
if (Array.isArray(y)) y = { min: y[0], max: y[1] }
243315
else if (typeof y == 'number') y = { min: y, max: y }
244316
return { x, y }
245317
})
246318
const expandMult = computed(() => {
247-
let x = primaryAxis?.x?.['expand-mult'] ?? $expandMult?.x ?? 0.05,
248-
y = primaryAxis?.y?.['expand-mult'] ?? $expandMult?.y ?? 0.05
319+
let x = primaryAxisConfig['expand-mult'].x ?? $expandMult?.x ?? 0.05,
320+
y = primaryAxisConfig['expand-mult'].y ?? $expandMult?.y ?? 0.05
249321
if (Array.isArray(x)) x = { min: x[0], max: x[1] }
250322
else if (typeof x == 'number') x = { min: x, max: x }
251323
if (Array.isArray(y)) y = { min: y[0], max: y[1] }
252324
else if (typeof y == 'number') y = { min: y, max: y }
253325
return { x, y }
254326
})
255327
const reverse = computed(() => ({
256-
x: _isPropTruthy(primaryAxis?.x?.['reverse']) ?? $reverse?.x ?? false,
257-
y: _isPropTruthy(primaryAxis?.y?.['reverse']) ?? $reverse?.y ?? false,
328+
x: _isPropTruthy(primaryAxisConfig.reverse.x) ?? $reverse?.x ?? false,
329+
y: _isPropTruthy(primaryAxisConfig.reverse.y) ?? $reverse?.y ?? false,
258330
}))
259331

260332
const buttonsMap = { left: 1, right: 2, middle: 4, X1: 8, X2: 16 }
@@ -304,12 +376,18 @@ const axes = computed(() => {
304376
return {
305377
coord, orientation, position, title, breaks, labels, minorBreaks,
306378
showGrid: _isPropTruthy(showGrid) ?? position !== "none",
307-
extend: extend ?? primaryAxis?.[coord]?.extend,
379+
extend: extend ?? primaryAxisConfig.extend[coord],
308380
theme: Object.assign({}, ...[theme.value?.axis?.[position] ?? theme.value?.axis?.[orientation]].concat($$theme)),
309381
action, ...etc,
310382
}
311383
}).filter(ax => ax != null)
312384
})
385+
const paddings = reactive({})
386+
watch(axes, ax => {
387+
for (let p of ["left", "right", "top", "bottom"]) {
388+
paddings[p] = ax.some(a => a.position == p)
389+
}
390+
}, { immediate: true })
313391
const action = computed(() => {
314392
return vaction.value.map(c => ({ ...c.type.$_props, ...c.props })).concat($action ?? [])
315393
.flatMap(props => {
@@ -374,6 +452,7 @@ const selections = computed(() => {
374452
buttons: buttons ?? buttonsMap[button] ?? 1,
375453
modelValue, "onUpdate:modelValue": onUpdate,
376454
theme: Object.assign({}, ...[theme.value?.selection].concat($$theme)),
455+
onSelect: (d, e) => emit('select', d, e),
377456
...etc
378457
}
379458
})
@@ -425,13 +504,12 @@ defineExpose({
425504
</script>
426505
<template>
427506
<div ref="wrapper" class="vvplot" :style="wrapperStyle" v-bind="vBind.wrapper">
428-
<CorePlot ref="plot" :schema="schema" :layers="layers" :range="range" :min-range="minRange"
507+
<CorePlot ref="plot" :paddings="paddings" :schema="schema" :layers="layers" :min-range="minRange"
429508
:expand-add="expandAdd" :expand-mult="expandMult" :reverse="reverse" :flip="flip"
430509
:coord-levels="coordLevels" :levels="levels" :scales="$scales" :axes="axes" :theme="theme"
431-
:selections="selections" v-model:active-selection="activeSelection" v-model:transcale-h="transcaleH"
432-
v-model:transcale-v="transcaleV" v-model:translate-h="translateH" v-model:translate-v="translateV"
433-
v-model:transition="transition" v-bind="vBind.plot" :action="action" :clip="clip"
434-
:legendTeleport="legendTeleport" />
510+
:selections="selections" v-model:transition="transition" v-bind="vBind.plot"
511+
v-model:selectionPreview="selectionPreview" v-model:selectionPreviewTheme="selectionPreviewTheme"
512+
:action="action" :clip="clip" :legendTeleport="legendTeleport" @select="(d, e) => emit('select', d, e)" />
435513
<div class="vvplot-panel-container" :style="panelStyle" v-if="vnodes.dom.panel?.length">
436514
<div class="vvplot-panel">
437515
<component v-for="c in vnodes.dom.panel" :is="c" />

src/components/core/CoreEventWrapper.vue

Lines changed: 0 additions & 37 deletions
This file was deleted.

0 commit comments

Comments
 (0)