This commit is contained in:
Gerard Burns 2024-04-18 13:03:18 +01:00
parent 78bb19967f
commit 337214d48c
5 changed files with 77 additions and 76 deletions

View File

@ -11,6 +11,7 @@
// Apex charts directly modifies the options object with default properties and internal variables. These being present could unintentionally cause issues to the provider of this prop as the changes are reflected in that component as well. To prevent any issues we clone options here to provide a buffer.
$: optionsCopy = cloneDeep(options);
$: console.log(cloneDeep(options));
let chartElement;
let chart;

View File

@ -3,7 +3,6 @@
import ApexChart from "./ApexChart.svelte"
import { get } from "lodash";
// Common props
export let title
export let dataProvider
export let labelColumn

View File

@ -3,7 +3,6 @@
import ApexChart from "./ApexChart.svelte"
import { get } from "lodash";
// Common props
export let title
export let dataProvider
export let labelColumn

View File

@ -1,6 +1,6 @@
<script>
import { ApexOptionsBuilder } from "./ApexOptionsBuilder"
import ApexChart from "./ApexChart.svelte"
import formatters from "./formatters";
export let title
export let dataProvider
@ -8,91 +8,85 @@
export let valueColumn
export let height
export let width
export let dataLabels
export let animate
export let dataLabels
export let legend
export let donut
export let palette
export let c1, c2, c3, c4, c5
$: options = setUpChart(
title,
dataProvider,
labelColumn,
valueColumn,
height,
width,
dataLabels,
animate,
legend,
donut,
palette,
c1 && c2 && c3 && c4 && c5 ? [c1, c2, c3, c4, c5] : null,
customColor
)
$: labelType = dataProvider?.schema?.[labelColumn]?.type === 'datetime' ?
"datetime" : "category"
$: series = getSeries(dataProvider, valueColumn)
$: labels = getLabels(dataProvider, labelColumn, labelType);
$: customColor = palette === "Custom"
$: options = {
series,
labels,
colors: palette === "Custom" ? [c1, c2, c3, c4, c5] : [],
theme: {
palette: palette === "Custom" ? null : palette
},
legend: {
show: legend,
position: "top",
horizontalAlign: "right",
showForSingleSeries: true,
showForNullSeries: true,
showForZeroSeries: true,
},
title: {
text: title,
},
dataLabels: {
enabled: dataLabels
},
chart: {
height: height == null || height === "" ? "auto" : height,
width: width == null || width === "" ? "100%" : width,
type: "pie",
animations: {
enabled: animate
},
toolbar: {
show: false,
},
zoom: {
enabled: false,
},
},
}
const setUpChart = (
title,
dataProvider,
labelColumn,
valueColumn,
height,
width,
dataLabels,
animate,
legend,
donut,
palette,
colors,
customColor
) => {
if (
!dataProvider ||
!dataProvider.rows?.length ||
!labelColumn ||
!valueColumn
) {
return null
}
const getSeries = (datasource, valueColumn) => {
const rows = datasource.rows ?? [];
// Fetch, filter and sort data
const { schema, rows } = dataProvider
const data = rows
.filter(row => row[labelColumn] != null && row[valueColumn] != null)
.slice(0, 100)
if (!schema || !data.length) {
return null
}
// Initialise default chart
let builder = new ApexOptionsBuilder()
.title(title)
.type(donut ? "donut" : "pie")
.width(width)
.height(height)
.dataLabels(dataLabels)
.animate(animate)
.legend(legend)
.legendPosition("right")
.palette(palette)
.colors(customColor ? colors : null)
// Add data if valid datasource
const series = data.map(row => {
if (schema[valueColumn].type === 'datetime') {
return Date.parse(row[valueColumn])
return rows.map(row => {
const value = row?.[valueColumn]
const numValue = parseFloat(value);
if (isNaN(numValue)) {
return 0;
}
return parseFloat(row[valueColumn])
return numValue;
})
const labels = data.map(row => row[labelColumn])
builder = builder.series(series).labels(labels)
// Build chart options
return builder.getOptions()
}
const getLabels = (datasource, labelColumn, labelType) => {
const rows = datasource.rows ?? [];
return rows.map(row => {
const value = row?.[labelColumn]
// If a nullish or non-scalar type, replace it with an empty string
if (!["string", "number", "boolean"].includes(typeof value)) {
return ""
} else if (labelType === "datetime") {
return formatters["Datetime"](value)
}
return value;
})
}
$: console.log("opt", options);
</script>
<ApexChart {options} />

View File

@ -0,0 +1,8 @@
const formatters = {
["Default"]: val => val,
["Thousands"]: val => `${Math.round(val / 1000)}K`,
["Millions"]: val => `${Math.round(val / 1000000)}M`,
["Datetime"]: val => (new Date(val)).toLocaleString()
}
export default formatters