Functional Chart Wrapper for Britecharts
This commit is contained in:
parent
10137d1aa8
commit
133445ccda
|
@ -68,7 +68,7 @@
|
||||||
"lunr": "^2.3.5",
|
"lunr": "^2.3.5",
|
||||||
"mustache": "^4.0.1",
|
"mustache": "^4.0.1",
|
||||||
"safe-buffer": "^5.1.2",
|
"safe-buffer": "^5.1.2",
|
||||||
"shortid": "^2.2.8",
|
"shortid": "^2.2.15",
|
||||||
"string_decoder": "^1.2.0",
|
"string_decoder": "^1.2.0",
|
||||||
"svelte-portal": "^0.1.0",
|
"svelte-portal": "^0.1.0",
|
||||||
"svelte-simple-modal": "^0.4.2",
|
"svelte-simple-modal": "^0.4.2",
|
||||||
|
|
|
@ -15,32 +15,41 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
|
import shortid from "shortid"
|
||||||
|
|
||||||
|
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 useTooltip = 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
|
||||||
|
|
||||||
let chartElement = null;
|
let chartElement = null;
|
||||||
let chartContainer = null;
|
let chartContainer = null;
|
||||||
let tooltipContainer = null;
|
let tooltipContainer = null;
|
||||||
|
let legendContainer = null;
|
||||||
let tooltipElement = null;
|
let legend = 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
|
|
||||||
|
const chartClass = `chart-container-${_id}`
|
||||||
|
const legendClass = `legend-container-${_id}`
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (chart) {
|
if (chart) {
|
||||||
chartContainer = d3.select(chartElement);
|
chartContainer = d3.select(`.${chartClass}`);
|
||||||
bindChartColors();
|
bindChartColors();
|
||||||
bindChartTooltip();
|
|
||||||
bindChartUIProps();
|
bindChartUIProps();
|
||||||
bindChartEvents();
|
bindChartEvents();
|
||||||
chartContainer.datum(data).call(chart);
|
chartContainer.datum(data).call(chart);
|
||||||
|
bindChartTooltip();
|
||||||
|
bindChartLegend();
|
||||||
} else {
|
} else {
|
||||||
console.error("Britecharts could not be found");
|
console.error("Britecharts could not be found");
|
||||||
}
|
}
|
||||||
|
@ -58,17 +67,72 @@
|
||||||
if (canUseTooltip) {
|
if (canUseTooltip) {
|
||||||
tooltip = britecharts.tooltip();
|
tooltip = britecharts.tooltip();
|
||||||
|
|
||||||
const validTooltipProps = Object.getOwnPropertyNames(tooltip);
|
bindProps(tooltip, tooltipProps)
|
||||||
|
|
||||||
const props = Object.entries(tooltipProps);
|
tooltipContainer = d3.select(`.${chartClass} .metadata-group .vertical-marker-container`);
|
||||||
for (let [key, value] of props) {
|
|
||||||
if (validTooltipProps.includes(key)) {
|
|
||||||
tooltip[key](value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tooltipContainer = d3.select(tooltipElement);
|
|
||||||
tooltipContainer.datum([]).call(tooltip);
|
tooltipContainer.datum([]).call(tooltip);
|
||||||
|
// tooltip.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindChartLegend() {
|
||||||
|
if(useLegend) {
|
||||||
|
|
||||||
|
if(!Array.isArray(data)) {
|
||||||
|
console.warn("Cannot use legend as data is not an array")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let excludeProps = []
|
||||||
|
|
||||||
|
legend = britecharts.legend();
|
||||||
|
|
||||||
|
if(!legendProps || !legendProps.width) {
|
||||||
|
excludeProps = ["width"]
|
||||||
|
legend.width(chart.width())
|
||||||
|
}
|
||||||
|
|
||||||
|
if(legendProps){
|
||||||
|
bindProps(legend, legendProps, excludeProps)
|
||||||
|
}
|
||||||
|
|
||||||
|
legendContainer = d3.select(`.${legendClass}`)
|
||||||
|
legendContainer.datum(data).call(legend)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindChartEvents() {
|
||||||
|
if ($$props.on) {
|
||||||
|
const events = Object.entries($$props.on);
|
||||||
|
for (let [type, fn] of events) {
|
||||||
|
chart.on(type, fn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindChartUIProps() {
|
||||||
|
const excludeProps = ["data", "colors", "type", "gradients", "on", "useTooltip", "tooltip", "tooltipProps", "legendProps", "useLegend"]
|
||||||
|
|
||||||
|
if (!$$props.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);
|
||||||
|
|
||||||
|
for (let [prop, value] of props) {
|
||||||
|
if (validElementProps.includes(prop)) {
|
||||||
|
chart[prop](value);
|
||||||
|
} else {
|
||||||
|
console.warn(
|
||||||
|
`${type} - ${prop} is an unrecognised chart prop and wont be applied`
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,42 +146,12 @@
|
||||||
return modifiedProps;
|
return modifiedProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindChartEvents() {
|
|
||||||
if ($$props.on) {
|
|
||||||
const events = Object.entries($$props.on);
|
|
||||||
for (let [type, fn] of events) {
|
|
||||||
chart.on(type, fn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function bindChartUIProps() {
|
|
||||||
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;
|
$: validChartProps = chart ? Object.getOwnPropertyNames(chart) : null;
|
||||||
$: canUseTooltip = type === "groupedBar" && tooltipProps;
|
$: canUseTooltip = type === "groupedBar" && tooltipProps && useTooltip;
|
||||||
$: console.log("VALID CHART PROPS", validChartProps);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div bind:this={chartElement} class="chart-container" />
|
<div bind:this={chartElement} class={chartClass} />
|
||||||
|
{#if useLegend}
|
||||||
{#if canUseTooltip}
|
<div class={legendClass}/>
|
||||||
<div bind:this={tooltipElement} class="tooltip-container" />
|
|
||||||
{/if}
|
{/if}
|
Loading…
Reference in New Issue