Skip to content

Commit 6b71d84

Browse files
committed
Merge branch 'main' into demo
2 parents 4603c64 + cdcef8c commit 6b71d84

79 files changed

Lines changed: 2442 additions & 1058 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
## Usage
66

7+
### ES Module (Vue SFC)
8+
79
```vue
810
<template>
9-
<VVPlot :data="data">
11+
<VVPlot :data="data" :width="600" :height="400">
1012
<VVGeomPoint :x="d => d.x" :y="d => d.y" />
1113
</VVPlot>
1214
</template>
@@ -18,6 +20,37 @@ const data = [{ x: 1, y: 2 }, { x: 2, y: 3 }, { x: 3, y: 5 }]
1820
</script>
1921
```
2022

23+
### CDN
24+
25+
```html
26+
<html>
27+
<head>
28+
<link rel="stylesheet" href="https://unpkg.com/vvplot@latest/dist/style.css">
29+
</head>
30+
<body>
31+
<div id="plot"></div>
32+
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
33+
<script src="https://unpkg.com/vvplot@latest/dist/vvplot.global.js"></script>
34+
<script>
35+
const { createApp, ref } = Vue
36+
const { components } = VVPlot
37+
const data = [{ x: 1, y: 2 }, { x: 2, y: 3 }, { x: 3, y: 5 }]
38+
let template = `<VVPlot :data="data" :width="600" :height="400">
39+
<VVGeomPoint :x="d => d.x" :y="d => d.y" />
40+
</VVPlot>`
41+
let app = createApp({
42+
setup() { return { data } },
43+
template
44+
})
45+
for (let c in components) {
46+
app.component(c, components[c])
47+
}
48+
app.mount('#plot')
49+
</script>
50+
</body>
51+
</html>
52+
```
53+
2154
## Development
2255

2356
`node` and `npm` are required for development.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vvplot",
3-
"version": "0.2.0",
3+
"version": "0.3.0",
44
"license": "MIT",
55
"files": [
66
"dist"
@@ -29,6 +29,7 @@
2929
},
3030
"dependencies": {
3131
"@vueuse/core": "^13.7.0",
32+
"commonmark": "^0.31.2",
3233
"d3": "^7.9.0",
3334
"vue": "^3.5.18"
3435
},
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script>
2+
export default {
3+
$_props: {
4+
geom: 'ellipse',
5+
stat: 'ellipse',
6+
},
7+
$_type: 'layer',
8+
$_argnames: ["CI"]
9+
}
10+
</script>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script>
2+
export default {
3+
$_props: {
4+
geom: 'markdown',
5+
stat: 'text',
6+
},
7+
$_type: 'layer'
8+
}
9+
</script>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script>
2+
export default {
3+
$_props: {
4+
geom: 'markdownsegment',
5+
stat: 'textsegment',
6+
},
7+
$_type: 'layer'
8+
}
9+
</script>

src/components/geom/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ export { default as VVGeomBlank } from './GeomBlank.vue';
44
export { default as VVGeomBoxplot } from './GeomBoxplot.vue';
55
export { default as VVGeomCurve } from './GeomCurve.vue';
66
export { default as VVGeomDensity } from './GeomDensity.vue';
7+
export { default as VVGeomEllipse } from './GeomEllipse.vue';
78
export { default as VVGeomHistogram } from './GeomHistogram.vue';
89
export { default as VVGeomLine } from './GeomLine.vue';
910
export { default as VVGeomLinerange } from './GeomLinerange.vue';
11+
export { default as VVGeomMarkdown } from './GeomMarkdown.vue';
12+
export { default as VVGeomMarkdownsegment } from './GeomMarkdownsegment.vue';
1013
export { default as VVGeomPath } from './GeomPath.vue';
1114
export { default as VVGeomPoint } from './GeomPoint.vue';
1215
export { default as VVGeomPolygon } from './GeomPolygon.vue';

src/core/axis/CoreAxisH.vue

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { computed, inject, useTemplateRef } from 'vue'
33
import { oob_squish_any, emitEvent, dropNull } from '#base/js/utils'
44
import CoreText from '../element/CoreText.vue'
5+
import CoreMarkdown from '../element/CoreMarkdown.vue'
56
const { coord, ticks, title, coord2pos, pos2coord, layout, theme, action, position, activeTransform, transition } = defineProps({
67
coord: String,
78
ticks: { type: Array, default: () => [] }, title: String,
@@ -40,7 +41,8 @@ const axisTitle = computed(() => {
4041
dockX, dockY,
4142
fontSize: theme.title_size,
4243
text: title,
43-
'fill': theme.title_color,
44+
fill: theme.title_color,
45+
'font-family': "sans-serif",
4446
...theme.title_style,
4547
}
4648
})
@@ -82,7 +84,7 @@ const tickTexts = computed(() => {
8284
let tsl = pos * (activeTransform.scaleH - 1) + activeTransform.translateH
8385
let position = pos + layout.l
8486
if (position + tsl < 0 || position + tsl > width.value) continue
85-
let offset = (isTop ? -1 : 1) * ((tick.length ?? theme.tick_length) + 3)
87+
let offset = (isTop ? -1 : 1) * ((tick.length ?? theme.tick_length))
8688
let anchorX, anchorY, dockX, dockY
8789
if (theme.tick_anchor_x != null || theme.tick_anchor_y != null) {
8890
anchorX = theme.tick_anchor_x ?? 0.5
@@ -105,7 +107,9 @@ const tickTexts = computed(() => {
105107
text: tick.label,
106108
title: tick.title ?? tick.label,
107109
fontSize: tick.size ?? theme.label_size,
108-
'fill': tick.color ?? theme.label_color
110+
fill: tick.color ?? theme.label_color,
111+
'font-family': "sans-serif",
112+
...theme.label_style,
109113
},
110114
})
111115
}
@@ -305,7 +309,8 @@ const axisVOn = {
305309
<line ref="i" :x1="0" :x2="width" :y1="0" :y2="0" v-bind="axisLine" />
306310
<line v-for="tick in tickLines" v-bind="tick" />
307311
<g v-for="tick in tickTexts" v-bind="tick.wrapper">
308-
<CoreText v-bind="tick.text" />
312+
<CoreMarkdown v-bind="tick.text" v-if="theme.label_type == 'markdown'" />
313+
<CoreText v-bind="tick.text" v-else />
309314
</g>
310315
<g class="vvplot-interactive" fill="transparent">
311316
<rect :width="width" :height="10" :y="-5" v-on="axisVOn"
@@ -317,6 +322,9 @@ const axisVOn = {
317322
<rect :width="20" :height="10" :y="-5" :x="width - 20" style="cursor:ew-resize;"
318323
@pointerdown="axisRescaleRightPointerdown" />
319324
</g>
320-
<CoreText v-bind="axisTitle" v-if="axisTitle.text" />
325+
<template v-if="axisTitle.text">
326+
<CoreMarkdown v-bind="axisTitle" v-if="theme.title_type == 'markdown'" />
327+
<CoreText v-bind="axisTitle" v-else />
328+
</template>
321329
</g>
322330
</template>

src/core/axis/CoreAxisV.vue

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { computed, inject, useTemplateRef } from 'vue'
33
import { oob_squish_any, emitEvent, dropNull } from '#base/js/utils'
44
import CoreText from '../element/CoreText.vue'
5+
import CoreMarkdown from '../element/CoreMarkdown.vue'
56
const { coord, ticks, title, coord2pos, pos2coord, layout, theme, action, position, activeTransform, transition } = defineProps({
67
coord: String,
78
ticks: { type: Array, default: () => [] }, title: String,
@@ -40,7 +41,8 @@ const axisTitle = computed(() => {
4041
dockX, dockY,
4142
fontSize: theme.title_size,
4243
text: title,
43-
'fill': theme.title_color,
44+
fill: theme.title_color,
45+
'font-family': "sans-serif",
4446
...theme.title_style,
4547
}
4648
})
@@ -105,7 +107,9 @@ const tickTexts = computed(() => {
105107
text: tick.label,
106108
title: tick.title ?? tick.label,
107109
fontSize: tick.size ?? theme.label_size,
108-
'fill': tick.color ?? theme.label_color,
110+
fill: tick.color ?? theme.label_color,
111+
'font-family': "sans-serif",
112+
...theme.label_style,
109113
}
110114
})
111115
}
@@ -305,7 +309,8 @@ const axisVOn = {
305309
<line ref="i" :x1="0" :x2="0" :y1="0" :y2="height" v-bind="axisLine" />
306310
<line v-for="tick in tickLines" v-bind="tick" />
307311
<g v-for="tick in tickTexts" v-bind="tick.wrapper">
308-
<CoreText v-bind="tick.text" />
312+
<CoreMarkdown v-bind="tick.text" v-if="theme.label_type == 'markdown'" />
313+
<CoreText v-bind="tick.text" v-else />
309314
</g>
310315
<g class="vvplot-interactive" fill="transparent">
311316
<rect :width="10" :height="height" :x="-5" v-on="axisVOn"
@@ -316,6 +321,9 @@ const axisVOn = {
316321
<rect :width="10" :height="20" :x="-5" :y="height - 20" style="cursor:ns-resize;"
317322
@pointerdown="axisRescaleBottomPointerdown" />
318323
</g>
319-
<CoreText v-bind="axisTitle" v-if="axisTitle.text" />
324+
<template v-if="axisTitle.text">
325+
<CoreMarkdown v-bind="axisTitle" v-if="theme.title_type == 'markdown'" />
326+
<CoreText v-bind="axisTitle" v-else />
327+
</template>
320328
</g>
321329
</template>

src/core/element/CoreCurve.vue

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
<script setup>
22
import { computed } from 'vue'
3+
import { parseLinetype } from '#base/js/utils'
34
import * as d3 from 'd3'
45
const {
5-
points, interpolate, fill, color, stroke, linewidth, linetype, alpha,
6+
points, interpolate, fill, color, stroke, linewidth, linetype, alpha, title,
67
translateX, translateY,
78
} = defineProps({
89
points: { type: Array, default: () => [] }, interpolate: { default: 'natural' },
910
fill: { type: String, default: 'none' },
1011
color: String,
1112
stroke: String, linewidth: Number, linetype: String,
12-
alpha: { type: Number, default: 1 },
13+
alpha: { type: Number, default: 1 }, title: String,
1314
translateX: { type: Number, default: 0 }, translateY: { type: Number, default: 0 },
1415
})
1516
const binds = computed(() => {
@@ -20,7 +21,7 @@ const binds = computed(() => {
2021
stroke: color || null,
2122
'stroke-width': linewidth,
2223
'stroke-opacity': alpha == 1 ? null : alpha,
23-
'stroke-dasharray': parseLineType(linetype),
24+
'stroke-dasharray': parseLinetype(linetype).join(" ") || null,
2425
transform: (translateX || translateY) ? `translate(${translateX}, ${translateY})` : null,
2526
}
2627
})
@@ -31,20 +32,9 @@ const interpolators = {
3132
linear: d3.curveLinear,
3233
natural: d3.curveNatural,
3334
}
34-
35-
function parseLineType(linetype) {
36-
if (linetype == null) return null
37-
if (Array.isArray(linetype)) return linetype.join(' ')
38-
if (linetype === 'solid') return null
39-
if (linetype === 'dashed') return '4 4'
40-
if (linetype === 'dotted') return '1 3'
41-
if (linetype === 'dotdash') return '1 3 4 3'
42-
if (linetype === 'longdash') return '8 4'
43-
if (linetype === 'twodash') return '2 2 6 2'
44-
if (linetype.includes(' ')) return linetype
45-
return linetype.split('').map(v => +('0x' + v)).join(' ')
46-
}
4735
</script>
4836
<template>
49-
<path v-bind="binds" />
37+
<path v-bind="binds">
38+
<title v-if="title">{{ title }}</title>
39+
</path>
5040
</template>

src/core/element/CoreEllipse.vue

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<script setup>
2+
import { computed } from 'vue'
3+
import { parseLinetype } from '#base/js/utils'
4+
const {
5+
cx, cy, rx, ry, angle,
6+
fill, color, linewidth, linetype, alpha, title,
7+
translateX, translateY,
8+
} = defineProps({
9+
cx: { type: Number, default: 0 }, cy: { type: Number, default: 0 },
10+
rx: { type: Number, default: 0 }, ry: { type: Number, default: 0 },
11+
angle: { type: Number, default: 0 },
12+
fill: String,
13+
color: String, linewidth: Number, linetype: String,
14+
alpha: { type: Number, default: 1 }, title: String,
15+
translateX: { type: Number, default: 0 }, translateY: { type: Number, default: 0 },
16+
})
17+
const binds = computed(() => {
18+
let transform = []
19+
if (translateX || translateY) transform.push(`translate(${translateX}, ${translateY})`)
20+
if (angle) transform.push(`rotate(${angle})`)
21+
return {
22+
cx, cy, rx, ry,
23+
fill: fill || null,
24+
'fill-opacity': alpha == 1 ? null : alpha,
25+
stroke: color || null,
26+
'stroke-width': linewidth,
27+
'stroke-opacity': alpha == 1 ? null : alpha,
28+
'stroke-dasharray': parseLinetype(linetype).join(" ") || null,
29+
transform: transform.join(' ') || null,
30+
'transform-origin': `${cx} ${cy}`,
31+
}
32+
})
33+
</script>
34+
<template>
35+
<ellipse v-bind="binds">
36+
<title v-if="title">{{ title }}</title>
37+
</ellipse>
38+
</template>

0 commit comments

Comments
 (0)