1+ <script setup>
2+ import { ref , computed } from " vue" ;
3+ import LocalVueUiScatter from ' ../src/components/vue-ui-scatter.vue' ;
4+ import LocalVueDataUi from ' ../src/components/vue-data-ui.vue' ;
5+ import Box from " ./Box.vue" ;
6+ import convertArrayToObject from " ./convertModel" ;
7+
8+ const scat1 = computed (() => {
9+ const arr = [];
10+ for (let i = - 100 ; i < 100 ; i += 1 ) {
11+ arr .push ({
12+ x: Math .random () * (Math .random () > 0.3 ? i / 3 : - i / 5 ),
13+ y: Math .random () * i / 20 ,
14+ name: ` plot_${ i} _cluster_1`
15+ });
16+ }
17+ return arr;
18+ });
19+
20+ const scat2 = computed (() => {
21+ const arr = [];
22+ for (let i = - 100 ; i < 100 ; i += 1 ) {
23+ arr .push ({
24+ x: Math .random () * (Math .random () > 0.1 ? i / 10 : - i / 10 ),
25+ y: Math .random () * i / 10 ,
26+ name: ` plot_${ i} _cluster_2`
27+ });
28+ }
29+ return arr;
30+ });
31+
32+ const dataset = computed (() => {
33+
34+ return [
35+ {
36+ name: " Cluster 1" ,
37+ values: scat1 .value ,
38+ shape: " star"
39+ },
40+ {
41+ name: " Cluster 2" ,
42+ values: scat2 .value ,
43+ shape: " triangle"
44+ }
45+ ]
46+ });
47+
48+ const model = ref ([
49+ { key: ' useCssAnimation' , def: true , type: ' checkbox' },
50+ { key: ' style.fontFamily' , def: " inherit" , type: ' text' },
51+ { key: ' style.backgroundColor' , def: ' #FFFFFF' , type: ' color' },
52+ { key: ' style.color' , def: ' #1A1A1A' , type: ' color' },
53+ { key: ' style.layout.useDiv' , def: true , type: ' checkbox' }, // DEPRECATED
54+ { key: ' style.layout.height' , def: 316 , type: ' number' , min: 100 , max: 1000 },
55+ { key: ' style.layout.width' , def: 512 , type: ' number' , min: 100 , max: 1000 },
56+ { key: ' style.layout.padding.top' , def: 36 , type: ' number' , min: 0 , max: 100 },
57+ { key: ' style.layout.padding.right' , def: 48 , type: ' number' , min: 0 , max: 100 },
58+ { key: ' style.layout.padding.bottom' , def: 36 , type: ' number' , min: 0 , max: 100 },
59+ { key: ' style.layout.padding.left' , def: 48 , type: ' number' , min: 0 , max: 100 },
60+ { key: ' style.layout.axis.show' , def: true , type: ' checkbox' },
61+ { key: ' style.layout.axis.stroke' , def: ' #e1e5e8' , type: ' color' },
62+ { key: ' style.layout.axis.strokeWidth' , def: 1 , type: ' number' , min: 0 , max: 12 },
63+ { key: ' style.layout.marginalBars.show' , def: true , type: ' checkbox' },
64+ { key: ' style.layout.marginalBars.size' , def: 40 , type: ' number' , min: 12 , max: 100 },
65+ { key: ' style.layout.marginalBars.tranches' , def: 20 , type: ' number' , min: 5 , max: 100 },
66+ { key: ' style.layout.marginalBars.opacity' , def: 0.6 , type: ' range' , min: 0 , max: 1 , step: 0.01 },
67+ { key: ' style.layout.marginalBars.fill' , def: ' #1A1A1A' , type: ' color' },
68+ { key: ' style.layout.marginalBars.strokeWidth' , def: 1 , type: ' number' , min: 0 , max: 12 },
69+ { key: ' style.layout.marginalBars.offset' , def: 20 , type: ' number' , min: 0 , max: 100 },
70+ { key: ' style.layout.marginalBars.borderRadius' , def: 2 , type: ' number' , min: 0 , max: 24 },
71+ { key: ' style.layout.marginalBars.useGradient' , def: true , type: ' checkbox' },
72+ { key: ' style.layout.marginalBars.showLines' , def: true , type: ' checkbox' },
73+ { key: ' style.layout.marginalBars.linesStrokeWidth' , def: 1 , type: ' number' , min: 0.5 , max: 12 , step: 0.5 },
74+ { key: ' style.layout.plots.radius' , def: 2 , type: ' number' , min: 0 , max: 24 },
75+ { key: ' style.layout.plots.stroke' , def: ' #FFFFFF' , type: ' color' },
76+ { key: ' style.layout.plots.strokeWidth' , def: 0.3 , type: ' range' , min: 0.1 , max: 12 , step: 0.1 },
77+ { key: ' style.layout.plots.opacity' , def: 0.6 , type: ' number' , min: 0 , max: 1 , step: 0.01 },
78+ { key: ' style.layout.plots.significance.show' , def: true , type: ' checkbox' },
79+ { key: ' style.layout.plots.significance.deviationThreshold' , def: 10 , type: ' number' , min: 0 , max: 100 },
80+ { key: ' style.layout.plots.significance.opacity' , def: 0.3 , type: ' number' , min: 0 , max: 1 , step: 0.01 },
81+ { key: ' style.layout.plots.deviation.translation' , def: ' deviation' , type: ' text' },
82+ { key: ' style.layout.plots.deviation.roundingValue' , def: 1 , type: ' number' , min: 0 , max: 12 },
83+ { key: ' style.layout.plots.giftWrap.show' , def: false , type: ' checkbox' },
84+ { key: ' style.layout.plots.giftWrap.strokeWidth' , def: 1 , type: ' number' , min: 0 , max: 12 },
85+ { key: ' style.layout.plots.giftWrap.strokeDasharray' , def: 0 , type: ' number' , min: 0 , max: 100 },
86+ { key: ' style.layout.plots.giftWrap.fillOpacity' , def: 0.2 , type: ' number' , min: 0 , max: 1 , step: 0.01 },
87+ { key: ' style.layout.correlation.show' , def: true , type: ' checkbox' },
88+ { key: ' style.layout.correlation.strokeDasharray' , def: 2 , type: ' number' , min: 0 , max: 100 },
89+ { key: ' style.layout.correlation.strokeWidth' , def: 1 , type: ' number' , min: 0 , max: 12 },
90+ { key: ' style.layout.correlation.label.show' , def: true , type: ' checkbox' },
91+ { key: ' style.layout.correlation.label.fontSize' , def: 12 , type: ' number' , min: 8 , max: 48 },
92+ { key: ' style.layout.correlation.label.color' , def: ' #1A1A1A' , type: ' color' },
93+ { key: ' style.layout.correlation.label.bold' , def: true , type: ' checkbox' },
94+ { key: ' style.layout.correlation.label.roundingValue' , def: 2 , type: ' number' , min: 0 , max: 12 },
95+ { key: ' style.layout.correlation.label.useSerieColor' , def: true , type: ' checkbox' },
96+ { key: ' style.layout.dataLabels.xAxis.name' , def: ' Lorem Ipsum X' , type: ' text' },
97+ { key: ' style.layout.dataLabels.xAxis.show' , def: true , type: ' checkbox' },
98+ { key: ' style.layout.dataLabels.xAxis.fontSize' , def: 8 , type: ' number' , min: 8 , max: 24 },
99+ { key: ' style.layout.dataLabels.xAxis.color' , def: ' #1A1A1A' , type: ' color' },
100+ { key: ' style.layout.dataLabels.xAxis.bold' , def: false , type: ' checkbox' },
101+ { key: ' style.layout.dataLabels.xAxis.offsetX' , def: 0 , type: ' number' , min: - 100 , max: 100 },
102+ { key: ' style.layout.dataLabels.xAxis.offsetY' , def: 0 , type: ' number' , min: - 100 , max: 100 },
103+ { key: ' style.layout.dataLabels.xAxis.roundingValue' , def: 2 , type: ' number' , min: 0 , max: 12 },
104+ { key: ' style.layout.dataLabels.yAxis.name' , def: ' Lorem Ipsum Y' , type: ' text' },
105+ { key: ' style.layout.dataLabels.yAxis.show' , def: true , type: ' checkbox' },
106+ { key: ' style.layout.dataLabels.yAxis.fontSize' , def: 8 , type: ' number' , min: 8 , max: 24 },
107+ { key: ' style.layout.dataLabels.yAxis.color' , def: ' #1A1A1A' , type: ' color' },
108+ { key: ' style.layout.dataLabels.yAxis.bold' , def: false , type: ' checkbox' },
109+ { key: ' style.layout.dataLabels.yAxis.offsetX' , def: 0 , type: ' number' , min: - 100 , max: 100 },
110+ { key: ' style.layout.dataLabels.yAxis.offsetY' , def: 0 , type: ' number' , min: - 100 , max: 100 },
111+ { key: ' style.layout.dataLabels.yAxis.roundingValue' , def: 2 , type: ' number' , min: 0 , max: 12 },
112+ { key: ' style.title.text' , def: ' At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis' , type: ' text' },
113+ { key: ' style.title.color' , def: ' #1A1A1A' , type: ' color' },
114+ { key: ' style.title.fontSize' , def: 20 , type: ' number' , min: 8 , max: 48 },
115+ { key: ' style.title.bold' , def: true , type: ' checkbox' },
116+ { key: ' style.title.subtitle.text' , def: ' At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis' , type: ' text' },
117+ { key: ' style.title.subtitle.color' , def: ' #CCCCCC' , type: ' color' },
118+ { key: ' style.title.subtitle.fontSize' , def: 16 , type: ' range' , min: 8 , max: 48 },
119+ { key: ' style.title.subtitle.bold' , def: false , type: ' checkbox' },
120+ { key: ' style.legend.show' , def: true , type: ' checkbox' },
121+ { key: ' style.legend.backgroundColor' , def: ' #FFFFFF' , type: ' color' },
122+ { key: ' style.legend.color' , def: ' #1A1A1A' , type: ' color' },
123+ { key: ' style.legend.fontSize' , def: 14 , type: ' number' , min: 6 , max: 42 },
124+ { key: ' style.legend.bold' , def: false , type: ' checkbox' },
125+ { key: ' style.legend.roundingValue' , def: 0 , type: ' number' , min: 0 , max: 6 },
126+ { key: ' style.tooltip.show' , def: true , type: ' checkbox' },
127+ { key: ' style.tooltip.backgroundColor' , def: ' #FFFFFF' , type: ' color' },
128+ { key: ' style.tooltip.color' , def: ' #1A1A1A' , type: ' color' },
129+ { key: ' style.tooltip.fontSize' , def: 14 , type: ' number' , min: 6 , max: 24 },
130+ { key: ' style.tooltip.showValue' , def: true , type: ' checkbox' },
131+ { key: ' style.tooltip.roundingValue' , def: 0 , type: ' number' , min: 0 , max: 6 },
132+ { key: ' style.tooltip.showShape' , def: true , type: ' checkbox' },
133+ { key: ' userOptions.show' , def: true , type: ' checkbox' },
134+ { key: ' table.show' , def: false , type: ' checkbox' , label: ' show' , category: ' table' },
135+ { key: ' table.responsiveBreakpoint' , def: 400 , type: ' number' , min: 300 , max: 800 },
136+ { key: ' table.th.backgroundColor' , def: ' #FFFFFF' , type: ' color' },
137+ { key: ' table.th.color' , def: ' #1A1A1A' , type: ' color' },
138+ { key: ' table.th.outline' , def: ' none' , type: ' text' },
139+ { key: ' table.td.backgroundColor' , def: ' #FFFFFF' , type: ' color' },
140+ { key: ' table.td.color' , def: ' #1A1A1A' , type: ' color' },
141+ { key: ' table.td.outline' , def: ' none' , type: ' text' },
142+ { key: ' table.td.roundingValue' , def: 2 , type: ' number' , min: 0 , max: 6 },
143+ { key: ' table.td.roundingAverage' , def: 1 , type: ' number' , min: 0 , max: 6 },
144+ { key: ' table.translations.correlationCoefficient' , def: ' Correlation coef.' , type: ' text' },
145+ { key: ' table.translations.nbrPlots' , def: ' Nbr plots' , type: ' text' },
146+ { key: ' table.translations.average' , def: ' Average' , type: ' text' },
147+ { key: ' table.translations.series' , def: ' Series' , type: ' text' }
148+ ])
149+
150+ const testCustomTooltip = ref (false );
151+
152+ const config = computed (() => {
153+ const c = convertArrayToObject (model .value );
154+ if (testCustomTooltip .value ) {
155+ return {
156+ ... c,
157+ style: {
158+ ... c .style ,
159+ tooltip: {
160+ ... c .style .tooltip ,
161+ customFormat : ({ datapoint }) => {
162+ let html = ' ' ;
163+ console .log (datapoint);
164+ return " test"
165+ }
166+ }
167+ }
168+
169+ }
170+ } else {
171+ return {
172+ ... c
173+ }
174+ }
175+ });
176+
177+ const step = ref (0 )
178+
179+ function selectLegend (legend ) {
180+ console .log ({legend})
181+ }
182+
183+ </script >
184+
185+ <template >
186+ <div style =" margin : 12px 0 " >
187+ <input type =" checkbox" v-model =" testCustomTooltip" id =" custom-tooltip" />
188+ <label for =" custom-tooltip" style =" color :#CCCCCC " >Test custom tooltip</label >
189+ </div >
190+
191+ <Box >
192+ <template #title >VueUiScatter</template >
193+
194+ <template #local >
195+ <LocalVueUiScatter :dataset =" dataset" :config =" config" :key =" `local_${step}`" >
196+ <template #svg =" { svg } " >
197+ <circle :cx =" svg.width / 2" :cy =" svg.height / 2" :r =" 30" fill =" #42d392" />
198+ <text :x =" svg.width / 2" :y =" svg.height / 2" text-anchor =" middle" >#SVG</text >
199+ </template >
200+ <template #legend =" { legend } " >
201+ #LEGEND
202+ <div style =" font-size : 8px " >
203+ {{ legend }}
204+ </div >
205+ </template >
206+ <template #tooltip-before =" { datapoint , seriesIndex , series , config , bars , lines , plots } " >
207+ #BEFORE {{ series.name }}
208+ </template >
209+ <template #tooltip-after =" { datapoint , seriesIndex , series , config , bars , lines , plots } " >
210+ #AFTER {{ series.name }}
211+ </template >
212+ </LocalVueUiScatter >
213+ </template >
214+
215+ <template #VDUI-local >
216+ <LocalVueDataUi component =" VueUiScatter" :dataset =" dataset" :config =" config" :key =" `VDUI-lodal_${step}`" >
217+ <template #svg =" { svg } " >
218+ <circle :cx =" svg.width / 2" :cy =" svg.height / 2" :r =" 30" fill =" #42d392" />
219+ <text :x =" svg.width / 2" :y =" svg.height / 2" text-anchor =" middle" >#SVG</text >
220+ </template >
221+ <template #legend =" { legend } " >
222+ #LEGEND
223+ <div style =" font-size : 8px " >
224+ {{ legend }}
225+ </div >
226+ </template >
227+ <template #tooltip-before =" { datapoint , seriesIndex , series , config , bars , lines , plots } " >
228+ #BEFORE {{ series.name }}
229+ </template >
230+ <template #tooltip-after =" { datapoint , seriesIndex , series , config , bars , lines , plots } " >
231+ #AFTER {{ series.name }}
232+ </template >
233+ </LocalVueDataUi >
234+ </template >
235+
236+ <template #build >
237+ <VueUiScatter :dataset =" dataset" :config =" config" :key =" `build_${step}`" >
238+ <template #svg =" { svg } " >
239+ <circle :cx =" svg.width / 2" :cy =" svg.height / 2" :r =" 30" fill =" #42d392" />
240+ <text :x =" svg.width / 2" :y =" svg.height / 2" text-anchor =" middle" >#SVG</text >
241+ </template >
242+ <template #legend =" { legend } " >
243+ #LEGEND
244+ <div style =" font-size : 8px " >
245+ {{ legend }}
246+ </div >
247+ </template >
248+ <template #tooltip-before =" { datapoint , seriesIndex , series , config , bars , lines , plots } " >
249+ #BEFORE {{ series.name }}
250+ </template >
251+ <template #tooltip-after =" { datapoint , seriesIndex , series , config , bars , lines , plots } " >
252+ #AFTER {{ series.name }}
253+ </template >
254+ </VueUiScatter >
255+ </template >
256+
257+ <template #VDUI-build >
258+ <VueDataUi component =" VueUiScatter" :dataset =" dataset" :config =" config" :key =" `VDUI-build_${step}`" >
259+ <template #svg =" { svg } " >
260+ <circle :cx =" svg.width / 2" :cy =" svg.height / 2" :r =" 30" fill =" #42d392" />
261+ <text :x =" svg.width / 2" :y =" svg.height / 2" text-anchor =" middle" >#SVG</text >
262+ </template >
263+ <template #legend =" { legend } " >
264+ #LEGEND
265+ <div style =" font-size : 8px " >
266+ {{ legend }}
267+ </div >
268+ </template >
269+ <template #tooltip-before =" { datapoint , seriesIndex , series , config , bars , lines , plots } " >
270+ #BEFORE {{ series.name }}
271+ </template >
272+ <template #tooltip-after =" { datapoint , seriesIndex , series , config , bars , lines , plots } " >
273+ #AFTER {{ series.name }}
274+ </template >
275+ </VueDataUi >
276+ </template >
277+
278+ <template #knobs >
279+ <div
280+ style =" display : flex ; flex-direction : row ; flex-wrap :wrap ; align-items :center ; width : 100% ; color : #CCCCCC ; gap :24px ;" >
281+ <div v-for =" knob in model" >
282+ <label style =" font-size : 10px " >{{ knob.key }}</label >
283+ <div
284+ style =" display :flex ; flex-direction :row ; flex-wrap : wrap ; align-items :center ; gap :6px ; height : 40px " >
285+ <input v-if =" !['none', 'select'].includes(knob.type)" :step =" knob.step" :type =" knob.type" :min =" knob.min ?? 0"
286+ :max =" knob.max ?? 0" v-model =" knob.def" @change =" step += 1" >
287+ <select v-if =" knob.type === 'select'" v-model =" knob.def" @change =" step += 1" >
288+ <option v-for =" opt in knob.options" >{{ opt }}</option >
289+ </select >
290+ </div >
291+ </div >
292+ </div >
293+ </template >
294+
295+ <template #config >
296+ {{ config }}
297+ </template >
298+ </Box >
299+ </template >
0 commit comments