Skip to content

Commit fba9f62

Browse files
committed
wip improvements
1 parent bdbf0ea commit fba9f62

File tree

18 files changed

+303
-121
lines changed

18 files changed

+303
-121
lines changed

demo/app/Sharp/Dashboard/DemoDashboard.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ protected function buildWidgets(WidgetsContainer $widgetsContainer): void
4545
->addWidget(
4646
SharpBarGraphWidget::make('authors_bar')
4747
->setTitle('Posts by author')
48-
->setShowAllLabels()
4948
->setShowLegend(false)
5049
// ->setHorizontal(),
5150
)
@@ -59,6 +58,8 @@ protected function buildWidgets(WidgetsContainer $widgetsContainer): void
5958
->setHeight(200)
6059
// ->setShowLegend()
6160
->setDisplayHorizontalAxisAsTimeline()
61+
// ->setEnableHorizontalAxisLabelSampling()
62+
// ->setShowGradient()
6263
// ->setShowAllLabels()
6364
// ->setShowDots()
6465
// ->setFilled()

resources/js/components/ui/chart/ChartContainer.vue

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import ChartStyle from "./ChartStyle.vue"
99
</script>
1010

1111
<script setup lang="ts">
12+
import { useElementVisibility, useIntersectionObserver } from "@vueuse/core";
13+
import { ref, useTemplateRef } from "vue";
14+
1215
const props = defineProps<{
1316
id?: HTMLAttributes["id"]
1417
class?: HTMLAttributes["class"]
@@ -31,6 +34,16 @@ provideChartContext({
3134
id: uniqueId,
3235
config,
3336
})
37+
38+
39+
const el = useTemplateRef('el');
40+
const isIntersecting = ref(false);
41+
useIntersectionObserver(el, (entries, observer) => {
42+
if(entries[0].isIntersecting) {
43+
isIntersecting.value = true;
44+
observer.disconnect();
45+
}
46+
});
3447
</script>
3548

3649
<template>
@@ -55,8 +68,12 @@ provideChartContext({
5568
'--vis-font-family': 'var(--font-sans)',
5669
'--vis-donut-background-color': 'var(--muted)'
5770
}"
71+
ref="el"
5872
>
59-
<slot :id="uniqueId" :config="config" />
73+
<template v-if="isIntersecting">
74+
<slot :id="uniqueId" :config="config" />
75+
</template>
76+
6077
<ChartStyle :id="chartId" />
6178
</div>
6279
</template>

resources/js/dashboard/components/widgets/Graph.vue

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
<script setup lang="ts">
2-
import { GraphWidgetData } from "@/types";
3-
import type { Component } from "vue";
4-
import Bar from "./graph/Bar.vue";
5-
import Line from "./graph/Line.vue";
6-
import Pie from "./graph/Pie.vue";
7-
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
8-
import { DashboardWidgetProps } from "@/dashboard/types";
2+
import { GraphWidgetData } from '@/types';
3+
import type { Component } from 'vue';
4+
import Bar from './graph/Bar.vue';
5+
import Line from './graph/Line.vue';
6+
import Pie from './graph/Pie.vue';
7+
import Area from './graph/Area.vue';
8+
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
9+
import { DashboardWidgetProps } from '@/dashboard/types';
910
1011
const props = defineProps<DashboardWidgetProps<GraphWidgetData>>();
1112
1213
const components: Record<GraphWidgetData['display'], Component> = {
1314
'bar': Bar,
1415
'line': Line,
1516
'pie': Pie,
17+
'area': Area,
1618
};
1719
</script>
1820

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<script setup lang="ts">
2+
import { GraphWidgetData } from "@/types";
3+
import { DashboardWidgetProps } from "@/dashboard/types";
4+
import { VisXYContainer, VisAxis, VisLine, VisTooltip, VisCrosshair, VisScatter, VisArea } from "@unovis/vue";
5+
import {
6+
AxisConfigInterface, BulletLegendConfigInterface,
7+
CrosshairConfigInterface,
8+
CurveType,
9+
LineConfigInterface, ScatterConfigInterface, XYContainerConfigInterface,
10+
Scale, TextAlign, FitMode, Scatter, AreaConfigInterface,
11+
} from "@unovis/ts";
12+
import { Datum, useXYChart } from "@/dashboard/components/widgets/graph/useXYChart";
13+
import { ChartContainer, ChartLegendContent, ChartTooltip, ChartCrosshair } from "@/components/ui/chart";
14+
import { computed } from "vue";
15+
16+
const props = defineProps<DashboardWidgetProps<GraphWidgetData>>();
17+
18+
const { data, x, y, color, tooltipTemplate, xScale, chartConfig, xAxisConfig, yAxisConfig } = useXYChart(props);
19+
20+
const svgDefs = computed(() => props.value?.datasets.map((dataset, i) => `
21+
<linearGradient id="fill-${i}" x1="0" y1="0" x2="0" y2="1">
22+
<stop
23+
offset="5%"
24+
stop-color="${dataset.color}"
25+
stop-opacity="0.8"
26+
/>
27+
<stop
28+
offset="95%"
29+
stop-color="${dataset.color}"
30+
stop-opacity="0.1"
31+
/>
32+
</linearGradient>
33+
`).join(''));
34+
</script>
35+
36+
<template>
37+
<ChartContainer class="flex flex-col" :config="chartConfig" cursor>
38+
<VisXYContainer class="flex-1 min-h-0"
39+
v-bind="{
40+
xScale: xScale,
41+
svgDefs: svgDefs,
42+
} as XYContainerConfigInterface<Datum>"
43+
:data="data"
44+
>
45+
<template v-if="!props.widget.minimal">
46+
<VisAxis
47+
v-bind="{
48+
type: 'x',
49+
gridLine: false,
50+
domainLine: false,
51+
...xAxisConfig,
52+
} as AxisConfigInterface<Datum>"
53+
/>
54+
<VisAxis v-bind="{
55+
type: 'y',
56+
domainLine: false,
57+
...yAxisConfig,
58+
} as AxisConfigInterface<Datum>" />
59+
</template>
60+
61+
<VisLine
62+
v-bind="{
63+
x: x,
64+
y: y,
65+
color: color,
66+
lineWidth: 1,
67+
curveType: props.widget.options.curved ? CurveType.MonotoneX : CurveType.Linear,
68+
// stacked: true,
69+
} as LineConfigInterface<Datum>"
70+
/>
71+
72+
<template v-for="(dataset, i) in props.value?.datasets">
73+
<VisArea
74+
v-bind="{
75+
x: x,
76+
// y: y,
77+
y: (d) => d[i],
78+
// color: props.value?.datasets.map((dataset, i) => props.widget.options.gradient ? `url(#fill-${i})` : dataset.color),
79+
color: props.widget.options.gradient ? `url(#fill-${i})` : dataset.color,
80+
opacity: props.widget.options.opacity,
81+
curveType: props.widget.options.curved ? CurveType.MonotoneX : CurveType.Linear,
82+
} as AreaConfigInterface<Datum>"
83+
/>
84+
</template>
85+
86+
<ChartCrosshair
87+
v-bind="{
88+
color: color,
89+
template: tooltipTemplate,
90+
hideWhenFarFromPointer: false,
91+
} as CrosshairConfigInterface<Datum>"
92+
/>
93+
94+
<ChartTooltip />
95+
</VisXYContainer>
96+
97+
<template v-if="props.widget.showLegend && !props.widget.minimal">
98+
<ChartLegendContent />
99+
</template>
100+
</ChartContainer>
101+
</template>

resources/js/dashboard/components/widgets/graph/Bar.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
2020
const props = defineProps<DashboardWidgetProps<GraphWidgetData>>();
2121
22-
const { data, x, y, color, tooltipTemplate, chartConfig, xAxisConfig, xScale } = useXYChart(props);
22+
const { data, x, y, color, tooltipTemplate, chartConfig, xAxisConfig, xScale, yAxisConfig } = useXYChart(props);
2323
</script>
2424

2525
<template>
@@ -43,6 +43,7 @@
4343
v-bind="{
4444
type: props.widget.options?.horizontal ? 'x' : 'y',
4545
domainLine: false,
46+
...yAxisConfig,
4647
} as AxisConfigInterface<Datum>"
4748
/>
4849
</template>

resources/js/dashboard/components/widgets/graph/Line.vue

Lines changed: 5 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,14 @@
1515
1616
const props = defineProps<DashboardWidgetProps<GraphWidgetData>>();
1717
18-
const { data, x, y, color, tooltipTemplate, xScale, chartConfig, xAxisConfig } = useXYChart(props);
19-
20-
const svgDefs = computed(() => props.value?.datasets.map((dataset, i) => `
21-
<linearGradient id="fill-${i}" x1="0" y1="0" x2="0" y2="1">
22-
<stop
23-
offset="5%"
24-
stop-color="${dataset.color}"
25-
stop-opacity="0.8"
26-
/>
27-
<stop
28-
offset="95%"
29-
stop-color="${dataset.color}"
30-
stop-opacity="0.1"
31-
/>
32-
</linearGradient>
33-
`).join(''));
18+
const { data, x, y, color, tooltipTemplate, xScale, chartConfig, xAxisConfig, yAxisConfig } = useXYChart(props);
3419
</script>
3520

3621
<template>
3722
<ChartContainer class="flex flex-col" :config="chartConfig" cursor>
3823
<VisXYContainer class="flex-1 min-h-0"
3924
v-bind="{
4025
xScale: xScale,
41-
svgDefs: svgDefs,
4226
} as XYContainerConfigInterface<Datum>"
4327
:data="data"
4428
>
@@ -54,6 +38,7 @@
5438
<VisAxis v-bind="{
5539
type: 'y',
5640
domainLine: false,
41+
...yAxisConfig,
5742
} as AxisConfigInterface<Datum>" />
5843
</template>
5944

@@ -62,40 +47,25 @@
6247
x: x,
6348
y: y,
6449
color: color,
65-
lineWidth: props.widget.options.filled ? 1 : 2,
50+
lineWidth: 2,
6651
curveType: props.widget.options.curved ? CurveType.MonotoneX : CurveType.Linear,
6752
} as LineConfigInterface<Datum>"
6853
/>
6954

70-
<template v-if="props.widget.options.filled">
71-
<template v-for="(dataset, i) in props.value?.datasets.toReversed()">
72-
<VisArea
73-
v-bind="{
74-
x: x,
75-
y: (d) => d[i],
76-
color: () => `url(#fill-${i})`,
77-
opacity: 0.6,
78-
curveType: props.widget.options.curved ? CurveType.MonotoneX : CurveType.Linear,
79-
} as AreaConfigInterface<Datum>"
80-
/>
81-
</template>
82-
</template>
83-
8455
<ChartCrosshair
8556
v-bind="{
8657
color: color,
8758
template: tooltipTemplate,
8859
hideWhenFarFromPointer: false,
8960
} as CrosshairConfigInterface<Datum>"
9061
/>
62+
9163
<ChartTooltip />
9264

9365
<template v-if="props.widget.options.showDots">
9466
<template v-for="dataset in props.value?.datasets">
9567
<VisScatter
96-
v-bind="{ size: 6, x: x, y: y,
97-
// strokeColor: color,
98-
color: color } as ScatterConfigInterface<Datum>"
68+
v-bind="{ size: 6, x: x, y: y, color: color } as ScatterConfigInterface<Datum>"
9969
/>
10070
</template>
10171
</template>

0 commit comments

Comments
 (0)