Chart component - CDN to NPM Pkg
This commit is contained in:
parent
232bdb0aa5
commit
96d80cf30d
|
@ -58,7 +58,9 @@
|
||||||
"@budibase/bbui": "^1.15.4",
|
"@budibase/bbui": "^1.15.4",
|
||||||
"@budibase/client": "^0.0.32",
|
"@budibase/client": "^0.0.32",
|
||||||
"@nx-js/compiler-util": "^2.0.0",
|
"@nx-js/compiler-util": "^2.0.0",
|
||||||
|
"britecharts": "^2.16.0",
|
||||||
"codemirror": "^5.51.0",
|
"codemirror": "^5.51.0",
|
||||||
|
"d3-selection": "^1.4.1",
|
||||||
"date-fns": "^1.29.0",
|
"date-fns": "^1.29.0",
|
||||||
"deepmerge": "^4.2.2",
|
"deepmerge": "^4.2.2",
|
||||||
"feather-icons": "^4.21.0",
|
"feather-icons": "^4.21.0",
|
||||||
|
|
|
@ -1,156 +1,172 @@
|
||||||
<script context="module">
|
<script context="module">
|
||||||
//expose chart types for use or reference outside compnent
|
//expose chart types for use or reference outside compnent
|
||||||
export const chartTypes = britecharts ? Object.keys(britecharts) : null;
|
export const chartTypes = britecharts ? Object.keys(britecharts) : null
|
||||||
|
|
||||||
//expose chart color schemas for use or reference outside compnent
|
//expose chart color schemas for use or reference outside compnent
|
||||||
export const colorSchemas = britecharts
|
export const colorSchemas = britecharts
|
||||||
? britecharts.colors.colorSchemas
|
? britecharts.colors.colorSchemas
|
||||||
: null;
|
: null
|
||||||
|
|
||||||
//export color gradients for use or reference outside the component
|
//export color gradients for use or reference outside the component
|
||||||
export const colorGradients = britecharts
|
export const colorGradients = britecharts
|
||||||
? britecharts.colors.colorGradients
|
? britecharts.colors.colorGradients
|
||||||
: null;
|
: null
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte";
|
import britecharts from "britecharts"
|
||||||
|
import { select } from "d3-selection"
|
||||||
|
|
||||||
|
import { onMount } from "svelte"
|
||||||
import shortid from "shortid"
|
import shortid from "shortid"
|
||||||
|
|
||||||
const _id = shortid.generate()
|
const _id = shortid.generate()
|
||||||
|
|
||||||
export let type = "bar";
|
export let type = "bar"
|
||||||
export let data = [];
|
export let data = []
|
||||||
export let tooltipProps = null;
|
export let tooltipProps = null
|
||||||
export let legendProps = null;
|
export let legendProps = null
|
||||||
export let useTooltip = false;
|
export let useTooltip = false
|
||||||
export let useLegend = false;
|
export let useLegend = false
|
||||||
|
|
||||||
export let colors = colorSchemas ? colorSchemas.britecharts : null;
|
export let colors = colorSchemas ? colorSchemas.britecharts : null
|
||||||
export let gradients = colorGradients ? colorGradients.bluePurple : null;
|
export let gradients = colorGradients ? colorGradients.bluePurple : null
|
||||||
export let tooltip = null; //can bind to outside the component and therefore access
|
export let tooltip = null //can bind to outside the component and therefore access
|
||||||
|
|
||||||
let chartElement = null;
|
let chartElement = null
|
||||||
let chartContainer = null;
|
let chartContainer = null
|
||||||
let tooltipContainer = null;
|
let tooltipContainer = null
|
||||||
let legendContainer = null;
|
let legendContainer = null
|
||||||
let legend = null;
|
let legend = null
|
||||||
|
|
||||||
let chart = chartTypes.includes(type) ? britecharts[type]() : null;
|
let chart = chartTypes.includes(type) ? britecharts[type]() : null
|
||||||
|
|
||||||
const chartClass = `chart-container-${_id}`
|
const chartClass = `chart-container-${_id}`
|
||||||
const legendClass = `legend-container-${_id}`
|
const legendClass = `legend-container-${_id}`
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (chart) {
|
if (chart) {
|
||||||
chartContainer = d3.select(`.${chartClass}`);
|
chartContainer = select(`.${chartClass}`)
|
||||||
bindChartColors();
|
bindChartColors()
|
||||||
bindChartUIProps();
|
bindChartUIProps()
|
||||||
bindChartEvents();
|
bindChartEvents()
|
||||||
chartContainer.datum(data).call(chart);
|
chartContainer.datum(data).call(chart)
|
||||||
bindChartTooltip();
|
bindChartTooltip()
|
||||||
bindChartLegend();
|
bindChartLegend()
|
||||||
} else {
|
} else {
|
||||||
console.error("Britecharts could not be found");
|
console.error("Britecharts could not be found")
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
function bindChartColors() {
|
function bindChartColors() {
|
||||||
if (chart.colorSchema) {
|
if (chart.colorSchema) {
|
||||||
chart.colorSchema(colors);
|
chart.colorSchema(colors)
|
||||||
} else if (chart.gradient) {
|
} else if (chart.gradient) {
|
||||||
chart.gradient(gradients);
|
chart.gradient(gradients)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindChartTooltip() {
|
function bindChartTooltip() {
|
||||||
if (canUseTooltip) {
|
if (canUseTooltip) {
|
||||||
tooltip = britecharts.tooltip();
|
tooltip = britecharts.tooltip()
|
||||||
|
|
||||||
bindProps(tooltip, tooltipProps)
|
bindProps(tooltip, tooltipProps)
|
||||||
|
|
||||||
tooltipContainer = d3.select(`.${chartClass} .metadata-group .vertical-marker-container`);
|
tooltipContainer = select(
|
||||||
tooltipContainer.datum([]).call(tooltip);
|
`.${chartClass} .metadata-group .vertical-marker-container`
|
||||||
|
)
|
||||||
|
tooltipContainer.datum([]).call(tooltip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindChartLegend() {
|
function bindChartLegend() {
|
||||||
if(useLegend) {
|
if (useLegend) {
|
||||||
|
if (!Array.isArray(data)) {
|
||||||
if(!Array.isArray(data)) {
|
|
||||||
console.warn("Cannot use legend as data is not an array")
|
console.warn("Cannot use legend as data is not an array")
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let excludeProps = []
|
let excludeProps = []
|
||||||
|
|
||||||
legend = britecharts.legend();
|
legend = britecharts.legend()
|
||||||
|
|
||||||
if(!legendProps || !legendProps.width) {
|
if (!legendProps || !legendProps.width) {
|
||||||
excludeProps = ["width"]
|
excludeProps = ["width"]
|
||||||
legend.width(chart.width())
|
legend.width(chart.width())
|
||||||
}
|
}
|
||||||
|
|
||||||
if(legendProps){
|
if (legendProps) {
|
||||||
bindProps(legend, legendProps, excludeProps)
|
bindProps(legend, legendProps, excludeProps)
|
||||||
}
|
}
|
||||||
|
|
||||||
legendContainer = d3.select(`.${legendClass}`)
|
legendContainer = select(`.${legendClass}`)
|
||||||
legendContainer.datum(data).call(legend)
|
legendContainer.datum(data).call(legend)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindChartEvents() {
|
function bindChartEvents() {
|
||||||
if ($$props.on) {
|
if ($$props.on) {
|
||||||
const events = Object.entries($$props.on);
|
const events = Object.entries($$props.on)
|
||||||
for (let [type, fn] of events) {
|
for (let [type, fn] of events) {
|
||||||
chart.on(type, fn);
|
chart.on(type, fn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindChartUIProps() {
|
function bindChartUIProps() {
|
||||||
const excludeProps = ["data", "colors", "type", "gradients", "on", "useTooltip", "tooltip", "tooltipProps", "legendProps", "useLegend"]
|
const excludeProps = [
|
||||||
|
"data",
|
||||||
|
"colors",
|
||||||
|
"type",
|
||||||
|
"gradients",
|
||||||
|
"on",
|
||||||
|
"useTooltip",
|
||||||
|
"tooltip",
|
||||||
|
"tooltipProps",
|
||||||
|
"legendProps",
|
||||||
|
"useLegend",
|
||||||
|
]
|
||||||
|
|
||||||
if (!$$props.width) {
|
if (!$$props.width) {
|
||||||
chart.width(chartElement.getBoundingClientRect().width);
|
chart.width(chartElement.getBoundingClientRect().width)
|
||||||
}
|
}
|
||||||
|
|
||||||
bindProps(chart, $$props, excludeProps)
|
bindProps(chart, $$props, excludeProps)
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindProps(element, elProps, excludeArray) {
|
function bindProps(element, elProps, excludeArray) {
|
||||||
const props = excludeArray ? Object.entries(excludeProps(elProps, excludeArray)) : Object.entries(elProps)
|
const props = excludeArray
|
||||||
|
? Object.entries(excludeProps(elProps, excludeArray))
|
||||||
|
: Object.entries(elProps)
|
||||||
|
|
||||||
const validElementProps = Object.getOwnPropertyNames(element);
|
const validElementProps = Object.getOwnPropertyNames(element)
|
||||||
|
|
||||||
for (let [prop, value] of props) {
|
for (let [prop, value] of props) {
|
||||||
if (validElementProps.includes(prop)) {
|
if (validElementProps.includes(prop)) {
|
||||||
chart[prop](value);
|
chart[prop](value)
|
||||||
} else {
|
} else {
|
||||||
console.warn(
|
console.warn(
|
||||||
`${type} - ${prop} is an unrecognised chart prop and wont be applied`
|
`${type} - ${prop} is an unrecognised chart prop and wont be applied`
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function excludeProps(props, propsToExclude) {
|
function excludeProps(props, propsToExclude) {
|
||||||
const modifiedProps = {};
|
const modifiedProps = {}
|
||||||
for (const prop in props) {
|
for (const prop in props) {
|
||||||
if (!propsToExclude.includes(prop)) {
|
if (!propsToExclude.includes(prop)) {
|
||||||
modifiedProps[prop] = props[prop];
|
modifiedProps[prop] = props[prop]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return modifiedProps;
|
return modifiedProps
|
||||||
}
|
}
|
||||||
|
|
||||||
$: validChartProps = chart ? Object.getOwnPropertyNames(chart) : null;
|
$: validChartProps = chart ? Object.getOwnPropertyNames(chart) : null
|
||||||
$: canUseTooltip = tooltipProps && useTooltip;
|
$: canUseTooltip = tooltipProps && useTooltip
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div bind:this={chartElement} class={chartClass} />
|
<div bind:this={chartElement} class={chartClass} />
|
||||||
{#if useLegend}
|
{#if useLegend}
|
||||||
<div class={legendClass}/>
|
<div class={legendClass} />
|
||||||
{/if}
|
{/if}
|
|
@ -8,7 +8,6 @@
|
||||||
<title>Budibase Builder</title>
|
<title>Budibase Builder</title>
|
||||||
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/remixicon@2.3.0/fonts/remixicon.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/remixicon@2.3.0/fonts/remixicon.css" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/britecharts/dist/css/britecharts.min.css" type="text/css" />
|
|
||||||
|
|
||||||
<link rel='icon' type='image/png' href='/_builder/favicon.png'>
|
<link rel='icon' type='image/png' href='/_builder/favicon.png'>
|
||||||
<link rel='stylesheet' href='/_builder/global.css'>
|
<link rel='stylesheet' href='/_builder/global.css'>
|
||||||
|
@ -22,9 +21,6 @@
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body id="app">
|
<body id="app">
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.7.4/d3.js"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/britecharts@2/dist/bundled/britecharts.min.js"></script>
|
|
||||||
|
|
||||||
<script src='/_builder/bundle.js'></script>
|
<script src='/_builder/bundle.js'></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue