Skip to content

Commit c2c98bb

Browse files
authored
Merge pull request #209 from graphieros/ft-vue-ui-chord
Ft vue UI chord
2 parents 148b115 + 9bfe239 commit c2c98bb

19 files changed

+2061
-247
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# vue-data-ui
88

99
[![npm](https://img.shields.io/npm/v/vue-data-ui)](https://github.com/graphieros/vue-data-ui)
10-
[![Static Badge](https://img.shields.io/badge/components-62-blue)](https://github.com/graphieros/vue-data-ui)
10+
[![Static Badge](https://img.shields.io/badge/components-63-blue)](https://github.com/graphieros/vue-data-ui)
1111
[![GitHub issues](https://img.shields.io/github/issues/graphieros/vue-data-ui)](https://github.com/graphieros/vue-data-ui/issues)
1212
[![License](https://img.shields.io/badge/license-MIT-green)](https://github.com/graphieros/vue-data-ui?tab=MIT-1-ov-file#readme)
1313
[![MadeWithVueJs.com shield](https://madewithvuejs.com/storage/repo-shields/4526-shield.svg)](https://madewithvuejs.com/p/vue-data-ui/shield-link)
@@ -24,6 +24,7 @@ Available components
2424
- [VueUiAgePyramid](https://vue-data-ui.graphieros.com/docs#vue-ui-age-pyramid)
2525
- [VueUiCandlestick](https://vue-data-ui.graphieros.com/docs#vue-ui-candlestick)
2626
- [VueUiChestnut](https://vue-data-ui.graphieros.com/docs#vue-ui-chestnut)
27+
- [VueUiChord](https://vue-data-ui.graphieros.com/docs#vue-ui-chord)
2728
- [VueUiCirclePack](https://vue-data-ui.graphieros.com/docs#vue-ui-circle-pack)
2829
- [VueUiDonutEvolution](https://vue-data-ui.graphieros.com/docs#vue-ui-donut-evolution)
2930
- [VueUiDonut](https://vue-data-ui.graphieros.com/docs#vue-ui-donut)
@@ -429,6 +430,7 @@ From the dataset you pass into the props, this component will produce the most a
429430
| `VueUiAgePyramid` | `Array<Array<string / number>>` | `VueUiSparklineConfig` | `generatePdf`, `generateImage`, `generateCsv`, `toggleTable`, `toggleTooltip` | `#svg`, `#legend`, `#tooltip-before`, `#tooltip-after`, `#watermark`, `#chart-background` |||
430431
| `VueUiCandlestick` | `Array<Array<string / number>>` | `VueUiCandlestickConfig` | `generatePdf`, `generateImage`, `generateCsv`, `toggleTable`, `toggleTooltip` | `#svg`, `#legend`, `#tooltip-before`, `#tooltip-after`, `#reset-action`, `#watermark`, `#chart-background` |||
431432
| `VueUiChestnut` | `VueUiChestnutDatasetRoot[]` | `VueUiChestnutConfig` | `@selectRoot`, `@selectBranch`, `@selectNut`, `getData`, `generatePdf`, `generateCsv`, `generateImage`, `toggleTable` | `#svg`, `#legend`, `#watermark`, `#chart-background` |||
433+
| `VueUiChord` | `VueUiChordDataset` | `VueUiChordConfig` | `@selectLegend`, `@selectGroup`, `@selectRibbon`, `getData`, `generatePdf`, `generateCsv`, `generateImage`, `toggleTable` | `#svg`, `#legend`, `#watermark`, `#chart-background`, `#pattern` |||
432434
| `VueUiCirclePack` | `VueUiCirclePackDatasetItem[]` | `VueUiCirclePackConfig` | `@selectDatapoint`, `getData`, `generatePdf`, `generateImage`, `generateCsv`, `toggleTable` | `#svg`, `#legend`, `#watermark`, `#chart-background` , `#pattern`, `#zoom-label`, `#data-label` |||
433435
| `VueUiDonutEvolution` | `VueUiDonutEvolutionDatasetItem[]` | `VueUiDonutEvolutionConfig` | `@selectLegend`, `getData`, `generatePdf`, `generateCsv`, `generateImage`, `toggleTable` | `#svg`, `#legend`, `#reset-action`, `#watermark`, `#chart-background` |||
434436
| `VueUiDonut` | `VueUiDonutDatasetItem[]` | `VueUiDonutConfig` | `@selectDatapoint`, `@selectLegend`, `getData`, `generatePdf`, `generateCsv`, `generateImage`, `toggleTable`, `toggleLabels`, `toggleTooltip` | `#svg`, `#legend`, `#dataLabel`, `#tooltip-before`, `#tooltip-after`, `#plot-comment`, `#watermark`, `#chart-background`, `#pattern` |||
@@ -583,6 +585,7 @@ User options actions available per chart:
583585
| VueUiCandlestick | optionTooltip, optionPdf, optionImg, optionCsv, optionTable, optionFullscreen, optionAnnotator |
584586
| VueUiCarouselTable | optionPdf, optionImg, optionCsv, optionAnimation, optionFullscreen |
585587
| VueUiChestnut | optionPdf, optionImg, optionCsv, optionTable, optionFullscreen, optionAnnotator |
588+
| VueUiChord | optionPdf, optionImg, optionCsv, optionTable, optionFullscreen, optionAnnotator |
586589
| VueUiCirclePack | optionPdf, optionImg, optionCsv, optionTable, optionFullscreen, optionAnnotator |
587590
| VueUiDonut | optionTooltip, optionPdf, optionImg, optionCsv, optionTable, optionLabels, optionFullscreen, optionAnnotator |
588591
| VueUiDonutEvolution | optionPdf, optionImg, optionCsv, optionTable, optionFullscreen, optionAnnotator |
@@ -640,6 +643,7 @@ It is possible to provide a custom palette in the config prop through config.cus
640643

641644
- VueUi3dBar
642645
- VueUiChestnut
646+
- VueUiChord
643647
- VueUiCirclePack
644648
- VueUiDonut
645649
- VueUiDonutEvolution
@@ -688,6 +692,7 @@ However the folowing charts can be made fully responsive, making them better to
688692
| VueUiBullet | - |
689693
| VueUiCarouselTable | - |
690694
| VueUiChestnut | - |
695+
| VueUiChord ||
691696
| VueUiCirclePack | - |
692697
| VueUiDonut ||
693698
| VueUiDonutEvolution | - |
@@ -824,6 +829,7 @@ A pattern element must be used inside this slot. It will be injected inside a de
824829

825830
The #pattern slot is available on the following components:
826831

832+
- VueUiChord
827833
- VueUiCirclePack
828834
- VueUiDonut
829835
- VueUiGauge

TestingArena/ArenaVueUiChord.vue

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
<script setup>
2+
import { ref, computed } from "vue";
3+
import LocalVueUiChord from '../src/components/vue-ui-chord.vue';
4+
import LocalVueDataUi from '../src/components/vue-data-ui.vue';
5+
import Box from "./Box.vue";
6+
import convertArrayToObject from "./convertModel";
7+
import { useArena } from "../src/useArena";
8+
9+
const { local, build, vduiLocal, vduiBuild, toggleTable } = useArena()
10+
11+
const dataset = ref({
12+
matrix: [
13+
[ 12000, 6000, 9000, 3000],
14+
[ 2000, 10000, 2000, 6001],
15+
[ 8000, 1600, 8000, 8001],
16+
[ 1000, 1000, 1000, 7001]
17+
],
18+
labels: ['Group A', 'Group B with a long name', 'Group C', 'Group D'],
19+
colors: []
20+
})
21+
22+
const model = ref([
23+
{ key: 'responsive', def: false, type: 'checkbox' },
24+
{ key: 'enableRotation', def: true, type: 'checkbox'},
25+
{ key: 'initialRotation', def: 0, type: 'number', min: 0, max: 360},
26+
{ key: 'useCssAnimation', def: true, type: 'checkbox'},
27+
28+
{ key: 'style.chart.title.text', def: 'Title', type: 'text', label: 'textContent', category: 'title' },
29+
{ key: 'style.chart.title.color', def: '#1A1A1A', type: 'color', label: 'textColor', category: 'title' },
30+
{ key: 'style.chart.title.fontSize', def: 20, type: 'number', min: 6, max: 48, label: 'fontSize', category: 'title' },
31+
{ key: 'style.chart.title.bold', def: true, type: 'checkbox', label: 'bold', category: 'title' },
32+
{ key: 'style.chart.title.textAlign', def: 'center', type: 'select', options: ['left', 'center', 'right']},
33+
{ key: 'style.chart.title.paddingLeft', def: 0, type: 'number', min: 0, max: 24 },
34+
{ key: 'style.chart.title.paddingRight', def: 0, type: 'number', min: 0, max: 24 },
35+
36+
{ key: 'style.chart.title.subtitle.text', def: 'Lorem ipsum dolor sit amet', type: 'text', label: 'textContent', category: 'subtitle' },
37+
{ key: 'style.chart.title.subtitle.color', def: '#A1A1A1', type: 'color', label: 'textColor', category: 'subtitle' },
38+
{ key: 'style.chart.title.subtitle.fontSize', def: 16, type: 'number', min: 6, max: 42, label: 'fontSize', category: 'subtitle' },
39+
{ key: 'style.chart.title.subtitle.bold', def: false, type: 'checkbox', label: 'bold', category: 'subtitle' },
40+
41+
{ key: 'style.chart.backgroundColor', def: '#FFFFFF', type: 'color'},
42+
{ key: 'style.chart.color', def: '#1A1A1A', type: 'color'},
43+
44+
{ key: 'style.chart.legend.show', def: true, type: 'checkbox'},
45+
{ key: 'style.chart.legend.backgroundColor', def: '#FFFFFF', type: 'color'},
46+
{ key: 'style.chart.legend.color', def: '#1A1A1A', type: 'color'},
47+
{ key: 'style.chart.legend.fontSize', def: 14, type: 'number', min: 8, max: 42},
48+
{ key: 'style.chart.legend.bold', def: false, type: 'checkbox'},
49+
50+
{ key: 'style.chart.arcs.innerRadiusRatio', def: 1, type: 'number', min: 0.1, max: 1.5, step: 0.1 },
51+
{ key: 'style.chart.arcs.outerRadiusRatio', def: 1, type: 'number', min: 0.1, max: 1.5, step: 0.1 },
52+
{ key: 'style.chart.arcs.padAngle', def: 5, type: 'number', min: 0, max: 48 },
53+
{ key: 'style.chart.arcs.stroke', def: '#FFFFFF', type: 'color'},
54+
{ key: 'style.chart.arcs.strokeWidth', def: 1, min: 1, max:12, type: 'number'},
55+
56+
{ key: 'style.chart.arcs.labels.show', def: true, type: 'checkbox'},
57+
{ key: 'style.chart.arcs.labels.fontSize', def: 14, type: 'number', min: 8, max: 42},
58+
{ key: 'style.chart.arcs.labels.bold', def: false, type: 'checkbox'},
59+
{ key: 'style.chart.arcs.labels.curved', def: false, type: 'checkbox'},
60+
{ key: 'style.chart.arcs.labels.adaptColorToBackground', def: true, type: 'checkbox'},
61+
{ key: 'style.chart.arcs.labels.color', def: '#1A1A1A', type: 'color'},
62+
{ key: 'style.chart.arcs.labels.offset', def: 0, type: 'number', min: -100, max: 100},
63+
64+
{ key: 'style.chart.ribbons.stroke', def: '#FFFFFF', type: 'color'},
65+
{ key: 'style.chart.ribbons.strokeWidth', def: 1, type: 'number', min: 0, max: 12},
66+
{ key: 'style.chart.ribbons.underlayerOpacity', def: 1, type: 'range', min: 0, max: 1, step: 0.01},
67+
{ key: 'style.chart.ribbons.labels.show', def: true, type: 'checkbox'},
68+
{ key: 'style.chart.ribbons.labels.prefix', def: 'P', type: 'text'},
69+
{ key: 'style.chart.ribbons.labels.suffix', def: 'S', type: 'text'},
70+
{ key: 'style.chart.ribbons.labels.rounding', def: 0, min: 0, max: 6, type: 'number'},
71+
{ key: 'style.chart.ribbons.labels.fontSize', def: 14, type: 'number', min: 8, max: 42},
72+
{ key: 'style.chart.ribbons.labels.bold', def: false, type: 'checkbox'},
73+
{ key: 'style.chart.ribbons.labels.useSerieColor', def: false, type: 'checkbox'},
74+
{ key: 'style.chart.ribbons.labels.color', def: '#1A1A1A', type: 'color'},
75+
{ key: 'style.chart.ribbons.labels.offset', def: 0, type: 'number', min: -100, max: 100},
76+
{ key: 'style.chart.ribbons.labels.minSeparationDeg', def: 3, type: 'number', min: 0, max: 24},
77+
{ key: 'style.chart.ribbons.labels.connector.stroke', def: '#1A1A1A', type: 'color'},
78+
{ key: 'style.chart.ribbons.labels.connector.strokeWidth', def: 1, type: 'number', min: 0, max: 12},
79+
{ key: 'style.chart.ribbons.labels.marker.show', def: true, type: 'checkbox'},
80+
{ key: 'style.chart.ribbons.labels.marker.radius', def: 3, type: 'number', min: 0, max: 12},
81+
{ key: 'style.chart.ribbons.labels.marker.stroke', def: '#FFFFFF', type: 'color'},
82+
{ key: 'style.chart.ribbons.labels.marker.strokeWidth', def: 1, type: 'number', min: 0, max: 12}
83+
])
84+
85+
const themeOptions = ref([
86+
"",
87+
"hack",
88+
"zen",
89+
"concrete",
90+
"default",
91+
"celebration",
92+
"celebrationNight"
93+
])
94+
95+
const currentTheme = ref(themeOptions.value[0])
96+
97+
98+
const config = computed(()=> {
99+
const c = convertArrayToObject(model.value);
100+
return {
101+
...c,
102+
theme: currentTheme.value
103+
}
104+
})
105+
106+
</script>
107+
108+
<template>
109+
<div style="margin: 12px 0; color: white">
110+
Theme:
111+
<select v-model="currentTheme" @change="step += 1">
112+
<option v-for="opt in themeOptions">{{ opt }}</option>
113+
</select>
114+
</div>
115+
116+
<div style="width: 600px; height: 600px; resize: both; overflow: auto; background: white">
117+
<LocalVueUiChord
118+
:dataset="dataset"
119+
:config="{
120+
...config,
121+
responsive: true
122+
}"/>
123+
</div>
124+
125+
<Box>
126+
<template #title>VueUiChord</template>
127+
128+
<template #local>
129+
<LocalVueUiChord :dataset="dataset" :config="config" ref="local">
130+
<!-- <template #pattern="{ seriesIndex, patternId }">
131+
<pattern v-if="seriesIndex === 0" :id="patternId" width="70" height="8" patternTransform="scale(2)" patternUnits="userSpaceOnUse"><rect width="100%" height="100%" fill="#2b2b3100"/><path fill="none" stroke="#1A1A1A" d="M-.02 22c8.373 0 11.938-4.695 16.32-9.662C20.785 7.258 25.728 2 35 2s14.215 5.258 18.7 10.338C58.082 17.305 61.647 22 70.02 22M-.02 14.002C8.353 14 11.918 9.306 16.3 4.339 20.785-.742 25.728-6 35-6S49.215-.742 53.7 4.339c4.382 4.967 7.947 9.661 16.32 9.664M70 6.004c-8.373-.001-11.918-4.698-16.3-9.665C49.215-8.742 44.272-14 35-14S20.785-8.742 16.3-3.661C11.918 1.306 8.353 6-.02 6.002"/></pattern>
132+
133+
<pattern v-if="seriesIndex === 1" :id="patternId" width="29" height="50.115" patternTransform="scale(2)" patternUnits="userSpaceOnUse"><rect width="100%" height="100%" fill="#2b2b31"/><path fill="none" stroke="#ecc94b" stroke-linecap="square" stroke-width=".5" d="M14.5 6.628 8.886 3.372v-6.515L14.502-6.4l5.612 3.257-.001 6.514zm0 50.06-5.613-3.256v-6.515l5.614-3.258 5.612 3.257-.001 6.515zm14.497-25.117-5.612-3.257v-6.515L29 18.541l5.612 3.257-.001 6.515zm-29 0-5.612-3.257v-6.515L0 18.541l5.612 3.257v6.515zM14.5 11.82 4.36 5.967l.002-11.706 10.14-5.855L24.638-5.74l-.001 11.707zm0 50.06L4.36 56.028l.002-11.706 10.14-5.855 10.137 5.852-.001 11.707zm14.498-25.118-10.14-5.852.002-11.707L29 13.349l10.137 5.853-.001 11.706zm-29 0-10.139-5.852.002-11.707L0 13.349l10.138 5.853-.002 11.706zm14.501-19.905L0 8.488.002-8.257l14.5-8.374L29-8.26l-.002 16.745zm0 50.06L0 58.548l.002-16.745 14.5-8.373L29 41.8l-.002 16.744zM28.996 41.8l-14.498-8.37.002-16.744L29 8.312l14.498 8.37-.002 16.745zm-29 0-14.498-8.37.002-16.744L0 8.312l14.498 8.37-.002 16.745z"/></pattern>
134+
</template> -->
135+
</LocalVueUiChord>
136+
</template>
137+
138+
<template #VDUI-local>
139+
<LocalVueDataUi component="VueUiChord" :dataset="dataset" :config="config" ref="vduiLocal"/>
140+
</template>
141+
142+
<template #build>
143+
<VueUiChord :dataset="dataset" :config="config" ref="build"/>
144+
</template>
145+
146+
<template #VDUI-build>
147+
<VueDataUi component="VueUiChord" :dataset="dataset" :config="config" ref="vduiBuild"/>
148+
</template>
149+
150+
<template #knobs>
151+
<div
152+
style="display: flex; flex-direction: row; flex-wrap:wrap; align-items:center; width: 100%; color: #CCCCCC; gap:24px;">
153+
<div v-for="knob in model">
154+
<label style="font-size: 10px">{{ knob.key }}</label>
155+
<div
156+
style="display:flex; flex-direction:row; flex-wrap: wrap; align-items:center; gap:6px; height: 40px">
157+
<input v-if="!['none', 'select'].includes(knob.type)" :step="knob.step" :type="knob.type" :min="knob.min ?? 0"
158+
:max="knob.max ?? 0" v-model="knob.def" @change="step += 1">
159+
<select v-if="knob.type === 'select'" v-model="knob.def" @change="step += 1">
160+
<option v-for="opt in knob.options">{{ opt }}</option>
161+
</select>
162+
</div>
163+
</div>
164+
</div>
165+
</template>
166+
167+
<template #config>
168+
{{ config }}
169+
</template>
170+
</Box>
171+
</template>

0 commit comments

Comments
 (0)