forked from tsai/budibase
3 changed files with 79 additions and 65 deletions
@ -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)) |
||||
const validElementProps = Object.getOwnPropertyNames(element); |
: Object.entries(elProps) |
||||
|
|
||||
|
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} |
||||
|
|||||
Loading…
Reference in new issue