Skip to content

Commit c57babf

Browse files
committed
Improvement - VueUiWordCloud - Add zoom controls
1 parent 4019377 commit c57babf

File tree

6 files changed

+126
-43
lines changed

6 files changed

+126
-43
lines changed

TestingArena/ArenaVueUiWordCloud.vue

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ Maecenas convallis libero at nisl lacinia facilisis. Nulla facilisi. Sed bibendu
3030
3131
const shortText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus pulvinar pretium venenatis. Donec imperdiet elit id porttitor tristique. Aenean ac commodo justo. Vestibulum placerat molestie nisl, sit amet lacinia nulla posuere quis. Aenean ullamcorper eu ex vitae facilisis. Aliquam erat volutpat. Proin nunc felis, porttitor quis commodo lacinia, gravida sed orci. Interdum et malesuada fames ac ante ipsum primis in faucibus. Vivamus mattis vitae tellus ac luctus. Vestibulum faucibus sem nec varius eleifend. In gravida venenatis ipsum sit amet ultricies. Nam efficitur, dui ac imperdiet vestibulum, justo metus consectetur libero, posuere tempor neque magna vitae augue. Etiam gravida massa quis turpis vulputate, ac tempus nisi imperdiet.'
3232
33-
const dataset = ref(undefined);
33+
const dataset = ref(createWordCloudDatasetFromPlainText(longText));
3434
35-
onMounted(() => {
36-
setTimeout(() => {
37-
dataset.value = createWordCloudDatasetFromPlainText(longText);
38-
}, 2000)
39-
})
35+
// onMounted(() => {
36+
// setTimeout(() => {
37+
// dataset.value = createWordCloudDatasetFromPlainText(longText);
38+
// }, 2000)
39+
// })
4040
4141
const model = createModel([
4242
CHECKBOX("debug", { def: true }),

src/atoms/BaseZoomControls.vue

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,17 @@ const emit = defineEmits(['zoomIn', 'zoomOut', 'resetZoom', 'switchDirection']);
7676
:size="config.style.chart.controls.fontSize * 1.2"
7777
/>
7878
</button>
79+
<button
80+
:disabled="scale === 1"
81+
@click="emit('resetZoom')"
82+
class="vue-data-ui-zoom-controls-button"
83+
>
84+
<BaseIcon
85+
name="revert"
86+
:stroke="config.style.chart.controls.color"
87+
:size="config.style.chart.controls.fontSize * 1.2"
88+
/>
89+
</button>
7990
<button
8091
v-if="withDirection"
8192
@click="emit('switchDirection')"
@@ -134,4 +145,13 @@ const emit = defineEmits(['zoomIn', 'zoomOut', 'resetZoom', 'switchDirection']);
134145
transform: translateX(-50%) !important;
135146
bottom: 1rem;
136147
}
148+
149+
button:disabled {
150+
cursor:not-allowed;
151+
opacity: 0.3;
152+
}
153+
154+
button:disabled:hover {
155+
box-shadow: none;
156+
}
137157
</style>

src/components/vue-ui-word-cloud.vue

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {
2727
treeShake,
2828
XMLNS
2929
} from '../lib';
30-
import { throttle } from '../canvas-lib';
3130
import { useConfig } from '../useConfig';
3231
import { useLoading } from '../useLoading';
3332
import { usePrinter } from '../usePrinter';
@@ -43,6 +42,7 @@ import Title from '../atoms/Title.vue'; // Must be ready in responsive mode
4342
import themes from "../themes/vue_ui_word_cloud.json";
4443
import usePanZoom from '../usePanZoom';
4544
import BaseScanner from '../atoms/BaseScanner.vue';
45+
import BaseZoomControls from '../atoms/BaseZoomControls.vue';
4646
4747
const Tooltip = defineAsyncComponent(() => import('../atoms/Tooltip.vue'));
4848
const BaseIcon = defineAsyncComponent(() => import('../atoms/BaseIcon.vue'));
@@ -92,6 +92,7 @@ const tableUnit = ref(null);
9292
const userOptionsRef = ref(null);
9393
const cloudFinalized = ref(false);
9494
const isRelayout = ref(false);
95+
const zoomControls = ref(null);
9596
9697
const FINAL_CONFIG = ref(prepareConfig());
9798
@@ -279,6 +280,7 @@ const resizeJob = debounce(() => {
279280
const { width, height } = useResponsive({
280281
chart: wordCloudChart.value,
281282
title: FINAL_CONFIG.value.style.chart.title.text ? chartTitle.value : null,
283+
legend: FINAL_CONFIG.value.style.chart.controls.show ? zoomControls.value?.$el : null,
282284
source: source.value
283285
});
284286
@@ -562,7 +564,7 @@ function toggleZoom() {
562564
563565
const active = computed(() => !isAnnotator.value && mutableConfig.value.showZoom);
564566
565-
const { viewBox, resetZoom, isZoom, setInitialViewBox } = usePanZoom(svgRef, {
567+
const { viewBox, resetZoom, isZoom, setInitialViewBox, zoomByFactor, scale } = usePanZoom(svgRef, {
566568
x: 0,
567569
y: 0,
568570
width: svg.value.width <= 0 ? 10 : svg.value.width,
@@ -662,6 +664,14 @@ async function generateSvg({ isCb }) {
662664
}
663665
}
664666
667+
function zoomIn() {
668+
zoomByFactor(1.5, true);
669+
}
670+
671+
function zoomOut() {
672+
zoomByFactor(1 / 1.5, true);
673+
}
674+
665675
defineExpose({
666676
getData,
667677
getImage,
@@ -853,12 +863,23 @@ function useTooltip(word, index) {
853863
</template>
854864
</UserOptions>
855865

866+
<BaseZoomControls
867+
ref="zoomControls"
868+
v-if="FINAL_CONFIG.style.chart.controls.position === 'top' && FINAL_CONFIG.style.chart.controls.show && !loading"
869+
:config="FINAL_CONFIG"
870+
:scale="scale"
871+
:isFullscreen="isFullscreen"
872+
@zoomIn="zoomIn"
873+
@zoomOut="zoomOut"
874+
@resetZoom="resetZoom(true)"
875+
/>
876+
856877
<svg
857878
ref="svgRef"
858879
:class="{ 'vue-data-ui-fullscreen--on': isFullscreen, 'vue-data-ui-fulscreen--off': !isFullscreen }"
859880
:xmlns="XMLNS"
860881
:viewBox="`${viewBox.x} ${viewBox.y} ${viewBox.width} ${viewBox.height}`"
861-
:style="`overflow:hidden;background:transparent;`"
882+
:style="`overflow:hidden;background:transparent;display:block`"
862883
>
863884
<PackageVersion />
864885

@@ -929,20 +950,20 @@ function useTooltip(word, index) {
929950

930951
<div v-if="isZoom" data-dom-to-png-ignore class="reset-wrapper">
931952
<slot name="reset-action" :reset="resetZoom">
932-
<button
933-
data-cy-reset
934-
tabindex="0"
935-
role="button"
936-
class="vue-data-ui-refresh-button"
937-
:style="{
938-
background: FINAL_CONFIG.style.chart.backgroundColor
939-
}"
940-
@click="resetZoom(true)">
941-
<BaseIcon name="refresh" :stroke="FINAL_CONFIG.style.chart.color" />
942-
</button>
943953
</slot>
944954
</div>
945955

956+
<BaseZoomControls
957+
ref="zoomControls"
958+
v-if="FINAL_CONFIG.style.chart.controls.position === 'bottom' && FINAL_CONFIG.style.chart.controls.show && !loading"
959+
:config="FINAL_CONFIG"
960+
:scale="scale"
961+
:isFullscreen="isFullscreen"
962+
@zoomIn="zoomIn"
963+
@zoomOut="zoomOut"
964+
@resetZoom="resetZoom(true)"
965+
/>
966+
946967
<Tooltip
947968
:show="mutableConfig.showTooltip && isTooltip"
948969
:backgroundColor="FINAL_CONFIG.style.chart.tooltip.backgroundColor"

src/themes/vue_ui_word_cloud.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
"color": "#757575"
1212
}
1313
},
14+
"controls": {
15+
"backgroundColor": "#2A2A2A",
16+
"buttonColor": "#2A2A2A",
17+
"color": "#CCCCCC",
18+
"border": "1px solid #4A4A4A"
19+
},
1420
"words": {
1521
"selectedStroke": "#1A1A1A"
1622
},
@@ -44,6 +50,12 @@
4450
"color": "#757575"
4551
}
4652
},
53+
"controls": {
54+
"backgroundColor": "#FFF8E1",
55+
"buttonColor": "#FFF8E1",
56+
"color": "#424242",
57+
"border": "1px solid #d9bbb2"
58+
},
4759
"words": {
4860
"selectedStroke": "#FFF8E1"
4961
},
@@ -81,6 +93,12 @@
8193
"color": "#BDBDBD"
8294
}
8395
},
96+
"controls": {
97+
"backgroundColor": "#1E1E1E",
98+
"buttonColor": "#1E1E1E",
99+
"color": "#BDBDBD",
100+
"border": "1px solid #3A3A3A"
101+
},
84102
"words": {
85103
"selectedStroke": "#1E1E1E"
86104
},
@@ -112,6 +130,12 @@
112130
"chart": {
113131
"backgroundColor": "#1A1A1A",
114132
"color": "#99AA99",
133+
"controls": {
134+
"backgroundColor": "#1A1A1A",
135+
"buttonColor": "#1A1A1A",
136+
"color": "#99AA99",
137+
"border": "1px solid #1e361e"
138+
},
115139
"title": {
116140
"color": "#66CC66",
117141
"subtitle": {
@@ -139,6 +163,12 @@
139163
"chart": {
140164
"backgroundColor": "#fbfafa",
141165
"color": "#8A9892",
166+
"controls": {
167+
"backgroundColor": "#fbfafa",
168+
"buttonColor": "#fbfafa",
169+
"color": "#99AA99",
170+
"border": "1px solid #ebded3"
171+
},
142172
"title": {
143173
"color": "#8A9892",
144174
"subtitle": {
@@ -166,6 +196,13 @@
166196
"chart": {
167197
"backgroundColor": "#f6f6fb",
168198
"color": "#50606C",
199+
"controls": {
200+
"backgroundColor": "#f6f6fb",
201+
"buttonColor": "#f6f6fb",
202+
"color": "#50606C",
203+
"border": "1px solid #98aab8",
204+
"borderRadius": "0"
205+
},
169206
"title": {
170207
"color": "#50606C",
171208
"subtitle": {

src/useConfig.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4638,6 +4638,17 @@ export function useConfig() {
46384638
zoom: {
46394639
show: true,
46404640
},
4641+
controls: {
4642+
position: 'bottom',
4643+
show: true,
4644+
backgroundColor: COLOR_GREY_LIGHT,
4645+
buttonColor: COLOR_GREY_LIGHT,
4646+
color: COLOR_BLACK,
4647+
fontSize: 14,
4648+
border: `1px solid ${COLOR_GREY_MID}`,
4649+
padding: `0.5rem`,
4650+
borderRadius: `0.25rem`
4651+
},
46414652
words: {
46424653
maxFontSize: 100,
46434654
minFontSize: FONT._10,

types/vue-data-ui.d.ts

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,18 @@ declare module "vue-data-ui" {
291291
strokeDasharray?: number;
292292
}
293293

294+
export type ChartZoomControls = {
295+
position?: 'top' | 'bottom';
296+
show?: boolean;
297+
backgroundColor?: string;
298+
buttonColor?: string;
299+
color?: string;
300+
fontSize?: number;
301+
border?: string;
302+
padding?: string;
303+
borderRadius?: string;
304+
}
305+
294306
export type ChartUserOptions = {
295307
show?: boolean;
296308
showOnChartHover?: boolean;
@@ -1541,7 +1553,8 @@ declare module "vue-data-ui" {
15411553
| "triangleInformation"
15421554
| "triangleExclamation"
15431555
| "direction"
1544-
| "chartDag";
1556+
| "chartDag"
1557+
| "revert";
15451558

15461559
export const VueUiIcon: DefineComponent<{
15471560
name: VueUiIconName;
@@ -7030,6 +7043,7 @@ declare module "vue-data-ui" {
70307043
height?: number;
70317044
width?: number;
70327045
zoom?: Omit<ChartZoom, "fontSize">;
7046+
controls?: ChartZoomControls;
70337047
words?: {
70347048
maxFontSize?: number;
70357049
minFontSize?: number;
@@ -9517,17 +9531,7 @@ declare module "vue-data-ui" {
95179531
color?: string;
95189532
};
95199533
};
9520-
controls?: {
9521-
position?: 'top' | 'bottom';
9522-
show?: boolean;
9523-
backgroundColor?: string;
9524-
buttonColor?: string;
9525-
color?: string;
9526-
fontSize?: number;
9527-
border?: string;
9528-
padding?: string;
9529-
borderRadius?: string;
9530-
};
9534+
controls?: ChartZoomControls;
95319535
zoom?: {
95329536
active?: boolean;
95339537
};
@@ -9724,17 +9728,7 @@ declare module "vue-data-ui" {
97249728
offsetY?: number;
97259729
};
97269730
};
9727-
controls?: {
9728-
position?: 'top' | 'bottom';
9729-
show?: boolean;
9730-
backgroundColor?: string;
9731-
buttonColor?: string;
9732-
color?: string;
9733-
fontSize?: number;
9734-
border?: string;
9735-
padding?: string;
9736-
borderRadius?: string;
9737-
};
9731+
controls?: ChartZoomControls;
97389732
title?: ChartTitle;
97399733
tooltip?: ChartTooltip;
97409734
zoom?: {

0 commit comments

Comments
 (0)