Chart component - CDN to NPM Pkg

This commit is contained in:
cmack 2020-07-20 10:09:11 +01:00
parent 322c29f749
commit b5bc79488d
3 changed files with 79 additions and 65 deletions

View File

@ -58,7 +58,9 @@
"@budibase/bbui": "^1.15.4",
"@budibase/client": "^0.0.32",
"@nx-js/compiler-util": "^2.0.0",
"britecharts": "^2.16.0",
"codemirror": "^5.51.0",
"d3-selection": "^1.4.1",
"date-fns": "^1.29.0",
"deepmerge": "^4.2.2",
"feather-icons": "^4.21.0",

View File

@ -1,156 +1,172 @@
<script context="module">
//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
export const colorSchemas = britecharts
? britecharts.colors.colorSchemas
: null;
: null
//export color gradients for use or reference outside the component
export const colorGradients = britecharts
? britecharts.colors.colorGradients
: null;
: null
</script>
<script>
import { onMount } from "svelte";
import britecharts from "britecharts"
import { select } from "d3-selection"
import { onMount } from "svelte"
import shortid from "shortid"
const _id = shortid.generate()
export let type = "bar";
export let data = [];
export let tooltipProps = null;
export let legendProps = null;
export let useTooltip = false;
export let useLegend = false;
export let type = "bar"
export let data = []
export let tooltipProps = null
export let legendProps = null
export let useTooltip = false
export let useLegend = false
export let colors = colorSchemas ? colorSchemas.britecharts : null;
export let gradients = colorGradients ? colorGradients.bluePurple : null;
export let tooltip = null; //can bind to outside the component and therefore access
export let colors = colorSchemas ? colorSchemas.britecharts : null
export let gradients = colorGradients ? colorGradients.bluePurple : null
export let tooltip = null //can bind to outside the component and therefore access
let chartElement = null;
let chartContainer = null;
let tooltipContainer = null;
let legendContainer = null;
let legend = null;
let chartElement = null
let chartContainer = null
let tooltipContainer = null
let legendContainer = 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}`
onMount(() => {
if (chart) {
chartContainer = d3.select(`.${chartClass}`);
bindChartColors();
bindChartUIProps();
bindChartEvents();
chartContainer.datum(data).call(chart);
bindChartTooltip();
bindChartLegend();
chartContainer = select(`.${chartClass}`)
bindChartColors()
bindChartUIProps()
bindChartEvents()
chartContainer.datum(data).call(chart)
bindChartTooltip()
bindChartLegend()
} else {
console.error("Britecharts could not be found");
console.error("Britecharts could not be found")
}
});
})
function bindChartColors() {
if (chart.colorSchema) {
chart.colorSchema(colors);
chart.colorSchema(colors)
} else if (chart.gradient) {
chart.gradient(gradients);
chart.gradient(gradients)
}
}
function bindChartTooltip() {
if (canUseTooltip) {
tooltip = britecharts.tooltip();
tooltip = britecharts.tooltip()
bindProps(tooltip, tooltipProps)
tooltipContainer = d3.select(`.${chartClass} .metadata-group .vertical-marker-container`);
tooltipContainer.datum([]).call(tooltip);
tooltipContainer = select(
`.${chartClass} .metadata-group .vertical-marker-container`
)
tooltipContainer.datum([]).call(tooltip)
}
}
function bindChartLegend() {
if(useLegend) {
if(!Array.isArray(data)) {
if (useLegend) {
if (!Array.isArray(data)) {
console.warn("Cannot use legend as data is not an array")
return;
return
}
let excludeProps = []
legend = britecharts.legend();
legend = britecharts.legend()
if(!legendProps || !legendProps.width) {
if (!legendProps || !legendProps.width) {
excludeProps = ["width"]
legend.width(chart.width())
}
if(legendProps){
if (legendProps) {
bindProps(legend, legendProps, excludeProps)
}
legendContainer = d3.select(`.${legendClass}`)
legendContainer = select(`.${legendClass}`)
legendContainer.datum(data).call(legend)
}
}
function bindChartEvents() {
if ($$props.on) {
const events = Object.entries($$props.on);
const events = Object.entries($$props.on)
for (let [type, fn] of events) {
chart.on(type, fn);
chart.on(type, fn)
}
}
}
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) {
chart.width(chartElement.getBoundingClientRect().width);
chart.width(chartElement.getBoundingClientRect().width)
}
bindProps(chart, $$props, excludeProps)
}
function bindProps(element, elProps, excludeArray) {
const props = excludeArray ? Object.entries(excludeProps(elProps, excludeArray)) : Object.entries(elProps)
const validElementProps = Object.getOwnPropertyNames(element);
const props = excludeArray
? Object.entries(excludeProps(elProps, excludeArray))
: Object.entries(elProps)
const validElementProps = Object.getOwnPropertyNames(element)
for (let [prop, value] of props) {
if (validElementProps.includes(prop)) {
chart[prop](value);
chart[prop](value)
} else {
console.warn(
`${type} - ${prop} is an unrecognised chart prop and wont be applied`
);
)
}
}
}
function excludeProps(props, propsToExclude) {
const modifiedProps = {};
const modifiedProps = {}
for (const prop in props) {
if (!propsToExclude.includes(prop)) {
modifiedProps[prop] = props[prop];
modifiedProps[prop] = props[prop]
}
}
return modifiedProps;
return modifiedProps
}
$: validChartProps = chart ? Object.getOwnPropertyNames(chart) : null;
$: canUseTooltip = tooltipProps && useTooltip;
$: validChartProps = chart ? Object.getOwnPropertyNames(chart) : null
$: canUseTooltip = tooltipProps && useTooltip
</script>
<div bind:this={chartElement} class={chartClass} />
{#if useLegend}
<div class={legendClass}/>
{/if}
<div class={legendClass} />
{/if}

View File

@ -8,7 +8,6 @@
<title>Budibase Builder</title>
<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='stylesheet' href='/_builder/global.css'>
@ -22,9 +21,6 @@
</head>
<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>
</body>