forked from tsai/budibase
1 changed files with 74 additions and 16 deletions
@ -1,65 +1,123 @@ |
|||||
<script> |
<script context="module"> |
||||
import { onMount } from "svelte"; |
|
||||
|
|
||||
//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; |
||||
|
|
||||
//TODO: How do I access this from outside the component? |
|
||||
//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 const colorGradients = britecharts |
export const colorGradients = britecharts |
||||
? britecharts.colors.colorGradients |
? britecharts.colors.colorGradients |
||||
: null; |
: null; |
||||
|
</script> |
||||
|
|
||||
|
<script> |
||||
|
import { onMount } from "svelte"; |
||||
|
|
||||
export let type = "bar"; |
export let type = "bar"; |
||||
export let data = []; |
export let data = []; |
||||
|
export let tooltipProps = null; |
||||
|
|
||||
export let colors = britecharts |
export let colors = colorSchemas ? colorSchemas.britecharts : null; |
||||
? britecharts.colors.colorSchemas.britecharts |
|
||||
: null; |
export let gradients = colorGradients ? colorGradients.bluePurple : null; |
||||
|
|
||||
let chartElement = null; |
let chartElement = null; |
||||
let chartContainer = null; |
let chartContainer = null; |
||||
|
let tooltipContainer = null; |
||||
|
|
||||
|
let tooltipElement = null; |
||||
|
|
||||
let chart = chartTypes.includes(type) ? britecharts[type]() : null; |
let chart = chartTypes.includes(type) ? britecharts[type]() : null; |
||||
|
export let tooltip = null; //can bind and therefore access |
||||
|
|
||||
onMount(() => { |
onMount(() => { |
||||
//TODO: Error handling if can't find britecharts or d3Selection |
|
||||
if (chart) { |
if (chart) { |
||||
chartContainer = d3.select(chartElement); |
chartContainer = d3.select(chartElement); |
||||
bindChartColors(); |
bindChartColors(); |
||||
|
bindChartTooltip(); |
||||
bindChartUIProps(); |
bindChartUIProps(); |
||||
|
bindChartEvents(); |
||||
chartContainer.datum(data).call(chart); |
chartContainer.datum(data).call(chart); |
||||
|
} else { |
||||
|
console.error("Britecharts could not be found"); |
||||
} |
} |
||||
}); |
}); |
||||
|
|
||||
function bindChartColors() { |
function bindChartColors() { |
||||
/* |
|
||||
TODO: some charts support gradients, others support colours.Find out and cater for this here |
|
||||
Can a chart support support both color and gradient schemas? |
|
||||
Can a chart support no colors or gradients |
|
||||
Can a user define there own color schema? |
|
||||
*/ |
|
||||
if (chart.colorSchema) { |
if (chart.colorSchema) { |
||||
chart.colorSchema(colors); |
chart.colorSchema(colors); |
||||
|
} else if (chart.gradient) { |
||||
|
chart.gradient(gradients); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartTooltip() { |
||||
|
if (canUseTooltip) { |
||||
|
tooltip = britecharts.tooltip(); |
||||
|
|
||||
|
const validTooltipProps = Object.getOwnPropertyNames(tooltip); |
||||
|
|
||||
|
const props = Object.entries(tooltipProps); |
||||
|
for (let [key, value] of props) { |
||||
|
if (validTooltipProps.includes(key)) { |
||||
|
tooltip[key](value); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
tooltipContainer = d3.select(tooltipElement); |
||||
|
tooltipContainer.datum([]).call(tooltip); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function excludeProps(props, propsToExclude) { |
||||
|
const modifiedProps = {}; |
||||
|
for (const prop in props) { |
||||
|
if (!propsToExclude.includes(prop)) { |
||||
|
modifiedProps[prop] = props[prop]; |
||||
|
} |
||||
|
} |
||||
|
return modifiedProps; |
||||
|
} |
||||
|
|
||||
|
function bindChartEvents() { |
||||
|
if ($$props.on) { |
||||
|
const events = Object.entries($$props.on); |
||||
|
for (let [type, fn] of events) { |
||||
|
chart.on(type, fn); |
||||
|
} |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
//TODO: Ability to match height and width of container (similar to how this is done in docs). Maybe default this if no width or height |
|
||||
function bindChartUIProps() { |
function bindChartUIProps() { |
||||
const props = Object.entries($$props); |
const props = Object.entries( |
||||
|
excludeProps($$props, ["data", "colors", "type", "gradients", "on"]) |
||||
|
); |
||||
|
|
||||
|
if (!props.includes("width")) { |
||||
|
chart.width(chartElement.getBoundingClientRect().width); |
||||
|
} |
||||
|
|
||||
for (let [prop, value] of props) { |
for (let [prop, value] of props) { |
||||
if (validChartProps.includes(prop)) { |
if (validChartProps.includes(prop)) { |
||||
chart[prop](value); |
chart[prop](value); |
||||
|
} else { |
||||
|
console.warn( |
||||
|
`${type} chart - ${prop} is an unrecognised prop and wont be applied` |
||||
|
); |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
$: validChartProps = chart ? Object.getOwnPropertyNames(chart) : null; |
$: validChartProps = chart ? Object.getOwnPropertyNames(chart) : null; |
||||
|
$: canUseTooltip = type === "groupedBar" && tooltipProps; |
||||
|
$: console.log("VALID CHART PROPS", validChartProps); |
||||
</script> |
</script> |
||||
|
|
||||
<div bind:this={chartElement} class="chart-container" /> |
<div bind:this={chartElement} class="chart-container" /> |
||||
|
|
||||
|
{#if canUseTooltip} |
||||
|
<div bind:this={tooltipElement} class="tooltip-container" /> |
||||
|
{/if} |
||||
|
|||||
Loading…
Reference in new issue