forked from tsai/budibase
38 changed files with 11230 additions and 53 deletions
File diff suppressed because it is too large
@ -0,0 +1,218 @@ |
|||||
|
<script> |
||||
|
import { getColorSchema, getChartGradient } from "./Chart.svelte" |
||||
|
import britecharts from "britecharts" |
||||
|
import { onMount } from "svelte" |
||||
|
|
||||
|
import { select } from "d3-selection" |
||||
|
import shortid from "shortid" |
||||
|
/* |
||||
|
ISSUES: |
||||
|
- x and y axis label set and appear in the dom but do not display next to the axis |
||||
|
- x and y axis label offset - does effect position of labels but does not render text (see above) |
||||
|
- x tick label overlaps bar, seems to be no apu method to change this? Could do it by querying for it in the dom |
||||
|
specifically and doing this: <tspan x="-10" dy="0.32em">4.0</tspan> |
||||
|
*/ |
||||
|
|
||||
|
let tooltip |
||||
|
const _id = shortid.generate() |
||||
|
const chart = britecharts.bar() |
||||
|
const chartClass = `bar-container-${_id}` |
||||
|
const legendClass = `legend-container-${_id}` |
||||
|
|
||||
|
let chartElement = null |
||||
|
let chartContainer = null |
||||
|
let tooltipContainer = null |
||||
|
|
||||
|
export let customMouseOver = () => tooltip.show() |
||||
|
export let customMouseMove = (datapoint, colorMapping, x, y) => |
||||
|
tooltip.update(datapoint, colorMapping, x, y) |
||||
|
export let customMouseOut = () => tooltip.hide() |
||||
|
export let customClick = null |
||||
|
|
||||
|
export let data = [] |
||||
|
export let xAxisLabel = "" |
||||
|
export let yAxisLabel = "" |
||||
|
export let betweenBarsPadding = 0.1 //takes decimal values 0.1, 0.5 etc |
||||
|
export let gradient = null |
||||
|
export let color = "britecharts" |
||||
|
export let enableLabels = true |
||||
|
export let hasPercentage = null |
||||
|
export let hasSingleBarHighlight = true |
||||
|
export let highlightBarFunction = null |
||||
|
export let height = 200 |
||||
|
export let width = 300 |
||||
|
export let labelsMargin = null |
||||
|
export let isAnimated = true |
||||
|
export let isHorizontal = true |
||||
|
export let xAxisLabelOffset = null |
||||
|
export let yAxisLabelOffset = null |
||||
|
export let labelsNumberFormat = null |
||||
|
export let locale = null |
||||
|
export let valueLabel = null |
||||
|
export let nameLabel = null |
||||
|
export let numberFormat = null |
||||
|
export let labelsSize = null |
||||
|
export let xTicks = null |
||||
|
export let yTicks = null |
||||
|
export let percentageAxisToMaxRatio = null |
||||
|
|
||||
|
export let useLegend = true |
||||
|
|
||||
|
export let _bb |
||||
|
export let model |
||||
|
|
||||
|
let store = _bb.store |
||||
|
|
||||
|
onMount(async () => { |
||||
|
if (chartElement) { |
||||
|
if (model) { |
||||
|
await fetchData() |
||||
|
} |
||||
|
chartContainer = select(`.${chartClass}`) |
||||
|
bindChartUIProps() |
||||
|
bindChartEvents() |
||||
|
chartContainer.datum(_data).call(chart) |
||||
|
bindChartTooltip() |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
async function fetchData() { |
||||
|
const FETCH_RECORDS_URL = `/api/views/all_${model}` |
||||
|
const response = await _bb.api.get(FETCH_RECORDS_URL) |
||||
|
if (response.status === 200) { |
||||
|
const json = await response.json() |
||||
|
store.update(state => { |
||||
|
state[model] = json |
||||
|
return state |
||||
|
}) |
||||
|
} else { |
||||
|
throw new Error("Failed to fetch records.", response) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartUIProps() { |
||||
|
chart.numberFormat(".1f") |
||||
|
chart.labelsNumberFormat(".1f") |
||||
|
|
||||
|
if (color) { |
||||
|
chart.colorSchema(colorSchema) |
||||
|
} |
||||
|
if (gradient) { |
||||
|
chart.chartGradient(chartGradient) |
||||
|
} |
||||
|
if (xAxisLabel) { |
||||
|
chart.xAxisLabel(xAxisLabel) |
||||
|
} |
||||
|
if (yAxisLabel) { |
||||
|
chart.yAxisLabel(yAxisLabel) |
||||
|
} |
||||
|
if (betweenBarsPadding) { |
||||
|
chart.betweenBarsPadding(Number(betweenBarsPadding)) |
||||
|
} |
||||
|
if (enableLabels) { |
||||
|
chart.enableLabels(enableLabels) |
||||
|
} |
||||
|
if (hasPercentage) { |
||||
|
chart.hasPercentage(hasPercentage) |
||||
|
} |
||||
|
if (hasSingleBarHighlight) { |
||||
|
chart.hasSingleBarHighlight(hasSingleBarHighlight) |
||||
|
} |
||||
|
if (labelsMargin) { |
||||
|
chart.labelsMargin(labelsMargin) |
||||
|
} |
||||
|
if (height) { |
||||
|
chart.height(height) |
||||
|
} |
||||
|
if (highlightBarFunction) { |
||||
|
chart.highlightBarFunction(highlightBarFunction) |
||||
|
} |
||||
|
if (width) { |
||||
|
chart.width(width) |
||||
|
} |
||||
|
if (isAnimated) { |
||||
|
chart.isAnimated(isAnimated) |
||||
|
} |
||||
|
if (isHorizontal) { |
||||
|
chart.isHorizontal(isHorizontal) |
||||
|
} |
||||
|
if (yAxisLabelOffset) { |
||||
|
chart.yAxisLabelOffset(yAxisLabelOffset) |
||||
|
} |
||||
|
if (xAxisLabelOffset) { |
||||
|
chart.xAxisLabelOffset(Number(xAxisLabelOffset)) |
||||
|
} |
||||
|
if (labelsNumberFormat) { |
||||
|
chart.labelsNumberFormat(labelsNumberFormat) |
||||
|
} |
||||
|
if (valueLabel) { |
||||
|
chart.valueLabel(valueLabel) |
||||
|
} |
||||
|
if (locale) { |
||||
|
chart.locale(locale) |
||||
|
} |
||||
|
if (nameLabel) { |
||||
|
chart.nameLabel(nameLabel) |
||||
|
} |
||||
|
if (numberFormat) { |
||||
|
chart.numberFormat(numberFormat) |
||||
|
} |
||||
|
if (labelsSize) { |
||||
|
chart.labelsSize(labelsSize) |
||||
|
} |
||||
|
if (xTicks) { |
||||
|
chart.xTicks(xTicks) |
||||
|
} |
||||
|
if (yTicks) { |
||||
|
chart.yTicks(yTicks) |
||||
|
} |
||||
|
if (percentageAxisToMaxRatio) { |
||||
|
chart.percentageAxisToMaxRatio(percentageAxisToMaxRatio) |
||||
|
} |
||||
|
chartContainer.datum(_data).call(chart) |
||||
|
} |
||||
|
|
||||
|
function bindChartEvents() { |
||||
|
if (customMouseMove) { |
||||
|
chart.on("customMouseMove", customMouseMove) |
||||
|
} |
||||
|
if (customMouseOut) { |
||||
|
chart.on("customMouseOut", customMouseOut) |
||||
|
} |
||||
|
if (customMouseOver) { |
||||
|
chart.on("customMouseOver", customMouseOver) |
||||
|
} |
||||
|
if (customClick) { |
||||
|
chart.on("customClick", customClick) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartTooltip() { |
||||
|
tooltip = britecharts.miniTooltip() |
||||
|
tooltip.numberFormat(".0f") |
||||
|
tooltipContainer = select(`.${chartClass} .metadata-group`) |
||||
|
tooltipContainer.datum([]).call(tooltip) |
||||
|
} |
||||
|
|
||||
|
$: _data = model ? $store[model] : data |
||||
|
|
||||
|
$: colorSchema = getColorSchema(color) |
||||
|
$: chartGradient = getChartGradient(gradient) |
||||
|
</script> |
||||
|
|
||||
|
<!-- SVG Test |
||||
|
<svg viewBox="6 -8 200 22"> |
||||
|
<text x="5" y="10" class="text-svg">Hello World</text> |
||||
|
</svg>--> |
||||
|
|
||||
|
<div bind:this={chartElement} class={chartClass} /> |
||||
|
{#if useLegend} |
||||
|
<div class={legendClass} /> |
||||
|
{/if} |
||||
|
|
||||
|
<style> |
||||
|
.text-svg { |
||||
|
font: italic 15px serif; |
||||
|
fill: red; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,118 @@ |
|||||
|
<script> |
||||
|
import { getColorSchema, getChartGradient, notNull } from "./utils" |
||||
|
import britecharts from "britecharts" |
||||
|
import { onMount } from "svelte" |
||||
|
|
||||
|
import { select } from "d3-selection" |
||||
|
import shortid from "shortid" |
||||
|
|
||||
|
/* |
||||
|
ISSUES |
||||
|
- Chart gradient doesn't seem to do anything |
||||
|
*/ |
||||
|
|
||||
|
export let _bb |
||||
|
export let model |
||||
|
|
||||
|
let store = _bb.store |
||||
|
|
||||
|
const _id = shortid.generate() |
||||
|
|
||||
|
const chart = britecharts.brush() |
||||
|
const chartClass = `brush-container-${_id}` |
||||
|
const legendClass = `legend-container-${_id}` |
||||
|
|
||||
|
let chartElement = null |
||||
|
let chartContainer = null |
||||
|
|
||||
|
export let customBrushEnd = null |
||||
|
export let customBrushStart = null |
||||
|
|
||||
|
export let data = [] |
||||
|
export let gradient = null |
||||
|
export let height = 200 |
||||
|
export let width = 200 |
||||
|
export let margin = { top: 0, right: 0, bottom: 0, left: 0 } |
||||
|
|
||||
|
export let dateRange = null |
||||
|
export let locale = null |
||||
|
export let roundingTimeInterval = null |
||||
|
export let xAxisFormat = null |
||||
|
export let xTicks = null |
||||
|
export let xAxisCustomFormat = null |
||||
|
|
||||
|
onMount(async () => { |
||||
|
if (chart) { |
||||
|
if (model) { |
||||
|
await fetchData() |
||||
|
} |
||||
|
chartContainer = select(`.${chartClass}`) |
||||
|
bindChartUIProps() |
||||
|
bindChartEvents() |
||||
|
chartContainer.datum(_data).call(chart) |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
async function fetchData() { |
||||
|
const FETCH_RECORDS_URL = `/api/views/all_${model}` |
||||
|
const response = await _bb.api.get(FETCH_RECORDS_URL) |
||||
|
if (response.status === 200) { |
||||
|
const json = await response.json() |
||||
|
store.update(state => { |
||||
|
state[model] = json |
||||
|
return state |
||||
|
}) |
||||
|
} else { |
||||
|
throw new Error("Failed to fetch records.", response) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartUIProps() { |
||||
|
if (notNull(gradient)) { |
||||
|
chart.gradient(chartGradient) |
||||
|
} |
||||
|
if (notNull(height)) { |
||||
|
chart.height(height) |
||||
|
} |
||||
|
if (notNull(width)) { |
||||
|
chart.width(width) |
||||
|
} |
||||
|
if (notNull(margin)) { |
||||
|
chart.margin(margin) |
||||
|
} |
||||
|
if (notNull(dateRange)) { |
||||
|
chart.dateRange(dateRange) |
||||
|
} |
||||
|
if (notNull(locale)) { |
||||
|
chart.locale(locale) |
||||
|
} |
||||
|
if (notNull(roundingTimeInterval)) { |
||||
|
chart.roundingTimeInterval(roundingTimeInterval) |
||||
|
} |
||||
|
if (notNull(xAxisFormat)) { |
||||
|
chart.xAxisFormat(xAxisFormat) |
||||
|
} |
||||
|
if (notNull(xTicks)) { |
||||
|
chart.xTicks(xTicks) |
||||
|
} |
||||
|
if (notNull(xAxisCustomFormat)) { |
||||
|
chart.xAxisCustomFormat(xAxisCustomFormat) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartEvents() { |
||||
|
if (customBrushEnd) { |
||||
|
chart.on("customBrushEnd", customBrushEnd) |
||||
|
} |
||||
|
if (customBrushStart) { |
||||
|
chart.on("customBrushStart", customBrushStart) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$: _data = model ? $store[model] : data |
||||
|
|
||||
|
$: chartGradient = getChartGradient(gradient) |
||||
|
$: console.log(chartGradient) |
||||
|
</script> |
||||
|
|
||||
|
<div bind:this={chartElement} class={chartClass} /> |
||||
@ -0,0 +1,103 @@ |
|||||
|
<script> |
||||
|
import { getColorSchema, getChartGradient, notNull } from "./utils" |
||||
|
import britecharts from "britecharts" |
||||
|
import { onMount } from "svelte" |
||||
|
|
||||
|
import { select } from "d3-selection" |
||||
|
import shortid from "shortid" |
||||
|
|
||||
|
const _id = shortid.generate() |
||||
|
|
||||
|
export let _bb |
||||
|
export let model |
||||
|
|
||||
|
let store = _bb.store |
||||
|
|
||||
|
const chart = britecharts.bullet() |
||||
|
const chartClass = `bullet-container-${_id}` |
||||
|
const legendClass = `legend-container-${_id}` |
||||
|
|
||||
|
let chartElement = null |
||||
|
let chartContainer = null |
||||
|
|
||||
|
export let data = [] |
||||
|
export let aspectRatio = null |
||||
|
export let color = "britecharts" |
||||
|
export let customSubtitle = null |
||||
|
export let customTitle = null |
||||
|
export let numberFormat = null |
||||
|
export let paddingBetweenAxisAndChart = null |
||||
|
export let startMaxRangeOpacity = null |
||||
|
export let ticks = null |
||||
|
export let isReverse = false |
||||
|
export let height = 200 |
||||
|
export let width = 200 |
||||
|
export let margin = { top: 0, right: 0, bottom: 0, left: 0 } |
||||
|
|
||||
|
onMount(async () => { |
||||
|
if (chart) { |
||||
|
if (model) { |
||||
|
await fetchData() |
||||
|
} |
||||
|
chartContainer = select(`.${chartClass}`) |
||||
|
bindChartUIProps() |
||||
|
chartContainer.datum(_data).call(chart) |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
async function fetchData() { |
||||
|
const FETCH_RECORDS_URL = `/api/views/all_${model}` |
||||
|
const response = await _bb.api.get(FETCH_RECORDS_URL) |
||||
|
if (response.status === 200) { |
||||
|
const json = await response.json() |
||||
|
store.update(state => { |
||||
|
state[model] = json |
||||
|
return state |
||||
|
}) |
||||
|
} else { |
||||
|
throw new Error("Failed to fetch records.", response) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartUIProps() { |
||||
|
if (notNull(color)) { |
||||
|
chart.colorSchema(colorSchema) |
||||
|
} |
||||
|
if (notNull(aspectRatio)) { |
||||
|
chart.aspectRatio(aspectRatio) |
||||
|
} |
||||
|
if (notNull(customSubtitle)) { |
||||
|
chart.customSubtitle(customSubtitle) |
||||
|
} |
||||
|
if (notNull(customTitle)) { |
||||
|
chart.customTitle(customTitle) |
||||
|
} |
||||
|
if (notNull(numberFormat)) { |
||||
|
chart.numberFormat(numberFormat) |
||||
|
} |
||||
|
if (notNull(paddingBetweenAxisAndChart)) { |
||||
|
chart.paddingBetweenAxisAndChart(paddingBetweenAxisAndChart) |
||||
|
} |
||||
|
if (notNull(startMaxRangeOpacity)) { |
||||
|
chart.startMaxRangeOpacity(startMaxRangeOpacity) |
||||
|
} |
||||
|
if (notNull(ticks)) { |
||||
|
chart.ticks(ticks) |
||||
|
} |
||||
|
if (notNull(isReverse)) { |
||||
|
chart.isReverse(isReverse) |
||||
|
} |
||||
|
if (notNull(height)) { |
||||
|
chart.height(height) |
||||
|
} |
||||
|
if (notNull(width)) { |
||||
|
chart.width(width) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$: _data = model ? $store[model] : data |
||||
|
|
||||
|
$: colorSchema = getColorSchema(color) |
||||
|
</script> |
||||
|
|
||||
|
<div bind:this={chartElement} class={chartClass} /> |
||||
@ -0,0 +1,169 @@ |
|||||
|
<script context="module"> |
||||
|
//expose chart types for use or reference outside compnent |
||||
|
export const chartTypes = britecharts ? Object.keys(britecharts) : null |
||||
|
|
||||
|
//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 |
||||
|
|
||||
|
export const getColorSchema = color => |
||||
|
color ? colorSchemas[color] : colorSchemas["britecharts"] |
||||
|
|
||||
|
export const getChartGradient = gradient => |
||||
|
gradient ? colorGradients[gradient] : null |
||||
|
</script> |
||||
|
|
||||
|
<script> |
||||
|
import { beforeUpdate } from "svelte" |
||||
|
import britecharts from "britecharts" |
||||
|
import { select } from "d3-selection" |
||||
|
|
||||
|
import { onMount } from "svelte" |
||||
|
import shortid from "shortid" |
||||
|
|
||||
|
const _id = shortid.generate() |
||||
|
|
||||
|
export let type = "bar" |
||||
|
export let data = [] |
||||
|
export let tooltipProps = null |
||||
|
export let legendProps = null |
||||
|
export let useTooltip = false |
||||
|
export let useLegend = false |
||||
|
|
||||
|
export let tooltip = null //can bind to outside the component and therefore access |
||||
|
|
||||
|
let chartElement = null |
||||
|
let chartContainer = null |
||||
|
let tooltipContainer = null |
||||
|
let legendContainer = null |
||||
|
let legend = null |
||||
|
|
||||
|
let chart = chartTypes.includes(type) ? britecharts[type]() : null |
||||
|
|
||||
|
const chartClass = `chart-container-${_id}` |
||||
|
const legendClass = `legend-container-${_id}` |
||||
|
|
||||
|
onMount(() => { |
||||
|
if (chart) { |
||||
|
chartContainer = select(`.${chartClass}`) |
||||
|
bindChartUIProps() |
||||
|
bindChartEvents() |
||||
|
chartContainer.datum(data).call(chart) |
||||
|
bindChartTooltip() |
||||
|
bindChartLegend() |
||||
|
} else { |
||||
|
console.error("Britecharts could not be found") |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
function bindChartTooltip() { |
||||
|
if (useTooltip) { |
||||
|
tooltip = britecharts.miniTooltip() |
||||
|
|
||||
|
bindProps(tooltip, tooltipProps) |
||||
|
|
||||
|
tooltipContainer = select(`.${chartClass} .metadata-group`) |
||||
|
tooltipContainer.datum([]).call(tooltip) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
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 = select(`.${legendClass}`) |
||||
|
legendContainer.datum(data).call(legend) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartEvents() { |
||||
|
if ($$props.on) { |
||||
|
const events = Object.entries($$props.on) |
||||
|
for (let [type, fn] of events) { |
||||
|
if (fn) { |
||||
|
chart.on(type, fn) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartUIProps() { |
||||
|
const excludeProps = [ |
||||
|
"data", |
||||
|
"type", |
||||
|
"on", |
||||
|
"useTooltip", |
||||
|
"tooltip", |
||||
|
"tooltipProps", |
||||
|
"legendProps", |
||||
|
"useLegend", |
||||
|
] |
||||
|
|
||||
|
if (!$$props.width) { |
||||
|
chart.width(chartElement.getBoundingClientRect().width) |
||||
|
} |
||||
|
|
||||
|
bindProps(chart, $$props, excludeProps) |
||||
|
} |
||||
|
|
||||
|
function bindProps(element, elProps, excludeArray) { |
||||
|
if (elProps) { |
||||
|
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)) { |
||||
|
if (!!value) { |
||||
|
chart[prop](value) |
||||
|
} |
||||
|
} else { |
||||
|
console.warn( |
||||
|
`${type} - ${prop} is an unrecognised chart prop and wont be applied` |
||||
|
) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function excludeProps(props, propsToExclude) { |
||||
|
const modifiedProps = {} |
||||
|
for (const prop in props) { |
||||
|
if (!propsToExclude.includes(prop)) { |
||||
|
modifiedProps[prop] = props[prop] |
||||
|
} |
||||
|
} |
||||
|
return modifiedProps |
||||
|
} |
||||
|
|
||||
|
$: validChartProps = chart ? Object.getOwnPropertyNames(chart) : null |
||||
|
</script> |
||||
|
|
||||
|
<div bind:this={chartElement} class={chartClass} /> |
||||
|
{#if useLegend} |
||||
|
<div class={legendClass} /> |
||||
|
{/if} |
||||
@ -0,0 +1,224 @@ |
|||||
|
<script> |
||||
|
import { getColorSchema, notNull } from "./utils.js" |
||||
|
import Legend from "./Legend.svelte" |
||||
|
import britecharts from "britecharts" |
||||
|
import { onMount } from "svelte" |
||||
|
|
||||
|
import { select } from "d3-selection" |
||||
|
import shortid from "shortid" |
||||
|
|
||||
|
const _id = shortid.generate() |
||||
|
|
||||
|
const chart = britecharts.donut() |
||||
|
const chartClass = `donut-container-${_id}` |
||||
|
const legendClass = `legend-container-${_id}` |
||||
|
let legendChart |
||||
|
|
||||
|
let chartElement = null |
||||
|
let chartContainer = null |
||||
|
|
||||
|
let chartSvgWidth = 0 |
||||
|
let chartSvg = null |
||||
|
|
||||
|
export let _bb |
||||
|
export let model |
||||
|
|
||||
|
let store = _bb.store |
||||
|
|
||||
|
export let customMouseMove = null |
||||
|
export let customClick = null |
||||
|
|
||||
|
export let orderingFunction = null |
||||
|
|
||||
|
let data = [] |
||||
|
export let color = "britecharts" |
||||
|
export let height = 200 |
||||
|
export let width = 200 |
||||
|
export let margin = null |
||||
|
|
||||
|
export let centeredTextFunction = null |
||||
|
export let externalRadius = 25 |
||||
|
export let percentageFormat = null |
||||
|
export let hasFixedHighlightedSlice = false |
||||
|
export let hasLastHoverSliceHighlighted = false |
||||
|
export let hasHoverAnimation = true |
||||
|
export let highlightSliceById = null |
||||
|
export let numberFormat = null |
||||
|
export let internalRadius = 25 |
||||
|
export let isAnimated = true |
||||
|
export let radiusHoverOffset = 0 |
||||
|
export let nameKey = null |
||||
|
export let valueKey = null |
||||
|
// export let useLegend = true |
||||
|
export let horizontalLegend = false |
||||
|
export let legendWidth = null |
||||
|
export let legendHeight = null |
||||
|
|
||||
|
async function fetchData() { |
||||
|
const FETCH_RECORDS_URL = `/api/views/all_${model}` |
||||
|
const response = await _bb.api.get(FETCH_RECORDS_URL) |
||||
|
if (response.status === 200) { |
||||
|
const json = await response.json() |
||||
|
store.update(state => { |
||||
|
state[model] = json |
||||
|
return state |
||||
|
}) |
||||
|
} else { |
||||
|
throw new Error("Failed to fetch records.", response) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
onMount(async () => { |
||||
|
if (chart) { |
||||
|
if (model) { |
||||
|
await fetchData() |
||||
|
data = checkAndReformatData($store[model]) |
||||
|
if (data.length === 0) { |
||||
|
console.error( |
||||
|
"Donut - please provide a valid name and value field for the chart" |
||||
|
) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
chart.emptyDataConfig({ |
||||
|
showEmptySlice: true, |
||||
|
emptySliceColor: "#F0F0F0", |
||||
|
}) |
||||
|
|
||||
|
chartContainer = select(`.${chartClass}`) |
||||
|
bindChartUIProps() |
||||
|
bindChartEvents() |
||||
|
chartContainer.datum(data).call(chart) |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
function checkAndReformatData(data) { |
||||
|
let _data = [...data] |
||||
|
|
||||
|
if (valueKey) { |
||||
|
_data = reformatDataKey(_data, valueKey, "quantity") |
||||
|
} |
||||
|
|
||||
|
if (nameKey) { |
||||
|
_data = reformatDataKey(_data, nameKey, "name") |
||||
|
} |
||||
|
|
||||
|
return _data.every(d => d.quantity) && _data.every(d => d.name) ? _data : [] |
||||
|
} |
||||
|
|
||||
|
function reformatDataKey(data = [], dataKey = null, formatKey = null) { |
||||
|
let ignoreList = ["_id", "_rev", "id"] |
||||
|
if (dataKey && data.every(d => d[dataKey])) { |
||||
|
return data.map(d => { |
||||
|
let clonedRecord = { ...d } |
||||
|
if (clonedRecord[formatKey]) { |
||||
|
delete clonedRecord[formatKey] |
||||
|
} |
||||
|
let value = clonedRecord[dataKey] |
||||
|
if (!ignoreList.includes(dataKey)) { |
||||
|
delete clonedRecord[dataKey] |
||||
|
} |
||||
|
clonedRecord[formatKey] = value |
||||
|
return clonedRecord |
||||
|
}) |
||||
|
} else { |
||||
|
return data |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartUIProps() { |
||||
|
chart.percentageFormat(".0f") |
||||
|
|
||||
|
if (notNull(color)) { |
||||
|
chart.colorSchema(getColorSchema(color)) |
||||
|
} |
||||
|
if (notNull(height)) { |
||||
|
chart.height(height) |
||||
|
} |
||||
|
if (notNull(width)) { |
||||
|
chart.width(width) |
||||
|
} |
||||
|
if (notNull(margin)) { |
||||
|
chart.margin(margin) |
||||
|
} |
||||
|
if (notNull(centeredTextFunction)) { |
||||
|
chart.centeredTextFunction(centeredTextFunction) |
||||
|
} |
||||
|
if (notNull(externalRadius)) { |
||||
|
chart.externalRadius(externalRadius) |
||||
|
} |
||||
|
if (notNull(percentageFormat)) { |
||||
|
chart.percentageFormat(percentageFormat) |
||||
|
} |
||||
|
if (notNull(hasFixedHighlightedSlice)) { |
||||
|
chart.hasFixedHighlightedSlice(hasFixedHighlightedSlice) |
||||
|
} |
||||
|
if (notNull(hasLastHoverSliceHighlighted)) { |
||||
|
chart.hasLastHoverSliceHighlighted(hasLastHoverSliceHighlighted) |
||||
|
} |
||||
|
if (notNull(hasHoverAnimation)) { |
||||
|
chart.hasHoverAnimation(hasHoverAnimation) |
||||
|
} |
||||
|
if (notNull(highlightSliceById)) { |
||||
|
chart.highlightSliceById(highlightSliceById) |
||||
|
} |
||||
|
if (notNull(numberFormat)) { |
||||
|
chart.numberFormat(numberFormat) |
||||
|
} |
||||
|
if (notNull(internalRadius)) { |
||||
|
chart.internalRadius(internalRadius) |
||||
|
} |
||||
|
if (notNull(isAnimated)) { |
||||
|
chart.isAnimated(isAnimated) |
||||
|
} |
||||
|
if (notNull(radiusHoverOffset)) { |
||||
|
chart.radiusHoverOffset(radiusHoverOffset) |
||||
|
} |
||||
|
if (notNull(orderingFunction)) { |
||||
|
chart.orderingFunction(orderingFunction) |
||||
|
} |
||||
|
chartContainer.datum(data).call(chart) |
||||
|
chartSvg = document.querySelector(`.${chartClass} .britechart`) |
||||
|
} |
||||
|
|
||||
|
function bindChartEvents() { |
||||
|
if (customClick) { |
||||
|
chart.on("customClick", customClick) |
||||
|
} |
||||
|
if (customMouseMove) { |
||||
|
chart.on("customMouseMove", customMouseMove) |
||||
|
} |
||||
|
|
||||
|
if (legendChart) { |
||||
|
chart.on("customMouseOut", function() { |
||||
|
legendChart.clearHighlight() |
||||
|
}) |
||||
|
chart.on("customMouseOver", function(data) { |
||||
|
legendChart.highlight(data.data.id) |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$: if (!width && chartSvg) { |
||||
|
width = chartSvg.clientWidth |
||||
|
chart.width(width) |
||||
|
chartContainer.datum(data).call(chart) |
||||
|
} |
||||
|
|
||||
|
$: colorSchema = getColorSchema(color) |
||||
|
</script> |
||||
|
|
||||
|
<div> |
||||
|
<div bind:this={chartElement} class={chartClass} /> |
||||
|
{#if data.length > 0} |
||||
|
<Legend |
||||
|
bind:legend={legendChart} |
||||
|
{colorSchema} |
||||
|
useLegend |
||||
|
isHorizontal={horizontalLegend} |
||||
|
width={legendWidth || width} |
||||
|
height={legendHeight} |
||||
|
{chartClass} |
||||
|
{data} /> |
||||
|
{/if} |
||||
|
</div> |
||||
@ -0,0 +1,163 @@ |
|||||
|
<script> |
||||
|
import { getColorSchema, getChartGradient, notNull } from "./utils" |
||||
|
import britecharts from "britecharts" |
||||
|
import { onMount } from "svelte" |
||||
|
|
||||
|
/* |
||||
|
ISSUES |
||||
|
- Renders but seems to be a problem with tooltip hover |
||||
|
*/ |
||||
|
|
||||
|
import { select } from "d3-selection" |
||||
|
import shortid from "shortid" |
||||
|
|
||||
|
const _id = shortid.generate() |
||||
|
|
||||
|
export let _bb |
||||
|
export let model |
||||
|
|
||||
|
let store = _bb.store |
||||
|
|
||||
|
const chart = britecharts.groupedBar() |
||||
|
const chartClass = `groupedbar-container-${_id}` |
||||
|
const legendClass = `legend-container-${_id}` |
||||
|
|
||||
|
let tooltip |
||||
|
let tooltipContainer |
||||
|
let chartElement = null |
||||
|
let chartContainer = null |
||||
|
|
||||
|
export let customMouseOver = () => tooltip.show() |
||||
|
export let customMouseMove = (dataPoint, topicColorMap, dataPointXPosition) => |
||||
|
tooltip.update(dataPoint, topicColorMap, dataPointXPosition) |
||||
|
export let customMouseOut = () => tooltip.hide() |
||||
|
export let customClick = null |
||||
|
|
||||
|
export let data = [] |
||||
|
export let color = "britecharts" |
||||
|
export let height = 200 |
||||
|
export let width = 200 |
||||
|
export let margin = { top: 0, right: 0, bottom: 0, left: 0 } |
||||
|
export let aspectRatio = null |
||||
|
export let grid = null |
||||
|
export let groupLabel = null |
||||
|
export let isAnimated = null |
||||
|
export let isHorizontal = null |
||||
|
export let nameLabel = null |
||||
|
export let valueLabel = null |
||||
|
export let valueLabelFormat = null |
||||
|
export let xTicks = null |
||||
|
export let yAxisLabel = null |
||||
|
export let yAxisLabelOffset = null |
||||
|
export let yTicks = null |
||||
|
export let yTickTextOffset = null |
||||
|
export let useLegend = true |
||||
|
|
||||
|
onMount(async () => { |
||||
|
if (chart) { |
||||
|
if (model) { |
||||
|
await fetchData() |
||||
|
} |
||||
|
chartContainer = select(`.${chartClass}`) |
||||
|
bindChartUIProps() |
||||
|
// bindChartEvents() |
||||
|
chartContainer.datum(data).call(chart) |
||||
|
// bindChartTooltip() |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
async function fetchData() { |
||||
|
const FETCH_RECORDS_URL = `/api/views/all_${model}` |
||||
|
const response = await _bb.api.get(FETCH_RECORDS_URL) |
||||
|
if (response.status === 200) { |
||||
|
const json = await response.json() |
||||
|
store.update(state => { |
||||
|
state[model] = json |
||||
|
return state |
||||
|
}) |
||||
|
} else { |
||||
|
throw new Error("Failed to fetch records.", response) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartUIProps() { |
||||
|
if (notNull(color)) { |
||||
|
chart.colorSchema(colorSchema) |
||||
|
} |
||||
|
if (notNull(height)) { |
||||
|
chart.height(height) |
||||
|
} |
||||
|
if (notNull(width)) { |
||||
|
chart.width(width) |
||||
|
} |
||||
|
if (notNull(aspectRatio)) { |
||||
|
chart.aspectRatio(aspectRatio) |
||||
|
} |
||||
|
if (notNull(grid)) { |
||||
|
chart.grid(grid) |
||||
|
} |
||||
|
if (notNull(groupLabel)) { |
||||
|
chart.groupLabel(groupLabel) |
||||
|
} |
||||
|
if (notNull(isAnimated)) { |
||||
|
chart.isAnimated(isAnimated) |
||||
|
} |
||||
|
if (notNull(isHorizontal)) { |
||||
|
chart.isHorizontal(isHorizontal) |
||||
|
} |
||||
|
if (notNull(nameLabel)) { |
||||
|
chart.nameLabel(nameLabel) |
||||
|
} |
||||
|
if (notNull(valueLabel)) { |
||||
|
chart.valueLabel(valueLabel) |
||||
|
} |
||||
|
if (notNull(valueLabelFormat)) { |
||||
|
chart.valueLabelFormat(valueLabelFormat) |
||||
|
} |
||||
|
if (notNull(xTicks)) { |
||||
|
chart.xTicks(xTicks) |
||||
|
} |
||||
|
if (notNull(yAxisLabel)) { |
||||
|
chart.yAxisLabel(yAxisLabel) |
||||
|
} |
||||
|
if (notNull(yAxisLabelOffset)) { |
||||
|
chart.yAxisLabelOffset(yAxisLabelOffset) |
||||
|
} |
||||
|
if (notNull(yTicks)) { |
||||
|
chart.yTicks(yTicks) |
||||
|
} |
||||
|
if (notNull(yTickTextOffset)) { |
||||
|
chart.yTickTextOffset(yTickTextOffset) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartTooltip() { |
||||
|
tooltip = britecharts.miniTooltip() |
||||
|
tooltipContainer = select(`.${chartClass} .metadata-group`) |
||||
|
tooltipContainer.datum([]).call(tooltip) |
||||
|
} |
||||
|
|
||||
|
function bindChartEvents() { |
||||
|
if (customClick) { |
||||
|
chart.on("customClick", customClick) |
||||
|
} |
||||
|
if (customMouseMove) { |
||||
|
chart.on("customMouseMove", customMouseMove) |
||||
|
} |
||||
|
if (customMouseOut) { |
||||
|
chart.on("customMouseOut", customMouseOut) |
||||
|
} |
||||
|
if (customMouseOver) { |
||||
|
chart.on("customMouseOver", customMouseOver) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$: _data = model ? $store[model] : data |
||||
|
|
||||
|
$: colorSchema = getColorSchema(color) |
||||
|
</script> |
||||
|
|
||||
|
<div bind:this={chartElement} class={chartClass} /> |
||||
|
{#if useLegend} |
||||
|
<div class={legendClass} /> |
||||
|
{/if} |
||||
@ -0,0 +1,83 @@ |
|||||
|
<script> |
||||
|
import { getColorSchema, getChartGradient, notNull } from "./utils" |
||||
|
import britecharts from "britecharts" |
||||
|
import { onMount } from "svelte" |
||||
|
|
||||
|
import { select } from "d3-selection" |
||||
|
import shortid from "shortid" |
||||
|
|
||||
|
const _id = shortid.generate() |
||||
|
|
||||
|
export let _bb |
||||
|
export let model |
||||
|
|
||||
|
let store = _bb.store |
||||
|
|
||||
|
const chart = britecharts.heatmap() |
||||
|
const chartClass = `heatmap-container-${_id}` |
||||
|
const legendClass = `legend-container-${_id}` |
||||
|
|
||||
|
let chartElement = null |
||||
|
let chartContainer = null |
||||
|
|
||||
|
export let data = [] |
||||
|
export let color = "britecharts" |
||||
|
export let height = 200 |
||||
|
export let width = 200 |
||||
|
export let margin = { top: 0, right: 0, bottom: 0, left: 0 } |
||||
|
export let useLegend = true |
||||
|
export let yAxisLabels = null |
||||
|
export let boxSize = null |
||||
|
|
||||
|
onMount(async () => { |
||||
|
if (chart) { |
||||
|
if (model) { |
||||
|
await fetchData() |
||||
|
} |
||||
|
chartContainer = select(`.${chartClass}`) |
||||
|
bindChartUIProps() |
||||
|
chartContainer.datum(data).call(chart) |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
async function fetchData() { |
||||
|
const FETCH_RECORDS_URL = `/api/views/all_${model}` |
||||
|
const response = await _bb.api.get(FETCH_RECORDS_URL) |
||||
|
if (response.status === 200) { |
||||
|
const json = await response.json() |
||||
|
store.update(state => { |
||||
|
state[model] = json |
||||
|
return state |
||||
|
}) |
||||
|
} else { |
||||
|
throw new Error("Failed to fetch records.", response) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartUIProps() { |
||||
|
if (notNull(color)) { |
||||
|
chart.colorSchema(colorSchema) |
||||
|
} |
||||
|
if (notNull(height)) { |
||||
|
chart.height(height) |
||||
|
} |
||||
|
if (notNull(width)) { |
||||
|
chart.width(width) |
||||
|
} |
||||
|
if (notNull(boxSize)) { |
||||
|
chart.boxSize(boxSize) |
||||
|
} |
||||
|
if (notNull(yAxisLabels)) { |
||||
|
chart.yAxisLabels(yAxisLabels) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$: _data = model ? $store[model] : data |
||||
|
|
||||
|
$: colorSchema = getColorSchema(color) |
||||
|
</script> |
||||
|
|
||||
|
<div bind:this={chartElement} class={chartClass} /> |
||||
|
{#if useLegend} |
||||
|
<div class={legendClass} /> |
||||
|
{/if} |
||||
@ -0,0 +1,82 @@ |
|||||
|
<script> |
||||
|
import britecharts from "britecharts" |
||||
|
import { notNull } from "./utils" |
||||
|
import { select } from "d3-selection" |
||||
|
import { onMount } from "svelte" |
||||
|
|
||||
|
export let useLegend = true |
||||
|
export let data = [] |
||||
|
export let width = null |
||||
|
export let height = null |
||||
|
export let colorSchema = null |
||||
|
export let highlight = null |
||||
|
export let highlightByEntryId = null |
||||
|
export let isHorizontal = false |
||||
|
export let margin = null |
||||
|
export let marginRatio = null |
||||
|
export let markerSize = null |
||||
|
export let numberFormat = null |
||||
|
export let unit = null |
||||
|
|
||||
|
export let legend = britecharts.legend() //exported it can be bound to |
||||
|
let legendContainer = null |
||||
|
let legendElement = null |
||||
|
|
||||
|
$: { |
||||
|
if (legendElement) { |
||||
|
legendContainer = select(legendElement) |
||||
|
legend.numberFormat(".0f") |
||||
|
|
||||
|
if (width) { |
||||
|
legend.width(width) |
||||
|
} |
||||
|
|
||||
|
if (notNull(height)) { |
||||
|
legend.height(height) |
||||
|
} |
||||
|
|
||||
|
if (notNull(colorSchema)) { |
||||
|
legend.colorSchema(colorSchema) |
||||
|
} |
||||
|
|
||||
|
if (notNull(highlight)) { |
||||
|
legend.highlight(highlight) |
||||
|
} |
||||
|
|
||||
|
if (notNull(highlightByEntryId)) { |
||||
|
legend.highlightByEntryId(highlightByEntryId) |
||||
|
} |
||||
|
|
||||
|
if (notNull(isHorizontal)) { |
||||
|
legend.isHorizontal(isHorizontal) |
||||
|
} |
||||
|
|
||||
|
if (notNull(margin)) { |
||||
|
legend.margin(margin) |
||||
|
} |
||||
|
|
||||
|
if (notNull(marginRatio)) { |
||||
|
legend.marginRatio(marginRatio) |
||||
|
} |
||||
|
|
||||
|
if (notNull(markerSize)) { |
||||
|
legend.markerSize(markerSize) |
||||
|
} |
||||
|
|
||||
|
if (notNull(numberFormat)) { |
||||
|
legend.numberFormat(numberFormat) |
||||
|
} |
||||
|
|
||||
|
if (notNull(unit)) { |
||||
|
legend.unit(unit) |
||||
|
} |
||||
|
legendContainer.datum(data).call(legend) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const legendClass = `legend-container` |
||||
|
</script> |
||||
|
|
||||
|
{#if useLegend} |
||||
|
<div bind:this={legendElement} class={legendClass} /> |
||||
|
{/if} |
||||
@ -0,0 +1,209 @@ |
|||||
|
<script> |
||||
|
import { getColorSchema, getChartGradient, notNull } from "./utils" |
||||
|
import britecharts from "britecharts" |
||||
|
import { onMount } from "svelte" |
||||
|
|
||||
|
import { select } from "d3-selection" |
||||
|
import shortid from "shortid" |
||||
|
|
||||
|
const _id = shortid.generate() |
||||
|
|
||||
|
export let _bb |
||||
|
export let model |
||||
|
|
||||
|
let store = _bb.store |
||||
|
|
||||
|
const chart = britecharts.line() |
||||
|
const chartClass = `line-container-${_id}` |
||||
|
const legendClass = `legend-container-${_id}` |
||||
|
|
||||
|
let chartElement |
||||
|
let chartContainer |
||||
|
let tooltip |
||||
|
let tooltipContainer |
||||
|
|
||||
|
export let customMouseHover = null |
||||
|
export let customMouseMove = null |
||||
|
export let customMouseOut = null |
||||
|
export let customDataEntryClick = null |
||||
|
export let customTouchMove = null |
||||
|
|
||||
|
export let data = [] |
||||
|
export let color = "britecharts" |
||||
|
export let axisTimeCombinations = "" |
||||
|
export let grid = "horizontal" |
||||
|
export let aspectRatio = 0.5 |
||||
|
export let dateLabel = "date" |
||||
|
export let width = null |
||||
|
export let height = null |
||||
|
export let isAnimated = true |
||||
|
export let lineCurve = "linear" //see api for possible opts |
||||
|
export let locale = "en-GB" |
||||
|
export let numberFormat = "" |
||||
|
export let shouldShowAllDataPoints = true |
||||
|
export let topicLabel = null |
||||
|
export let valueLabel = null |
||||
|
export let xAxisLabel = "" |
||||
|
export let xAxisValueType = "date" |
||||
|
export let xAxisScale = "linear" |
||||
|
export let xAxisFormat = "day-month" |
||||
|
export let xAxisCustomFormat = "%H" |
||||
|
export let yAxisLabel = null |
||||
|
export let useLegend = true |
||||
|
export let yAxisLabelPadding = null |
||||
|
export let lines = null //not handled by setting prop |
||||
|
export let tooltipThreshold = null |
||||
|
|
||||
|
onMount(async () => { |
||||
|
if (chart) { |
||||
|
if (model) { |
||||
|
await fetchData() |
||||
|
} |
||||
|
chartContainer = select(`.${chartClass}`) |
||||
|
bindChartUIProps() |
||||
|
bindChartEvents() |
||||
|
chartContainer.datum(_data).call(chart) |
||||
|
bindChartTooltip() |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
async function fetchData() { |
||||
|
const FETCH_RECORDS_URL = `/api/views/all_${model}` |
||||
|
const response = await _bb.api.get(FETCH_RECORDS_URL) |
||||
|
if (response.status === 200) { |
||||
|
const json = await response.json() |
||||
|
store.update(state => { |
||||
|
state[model] = json |
||||
|
return state |
||||
|
}) |
||||
|
} else { |
||||
|
throw new Error("Failed to fetch records.", response) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartUIProps() { |
||||
|
if (notNull(color)) { |
||||
|
chart.colorSchema(colorSchema) |
||||
|
} |
||||
|
if (notNull(axisTimeCombinations)) { |
||||
|
chart.axisTimeCombinations(axisTimeCombinations) |
||||
|
} |
||||
|
if (notNull(grid)) { |
||||
|
chart.grid(grid) |
||||
|
} |
||||
|
if (notNull(aspectRatio)) { |
||||
|
chart.aspectRatio(aspectRatio) |
||||
|
} |
||||
|
if (notNull(dateLabel)) { |
||||
|
chart.dateLabel(dateLabel) |
||||
|
} |
||||
|
if (notNull(width)) { |
||||
|
chart.width(width) |
||||
|
} |
||||
|
if (notNull(height)) { |
||||
|
chart.height(height) |
||||
|
} |
||||
|
if (notNull(isAnimated)) { |
||||
|
chart.isAnimated(isAnimated) |
||||
|
} |
||||
|
if (notNull(lineCurve)) { |
||||
|
chart.lineCurve(lineCurve) |
||||
|
} |
||||
|
if (notNull(locale)) { |
||||
|
chart.locale(locale) |
||||
|
} |
||||
|
if (notNull(numberFormat)) { |
||||
|
chart.numberFormat(numberFormat) |
||||
|
} |
||||
|
if (notNull(shouldShowAllDataPoints)) { |
||||
|
chart.shouldShowAllDataPoints(shouldShowAllDataPoints) |
||||
|
} |
||||
|
if (notNull(topicLabel)) { |
||||
|
chart.topicLabel(topicLabel) |
||||
|
} |
||||
|
if (notNull(valueLabel)) { |
||||
|
chart.valueLabel(valueLabel) |
||||
|
} |
||||
|
if (notNull(xAxisLabel)) { |
||||
|
chart.xAxisLabel(xAxisLabel) |
||||
|
} |
||||
|
if (notNull(xAxisValueType)) { |
||||
|
chart.xAxisValueType(xAxisValueType) |
||||
|
} |
||||
|
if (notNull(xAxisScale)) { |
||||
|
chart.xAxisScale(xAxisScale) |
||||
|
} |
||||
|
if (notNull(xAxisFormat)) { |
||||
|
chart.xAxisFormat(xAxisFormat) |
||||
|
} |
||||
|
if (notNull(xAxisCustomFormat)) { |
||||
|
chart.xAxisCustomFormat(xAxisCustomFormat) |
||||
|
} |
||||
|
if (notNull(yAxisLabel)) { |
||||
|
chart.yAxisLabel(yAxisLabel) |
||||
|
} |
||||
|
if (notNull(yAxisLabelPadding)) { |
||||
|
chart.yAxisLabelPadding(yAxisLabelPadding) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartEvents() { |
||||
|
if (customMouseHover) { |
||||
|
chart.on("customMouseHover", customMouseHover) |
||||
|
} |
||||
|
if (customMouseMove) { |
||||
|
chart.on("customMouseMove", customMouseMove) |
||||
|
} |
||||
|
if (customMouseOut) { |
||||
|
chart.on("customMouseOut", customMouseOut) |
||||
|
} |
||||
|
if (customDataEntryClick) { |
||||
|
chart.on("customDataEntryClick", customDataEntryClick) |
||||
|
} |
||||
|
if (customTouchMove) { |
||||
|
chart.on("customTouchMove", customTouchMove) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartTooltip() { |
||||
|
tooltip = britecharts.miniTooltip() |
||||
|
|
||||
|
tooltipContainer = select(`.${chartClass} .metadata-group`) |
||||
|
tooltipContainer.datum([]).call(tooltip) |
||||
|
} |
||||
|
|
||||
|
$: _data = model ? $store[model] : data |
||||
|
|
||||
|
$: colorSchema = getColorSchema(color) |
||||
|
</script> |
||||
|
|
||||
|
<div bind:this={chartElement} class={chartClass} /> |
||||
|
{#if useLegend} |
||||
|
<div class={legendClass} /> |
||||
|
{/if} |
||||
|
|
||||
|
<!-- |
||||
|
|
||||
|
isAnimated={true} |
||||
|
aspectRatio={0.5} |
||||
|
grid='horizontal' |
||||
|
tooltipThreshold={600} |
||||
|
width={600} |
||||
|
dateLabel='fullDate' |
||||
|
|
||||
|
{type} |
||||
|
{data} |
||||
|
{colorSchema} |
||||
|
{axisTimeCombinations} |
||||
|
{lineCurve} |
||||
|
{numberFormat} |
||||
|
{height} |
||||
|
{topicLabel} |
||||
|
{shouldShowAllDataPoints} |
||||
|
{xAxisLabel} |
||||
|
{valueLabel} |
||||
|
{xAxisValueType} |
||||
|
{xAxisScale} |
||||
|
{xAxisCustomFormat} |
||||
|
|
||||
|
--> |
||||
@ -0,0 +1,187 @@ |
|||||
|
<script> |
||||
|
import { getColorSchema, getChartGradient, notNull } from "./utils" |
||||
|
import britecharts from "britecharts" |
||||
|
import { onMount } from "svelte" |
||||
|
|
||||
|
import { select } from "d3-selection" |
||||
|
import shortid from "shortid" |
||||
|
|
||||
|
const _id = shortid.generate() |
||||
|
|
||||
|
export let _bb |
||||
|
export let model |
||||
|
|
||||
|
let store = _bb.store |
||||
|
|
||||
|
const chart = britecharts.scatterPlot() |
||||
|
const chartClass = `scatterplot-container-${_id}` |
||||
|
const legendClass = `legend-container-${_id}` |
||||
|
|
||||
|
let chartElement = null |
||||
|
let chartContainer = null |
||||
|
let tooltip |
||||
|
let tooltipContainer |
||||
|
|
||||
|
export let customClick = null |
||||
|
export let customMouseOut = () => tooltip.hide() |
||||
|
export let customMouseOver = () => tooltip.show() |
||||
|
export let customMouseMove = ( |
||||
|
dataPoint, |
||||
|
colorMapping, |
||||
|
xPosition, |
||||
|
yPosition = null |
||||
|
) => tooltip.update(dataPoint, colorMapping, xPosition, (yPosition = null)) |
||||
|
|
||||
|
export let data = [] |
||||
|
export let color = "britecharts" |
||||
|
export let height = null |
||||
|
export let width = null |
||||
|
export let margin = null |
||||
|
export let aspectRatio = null |
||||
|
export let circleOpacity = null |
||||
|
export let grid = null |
||||
|
export let hasCrossHairs = null |
||||
|
export let hasHollowCircles = null |
||||
|
export let hasTrendline = null |
||||
|
export let highlightTextLegendOffset = null |
||||
|
export let isAnimated = null |
||||
|
export let maxCircleArea = null |
||||
|
export let xAxisFormat = null |
||||
|
export let xAxisLabel = null |
||||
|
export let xAxisLabelOffset = null |
||||
|
export let xTicks = null |
||||
|
export let yAxisFormat = null |
||||
|
export let yAxisLabel = null |
||||
|
export let yAxisLabelOffset = null |
||||
|
export let yTicks = null |
||||
|
export let useLegend = true |
||||
|
|
||||
|
onMount(async () => { |
||||
|
if (chart) { |
||||
|
if (model) { |
||||
|
await fetchData() |
||||
|
} |
||||
|
chartContainer = select(`.${chartClass}`) |
||||
|
bindChartUIProps() |
||||
|
bindChartEvents() |
||||
|
chartContainer.datum(_data).call(chart) |
||||
|
bindChartTooltip() |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
async function fetchData() { |
||||
|
const FETCH_RECORDS_URL = `/api/views/all_${model}` |
||||
|
const response = await _bb.api.get(FETCH_RECORDS_URL) |
||||
|
if (response.status === 200) { |
||||
|
const json = await response.json() |
||||
|
store.update(state => { |
||||
|
state[model] = json |
||||
|
return state |
||||
|
}) |
||||
|
} else { |
||||
|
throw new Error("Failed to fetch records.", response) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartUIProps() { |
||||
|
if (notNull(color)) { |
||||
|
chart.colorSchema(colorSchema) |
||||
|
} |
||||
|
if (notNull(height)) { |
||||
|
chart.height(height) |
||||
|
} |
||||
|
if (notNull(width)) { |
||||
|
chart.width(width) |
||||
|
} |
||||
|
if (notNull(margin)) { |
||||
|
chart.width(margin) |
||||
|
} |
||||
|
if (notNull(aspectRatio)) { |
||||
|
chart.aspectRatio(aspectRatio) |
||||
|
} |
||||
|
if (notNull(circleOpacity)) { |
||||
|
chart.circleOpacity(circleOpacity) |
||||
|
} |
||||
|
if (notNull(grid)) { |
||||
|
chart.grid(grid) |
||||
|
} |
||||
|
if (notNull(hasCrossHairs)) { |
||||
|
chart.hasCrossHairs(hasCrossHairs) |
||||
|
} |
||||
|
if (notNull(hasHollowCircles)) { |
||||
|
chart.hasHollowCircles(hasHollowCircles) |
||||
|
} |
||||
|
if (notNull(hasTrendline)) { |
||||
|
chart.hasTrendline(hasTrendline) |
||||
|
} |
||||
|
if (notNull(highlightTextLegendOffset)) { |
||||
|
chart.highlightTextLegendOffset(highlightTextLegendOffset) |
||||
|
} |
||||
|
if (notNull(isAnimated)) { |
||||
|
chart.isAnimated(isAnimated) |
||||
|
} |
||||
|
if (notNull(maxCircleArea)) { |
||||
|
chart.maxCircleArea(maxCircleArea) |
||||
|
} |
||||
|
if (notNull(xAxisFormat)) { |
||||
|
chart.xAxisFormat(xAxisFormat) |
||||
|
} |
||||
|
if (notNull(xAxisLabel)) { |
||||
|
chart.xAxisLabel(xAxisLabel) |
||||
|
} |
||||
|
if (notNull(xAxisLabelOffset)) { |
||||
|
chart.xAxisLabelOffset(xAxisLabelOffset) |
||||
|
} |
||||
|
if (notNull(xTicks)) { |
||||
|
chart.xTicks(xTicks) |
||||
|
} |
||||
|
if (notNull(yAxisFormat)) { |
||||
|
chart.yAxisFormat(yAxisFormat) |
||||
|
} |
||||
|
if (notNull(yAxisLabel)) { |
||||
|
chart.yAxisLabel(yAxisLabel) |
||||
|
} |
||||
|
if (notNull(yAxisLabelOffset)) { |
||||
|
chart.yAxisLabelOffset(yAxisLabelOffset) |
||||
|
} |
||||
|
if (notNull(yTicks)) { |
||||
|
chart.yTicks(yTicks) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartEvents() { |
||||
|
if (customClick) { |
||||
|
chart.on("customClick", customClick) |
||||
|
} |
||||
|
if (customMouseMove) { |
||||
|
chart.on("customMouseMove", customMouseMove) |
||||
|
} |
||||
|
if (customMouseOut) { |
||||
|
chart.on("customMouseOut", customMouseOut) |
||||
|
} |
||||
|
if (customMouseOver) { |
||||
|
chart.on("customMouseOver", customMouseOver) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartTooltip() { |
||||
|
//TODO: May be more apt to use tooltip() here. Currently erroring however |
||||
|
tooltip = britecharts.miniTooltip() |
||||
|
tooltipContainer = select(`.${chartClass} .metadata-group`) |
||||
|
// tooltip |
||||
|
// .title("Temperature") |
||||
|
// .valueLabel("y") |
||||
|
// .nameLabel("x") |
||||
|
// .numberFormat("$") |
||||
|
tooltipContainer.datum([]).call(tooltip) |
||||
|
} |
||||
|
|
||||
|
$: _data = model ? $store[model] : data |
||||
|
|
||||
|
$: colorSchema = getColorSchema(color) |
||||
|
</script> |
||||
|
|
||||
|
<div bind:this={chartElement} class={chartClass} /> |
||||
|
{#if useLegend} |
||||
|
<div class={legendClass} /> |
||||
|
{/if} |
||||
@ -0,0 +1,103 @@ |
|||||
|
<script> |
||||
|
import { getColorSchema, getChartGradient, notNull } from "./utils" |
||||
|
import britecharts from "britecharts" |
||||
|
import { onMount } from "svelte" |
||||
|
|
||||
|
import { select } from "d3-selection" |
||||
|
import shortid from "shortid" |
||||
|
|
||||
|
const _id = shortid.generate() |
||||
|
|
||||
|
export let _bb |
||||
|
export let model |
||||
|
|
||||
|
let store = _bb.store |
||||
|
|
||||
|
const chart = britecharts.sparkline() |
||||
|
const chartClass = `sparkline-container-${_id}` |
||||
|
const legendClass = `legend-container-${_id}` |
||||
|
|
||||
|
let chartElement = null |
||||
|
let chartContainer = null |
||||
|
|
||||
|
export let data = [] |
||||
|
export let areaGradient = null |
||||
|
export let height = null |
||||
|
export let width = null |
||||
|
export let dateLabel = null |
||||
|
export let duration = null |
||||
|
export let isAnimated = null |
||||
|
export let lineGradient = null |
||||
|
export let titleText = null |
||||
|
export let titleTextStyle = null |
||||
|
export let valueLabel = null |
||||
|
export let useLegend = true |
||||
|
|
||||
|
onMount(async () => { |
||||
|
if (chart) { |
||||
|
if (model) { |
||||
|
await fetchData() |
||||
|
} |
||||
|
chartContainer = select(`.${chartClass}`) |
||||
|
bindChartUIProps() |
||||
|
chartContainer.datum(_data).call(chart) |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
async function fetchData() { |
||||
|
const FETCH_RECORDS_URL = `/api/views/all_${model}` |
||||
|
const response = await _bb.api.get(FETCH_RECORDS_URL) |
||||
|
if (response.status === 200) { |
||||
|
const json = await response.json() |
||||
|
store.update(state => { |
||||
|
state[model] = json |
||||
|
return state |
||||
|
}) |
||||
|
} else { |
||||
|
throw new Error("Failed to fetch records.", response) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartUIProps() { |
||||
|
if (notNull(areaGradient)) { |
||||
|
chart.areaGradient(aGradient) |
||||
|
} |
||||
|
if (notNull(lineGradient)) { |
||||
|
chart.lineGradient(lGradient) |
||||
|
} |
||||
|
if (notNull(height)) { |
||||
|
chart.height(height) |
||||
|
} |
||||
|
if (notNull(width)) { |
||||
|
chart.width(width) |
||||
|
} |
||||
|
if (notNull(dateLabel)) { |
||||
|
chart.dateLabel(dateLabel) |
||||
|
} |
||||
|
if (notNull(duration)) { |
||||
|
chart.duration(duration) |
||||
|
} |
||||
|
if (notNull(isAnimated)) { |
||||
|
chart.isAnimated(isAnimated) |
||||
|
} |
||||
|
if (notNull(titleText)) { |
||||
|
chart.titleText(titleText) |
||||
|
} |
||||
|
if (notNull(titleTextStyle)) { |
||||
|
chart.titleTextStyle(titleTextStyle) |
||||
|
} |
||||
|
if (notNull(valueLabel)) { |
||||
|
chart.valueLabel(valueLabel) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$: _data = model ? $store[model] : data |
||||
|
|
||||
|
$: aGradient = getChartGradient(areaGradient) |
||||
|
$: lGradient = getChartGradient(lineGradient) |
||||
|
</script> |
||||
|
|
||||
|
<div bind:this={chartElement} class={chartClass} /> |
||||
|
{#if useLegend} |
||||
|
<div class={legendClass} /> |
||||
|
{/if} |
||||
@ -0,0 +1,181 @@ |
|||||
|
<script> |
||||
|
import { getColorSchema, getChartGradient, notNull } from "./utils" |
||||
|
import britecharts from "britecharts" |
||||
|
import { onMount } from "svelte" |
||||
|
|
||||
|
import { select } from "d3-selection" |
||||
|
import shortid from "shortid" |
||||
|
|
||||
|
const _id = shortid.generate() |
||||
|
|
||||
|
export let _bb |
||||
|
export let model |
||||
|
|
||||
|
let store = _bb.store |
||||
|
|
||||
|
const chart = britecharts.stackedArea() |
||||
|
const chartClass = `stackedarea-container-${_id}` |
||||
|
const legendClass = `legend-container-${_id}` |
||||
|
|
||||
|
let chartElement = null |
||||
|
let chartContainer = null |
||||
|
|
||||
|
export let customMouseOver = () => tooltip.show() |
||||
|
export let customMouseMove = ( |
||||
|
dataPoint, |
||||
|
colorMapping, |
||||
|
xPosition, |
||||
|
yPosition = null |
||||
|
) => tooltip.update(dataPoint, colorMapping, xPosition, (yPosition = null)) |
||||
|
export let customMouseOut = () => tooltip.hide() |
||||
|
|
||||
|
export let data = [] |
||||
|
export let color = "britecharts" |
||||
|
export let height = null |
||||
|
export let width = null |
||||
|
export let margin = null |
||||
|
export let areaCurve = null |
||||
|
export let areaOpacity = null |
||||
|
export let aspectRatio = null |
||||
|
export let dateLabel = null |
||||
|
export let grid = null |
||||
|
export let isAnimated = null |
||||
|
export let keyLabel = null |
||||
|
export let locale = null |
||||
|
export let tooltipThreshold = null |
||||
|
export let topicsOrder = null |
||||
|
export let valueLabel = null |
||||
|
export let xAxisCustomFormat = null |
||||
|
export let xAxisFormat = null |
||||
|
export let xAxisScale = null |
||||
|
export let xAxisValueType = null |
||||
|
export let xTicks = null |
||||
|
export let yAxisBaseline = null |
||||
|
export let yAxisLabel = null |
||||
|
export let yAxisLabelOffset = null |
||||
|
export let yTicks = null |
||||
|
export let useLegend = true |
||||
|
|
||||
|
onMount(async () => { |
||||
|
if (chart) { |
||||
|
if (model) { |
||||
|
await fetchData() |
||||
|
} |
||||
|
chartContainer = select(`.${chartClass}`) |
||||
|
bindChartUIProps() |
||||
|
bindChartEvents() |
||||
|
chartContainer.datum(_data).call(chart) |
||||
|
bindChartTooltip() |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
async function fetchData() { |
||||
|
const FETCH_RECORDS_URL = `/api/views/all_${model}` |
||||
|
const response = await _bb.api.get(FETCH_RECORDS_URL) |
||||
|
if (response.status === 200) { |
||||
|
const json = await response.json() |
||||
|
store.update(state => { |
||||
|
state[model] = json |
||||
|
return state |
||||
|
}) |
||||
|
} else { |
||||
|
throw new Error("Failed to fetch records.", response) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartUIProps() { |
||||
|
if (notNull(color)) { |
||||
|
chart.colorSchema(colorSchema) |
||||
|
} |
||||
|
if (notNull(height)) { |
||||
|
chart.height(height) |
||||
|
} |
||||
|
if (notNull(width)) { |
||||
|
chart.width(width) |
||||
|
} |
||||
|
if (notNull(margin)) { |
||||
|
chart.margin(margin) |
||||
|
} |
||||
|
if (notNull(areaCurve)) { |
||||
|
chart.areaCurve(areaCurve) |
||||
|
} |
||||
|
if (notNull(areaOpacity)) { |
||||
|
chart.areaOpacity(areaOpacity) |
||||
|
} |
||||
|
if (notNull(aspectRatio)) { |
||||
|
chart.aspectRatio(aspectRatio) |
||||
|
} |
||||
|
if (notNull(dateLabel)) { |
||||
|
chart.dateLabel(dateLabel) |
||||
|
} |
||||
|
if (notNull(grid)) { |
||||
|
chart.grid(grid) |
||||
|
} |
||||
|
if (notNull(isAnimated)) { |
||||
|
chart.isAnimated(isAnimated) |
||||
|
} |
||||
|
if (notNull(keyLabel)) { |
||||
|
chart.keyLabel(keyLabel) |
||||
|
} |
||||
|
if (notNull(locale)) { |
||||
|
chart.locale(locale) |
||||
|
} |
||||
|
if (notNull(tooltipThreshold)) { |
||||
|
chart.tooltipThreshold(tooltipThreshold) |
||||
|
} |
||||
|
if (notNull(topicsOrder)) { |
||||
|
chart.topicsOrder(topicsOrder) |
||||
|
} |
||||
|
if (notNull(valueLabel)) { |
||||
|
chart.valueLabel(valueLabel) |
||||
|
} |
||||
|
if (notNull(xAxisCustomFormat)) { |
||||
|
chart.xAxisCustomFormat(xAxisCustomFormat) |
||||
|
} |
||||
|
if (notNull(xAxisFormat)) { |
||||
|
chart.xAxisFormat(xAxisFormat) |
||||
|
} |
||||
|
if (notNull(xAxisScale)) { |
||||
|
chart.xAxisScale(xAxisScale) |
||||
|
} |
||||
|
if (notNull(xAxisValueType)) { |
||||
|
chart.xAxisValueType(xAxisValueType) |
||||
|
} |
||||
|
if (notNull(xTicks)) { |
||||
|
chart.xTicks(xTicks) |
||||
|
} |
||||
|
if (notNull(yAxisBaseline)) { |
||||
|
chart.yAxisBaseline(yAxisBaseline) |
||||
|
} |
||||
|
if (notNull(yAxisLabel)) { |
||||
|
chart.yAxisLabel(yAxisLabel) |
||||
|
} |
||||
|
if (notNull(yAxisLabelOffset)) { |
||||
|
chart.yAxisLabelOffset(yAxisLabelOffset) |
||||
|
} |
||||
|
if (notNull(yTicks)) { |
||||
|
chart.yTicks(yTicks) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartEvents() { |
||||
|
if (customMouseMove) { |
||||
|
chart.on("customMouseMove", customMouseMove) |
||||
|
} |
||||
|
if (customMouseOut) { |
||||
|
chart.on("customMouseOut", customMouseOut) |
||||
|
} |
||||
|
if (customMouseOver) { |
||||
|
chart.on("customMouseOver", customMouseOver) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$: _data = model ? $store[model] : data |
||||
|
|
||||
|
$: colorSchema = getColorSchema(color) |
||||
|
</script> |
||||
|
|
||||
|
<div bind:this={chartElement} class={chartClass} /> |
||||
|
{#if useLegend} |
||||
|
<div class={legendClass} /> |
||||
|
{/if} |
||||
@ -0,0 +1,176 @@ |
|||||
|
<script> |
||||
|
import { getColorSchema, getChartGradient, notNull } from "./utils" |
||||
|
import britecharts from "britecharts" |
||||
|
import { onMount } from "svelte" |
||||
|
|
||||
|
import { select } from "d3-selection" |
||||
|
import shortid from "shortid" |
||||
|
|
||||
|
const _id = shortid.generate() |
||||
|
|
||||
|
const chart = britecharts.stackedBar() |
||||
|
const chartClass = `stackedbar-container-${_id}` |
||||
|
const legendClass = `legend-container-${_id}` |
||||
|
|
||||
|
export let _bb |
||||
|
export let model |
||||
|
|
||||
|
let store = _bb.store |
||||
|
|
||||
|
let chartElement = null |
||||
|
let chartContainer = null |
||||
|
let tooltip |
||||
|
let tooltipContainer |
||||
|
|
||||
|
export let customMouseOver = () => tooltip.show() |
||||
|
export let customMouseMove = (dataPoint, colorMapping, xPosition) => |
||||
|
tooltip.update(dataPoint, colorMapping, xPosition) |
||||
|
export let customMouseOut = () => tooltip.hide() |
||||
|
|
||||
|
export let data = [] |
||||
|
export let color = "britecharts" |
||||
|
export let height = null |
||||
|
export let width = null |
||||
|
export let margin = null |
||||
|
export let aspectRatio = null |
||||
|
export let betweenBarsPadding = null |
||||
|
export let grid = null |
||||
|
export let hasPercentage = null |
||||
|
export let hasReversedStacks = null |
||||
|
export let isAnimated = null |
||||
|
export let isHorizontal = null |
||||
|
export let locale = null |
||||
|
export let nameLabel = null |
||||
|
export let percentageAxisToMaxRatio = null |
||||
|
export let stackLabel = null |
||||
|
export let valueLabel = null |
||||
|
export let valueLabelFormat = null |
||||
|
export let xTicks = null |
||||
|
export let yTicks = null |
||||
|
export let yAxisLabel = null |
||||
|
export let yAxisLabelOffset = null |
||||
|
export let useLegend = true |
||||
|
|
||||
|
onMount(async () => { |
||||
|
if (chart) { |
||||
|
if (model) { |
||||
|
await fetchData() |
||||
|
} |
||||
|
chartContainer = select(`.${chartClass}`) |
||||
|
bindChartUIProps() |
||||
|
bindChartEvents() |
||||
|
chartContainer.datum(_data).call(chart) |
||||
|
// bindChartTooltip() |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
async function fetchData() { |
||||
|
const FETCH_RECORDS_URL = `/api/views/all_${model}` |
||||
|
const response = await _bb.api.get(FETCH_RECORDS_URL) |
||||
|
if (response.status === 200) { |
||||
|
const json = await response.json() |
||||
|
store.update(state => { |
||||
|
state[model] = json |
||||
|
return state |
||||
|
}) |
||||
|
} else { |
||||
|
throw new Error("Failed to fetch records.", response) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartUIProps() { |
||||
|
//UI PROPS |
||||
|
if (notNull(color)) { |
||||
|
chart.colorSchema(colorSchema) |
||||
|
} |
||||
|
if (notNull(height)) { |
||||
|
chart.height(height) |
||||
|
} |
||||
|
if (notNull(width)) { |
||||
|
chart.width(width) |
||||
|
} |
||||
|
if (notNull(margin)) { |
||||
|
chart.margin(margin) |
||||
|
} |
||||
|
if (notNull(aspectRatio)) { |
||||
|
chart.aspectRatio(aspectRatio) |
||||
|
} |
||||
|
if (notNull(betweenBarsPadding)) { |
||||
|
chart.betweenBarsPadding(betweenBarsPadding) |
||||
|
} |
||||
|
if (notNull(grid)) { |
||||
|
chart.grid(grid) |
||||
|
} |
||||
|
if (notNull(hasPercentage)) { |
||||
|
chart.hasPercentage(hasPercentage) |
||||
|
} |
||||
|
if (notNull(hasReversedStacks)) { |
||||
|
chart.hasReversedStacks(hasReversedStacks) |
||||
|
} |
||||
|
if (notNull(isAnimated)) { |
||||
|
chart.isAnimated(isAnimated) |
||||
|
} |
||||
|
if (notNull(isHorizontal)) { |
||||
|
chart.isHorizontal(isHorizontal) |
||||
|
} |
||||
|
if (notNull(locale)) { |
||||
|
chart.locale(locale) |
||||
|
} |
||||
|
if (notNull(nameLabel)) { |
||||
|
chart.nameLabel(nameLabel) |
||||
|
} |
||||
|
if (notNull(percentageAxisToMaxRatio)) { |
||||
|
chart.percentageAxisToMaxRatio(percentageAxisToMaxRatio) |
||||
|
} |
||||
|
if (notNull(stackLabel)) { |
||||
|
chart.stackLabel(stackLabel) |
||||
|
} |
||||
|
if (notNull(valueLabel)) { |
||||
|
chart.valueLabel(valueLabel) |
||||
|
} |
||||
|
if (notNull(valueLabelFormat)) { |
||||
|
chart.valueLabelFormat(valueLabelFormat) |
||||
|
} |
||||
|
if (notNull(xTicks)) { |
||||
|
chart.xTicks(xTicks) |
||||
|
} |
||||
|
if (notNull(yTicks)) { |
||||
|
chart.yTicks(yTicks) |
||||
|
} |
||||
|
if (notNull(yAxisLabel)) { |
||||
|
chart.yAxisLabel(yAxisLabel) |
||||
|
} |
||||
|
if (notNull(yAxisLabelOffset)) { |
||||
|
chart.yAxisLabelOffset(yAxisLabelOffset) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartEvents() { |
||||
|
if (customMouseMove) { |
||||
|
chart.on("customMouseMove", customMouseMove) |
||||
|
} |
||||
|
if (customMouseOut) { |
||||
|
chart.on("customMouseOut", customMouseOut) |
||||
|
} |
||||
|
if (customMouseOver) { |
||||
|
chart.on("customMouseOver", customMouseOver) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartTooltip() { |
||||
|
tooltip = britecharts.tooltip() |
||||
|
// tooltip.topicLabel("Hi Im the topic") |
||||
|
// tooltip.topicsOrder(["x", "y"]) |
||||
|
tooltipContainer = select(`.${chartClass} .metadata-group`) |
||||
|
tooltipContainer.datum([]).call(tooltip) |
||||
|
} |
||||
|
|
||||
|
$: _data = model ? $store[model] : data |
||||
|
|
||||
|
$: colorSchema = getColorSchema(color) |
||||
|
</script> |
||||
|
|
||||
|
<div bind:this={chartElement} class={chartClass} /> |
||||
|
{#if useLegend} |
||||
|
<div class={legendClass} /> |
||||
|
{/if} |
||||
@ -0,0 +1,129 @@ |
|||||
|
<script> |
||||
|
import { getColorSchema, getChartGradient, notNull } from "./utils" |
||||
|
import britecharts from "britecharts" |
||||
|
import { onMount } from "svelte" |
||||
|
|
||||
|
import { select } from "d3-selection" |
||||
|
import shortid from "shortid" |
||||
|
|
||||
|
/* |
||||
|
ISSUES - Doesn't seem to allow color change. Chart is colored black by default |
||||
|
*/ |
||||
|
|
||||
|
const _id = shortid.generate() |
||||
|
|
||||
|
export let _bb |
||||
|
export let model |
||||
|
|
||||
|
let store = _bb.store |
||||
|
|
||||
|
const chart = britecharts.step() |
||||
|
const chartClass = `step-container-${_id}` |
||||
|
const legendClass = `legend-container-${_id}` |
||||
|
|
||||
|
let chartElement = null |
||||
|
let chartContainer = null |
||||
|
let tooltip |
||||
|
let tooltipContainer |
||||
|
|
||||
|
export let customMouseOver = () => tooltip.show() |
||||
|
export let customMouseMove = ( |
||||
|
dataPoint, |
||||
|
colorMapping, |
||||
|
xPosition, |
||||
|
yPosition = null |
||||
|
) => tooltip.update(dataPoint, colorMapping, xPosition, (yPosition = null)) |
||||
|
export let customMouseOut = () => tooltip.hide() |
||||
|
|
||||
|
export let data = [] |
||||
|
export let height = null |
||||
|
export let width = null |
||||
|
export let margin = null |
||||
|
export let xAxisLabel = null |
||||
|
export let xAxisLabelOffset = null |
||||
|
export let yAxisLabel = null |
||||
|
export let yAxisLabelOffset = null |
||||
|
export let yTicks = null |
||||
|
export let useLegend = true |
||||
|
|
||||
|
onMount(async () => { |
||||
|
if (chart) { |
||||
|
if (model) { |
||||
|
await fetchData() |
||||
|
} |
||||
|
chartContainer = select(`.${chartClass}`) |
||||
|
bindChartUIProps() |
||||
|
bindChartEvents() |
||||
|
chartContainer.datum(_data).call(chart) |
||||
|
bindChartTooltip() |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
async function fetchData() { |
||||
|
const FETCH_RECORDS_URL = `/api/views/all_${model}` |
||||
|
const response = await _bb.api.get(FETCH_RECORDS_URL) |
||||
|
if (response.status === 200) { |
||||
|
const json = await response.json() |
||||
|
store.update(state => { |
||||
|
state[model] = json |
||||
|
return state |
||||
|
}) |
||||
|
} else { |
||||
|
throw new Error("Failed to fetch records.", response) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartUIProps() { |
||||
|
if (notNull(height)) { |
||||
|
chart.height(height) |
||||
|
} |
||||
|
if (notNull(width)) { |
||||
|
chart.width(width) |
||||
|
} |
||||
|
if (notNull(margin)) { |
||||
|
chart.margin(margin) |
||||
|
} |
||||
|
if (notNull(xAxisLabel)) { |
||||
|
chart.xAxisLabel(xAxisLabel) |
||||
|
} |
||||
|
if (notNull(xAxisLabelOffset)) { |
||||
|
chart.xAxisLabelOffset(xAxisLabelOffset) |
||||
|
} |
||||
|
if (notNull(yAxisLabel)) { |
||||
|
chart.yAxisLabel(yAxisLabel) |
||||
|
} |
||||
|
if (notNull(yAxisLabelOffset)) { |
||||
|
chart.yAxisLabelOffset(yAxisLabelOffset) |
||||
|
} |
||||
|
if (notNull(yTicks)) { |
||||
|
chart.yTicks(yTicks) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartEvents() { |
||||
|
if (customMouseMove) { |
||||
|
chart.on("customMouseMove", customMouseMove) |
||||
|
} |
||||
|
if (customMouseOut) { |
||||
|
chart.on("customMouseOut", customMouseOut) |
||||
|
} |
||||
|
if (customMouseOver) { |
||||
|
chart.on("customMouseOver", customMouseOver) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function bindChartTooltip() { |
||||
|
tooltip = britecharts.miniTooltip() |
||||
|
tooltipContainer = select(`.${chartClass} .metadata-group`) |
||||
|
tooltipContainer.datum([]).call(tooltip) |
||||
|
} |
||||
|
|
||||
|
$: _data = model ? $store[model] : data |
||||
|
|
||||
|
$: colorSchema = getColorSchema(color) |
||||
|
</script> |
||||
|
|
||||
|
<div bind:this={chartElement} class={chartClass} /> |
||||
|
{#if useLegend} |
||||
|
<div class={legendClass} /> |
||||
|
{/if} |
||||
@ -0,0 +1,41 @@ |
|||||
|
<script> |
||||
|
import { getColorSchema, getChartGradient, notNull } from "./utils" |
||||
|
import britecharts from "britecharts" |
||||
|
import { onMount } from "svelte" |
||||
|
|
||||
|
import { select } from "d3-selection" |
||||
|
import shortid from "shortid" |
||||
|
|
||||
|
const _id = shortid.generate() |
||||
|
|
||||
|
const chart = britecharts.chartname() |
||||
|
const chartClass = `donut-container-${_id}` |
||||
|
const legendClass = `legend-container-${_id}` |
||||
|
|
||||
|
let chartElement = null |
||||
|
let chartContainer = null |
||||
|
|
||||
|
export let data = [] |
||||
|
export let color = "britecharts" |
||||
|
export let height = 200 |
||||
|
export let width = 200 |
||||
|
export let margin = { top: 0, right: 0, bottom: 0, left: 0 } |
||||
|
export let useLegend = true |
||||
|
|
||||
|
onMount(() => { |
||||
|
if (chart) { |
||||
|
chartContainer = select(`.${chartClass}`) |
||||
|
bindChartUIProps() |
||||
|
bindChartEvents() |
||||
|
chartContainer.datum(data).call(chart) |
||||
|
bindChartTooltip() |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
$: colorSchema = getColorSchema(color) |
||||
|
</script> |
||||
|
|
||||
|
<div bind:this={chartElement} class={chartClass} /> |
||||
|
{#if useLegend} |
||||
|
<div class={legendClass} /> |
||||
|
{/if} |
||||
@ -0,0 +1,12 @@ |
|||||
|
export { default as donut } from "./Donut.svelte" |
||||
|
export { default as bar } from "./Bar.svelte" |
||||
|
export { default as line } from "./Line.svelte" |
||||
|
export { default as brush } from "./Brush.svelte" |
||||
|
export { default as bullet } from "./Bullet.svelte" |
||||
|
export { default as groupedbar } from "./GroupedBar.svelte" |
||||
|
export { default as heatmap } from "./Heatmap.svelte" |
||||
|
export { default as sparkline } from "./Sparkline.svelte" |
||||
|
export { default as scatterplot } from "./ScatterPlot.svelte" |
||||
|
export { default as step } from "./Step.svelte" |
||||
|
export { default as stackedarea } from "./StackedArea.svelte" |
||||
|
export { default as stackedbar } from "./StackedBar.svelte" |
||||
@ -0,0 +1,73 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang="en"> |
||||
|
<head> |
||||
|
<meta charset="UTF-8"> |
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
|
<title>Document</title> |
||||
|
|
||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-selection/1.2.0/d3-selection.js"></script> |
||||
|
<script src="https://cdn.jsdelivr.net/npm/britecharts@2.10.0/dist/umd/bar.min.js" |
||||
|
type="text/javascript"></script> |
||||
|
|
||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/britecharts/dist/css/britecharts.min.css" type="text/css" /> |
||||
|
|
||||
|
</head> |
||||
|
<body> |
||||
|
|
||||
|
<article> |
||||
|
<h2 class="tutorial__heading">Bar Chart</h2> |
||||
|
<div class="bar-chart"></div> |
||||
|
</article> |
||||
|
|
||||
|
<script> |
||||
|
|
||||
|
const dataset = [ |
||||
|
{ |
||||
|
"name": "Radiating", |
||||
|
"value": 2 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "Opalescent", |
||||
|
"value": 4 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "Shining", |
||||
|
"value": 3 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "Vibrant", |
||||
|
"value": 6 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "Vivid", |
||||
|
"value": 6 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "Brilliant", |
||||
|
"value": 1 |
||||
|
} |
||||
|
] |
||||
|
|
||||
|
const barContainer = d3.select('.bar-chart'); |
||||
|
|
||||
|
const barChart = britecharts.bar() |
||||
|
|
||||
|
barChart |
||||
|
.width(700) |
||||
|
.height(300) |
||||
|
.enableLabels(true) |
||||
|
.labelsNumberFormat('.0%') |
||||
|
.isAnimated(true) |
||||
|
.yAxisLabel("Quantity") |
||||
|
.xAxisLabel("Color") |
||||
|
.betweenBarsPadding("0.8") |
||||
|
|
||||
|
// .on('customMouseOver', tooltip.show) |
||||
|
// .on('customMouseMove', tooltip.update) |
||||
|
// .on('customMouseOut', tooltip.hide); |
||||
|
|
||||
|
barContainer.datum(dataset).call(barChart); |
||||
|
|
||||
|
</script> |
||||
|
</body> |
||||
|
</html> |
||||
@ -0,0 +1,19 @@ |
|||||
|
import britecharts from "britecharts" |
||||
|
|
||||
|
export const notNull = value => value || value === false |
||||
|
|
||||
|
export const chartTypes = britecharts ? Object.keys(britecharts) : null |
||||
|
|
||||
|
//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 |
||||
|
|
||||
|
export const getColorSchema = color => |
||||
|
color ? colorSchemas[color] : colorSchemas["britecharts"] |
||||
|
|
||||
|
export const getChartGradient = gradient => |
||||
|
gradient ? colorGradients[gradient] : null |
||||
Loading…
Reference in new issue