Skip to content

Commit

Permalink
Improve documentation and allow badly formatted dataset values in all…
Browse files Browse the repository at this point in the history
… charts
  • Loading branch information
graphieros committed Jan 28, 2024
1 parent fe5159b commit 1bffaf8
Show file tree
Hide file tree
Showing 9 changed files with 525 additions and 60 deletions.
81 changes: 36 additions & 45 deletions playground/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { chartXy, arrow, chartDonut, chartGauge, clipPath, path, use, findArcMidpoint, ChartXyDatasetItem } from "savyg";
import { chartXy, arrow, chartDonut, text, chartGauge, clipPath, path, use, findArcMidpoint, ChartXyDatasetItem } from "savyg";

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

const gaugeDs = {
value: 4.56,
value: "4.56",
segments: [
{
from: 0,
to: 1
from: "0",
to: "1"
},
{
from: 1,
to: 2
from: "1",
to: "2"
},
{
from: 2,
Expand All @@ -34,6 +34,8 @@ let gauge1 = chartGauge({
options: {
title: "Title",
valueRounding: 1,
pointerSize: 1,
pointerWidth: 12
},
parent: div
})
Expand Down Expand Up @@ -90,19 +92,41 @@ const xyDataset = [
plotRadius: 0,
gradientFrom: "#FF000033",
gradientTo: "#0000FF33",
rx: 3
rx: 3,
dataLabelsColor: "red"
}
] as ChartXyDatasetItem[]

let xy = chartXy({
dataset: xyDataset,
parent: div,
options: {
axisColor: "#000000",
backgroundColor: "#FFFFFF",
fontFamily: "inherit",
barSpacing: 2,
showAxis: true,
xAxisLabels: ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"],
zoomColor: "#0000FF10",
gridColor: "#CCCCCC",
interactive: true,
legendColor: "#000000",
legendFontSize: 10,
paddingBottom: 48,
paddingLeft: 48,
paddingRight: 24,
paddingTop: 48,
selectorColor: "#FF000010",
"shape-rendering": "auto",
showAxis: true,
showGrid: true,
showLegend: true,
title: "Title",
zoomColor: "#0000FF10"
titleColor: "#000000",
titleFontSize: 18,
titlePosition: "start",
tooltipBackgroundColor: "#FFFFFF",
tooltipColor: "#000000",
viewBox: "0 0 512 341"
},
callbacks: {
onClickLegend: xyCb,
Expand All @@ -124,43 +148,11 @@ let donut = chartDonut({
dataset: [
{
name: "serie 1",
value: 0.1,
value: "12",
},
{
name: "serie 1.1",
value: 0 / 1,
},
{
name: "serie 1.3",
value: 0.1,
},
{
name: "serie 1.3",
value: 0.1,
},
{
name: "serie 1.3",
value: 0.1,
},
{
name: "serie 1.3",
value: 0.1,
},
{
name: "serie 2",
value: 10,
},
{
name: "serie 3",
value: 10,
},
{
name: "serie 4",
value: 20,
},
{
name: "serie 4",
value: 20,
value: 12,
},
],
parent: div,
Expand All @@ -180,7 +172,6 @@ let donut = chartDonut({
}
})

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

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

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

genDs?.addEventListener('click', () => {
donut = donut.updateData(makeRandomDonutDataset())
gauge1 = gauge1.updateData(makeRandomGaugeDataset())
xy = xy.updateData(makeRandomXyDataset())
gauge1 = gauge1.updateData(makeRandomGaugeDataset())
})
2 changes: 1 addition & 1 deletion savyg/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "savyg",
"private": false,
"version": "1.2.1",
"version": "1.2.2",
"description": "A savvy library to create svg elements and charts with ease",
"author": "Alec Lloyd Probert",
"repository": {
Expand Down
147 changes: 144 additions & 3 deletions savyg/src/utils_chart_donut.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { palette } from "./palette"
import { createUid, fordinum, getSvgDimensions, makeDonut } from "./utils_common"
import { createUid, forceNum, fordinum, getSvgDimensions, makeDonut } from "./utils_common"
import { circle, element, findArcMidpoint, line, offsetFromCenterPoint, path, setTextAnchorFromCenterPoint, svg, text } from "./utils_svg"
import { ChartArea, DrawingArea, ShapeRendering, StrokeOptions, SvgItem, TextAnchor } from "./utils_svg_types"

Expand All @@ -10,44 +10,183 @@ export type ChartDonutDatasetItem = StrokeOptions & {
}

export type ChartDonutOptions = {
/**
* @option the background color applied to the chart
* @default "#FFFFFF"
*/
backgroundColor?: string
/**
* @option pass any strings separated by a space to generate class names. Example: "my-class1 my-class2"
*/
className?: string
/**
* @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.
* @default false
*/
dataLabelsAsDivs?: boolean
/**
* @option the text color of data labels
* @default "#000000"
*/
dataLabelsColor?: string
/**
* @option the font size of data labels
* @default 12
*/
dataLabelsFontSize?: number
/**
* @option the rounding of the percentage displayed in data labels
* @default 0
*/
dataLabelsRoundingPercentage?: number
/**
* @option the rounding of the value displayed in data labels
* @default 0
*/
dataLabelsRoundingValue?: number
/**
* @option the offset of data labels from the arcs
* @default 40
*/
dataLabelsOffset?: number
/**
* @option the offset of the data labels line markers
* @default 20
*/
dataLabelsLineOffset?: number
/**
* @option the border width of the donut arcs
* @default 1
*/
donutBorderWidth?: number
/**
* @option the size ratio of the overall donut radius
* @default 1
* @example 0.8 will make it smaller
*/
donutRadiusRatio?: number
/**
* @option the thickness of donut arcs
* @default 48
*/
donutThickness?: number
/**
* @option font family for all text elements
* @default "inherit"
*/
fontFamily?: string
/**
* @option values under this threshold will be displayed in smaller font and stacked to the top of the chart
* @default 3
*/
hideLabelUnderPercentage?: number
/**
* @option the id of the svg. Defaults to a random uid
*/
id?: string
/**
* @option activates user interactions (tooltip)
* @default true
*/
interactive?: boolean
/**
* @option the text color of legend elements
* @default "#000000"
*/
legendColor?: string
/**
* @option the font size of legend elements
* @default 10
*/
legendFontSize?: number
/**
* @option the vertical offset of the legend foreignObject container
* @default 40
*/
legendOffsetY?: number
paddingBottom?: number
paddingLeft?: number
paddingRight?: number
paddingTop?: number
/**
* @option standard svg rendering
* @default "auto"
*/
"shape-rendering"?: ShapeRendering
/**
* @option show or hide data labels
* @default true
*/
showDataLabels?: boolean
/**
* @option show or hide legend
* @default true
*/
showLegend?: boolean
/**
* @option show or hide total displayed inside the donut's hollow
* @default true
*/
showTotal?: boolean,
/**
* @option the text content of the title element
* @default ""
*/
title?: string;
/**
* @option the text color of the title element
* @default "#000000"
*/
titleColor?: string
/**
* @option the font size of the title element
* @default 18
*/
titleFontSize?: number
/**
* @option the horizontal position (text-anchor) of the title element
* @default "middle"
*/
titlePosition?: TextAnchor
/**
* @option the background color of the tooltip container
* @default "#FFFFFF"
*/
tooltipBackgroundColor?: string
/**
* @option the text color of the tooltip content
* @default "#000000"
*/
tooltipColor?: string
/**
* @option the text content of the total label inside the donut's hollow
* @default "Total"
*/
totalLabel?: string
/**
* @option the text color of the total label inside the donut's hollow
* @default "#000000"
*/
totalLabelColor?: string
/**
* @option the font size of the total label inside the donut's hollow
* @default 20
*/
totalLabelFontSize?: number
/**
* @option the font size of the total value inside the donut's hollow
* @default 20
*/
totalValueFontSize?: number
/**
* @option the rounding of the total value inside the donut's hollow
* @default 0
*/
totalValueRounding?: number
/**
* @option the viewBox dimensions of the chart's svg
* @default "0 0 450 450"
*/
viewBox?: string
}

Expand All @@ -69,16 +208,18 @@ export function chartDonut({
}) {

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

const formattedDataset = dataset.map((ds, i) => {
const value = forceNum(ds.value)
return {
...ds,
value,
color: ds.color ?? palette[i],
"stroke-width": ds["stroke-width"] ?? 20,
"stroke-linecap": ds["stroke-linecap"] ?? 'butt',
uid: createUid(),
proportion: (ds.value ?? 0) / grandTotal
proportion: value / grandTotal
}
}).sort((a, b) => b.proportion - a.proportion)

Expand Down
Loading

0 comments on commit 1bffaf8

Please sign in to comment.