Skip to content

Commit 1bffaf8

Browse files
committed
Improve documentation and allow badly formatted dataset values in all charts
1 parent fe5159b commit 1bffaf8

9 files changed

+525
-60
lines changed

playground/src/main.ts

+36-45
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
import { chartXy, arrow, chartDonut, chartGauge, clipPath, path, use, findArcMidpoint, ChartXyDatasetItem } from "savyg";
1+
import { chartXy, arrow, chartDonut, text, chartGauge, clipPath, path, use, findArcMidpoint, ChartXyDatasetItem } from "savyg";
22

33
// const parent = document.getElementById("svg") as HTMLElement
44
const div = document.getElementById("div") as HTMLElement
55

66
const gaugeDs = {
7-
value: 4.56,
7+
value: "4.56",
88
segments: [
99
{
10-
from: 0,
11-
to: 1
10+
from: "0",
11+
to: "1"
1212
},
1313
{
14-
from: 1,
15-
to: 2
14+
from: "1",
15+
to: "2"
1616
},
1717
{
1818
from: 2,
@@ -34,6 +34,8 @@ let gauge1 = chartGauge({
3434
options: {
3535
title: "Title",
3636
valueRounding: 1,
37+
pointerSize: 1,
38+
pointerWidth: 12
3739
},
3840
parent: div
3941
})
@@ -90,19 +92,41 @@ const xyDataset = [
9092
plotRadius: 0,
9193
gradientFrom: "#FF000033",
9294
gradientTo: "#0000FF33",
93-
rx: 3
95+
rx: 3,
96+
dataLabelsColor: "red"
9497
}
9598
] as ChartXyDatasetItem[]
9699

97100
let xy = chartXy({
98101
dataset: xyDataset,
99102
parent: div,
100103
options: {
104+
axisColor: "#000000",
105+
backgroundColor: "#FFFFFF",
106+
fontFamily: "inherit",
101107
barSpacing: 2,
102-
showAxis: true,
103108
xAxisLabels: ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"],
109+
zoomColor: "#0000FF10",
110+
gridColor: "#CCCCCC",
111+
interactive: true,
112+
legendColor: "#000000",
113+
legendFontSize: 10,
114+
paddingBottom: 48,
115+
paddingLeft: 48,
116+
paddingRight: 24,
117+
paddingTop: 48,
118+
selectorColor: "#FF000010",
119+
"shape-rendering": "auto",
120+
showAxis: true,
121+
showGrid: true,
122+
showLegend: true,
104123
title: "Title",
105-
zoomColor: "#0000FF10"
124+
titleColor: "#000000",
125+
titleFontSize: 18,
126+
titlePosition: "start",
127+
tooltipBackgroundColor: "#FFFFFF",
128+
tooltipColor: "#000000",
129+
viewBox: "0 0 512 341"
106130
},
107131
callbacks: {
108132
onClickLegend: xyCb,
@@ -124,43 +148,11 @@ let donut = chartDonut({
124148
dataset: [
125149
{
126150
name: "serie 1",
127-
value: 0.1,
151+
value: "12",
128152
},
129153
{
130154
name: "serie 1.1",
131-
value: 0 / 1,
132-
},
133-
{
134-
name: "serie 1.3",
135-
value: 0.1,
136-
},
137-
{
138-
name: "serie 1.3",
139-
value: 0.1,
140-
},
141-
{
142-
name: "serie 1.3",
143-
value: 0.1,
144-
},
145-
{
146-
name: "serie 1.3",
147-
value: 0.1,
148-
},
149-
{
150-
name: "serie 2",
151-
value: 10,
152-
},
153-
{
154-
name: "serie 3",
155-
value: 10,
156-
},
157-
{
158-
name: "serie 4",
159-
value: 20,
160-
},
161-
{
162-
name: "serie 4",
163-
value: 20,
155+
value: 12,
164156
},
165157
],
166158
parent: div,
@@ -180,7 +172,6 @@ let donut = chartDonut({
180172
}
181173
})
182174

183-
// console.log(findArcMidpoint(donut.arcs[0].pathElement))
184175

185176
const nuke = document.getElementById('nuke');
186177

@@ -220,6 +211,6 @@ const genDs = document.getElementById('genDs')
220211

221212
genDs?.addEventListener('click', () => {
222213
donut = donut.updateData(makeRandomDonutDataset())
223-
gauge1 = gauge1.updateData(makeRandomGaugeDataset())
224214
xy = xy.updateData(makeRandomXyDataset())
215+
gauge1 = gauge1.updateData(makeRandomGaugeDataset())
225216
})

savyg/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "savyg",
33
"private": false,
4-
"version": "1.2.1",
4+
"version": "1.2.2",
55
"description": "A savvy library to create svg elements and charts with ease",
66
"author": "Alec Lloyd Probert",
77
"repository": {

savyg/src/utils_chart_donut.ts

+144-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { palette } from "./palette"
2-
import { createUid, fordinum, getSvgDimensions, makeDonut } from "./utils_common"
2+
import { createUid, forceNum, fordinum, getSvgDimensions, makeDonut } from "./utils_common"
33
import { circle, element, findArcMidpoint, line, offsetFromCenterPoint, path, setTextAnchorFromCenterPoint, svg, text } from "./utils_svg"
44
import { ChartArea, DrawingArea, ShapeRendering, StrokeOptions, SvgItem, TextAnchor } from "./utils_svg_types"
55

@@ -10,44 +10,183 @@ export type ChartDonutDatasetItem = StrokeOptions & {
1010
}
1111

1212
export type ChartDonutOptions = {
13+
/**
14+
* @option the background color applied to the chart
15+
* @default "#FFFFFF"
16+
*/
1317
backgroundColor?: string
18+
/**
19+
* @option pass any strings separated by a space to generate class names. Example: "my-class1 my-class2"
20+
*/
1421
className?: string
22+
/**
23+
* @option display data labels as divs inside a foreignObject, to get more control on the styling (line breaks, etc). If false, displays the data labels as a svg text element, with no control over line breaks.
24+
* @default false
25+
*/
1526
dataLabelsAsDivs?: boolean
27+
/**
28+
* @option the text color of data labels
29+
* @default "#000000"
30+
*/
1631
dataLabelsColor?: string
32+
/**
33+
* @option the font size of data labels
34+
* @default 12
35+
*/
1736
dataLabelsFontSize?: number
37+
/**
38+
* @option the rounding of the percentage displayed in data labels
39+
* @default 0
40+
*/
1841
dataLabelsRoundingPercentage?: number
42+
/**
43+
* @option the rounding of the value displayed in data labels
44+
* @default 0
45+
*/
1946
dataLabelsRoundingValue?: number
47+
/**
48+
* @option the offset of data labels from the arcs
49+
* @default 40
50+
*/
2051
dataLabelsOffset?: number
52+
/**
53+
* @option the offset of the data labels line markers
54+
* @default 20
55+
*/
2156
dataLabelsLineOffset?: number
57+
/**
58+
* @option the border width of the donut arcs
59+
* @default 1
60+
*/
2261
donutBorderWidth?: number
62+
/**
63+
* @option the size ratio of the overall donut radius
64+
* @default 1
65+
* @example 0.8 will make it smaller
66+
*/
2367
donutRadiusRatio?: number
68+
/**
69+
* @option the thickness of donut arcs
70+
* @default 48
71+
*/
2472
donutThickness?: number
73+
/**
74+
* @option font family for all text elements
75+
* @default "inherit"
76+
*/
2577
fontFamily?: string
78+
/**
79+
* @option values under this threshold will be displayed in smaller font and stacked to the top of the chart
80+
* @default 3
81+
*/
2682
hideLabelUnderPercentage?: number
83+
/**
84+
* @option the id of the svg. Defaults to a random uid
85+
*/
2786
id?: string
87+
/**
88+
* @option activates user interactions (tooltip)
89+
* @default true
90+
*/
2891
interactive?: boolean
92+
/**
93+
* @option the text color of legend elements
94+
* @default "#000000"
95+
*/
2996
legendColor?: string
97+
/**
98+
* @option the font size of legend elements
99+
* @default 10
100+
*/
30101
legendFontSize?: number
102+
/**
103+
* @option the vertical offset of the legend foreignObject container
104+
* @default 40
105+
*/
31106
legendOffsetY?: number
32107
paddingBottom?: number
33108
paddingLeft?: number
34109
paddingRight?: number
35110
paddingTop?: number
111+
/**
112+
* @option standard svg rendering
113+
* @default "auto"
114+
*/
36115
"shape-rendering"?: ShapeRendering
116+
/**
117+
* @option show or hide data labels
118+
* @default true
119+
*/
37120
showDataLabels?: boolean
121+
/**
122+
* @option show or hide legend
123+
* @default true
124+
*/
38125
showLegend?: boolean
126+
/**
127+
* @option show or hide total displayed inside the donut's hollow
128+
* @default true
129+
*/
39130
showTotal?: boolean,
131+
/**
132+
* @option the text content of the title element
133+
* @default ""
134+
*/
40135
title?: string;
136+
/**
137+
* @option the text color of the title element
138+
* @default "#000000"
139+
*/
41140
titleColor?: string
141+
/**
142+
* @option the font size of the title element
143+
* @default 18
144+
*/
42145
titleFontSize?: number
146+
/**
147+
* @option the horizontal position (text-anchor) of the title element
148+
* @default "middle"
149+
*/
43150
titlePosition?: TextAnchor
151+
/**
152+
* @option the background color of the tooltip container
153+
* @default "#FFFFFF"
154+
*/
44155
tooltipBackgroundColor?: string
156+
/**
157+
* @option the text color of the tooltip content
158+
* @default "#000000"
159+
*/
45160
tooltipColor?: string
161+
/**
162+
* @option the text content of the total label inside the donut's hollow
163+
* @default "Total"
164+
*/
46165
totalLabel?: string
166+
/**
167+
* @option the text color of the total label inside the donut's hollow
168+
* @default "#000000"
169+
*/
47170
totalLabelColor?: string
171+
/**
172+
* @option the font size of the total label inside the donut's hollow
173+
* @default 20
174+
*/
48175
totalLabelFontSize?: number
176+
/**
177+
* @option the font size of the total value inside the donut's hollow
178+
* @default 20
179+
*/
49180
totalValueFontSize?: number
181+
/**
182+
* @option the rounding of the total value inside the donut's hollow
183+
* @default 0
184+
*/
50185
totalValueRounding?: number
186+
/**
187+
* @option the viewBox dimensions of the chart's svg
188+
* @default "0 0 450 450"
189+
*/
51190
viewBox?: string
52191
}
53192

@@ -69,16 +208,18 @@ export function chartDonut({
69208
}) {
70209

71210
const globalUid = createUid();
72-
const grandTotal = dataset.map(ds => ds.value ?? 0).reduce((a, b) => a + b, 0)
211+
const grandTotal = dataset.map(ds => forceNum(ds.value)).reduce((a, b) => a + b, 0)
73212

74213
const formattedDataset = dataset.map((ds, i) => {
214+
const value = forceNum(ds.value)
75215
return {
76216
...ds,
217+
value,
77218
color: ds.color ?? palette[i],
78219
"stroke-width": ds["stroke-width"] ?? 20,
79220
"stroke-linecap": ds["stroke-linecap"] ?? 'butt',
80221
uid: createUid(),
81-
proportion: (ds.value ?? 0) / grandTotal
222+
proportion: value / grandTotal
82223
}
83224
}).sort((a, b) => b.proportion - a.proportion)
84225

0 commit comments

Comments
 (0)