Chart component - CDN to NPM Pkg

This commit is contained in:
cmack 2020-07-20 10:09:11 +01:00
parent 232bdb0aa5
commit 96d80cf30d
3 changed files with 79 additions and 65 deletions

View File

@ -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",

View File

@ -1,90 +1,94 @@
<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"]
@ -95,59 +99,71 @@
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} />

View File

@ -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>