Skip to content

Commit 4187b6d

Browse files
committed
. VueUiSparkHistogram add shapes
. VueUiScatter add shapes . VueUiScreenshot add component test
1 parent b4b2cc8 commit 4187b6d

File tree

9 files changed

+210
-35
lines changed

9 files changed

+210
-35
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "vue-data-ui",
33
"private": false,
4-
"version": "1.9.37",
4+
"version": "1.9.38",
55
"type": "module",
66
"description": "A user-empowering data visualization Vue components library",
77
"keywords": [

src/App.vue

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,21 +577,25 @@ const donutDataset = [
577577
name: "serie 1",
578578
color: "",
579579
values: [1],
580+
shape: "star"
580581
},
581582
{
582583
name: "serie 2",
583584
color: "",
584585
values: [2],
586+
shape: "diamond"
585587
},
586588
{
587589
name: "serie 3",
588590
color: "",
589591
values: [3],
592+
shape: "triangle"
590593
},
591594
{
592595
name: "serie 4",
593596
color: "",
594597
values: [3, 5],
598+
shape: "hexagon"
595599
},
596600
];
597601
@@ -726,6 +730,7 @@ const donutConfig = {
726730
};
727731
728732
const waffleConfig = ref({
733+
shape: 'triangle',
729734
style: {
730735
fontFamily: "inherit",
731736
chart: {
@@ -2440,10 +2445,12 @@ const scatterDataset = computed(() => {
24402445
{
24412446
name: "Cluster 1",
24422447
values: scat1.value,
2448+
shape: "star"
24432449
},
24442450
{
24452451
name: "Cluster 2",
24462452
values: scat2.value,
2453+
shape: "diamond"
24472454
},
24482455
];
24492456
});
@@ -3300,6 +3307,7 @@ const histoConfig = ref({
33003307
}
33013308
},
33023309
"bars": {
3310+
"shape": "star",
33033311
"strokeWidth": 0,
33043312
"colors": {
33053313
"positive": "#3366cc",
@@ -3548,6 +3556,15 @@ const donutEvolutionDataset = ref([
35483556
}
35493557
])
35503558
3559+
const screenshotTest = ref(null)
3560+
const screenshotProd = ref(null)
3561+
3562+
function shootScreenTest() {
3563+
screenshotTest.value.shoot();
3564+
}
3565+
function shootScreenProd() {
3566+
screenshotProd.value.shoot();
3567+
}
35513568
35523569
</script>
35533570

@@ -3578,7 +3595,23 @@ const donutEvolutionDataset = ref([
35783595
</template>
35793596
</Box>
35803597

3581-
<Box @copy="copyConfig(PROD_CONFIG.vue_ui_donut_evolution)" open>
3598+
<Box @copy="copyConfig(PROD_CONFIG.vue_ui_screenshot)">
3599+
<template #title>VueUiScreenshot</template>
3600+
<template #dev>
3601+
<ScreenshotTest ref="screenshotTest"/>
3602+
<button class="btn--orange" @click="shootScreenTest">SCREENSHOT</button>
3603+
</template>
3604+
<template #prod>
3605+
<VueUiScreenshot ref="screenshotProd"/>
3606+
<button class="btn--green" @click="shootScreenProd">SCREENSHOT</button>
3607+
</template>
3608+
<template #config>
3609+
{{ PROD_CONFIG.vue_ui_screenshot }}
3610+
</template>
3611+
3612+
</Box>
3613+
3614+
<Box @copy="copyConfig(PROD_CONFIG.vue_ui_donut_evolution)">
35823615
<template #title>VueUiDonutEvolution</template>
35833616
<template #dev>
35843617
<DonutEvolutionTest
@@ -3590,6 +3623,9 @@ const donutEvolutionDataset = ref([
35903623
:dataset="donutEvolutionDataset"
35913624
/>
35923625
</template>
3626+
<template #config>
3627+
{{ PROD_CONFIG.vue_ui_donut_evolution }}
3628+
</template>
35933629
</Box>
35943630

35953631
<Box @copy="copyConfig(PROD_CONFIG.vue_ui_tiremarks)">
@@ -4253,3 +4289,31 @@ const donutEvolutionDataset = ref([
42534289
<img v-if="pic" :src="pic" />
42544290
</div>
42554291
</template>
4292+
4293+
<style scoped>
4294+
.btn--green,
4295+
.btn--orange {
4296+
border: none;
4297+
height: 40px;
4298+
cursor: pointer;
4299+
border-radius: 6px;
4300+
padding: 0 12px;
4301+
box-shadow: 0 6px 12px -6px rgba(0, 0,0,0.6);
4302+
color: white;
4303+
font-weight: bold;
4304+
4305+
}
4306+
.btn--green {
4307+
background: linear-gradient(to bottom right, #42d392, #42d392AA);
4308+
}
4309+
4310+
.btn--green:hover {
4311+
background: linear-gradient(to top left, #42d392, #42d392AA);
4312+
}
4313+
.btn--orange {
4314+
background: linear-gradient(to bottom right, #ff6400, #ff6400AA);
4315+
}
4316+
.btn--orange:hover {
4317+
background: linear-gradient(to top left, #ff6400, #ff6400AA);
4318+
}
4319+
</style>

src/components/vue-ui-scatter.vue

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import Title from "../atoms/Title.vue";
99
import UserOptions from "../atoms/UserOptions.vue";
1010
import Tooltip from "../atoms/Tooltip.vue";
1111
import Legend from "../atoms/Legend.vue";
12-
import BaseCheckbox from "../atoms/BaseCheckbox.vue";
12+
import Shape from "../atoms/Shape.vue";
1313
1414
const props = defineProps({
1515
config: {
@@ -102,7 +102,7 @@ const datasetWithId = computed(() => {
102102
id,
103103
color: ds.color ? ds.color : (palette[i] || palette[i % palette.length]),
104104
opacity: segregated.value.includes(id) ? 0.5: 1,
105-
shape: 'circle'
105+
shape: ds.shape ?? 'circle'
106106
}
107107
})
108108
})
@@ -185,7 +185,9 @@ const drawableDataset = computed(() => {
185185
const deviation = Math.sqrt(Math.pow(plot.x - x_proj, 2) + Math.pow(plot.y - y_proj, 2));
186186
return {
187187
...plot,
188-
deviation
188+
deviation,
189+
shape: ds.shape,
190+
color: ds.color
189191
}
190192
})
191193
}
@@ -197,13 +199,15 @@ function getData() {
197199
}
198200
199201
const selectedPlotId = ref(undefined);
202+
const selectedPlot = ref(null);
200203
201204
function hoverPlot(plot) {
202205
selectedPlotId.value = plot.id;
206+
selectedPlot.value = plot;
203207
let html = "";
204208
205209
if (plot.clusterName) {
206-
html += `<div style="display:flex;gap:3px;align-items:center"><svg viewBox="0 0 12 12" height="${scatterConfig.value.style.tooltip.fontSize}" width="${scatterConfig.value.style.tooltip.fontSize}"><circle cx="6" cy="6" r="6" stroke="none" fill="${plot.color}"/></svg>${plot.clusterName}</div>`
210+
html += `<div style="display:flex;gap:3px;align-items:center">${plot.clusterName}</div>`
207211
}
208212
209213
if (plot.v.name) {
@@ -222,7 +226,8 @@ function hoverPlot(plot) {
222226
223227
function clearHover() {
224228
isTooltip.value = false;
225-
selectedPlotId.value = undefined
229+
selectedPlotId.value = undefined;
230+
selectedPlot.value = null;
226231
}
227232
228233
const segregated = ref([]);
@@ -403,19 +408,36 @@ defineExpose({
403408
404409
<!-- PLOTS -->
405410
<g v-for="(ds, i) in drawableDataset">
406-
<circle
407-
v-for="(plot, j) in ds.plots"
408-
:data-cy="`scatter-plot-${i}-${j}`"
409-
:cx="plot.x"
410-
:cy="plot.y"
411-
:r="selectedPlotId && selectedPlotId === plot.id ? scatterConfig.style.layout.plots.radius * 2 : scatterConfig.style.layout.plots.radius"
412-
:fill="`${ds.color}${opacity[scatterConfig.style.layout.plots.opacity * 100]}`"
413-
:stroke="scatterConfig.style.layout.plots.stroke"
414-
:stroke-width="scatterConfig.style.layout.plots.strokeWidth"
415-
@mouseover="hoverPlot(plot)"
416-
@mouseleave="clearHover"
417-
:style="`opacity:${scatterConfig.style.layout.plots.significance.show && Math.abs(plot.deviation) > scatterConfig.style.layout.plots.significance.deviationThreshold ? scatterConfig.style.layout.plots.significance.opacity : 1}`"
418-
/>
411+
<g v-if="!ds.shape || ds.shape === 'circle'">
412+
<circle
413+
v-for="(plot, j) in ds.plots"
414+
:data-cy="`scatter-plot-${i}-${j}`"
415+
:cx="plot.x"
416+
:cy="plot.y"
417+
:r="selectedPlotId && selectedPlotId === plot.id ? scatterConfig.style.layout.plots.radius * 2 : scatterConfig.style.layout.plots.radius"
418+
:fill="`${ds.color}${opacity[scatterConfig.style.layout.plots.opacity * 100]}`"
419+
:stroke="scatterConfig.style.layout.plots.stroke"
420+
:stroke-width="scatterConfig.style.layout.plots.strokeWidth"
421+
@mouseover="hoverPlot(plot)"
422+
@mouseleave="clearHover"
423+
:style="`opacity:${scatterConfig.style.layout.plots.significance.show && Math.abs(plot.deviation) > scatterConfig.style.layout.plots.significance.deviationThreshold ? scatterConfig.style.layout.plots.significance.opacity : 1}`"
424+
/>
425+
</g>
426+
<g v-else>
427+
<Shape
428+
v-for="(plot, j) in ds.plots"
429+
:data-cy="`scatter-plot-${i}-${j}`"
430+
:plot="{x: plot.x, y: plot.y }"
431+
:radius="selectedPlotId && selectedPlotId === plot.id ? scatterConfig.style.layout.plots.radius * 2 : scatterConfig.style.layout.plots.radius"
432+
:shape="ds.shape"
433+
:color="`${ds.color}${opacity[scatterConfig.style.layout.plots.opacity * 100]}`"
434+
:stroke="scatterConfig.style.layout.plots.stroke"
435+
:strokeWidth="scatterConfig.style.layout.plots.strokeWidth"
436+
@mouseover="hoverPlot(plot)"
437+
@mouseleave="clearHover"
438+
:style="`opacity:${scatterConfig.style.layout.plots.significance.show && Math.abs(plot.deviation) > scatterConfig.style.layout.plots.significance.deviationThreshold ? scatterConfig.style.layout.plots.significance.opacity : 1}`"
439+
/>
440+
</g>
419441
</g>
420442
421443
<!-- AXIS LABELS -->
@@ -568,7 +590,18 @@ defineExpose({
568590
:color="scatterConfig.style.tooltip.color"
569591
:parent="scatterChart"
570592
:content="tooltipContent"
571-
/>
593+
>
594+
<div style="width: 100%; display: flex; align-items:center;justify-content:center;">
595+
<svg viewBox="0 0 20 20" height="20" width="20" style="overflow: hidden;background:transparent;">
596+
<Shape
597+
:shape="selectedPlot.shape"
598+
:color="selectedPlot.color"
599+
:plot="{x: 10, y: 10}"
600+
:radius="7"
601+
/>
602+
</svg>
603+
</div>
604+
</Tooltip>
572605
573606
<!-- DATA TABLE -->
574607
<div :style="`${isPrinting ? '' : 'max-height:400px'};overflow:auto;width:100%;margin-top:${mutableConfig.inside ? '48px' : ''}`" v-if="mutableConfig.showTable">
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { createApp } from 'vue';
2+
import VueUiScreenshot from './vue-ui-screenshot.vue'
3+
4+
describe('<VueUiScreenshot />', () => {
5+
6+
function redraw() {
7+
cy.mount(VueUiScreenshot).then((comp) => {
8+
const { wrapper } = comp;
9+
wrapper.componentVM.shoot();
10+
})
11+
}
12+
13+
it('renders', () => {
14+
cy.document().then((doc) => {
15+
const div = doc.createElement('div');
16+
div.style.height="400px";
17+
div.style.width = "400px";
18+
div.style.background="rgba(0,0,0,0.3)";
19+
doc.body.appendChild(div)
20+
21+
const app = createApp(VueUiScreenshot);
22+
23+
app.mount(div);
24+
redraw();
25+
const text = doc.createElement('div');
26+
text.innerHTML = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque vel urna luctus, cursus sapien at, ultrices lectus. Nunc id maximus turpis. Nullam turpis ipsum, fermentum quis erat sed, consectetur ultrices nunc. Nunc sed nisl sit amet dui eleifend blandit vitae a purus. Praesent congue rutrum viverra. Donec sit amet est consectetur, condimentum ipsum nec, egestas magna. Etiam at mi a mauris laoreet consequat quis sit amet leo. Phasellus id consequat nunc. Phasellus odio sapien, mollis sit amet nisi at, euismod bibendum ipsum. Quisque viverra vel nisi at venenatis.
27+
28+
Maecenas nulla massa, aliquet vitae posuere eu, pellentesque ac tortor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam eget quam porta, pretium odio vitae, egestas purus. In hac habitasse platea dictumst. Fusce dignissim urna a lacus sagittis, a ullamcorper dolor facilisis. Sed nec mattis eros. Nullam a euismod sapien. Donec viverra lacus porta dui euismod porttitor.
29+
30+
Maecenas mollis dictum turpis. In porttitor magna in ante euismod, eu feugiat ex ullamcorper. Proin semper bibendum nisl, a sagittis dui pellentesque at. Maecenas vitae ligula cursus, fermentum sem id, finibus dolor. Etiam luctus augue nec pharetra elementum. Donec id odio ut risus fringilla hendrerit non sit amet tortor. Donec.`;
31+
div.appendChild(text);
32+
33+
cy.get(`[data-cy="screenshot-info-text"]`).then(($info) => {
34+
cy.wrap($info).should('exist').contains('Resize or move and click to capture')
35+
})
36+
37+
cy.get(`[data-cy="screenshot-overlay"]`).should('exist').trigger('mousedown').trigger('mousemove', {clientX: 100, clientY: 100})
38+
39+
cy.get(`[data-cy="screenshot-handle-nw"]`).should('exist')
40+
cy.get(`[data-cy="screenshot-handle-ne"]`).should('exist')
41+
cy.get(`[data-cy="screenshot-handle-sw"]`).should('exist')
42+
cy.get(`[data-cy="screenshot-handle-se"]`).should('exist')
43+
44+
cy.get(`[data-cy="screenshot-save-button"]`).should('exist').contains('capture').click()
45+
cy.readFile(`cypress\\Downloads\\screenshot.png`);
46+
cy.get(`[data-cy="screenshot-overlay"]`).should('not.exist')
47+
redraw();
48+
cy.get(`[data-cy="screenshot-close-button"]`).should('exist').click();
49+
cy.get(`[data-cy="screenshot-overlay"]`).should('not.exist')
50+
redraw();
51+
cy.clearDownloads();
52+
});
53+
54+
})
55+
})

0 commit comments

Comments
 (0)