WIP: Chart Events, Tooltips and Validation

This commit is contained in:
cmack 2020-07-07 16:52:04 +01:00
parent 83cbf6c7b1
commit 3bcef037b4
1 changed files with 74 additions and 16 deletions

View File

@ -1,65 +1,123 @@
<script>
import { onMount } from "svelte";
<script context="module">
//expose chart types for use or reference outside compnent
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
export const colorSchemas = britecharts
? britecharts.colors.colorSchemas
: null;
//export color gradients for use or reference outside the component
export const colorGradients = britecharts
? britecharts.colors.colorGradients
: null;
</script>
<script>
import { onMount } from "svelte";
export let type = "bar";
export let data = [];
export let tooltipProps = null;
export let colors = britecharts
? britecharts.colors.colorSchemas.britecharts
: null;
export let colors = colorSchemas ? colorSchemas.britecharts : null;
export let gradients = colorGradients ? colorGradients.bluePurple : null;
let chartElement = null;
let chartContainer = null;
let tooltipContainer = null;
let tooltipElement = null;
let chart = chartTypes.includes(type) ? britecharts[type]() : null;
export let tooltip = null; //can bind and therefore access
onMount(() => {
//TODO: Error handling if can't find britecharts or d3Selection
if (chart) {
chartContainer = d3.select(chartElement);
bindChartColors();
bindChartTooltip();
bindChartUIProps();
bindChartEvents();
chartContainer.datum(data).call(chart);
} else {
console.error("Britecharts could not be found");
}
});
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) {
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() {
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) {
if (validChartProps.includes(prop)) {
chart[prop](value);
} else {
console.warn(
`${type} chart - ${prop} is an unrecognised prop and wont be applied`
);
}
}
}
$: validChartProps = chart ? Object.getOwnPropertyNames(chart) : null;
$: canUseTooltip = type === "groupedBar" && tooltipProps;
$: console.log("VALID CHART PROPS", validChartProps);
</script>
<div bind:this={chartElement} class="chart-container" />
{#if canUseTooltip}
<div bind:this={tooltipElement} class="tooltip-container" />
{/if}