commit
253568fd2d
|
@ -14,7 +14,7 @@
|
|||
class="nav-item"
|
||||
class:border
|
||||
class:selected
|
||||
style={`padding-left: ${indentLevel * 18}px`}
|
||||
style={`padding-left: ${indentLevel * 14}px`}
|
||||
{draggable}
|
||||
on:dragend
|
||||
on:dragstart
|
||||
|
@ -65,7 +65,7 @@
|
|||
}
|
||||
|
||||
.content {
|
||||
padding: 0 var(--spacing-m);
|
||||
padding: 0 var(--spacing-s);
|
||||
height: 32px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
@ -97,6 +97,9 @@
|
|||
flex: 1 1 auto;
|
||||
font-weight: 500;
|
||||
font-size: var(--font-size-xs);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.actions {
|
||||
|
|
|
@ -129,7 +129,7 @@
|
|||
ondragover="return false"
|
||||
ondragenter="return false"
|
||||
class="drop-item"
|
||||
style="margin-left: {(level + 1) * 18}px" />
|
||||
style="margin-left: {(level + 1) * 16}px" />
|
||||
{/if}
|
||||
|
||||
<NavItem
|
||||
|
@ -160,7 +160,7 @@
|
|||
ondragover="return false"
|
||||
ondragenter="return false"
|
||||
class="drop-item"
|
||||
style="margin-left: {(level + ($dragDropStore.dropPosition === 'inside' ? 3 : 1)) * 18}px" />
|
||||
style="margin-left: {(level + ($dragDropStore.dropPosition === 'inside' ? 3 : 1)) * 16}px" />
|
||||
{/if}
|
||||
</li>
|
||||
{/each}
|
||||
|
@ -176,6 +176,6 @@
|
|||
.drop-item {
|
||||
border-radius: var(--border-radius-m);
|
||||
height: 32px;
|
||||
background: var(--blue-light);
|
||||
background: var(--grey-3);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
<script>
|
||||
import { Multiselect } from "@budibase/bbui"
|
||||
|
||||
export let options = []
|
||||
export let value = []
|
||||
export let styleBindingProperty
|
||||
export let onChange = () => {}
|
||||
|
||||
let boundValue = getValidOptions(value, options)
|
||||
$: setValue(boundValue)
|
||||
$: sanitiseOptions(options)
|
||||
|
||||
function getValidOptions(selectedOptions, allOptions) {
|
||||
// Fix the hardcoded default string value
|
||||
if (!Array.isArray(selectedOptions)) {
|
||||
selectedOptions = []
|
||||
}
|
||||
return selectedOptions.filter(val => allOptions.indexOf(val) !== -1)
|
||||
}
|
||||
|
||||
function setValue(val) {
|
||||
onChange(val)
|
||||
}
|
||||
|
||||
function sanitiseOptions(options) {
|
||||
boundValue = getValidOptions(value, options)
|
||||
}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<Multiselect extraThin secondary bind:value={boundValue}>
|
||||
{#each options as option}
|
||||
<option value={option}>{option}</option>
|
||||
{/each}
|
||||
</Multiselect>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,5 @@
|
|||
<script>
|
||||
import TableViewFieldSelect from "./TableViewFieldSelect.svelte"
|
||||
</script>
|
||||
|
||||
<TableViewFieldSelect {...$$props} multiselect />
|
|
@ -1,12 +1,12 @@
|
|||
<script>
|
||||
import { onMount, beforeUpdate, afterUpdate } from "svelte"
|
||||
import { onMount } from "svelte"
|
||||
import Portal from "svelte-portal"
|
||||
import { buildStyle } from "../../helpers.js"
|
||||
|
||||
export let options = []
|
||||
export let value = ""
|
||||
export let styleBindingProperty
|
||||
export let onChange = value => {}
|
||||
export let onChange = () => {}
|
||||
|
||||
let open = null
|
||||
let rotate = ""
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
|
||||
let temp = runtimeToReadableBinding(bindableProperties, value)
|
||||
|
||||
return !value && props.defaultValue !== undefined
|
||||
return value == null && props.defaultValue !== undefined
|
||||
? props.defaultValue
|
||||
: temp
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@
|
|||
control={definition.control}
|
||||
label={definition.label}
|
||||
key={definition.key}
|
||||
value={componentInstance[definition.key] || componentInstance[definition.key]?.defaultValue}
|
||||
value={componentInstance[definition.key] ?? componentInstance[definition.key]?.defaultValue}
|
||||
{componentInstance}
|
||||
{onChange}
|
||||
props={{ ...excludeProps(definition, ['control', 'label']) }} />
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
<script>
|
||||
import OptionSelect from "./OptionSelect.svelte"
|
||||
import { backendUiStore } from "builderStore"
|
||||
import { onMount } from "svelte"
|
||||
import MultiOptionSelect from "./MultiOptionSelect.svelte"
|
||||
|
||||
export let componentInstance = {}
|
||||
export let value = ""
|
||||
export let onChange = (val = {})
|
||||
export let onChange = () => {}
|
||||
export let multiselect = false
|
||||
|
||||
const tables = $backendUiStore.tables
|
||||
|
||||
|
@ -24,4 +25,8 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<OptionSelect {value} {onChange} {options} />
|
||||
{#if multiselect}
|
||||
<MultiOptionSelect {value} {onChange} {options} />
|
||||
{:else}
|
||||
<OptionSelect {value} {onChange} {options} />
|
||||
{/if}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Input from "./PropertyPanelControls/Input.svelte"
|
||||
import OptionSelect from "./OptionSelect.svelte"
|
||||
import MultiTableViewFieldSelect from "./MultiTableViewFieldSelect.svelte"
|
||||
import Checkbox from "../common/Checkbox.svelte"
|
||||
import TableSelect from "components/userInterface/TableSelect.svelte"
|
||||
import TableViewSelect from "components/userInterface/TableViewSelect.svelte"
|
||||
|
@ -423,122 +424,40 @@ export default {
|
|||
isCategory: true,
|
||||
children: [
|
||||
{
|
||||
name: "Donut",
|
||||
_component: "@budibase/standard-components/donut",
|
||||
description: "Donut chart",
|
||||
icon: "ri-pie-chart-fill",
|
||||
properties: {
|
||||
settings: [
|
||||
{
|
||||
label: "Data",
|
||||
key: "datasource",
|
||||
control: TableViewSelect,
|
||||
},
|
||||
{
|
||||
label: "Name Field",
|
||||
key: "nameKey",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Value Field",
|
||||
key: "valueKey",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Animate Chart",
|
||||
key: "isAnimated",
|
||||
valueKey: "checked",
|
||||
control: Checkbox,
|
||||
},
|
||||
{
|
||||
label: "Hover Highlight",
|
||||
key: "hasHoverAnimation",
|
||||
valueKey: "checked",
|
||||
control: Checkbox,
|
||||
},
|
||||
{
|
||||
label: "Keep Last Hover",
|
||||
key: "hasLastHoverSliceHighlighted",
|
||||
valueKey: "checked",
|
||||
control: Checkbox,
|
||||
},
|
||||
{
|
||||
label: "Colors",
|
||||
key: "color",
|
||||
control: OptionSelect,
|
||||
options: [
|
||||
"britecharts",
|
||||
"blueGreen",
|
||||
"green",
|
||||
"grey",
|
||||
"orange",
|
||||
"pink",
|
||||
"purple",
|
||||
"red",
|
||||
"teal",
|
||||
"yellow",
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "External Radius",
|
||||
key: "externalRadius",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Internal Radius",
|
||||
key: "internalRadius",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Radius Offset",
|
||||
key: "radiusHoverOffset ",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Show Legend",
|
||||
key: "useLegend ",
|
||||
valueKey: "checked",
|
||||
control: Checkbox,
|
||||
},
|
||||
{
|
||||
label: "Horizontal Legend",
|
||||
key: "horizontalLegend",
|
||||
valueKey: "checked",
|
||||
control: Checkbox,
|
||||
},
|
||||
{
|
||||
label: "Legend Width",
|
||||
key: "legendWidth",
|
||||
control: Input,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Bar",
|
||||
name: "Bar Chart",
|
||||
_component: "@budibase/standard-components/bar",
|
||||
description: "Bar chart",
|
||||
icon: "ri-bar-chart-fill",
|
||||
icon: "ri-bar-chart-line",
|
||||
properties: {
|
||||
settings: [
|
||||
{
|
||||
label: "Title",
|
||||
key: "title",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Data",
|
||||
key: "datasource",
|
||||
control: TableViewSelect,
|
||||
},
|
||||
{
|
||||
label: "Name Label",
|
||||
key: "nameLabel",
|
||||
label: "Label Col.",
|
||||
key: "labelColumn",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Value Label",
|
||||
key: "valueLabel",
|
||||
label: "Data Cols.",
|
||||
key: "valueColumns",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
control: MultiTableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Format",
|
||||
key: "yAxisUnits",
|
||||
control: OptionSelect,
|
||||
options: ["Default", "Thousands", "Millions"],
|
||||
defaultValue: "Default",
|
||||
},
|
||||
{
|
||||
label: "Y Axis Label",
|
||||
|
@ -550,56 +469,6 @@ export default {
|
|||
key: "xAxisLabel",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "X Axis Label Offset",
|
||||
key: "xAxisLabelOffset",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Y Axis Label Offset",
|
||||
key: "yAxisLabelOffset",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Enable Labels",
|
||||
key: "enableLabels",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
},
|
||||
{
|
||||
label: "Colors",
|
||||
key: "color",
|
||||
control: OptionSelect,
|
||||
options: [
|
||||
{ label: "Normal", value: "britecharts" },
|
||||
{ label: "Blue Green", value: "blueGreen" },
|
||||
{ label: "Green", value: "green" },
|
||||
{ label: "Grey", value: "grey" },
|
||||
{ label: "Orange", value: "orange" },
|
||||
{ label: "Pink", value: "pink" },
|
||||
{ label: "Purple", value: "purple" },
|
||||
{ label: "Red", value: "red" },
|
||||
{ label: "Teal", value: "teal" },
|
||||
{ label: "Yellow", value: "yellow" },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Gradients",
|
||||
key: "gradient",
|
||||
control: OptionSelect,
|
||||
options: [
|
||||
{ value: "", label: "None" },
|
||||
{ value: "bluePurple", label: "Blue Purple" },
|
||||
{ value: "greenBlue", label: "Green Blue" },
|
||||
{ value: "orangePink", label: "Orange Pink" },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Highlight Single Bar",
|
||||
key: "hasSingleBarHighlight",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
},
|
||||
{
|
||||
label: "Width",
|
||||
key: "width",
|
||||
|
@ -609,221 +478,92 @@ export default {
|
|||
label: "Height",
|
||||
key: "height",
|
||||
control: Input,
|
||||
defaultValue: "400",
|
||||
},
|
||||
{
|
||||
label: "Colours",
|
||||
key: "palette",
|
||||
control: OptionSelect,
|
||||
defaultValue: "Palette 1",
|
||||
options: [
|
||||
"Palette 1",
|
||||
"Palette 2",
|
||||
"Palette 3",
|
||||
"Palette 4",
|
||||
"Palette 5",
|
||||
"Palette 6",
|
||||
"Palette 7",
|
||||
"Palette 8",
|
||||
"Palette 9",
|
||||
"Palette 10",
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Stacked",
|
||||
key: "stacked",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: false,
|
||||
},
|
||||
{
|
||||
label: "Data Labels",
|
||||
key: "dataLabels",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: false,
|
||||
},
|
||||
{
|
||||
label: "Animate",
|
||||
key: "isAnimate",
|
||||
key: "animate",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: true,
|
||||
},
|
||||
{
|
||||
label: "Horizontal",
|
||||
key: "isHorizontal",
|
||||
label: "Legend",
|
||||
key: "legend",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
},
|
||||
{
|
||||
label: "Label Number Format",
|
||||
key: "labelsNumberFormat",
|
||||
control: Input,
|
||||
defaultValue: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Grouped Bar",
|
||||
_component: "@budibase/standard-components/groupedbar",
|
||||
description: "Groupedbar chart",
|
||||
icon: "ri-bar-chart-grouped-fill",
|
||||
properties: {
|
||||
settings: [
|
||||
{
|
||||
label: "Data",
|
||||
key: "datasource",
|
||||
control: TableViewSelect,
|
||||
},
|
||||
{
|
||||
label: "Name Label",
|
||||
key: "nameLabel",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Group Label",
|
||||
key: "groupLabel",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Value Label",
|
||||
key: "valueLabel",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Color",
|
||||
key: "color",
|
||||
control: OptionSelect,
|
||||
options: [
|
||||
"britecharts",
|
||||
"blueGreen",
|
||||
"green",
|
||||
"grey",
|
||||
"orange",
|
||||
"pink",
|
||||
"purple",
|
||||
"red",
|
||||
"teal",
|
||||
"yellow",
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Height",
|
||||
key: "height",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Width",
|
||||
key: "width",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Aspect Ratio",
|
||||
key: "aspectRatio",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Grid",
|
||||
key: "grid",
|
||||
control: OptionSelect,
|
||||
options: ["vertical", "horizontal", "full"],
|
||||
},
|
||||
{
|
||||
label: "Value Label",
|
||||
key: "valueLabel",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Y Ticks",
|
||||
key: "yTicks",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Y Tick Text Offset",
|
||||
key: "yTickTextOffset",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Is Animated",
|
||||
key: "isAnimated",
|
||||
valueKey: "checked",
|
||||
control: Checkbox,
|
||||
},
|
||||
{
|
||||
label: "Is Horizontal",
|
||||
key: "isHorizontal",
|
||||
valueKey: "checked",
|
||||
control: Checkbox,
|
||||
},
|
||||
{
|
||||
label: "Tooltip Title",
|
||||
key: "tooltipTitle",
|
||||
control: Input,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Line",
|
||||
name: "Line Chart",
|
||||
_component: "@budibase/standard-components/line",
|
||||
description: "Line chart",
|
||||
icon: "ri-line-chart-line",
|
||||
properties: {
|
||||
settings: [
|
||||
{
|
||||
label: "Title",
|
||||
key: "title",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Data",
|
||||
key: "datasource",
|
||||
control: TableViewSelect,
|
||||
},
|
||||
{
|
||||
label: "Value Label",
|
||||
key: "valueLabel",
|
||||
label: "Label Col.",
|
||||
key: "labelColumn",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Topic Label",
|
||||
key: "topicLabel",
|
||||
label: "Data Cols.",
|
||||
key: "valueColumns",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
control: MultiTableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Date Label",
|
||||
key: "dateLabel",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Colors",
|
||||
key: "color",
|
||||
label: "Format",
|
||||
key: "yAxisUnits",
|
||||
control: OptionSelect,
|
||||
options: [
|
||||
"britecharts",
|
||||
"blueGreen",
|
||||
"green",
|
||||
"grey",
|
||||
"orange",
|
||||
"pink",
|
||||
"purple",
|
||||
"red",
|
||||
"teal",
|
||||
"yellow",
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Gradients",
|
||||
key: "lineGradient",
|
||||
control: OptionSelect,
|
||||
options: [
|
||||
{ value: "", label: "None" },
|
||||
{ value: "bluePurple", label: "Blue Purple" },
|
||||
{ value: "greenBlue", label: "Green Blue" },
|
||||
{ value: "orangePink", label: "Orange Pink" },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Line Curve",
|
||||
key: "lineCurve",
|
||||
control: OptionSelect,
|
||||
options: [
|
||||
"linear",
|
||||
"basis",
|
||||
"natural",
|
||||
"monotoneX",
|
||||
"monotoneY",
|
||||
"step",
|
||||
"stepAfter",
|
||||
"stepBefore",
|
||||
"cardinal",
|
||||
"catmullRom",
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "X Axis Value Type",
|
||||
key: "xAxisValueType",
|
||||
control: OptionSelect,
|
||||
options: ["date", "number"],
|
||||
},
|
||||
{
|
||||
label: "Grid",
|
||||
key: "grid",
|
||||
control: OptionSelect,
|
||||
options: ["vertical", "horizontal", "full"],
|
||||
},
|
||||
{
|
||||
label: "X Axis Label",
|
||||
key: "xAxisLabel",
|
||||
control: Input,
|
||||
options: ["Default", "Thousands", "Millions"],
|
||||
defaultValue: "Default",
|
||||
},
|
||||
{
|
||||
label: "Y Axis Label",
|
||||
|
@ -831,10 +571,9 @@ export default {
|
|||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Show All Datapoints",
|
||||
key: "shouldShowAllDataPoints",
|
||||
valueKey: "checked",
|
||||
control: Checkbox,
|
||||
label: "X Axis Label",
|
||||
key: "xAxisLabel",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Width",
|
||||
|
@ -845,57 +584,423 @@ export default {
|
|||
label: "Height",
|
||||
key: "height",
|
||||
control: Input,
|
||||
defaultValue: "400",
|
||||
},
|
||||
{
|
||||
label: "Is Animated",
|
||||
key: "isAnimated",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
},
|
||||
{
|
||||
label: "Locale",
|
||||
key: "locale",
|
||||
label: "Curve",
|
||||
key: "curve",
|
||||
control: OptionSelect,
|
||||
options: ["en-GB", "en-US"],
|
||||
options: ["Smooth", "Straight", "Stepline"],
|
||||
defaultValue: "Smooth",
|
||||
},
|
||||
{
|
||||
label: "X Axis Value Type",
|
||||
key: "xAxisValueType",
|
||||
control: OptionSelect,
|
||||
options: ["date", "numeric"],
|
||||
},
|
||||
{
|
||||
label: "X Axis Format",
|
||||
key: "xAxisFormat",
|
||||
label: "Colours",
|
||||
key: "palette",
|
||||
control: OptionSelect,
|
||||
defaultValue: "Palette 1",
|
||||
options: [
|
||||
"day-month",
|
||||
"minute-hour",
|
||||
"hour-daymonth",
|
||||
"month-year",
|
||||
"custom",
|
||||
"Palette 1",
|
||||
"Palette 2",
|
||||
"Palette 3",
|
||||
"Palette 4",
|
||||
"Palette 5",
|
||||
"Palette 6",
|
||||
"Palette 7",
|
||||
"Palette 8",
|
||||
"Palette 9",
|
||||
"Palette 10",
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "X Axis Custom Format",
|
||||
key: "xAxisCustomFormat",
|
||||
label: "Data Labels",
|
||||
key: "dataLabels",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: false,
|
||||
},
|
||||
{
|
||||
label: "Animate",
|
||||
key: "animate",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: true,
|
||||
},
|
||||
{
|
||||
label: "Legend",
|
||||
key: "legend",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Area Chart",
|
||||
_component: "@budibase/standard-components/area",
|
||||
description: "Line chart",
|
||||
icon: "ri-line-chart-fill",
|
||||
properties: {
|
||||
settings: [
|
||||
{
|
||||
label: "Title",
|
||||
key: "title",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Tooltip Title",
|
||||
key: "tooltipTitle",
|
||||
label: "Data",
|
||||
key: "datasource",
|
||||
control: TableViewSelect,
|
||||
},
|
||||
{
|
||||
label: "Label Col.",
|
||||
key: "labelColumn",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Data Cols.",
|
||||
key: "valueColumns",
|
||||
dependsOn: "datasource",
|
||||
control: MultiTableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Format",
|
||||
key: "yAxisUnits",
|
||||
control: OptionSelect,
|
||||
options: ["Default", "Thousands", "Millions"],
|
||||
defaultValue: "Default",
|
||||
},
|
||||
{
|
||||
label: "Y Label",
|
||||
key: "yAxisLabel",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "X Ticks",
|
||||
key: "xTicks",
|
||||
label: "X Label",
|
||||
key: "xAxisLabel",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Y Ticks",
|
||||
key: "yTicks",
|
||||
label: "Width",
|
||||
key: "width",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Height",
|
||||
key: "height",
|
||||
control: Input,
|
||||
defaultValue: "400",
|
||||
},
|
||||
{
|
||||
label: "Curve",
|
||||
key: "curve",
|
||||
control: OptionSelect,
|
||||
options: ["Smooth", "Straight", "Stepline"],
|
||||
defaultValue: "Smooth",
|
||||
},
|
||||
{
|
||||
label: "Colours",
|
||||
key: "palette",
|
||||
control: OptionSelect,
|
||||
defaultValue: "Palette 1",
|
||||
options: [
|
||||
"Palette 1",
|
||||
"Palette 2",
|
||||
"Palette 3",
|
||||
"Palette 4",
|
||||
"Palette 5",
|
||||
"Palette 6",
|
||||
"Palette 7",
|
||||
"Palette 8",
|
||||
"Palette 9",
|
||||
"Palette 10",
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Data Labels",
|
||||
key: "dataLabels",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: false,
|
||||
},
|
||||
{
|
||||
label: "Animate",
|
||||
key: "animate",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: true,
|
||||
},
|
||||
{
|
||||
label: "Legend",
|
||||
key: "legend",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: false,
|
||||
},
|
||||
{
|
||||
label: "Stacked",
|
||||
key: "stacked",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: true,
|
||||
},
|
||||
{
|
||||
label: "Gradient",
|
||||
key: "gradient",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Pie Chart",
|
||||
_component: "@budibase/standard-components/pie",
|
||||
description: "Pie chart",
|
||||
icon: "ri-pie-chart-line",
|
||||
properties: {
|
||||
settings: [
|
||||
{
|
||||
label: "Title",
|
||||
key: "title",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Data",
|
||||
key: "datasource",
|
||||
control: TableViewSelect,
|
||||
},
|
||||
{
|
||||
label: "Label Col.",
|
||||
key: "labelColumn",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Data Col.",
|
||||
key: "valueColumn",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Width",
|
||||
key: "width",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Height",
|
||||
key: "height",
|
||||
control: Input,
|
||||
defaultValue: "200",
|
||||
},
|
||||
{
|
||||
label: "Colours",
|
||||
key: "palette",
|
||||
control: OptionSelect,
|
||||
defaultValue: "Palette 1",
|
||||
options: [
|
||||
"Palette 1",
|
||||
"Palette 2",
|
||||
"Palette 3",
|
||||
"Palette 4",
|
||||
"Palette 5",
|
||||
"Palette 6",
|
||||
"Palette 7",
|
||||
"Palette 8",
|
||||
"Palette 9",
|
||||
"Palette 10",
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Data Labels",
|
||||
key: "dataLabels",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: false,
|
||||
},
|
||||
{
|
||||
label: "Animate",
|
||||
key: "animate",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: true,
|
||||
},
|
||||
{
|
||||
label: "Legend",
|
||||
key: "legend",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Donut Chart",
|
||||
_component: "@budibase/standard-components/donut",
|
||||
description: "Donut chart",
|
||||
icon: "ri-donut-chart-line",
|
||||
properties: {
|
||||
settings: [
|
||||
{
|
||||
label: "Title",
|
||||
key: "title",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Data",
|
||||
key: "datasource",
|
||||
control: TableViewSelect,
|
||||
},
|
||||
{
|
||||
label: "Label Col.",
|
||||
key: "labelColumn",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Data Col.",
|
||||
key: "valueColumn",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Width",
|
||||
key: "width",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Height",
|
||||
key: "height",
|
||||
control: Input,
|
||||
defaultValue: "200",
|
||||
},
|
||||
{
|
||||
label: "Colours",
|
||||
key: "palette",
|
||||
control: OptionSelect,
|
||||
defaultValue: "Palette 1",
|
||||
options: [
|
||||
"Palette 1",
|
||||
"Palette 2",
|
||||
"Palette 3",
|
||||
"Palette 4",
|
||||
"Palette 5",
|
||||
"Palette 6",
|
||||
"Palette 7",
|
||||
"Palette 8",
|
||||
"Palette 9",
|
||||
"Palette 10",
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Data Labels",
|
||||
key: "dataLabels",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: false,
|
||||
},
|
||||
{
|
||||
label: "Animate",
|
||||
key: "animate",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: true,
|
||||
},
|
||||
{
|
||||
label: "Legend",
|
||||
key: "legend",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Candlestick Chart",
|
||||
_component: "@budibase/standard-components/candlestick",
|
||||
description: "Candlestick chart",
|
||||
icon: "ri-stock-line",
|
||||
properties: {
|
||||
settings: [
|
||||
{
|
||||
label: "Title",
|
||||
key: "title",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Data",
|
||||
key: "datasource",
|
||||
control: TableViewSelect,
|
||||
},
|
||||
{
|
||||
label: "Date Col.",
|
||||
key: "dateColumn",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Open Col.",
|
||||
key: "openColumn",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Close Col.",
|
||||
key: "closeColumn",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "High Col.",
|
||||
key: "highColumn",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Low Col.",
|
||||
key: "lowColumn",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Format",
|
||||
key: "yAxisUnits",
|
||||
control: OptionSelect,
|
||||
options: ["Default", "Thousands", "Millions"],
|
||||
defaultValue: "Default",
|
||||
},
|
||||
{
|
||||
label: "Y Axis Label",
|
||||
key: "yAxisLabel",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "X Axis Label",
|
||||
key: "xAxisLabel",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Width",
|
||||
key: "width",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Height",
|
||||
key: "height",
|
||||
control: Input,
|
||||
defaultValue: "400",
|
||||
},
|
||||
{
|
||||
label: "Animate",
|
||||
key: "animate",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
|
|
@ -28,6 +28,7 @@ html, body {
|
|||
margin: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: var(--background);
|
||||
}
|
||||
|
||||
#app {
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-l);
|
||||
padding: var(--spacing-l) var(--spacing-xl);
|
||||
padding: var(--spacing-l) var(--spacing-xl) 60px var(--spacing-xl);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,27 +80,30 @@ const makeRowRequestBody = (parameters, state) => {
|
|||
if (body._table) delete body._table
|
||||
|
||||
// then override with supplied parameters
|
||||
for (let fieldName of Object.keys(parameters.fields)) {
|
||||
const field = parameters.fields[fieldName]
|
||||
if (parameters.fields) {
|
||||
for (let fieldName of Object.keys(parameters.fields)) {
|
||||
const field = parameters.fields[fieldName]
|
||||
|
||||
// ensure fields sent are of the correct type
|
||||
if (field.type === "boolean") {
|
||||
if (field.value === "true") body[fieldName] = true
|
||||
if (field.value === "false") body[fieldName] = false
|
||||
} else if (field.type === "number") {
|
||||
const val = parseFloat(field.value)
|
||||
if (!isNaN(val)) {
|
||||
body[fieldName] = val
|
||||
// ensure fields sent are of the correct type
|
||||
if (field.type === "boolean") {
|
||||
if (field.value === "true") body[fieldName] = true
|
||||
if (field.value === "false") body[fieldName] = false
|
||||
} else if (field.type === "number") {
|
||||
const val = parseFloat(field.value)
|
||||
if (!isNaN(val)) {
|
||||
body[fieldName] = val
|
||||
}
|
||||
} else if (field.type === "datetime") {
|
||||
const date = new Date(field.value)
|
||||
if (!isNaN(date.getTime())) {
|
||||
body[fieldName] = date.toISOString()
|
||||
}
|
||||
} else {
|
||||
body[fieldName] = field.value
|
||||
}
|
||||
} else if (field.type === "datetime") {
|
||||
const date = new Date(field.value)
|
||||
if (!isNaN(date.getTime())) {
|
||||
body[fieldName] = date.toISOString()
|
||||
}
|
||||
} else {
|
||||
body[fieldName] = field.value
|
||||
}
|
||||
}
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
|
|
|
@ -396,286 +396,283 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"datamap": {
|
||||
"description": "shiny chart",
|
||||
"data": true,
|
||||
"props": {
|
||||
"table": "tables"
|
||||
}
|
||||
},
|
||||
"donut": {
|
||||
"description": "Donut Chart",
|
||||
"data": true,
|
||||
"props": {
|
||||
"datasource": "string",
|
||||
"data": "string",
|
||||
"color": "string",
|
||||
"height": "number",
|
||||
"width": "number",
|
||||
"hasFixedHighlightedSlice": "bool",
|
||||
"hasLastHoverSliceHighlighted": "bool",
|
||||
"hasHoverAnimation": "bool",
|
||||
"numberFormat": "string",
|
||||
"nameKey": "string",
|
||||
"valueKey": "string",
|
||||
"isAnimated": "bool",
|
||||
"externalRadius": "number",
|
||||
"internalRadius": "number",
|
||||
"radiusHoverOffset": "number",
|
||||
"percentageFormat": "string",
|
||||
"useLegend": "bool",
|
||||
"legendWidth": "number",
|
||||
"legendHeight": "number"
|
||||
}
|
||||
},
|
||||
"sparkline": {
|
||||
"description": "Sparkline Chart",
|
||||
"data": true,
|
||||
"props": {
|
||||
"table": "string",
|
||||
"areaGradient": "string",
|
||||
"height": "number",
|
||||
"width": "number",
|
||||
"dateLabel": "string",
|
||||
"duration": "string",
|
||||
"isAnimated": "bool",
|
||||
"lineGradient": "string",
|
||||
"titleText": "string",
|
||||
"valueLabel": "string"
|
||||
}
|
||||
},
|
||||
"stackedbar": {
|
||||
"description": "Stacked Bar Chart",
|
||||
"data": true,
|
||||
"props": {
|
||||
"datasource": "tables",
|
||||
"color": "string",
|
||||
"height": "number",
|
||||
"width": "number",
|
||||
"margin": "string",
|
||||
"aspectRatio": "string",
|
||||
"betweenBarsPadding": "number",
|
||||
"grid": "string",
|
||||
"hasPercentage": "bool",
|
||||
"hasReversedStacks": "bool",
|
||||
"isAnimated": "bool",
|
||||
"isHorizontal": "bool",
|
||||
"locale": "string",
|
||||
"nameLabel": "string",
|
||||
"percentageAxisToMaxRatio": "number",
|
||||
"stackLabel": "string",
|
||||
"valueLabel": "string",
|
||||
"valueLabelFormat": "string",
|
||||
"xTicks": "number",
|
||||
"yTicks": "number",
|
||||
"yAxisLabel": "string",
|
||||
"yAxisLabelOffset": "number",
|
||||
"useLegend": "bool"
|
||||
}
|
||||
},
|
||||
"stackarea": {
|
||||
"description": "Step Chart",
|
||||
"data": true,
|
||||
"props": {
|
||||
"table": "string",
|
||||
"color": "string",
|
||||
"height": "number",
|
||||
"width": "number",
|
||||
"margin": "string",
|
||||
"xAxisLabel": "string",
|
||||
"xAxisLabelOffset": "string",
|
||||
"yAxisLabel": "string",
|
||||
"yAxisLabelOffset": "string",
|
||||
"areaCurve": "number",
|
||||
"areaOpacity": "number",
|
||||
"aspectRatio": "number",
|
||||
"dateLabel": "string",
|
||||
"grid": "string",
|
||||
"isAnimated": "bool",
|
||||
"keyLabel": "string",
|
||||
"locale": "string",
|
||||
"tooltipThreshold": "number",
|
||||
"topicsOrder": "string",
|
||||
"valueLabel": "string",
|
||||
"xAxisCustomFormat": "string",
|
||||
"xAxisFormat": "string",
|
||||
"xAxisScale": "string",
|
||||
"xAxisValueType": "string",
|
||||
"yTicks": "number",
|
||||
"xTicks": "number",
|
||||
"yAxisBaseline": "string",
|
||||
"useLegend": "bool"
|
||||
}
|
||||
},
|
||||
"step": {
|
||||
"description": "Step Chart",
|
||||
"data": true,
|
||||
"props": {
|
||||
"table": "string",
|
||||
"height": "number",
|
||||
"width": "number",
|
||||
"margin": "string",
|
||||
"xAxisLabel": "string",
|
||||
"xAxisLabelOffset": "string",
|
||||
"yAxisLabel": "string",
|
||||
"yAxisLabelOffset": "string",
|
||||
"yTicks": "string"
|
||||
}
|
||||
},
|
||||
"scatterplot": {
|
||||
"description": "Scatterplot Chart",
|
||||
"data": true,
|
||||
"props": {
|
||||
"table": "string",
|
||||
"color": "string",
|
||||
"height": "number",
|
||||
"width": "number",
|
||||
"aspectRatio": "string",
|
||||
"circleOpacity": "string",
|
||||
"grid": "string",
|
||||
"hasCrossHairs": "bool",
|
||||
"isAnimated": "bool",
|
||||
"maxCircleArea": "number",
|
||||
"xAxisLabel": "string",
|
||||
"xAxisLabelOffset": "string",
|
||||
"xTicks": "string",
|
||||
"yAxisFormat": "string",
|
||||
"yAxisLabel": "string",
|
||||
"yAxisLabelOffset": "string",
|
||||
"yTicks": "string"
|
||||
}
|
||||
},
|
||||
"bar": {
|
||||
"description": "Bar Chart",
|
||||
"data": true,
|
||||
"props": {
|
||||
"title": "string",
|
||||
"datasource": "tables",
|
||||
"nameLabel": "string",
|
||||
"valueLabel": "string",
|
||||
"betweenBarsPadding": "number",
|
||||
"gradient": "string",
|
||||
"color": "string",
|
||||
"hasSingleBarHighlight": "bool",
|
||||
"height": "number",
|
||||
"width": "number",
|
||||
"isAnimated": "bool",
|
||||
"isHorizontal": "bool",
|
||||
"labelNumberFormat": "number",
|
||||
"locale": "string",
|
||||
"labelColumn": "string",
|
||||
"valueColumns": "string",
|
||||
"height": {
|
||||
"type": "string",
|
||||
"default": "400"
|
||||
},
|
||||
"width": "string",
|
||||
"dataLabels": "bool",
|
||||
"animate": {
|
||||
"type": "bool",
|
||||
"default": true
|
||||
},
|
||||
"xAxisLabel": "string",
|
||||
"yAxisLabel": "string",
|
||||
"useLegend": "bool",
|
||||
"xTicks": "number",
|
||||
"yTicks": "number"
|
||||
"legend": "bool",
|
||||
"stacked": "bool",
|
||||
"yAxisUnits": {
|
||||
"type": "options",
|
||||
"default": "Default",
|
||||
"options": [
|
||||
"Default", "Thousands", "Millions"
|
||||
]
|
||||
},
|
||||
"palette": {
|
||||
"type": "options",
|
||||
"default": "Palette 1",
|
||||
"options": [
|
||||
"Palette 1",
|
||||
"Palette 2",
|
||||
"Palette 3",
|
||||
"Palette 4",
|
||||
"Palette 5",
|
||||
"Palette 6",
|
||||
"Palette 7",
|
||||
"Palette 8",
|
||||
"Palette 9",
|
||||
"Palette 10"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"line": {
|
||||
"description": "Line Chart",
|
||||
"data": true,
|
||||
"props": {
|
||||
"title": "string",
|
||||
"datasource": "tables",
|
||||
"width": "number",
|
||||
"height": "number",
|
||||
"axisTimeCombinations": "string",
|
||||
"color": "string",
|
||||
"grid": {
|
||||
"labelColumn": "string",
|
||||
"valueColumns": "string",
|
||||
"height": {
|
||||
"type": "string",
|
||||
"default": "horizontal"
|
||||
"default": "400"
|
||||
},
|
||||
"aspectRatio": "number",
|
||||
"dateLabel": "string",
|
||||
"isAnimated": {
|
||||
"width": "string",
|
||||
"dataLabels": {
|
||||
"type": "bool",
|
||||
"default": false
|
||||
},
|
||||
"animate": {
|
||||
"type": "bool",
|
||||
"default": true
|
||||
},
|
||||
"lineCurve": "string",
|
||||
"locale": "string",
|
||||
"numberFormat": "string",
|
||||
"shouldShowAllDataPoints": {
|
||||
"type": "bool",
|
||||
"default": true
|
||||
},
|
||||
"topicLabel": "string",
|
||||
"valueLabel": "string",
|
||||
"xAxisValueType": {
|
||||
"type": "string",
|
||||
"default": "date"
|
||||
},
|
||||
"xAxisScale": "string",
|
||||
"xAxisFormat": {
|
||||
"type": "string",
|
||||
"default": "custom"
|
||||
},
|
||||
"xAxisCustomFormat": "string",
|
||||
"xAxisLabel": "string",
|
||||
"yAxisLabel": "string",
|
||||
"tooltipTitle": "string",
|
||||
"xTicks": "number",
|
||||
"yTicks": "number"
|
||||
"curve": {
|
||||
"type": "options",
|
||||
"options": [
|
||||
"Smooth",
|
||||
"Straight",
|
||||
"Stepline"
|
||||
],
|
||||
"default": "Smooth"
|
||||
},
|
||||
"legend": "bool",
|
||||
"yAxisUnits": {
|
||||
"type": "options",
|
||||
"default": "Default",
|
||||
"options": [
|
||||
"Default", "Thousands", "Millions"
|
||||
]
|
||||
},
|
||||
"palette": {
|
||||
"type": "options",
|
||||
"default": "Palette 1",
|
||||
"options": [
|
||||
"Palette 1",
|
||||
"Palette 2",
|
||||
"Palette 3",
|
||||
"Palette 4",
|
||||
"Palette 5",
|
||||
"Palette 6",
|
||||
"Palette 7",
|
||||
"Palette 8",
|
||||
"Palette 9",
|
||||
"Palette 10"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"brush": {
|
||||
"description": "brush chart",
|
||||
"data": true,
|
||||
"props": {
|
||||
"table": "string",
|
||||
"gradient": "string",
|
||||
"height": "number",
|
||||
"width": "number",
|
||||
"margin": "string",
|
||||
"dateRange": "string",
|
||||
"locale": "string",
|
||||
"roundingTimeInterval": "string",
|
||||
"xAxisFormat": "string",
|
||||
"xTicks": "number",
|
||||
"xAxisCustomFormat": "string"
|
||||
}
|
||||
},
|
||||
"heatmap": {
|
||||
"description": "Heatmap chart",
|
||||
"data": true,
|
||||
"props": {
|
||||
"table": "string",
|
||||
"color": "string",
|
||||
"height": "number",
|
||||
"width": "number",
|
||||
"useLegend": "bool",
|
||||
"yAxisLabel": "string",
|
||||
"boxSize": "number"
|
||||
}
|
||||
},
|
||||
"groupedbar": {
|
||||
"description": "Groupedbar chart",
|
||||
"area": {
|
||||
"description": "Area Chart",
|
||||
"data": true,
|
||||
"props": {
|
||||
"title": "string",
|
||||
"datasource": "tables",
|
||||
"nameLabel": "string",
|
||||
"valueLabel": "string",
|
||||
"color": "string",
|
||||
"height": "string",
|
||||
"labelColumn": "string",
|
||||
"valueColumns": "string",
|
||||
"height": {
|
||||
"type": "string",
|
||||
"default": "400"
|
||||
},
|
||||
"width": "string",
|
||||
"margin": "string",
|
||||
"grid": "string",
|
||||
"groupLabel": "string",
|
||||
"isAnimated": "bool",
|
||||
"isHorizontal": "bool",
|
||||
"yTicks": "string",
|
||||
"useLegend": "bool",
|
||||
"tooltipTitle": "string"
|
||||
"dataLabels": {
|
||||
"type": "bool",
|
||||
"default": false
|
||||
},
|
||||
"animate": {
|
||||
"type": "bool",
|
||||
"default": true
|
||||
},
|
||||
"xAxisLabel": "string",
|
||||
"yAxisLabel": "string",
|
||||
"curve": {
|
||||
"type": "options",
|
||||
"options": [
|
||||
"Smooth",
|
||||
"Straight",
|
||||
"Stepline"
|
||||
],
|
||||
"default": "Smooth"
|
||||
},
|
||||
"legend": "bool",
|
||||
"stacked": {
|
||||
"type": "bool",
|
||||
"default": true
|
||||
},
|
||||
"gradient": "bool",
|
||||
"yAxisUnits": {
|
||||
"type": "options",
|
||||
"default": "Default",
|
||||
"options": [
|
||||
"Default", "Thousands", "Millions"
|
||||
]
|
||||
},
|
||||
"palette": {
|
||||
"type": "options",
|
||||
"default": "Palette 1",
|
||||
"options": [
|
||||
"Palette 1",
|
||||
"Palette 2",
|
||||
"Palette 3",
|
||||
"Palette 4",
|
||||
"Palette 5",
|
||||
"Palette 6",
|
||||
"Palette 7",
|
||||
"Palette 8",
|
||||
"Palette 9",
|
||||
"Palette 10"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"bullet": {
|
||||
"description": "Bullet chart",
|
||||
"pie": {
|
||||
"description": "Pie Chart",
|
||||
"data": true,
|
||||
"props": {
|
||||
"table": "string",
|
||||
"color": "string",
|
||||
"customSubtitle": "string",
|
||||
"customTitle": "string",
|
||||
"numberFormat": "string",
|
||||
"paddingBetweenAxisAndChart": "number",
|
||||
"height": "number",
|
||||
"width": "number"
|
||||
"title": "string",
|
||||
"datasource": "tables",
|
||||
"labelColumn": "string",
|
||||
"valueColumn": "string",
|
||||
"height": {
|
||||
"type": "string",
|
||||
"default": "200"
|
||||
},
|
||||
"width": "string",
|
||||
"dataLabels": "bool",
|
||||
"animate": {
|
||||
"type": "bool",
|
||||
"default": true
|
||||
},
|
||||
"legend": {
|
||||
"type": "bool",
|
||||
"default": true
|
||||
},
|
||||
"palette": {
|
||||
"type": "options",
|
||||
"default": "Palette 1",
|
||||
"options": [
|
||||
"Palette 1",
|
||||
"Palette 2",
|
||||
"Palette 3",
|
||||
"Palette 4",
|
||||
"Palette 5",
|
||||
"Palette 6",
|
||||
"Palette 7",
|
||||
"Palette 8",
|
||||
"Palette 9",
|
||||
"Palette 10"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"donut": {
|
||||
"description": "Donut Chart",
|
||||
"data": true,
|
||||
"props": {
|
||||
"title": "string",
|
||||
"datasource": "tables",
|
||||
"labelColumn": "string",
|
||||
"valueColumn": "string",
|
||||
"height": {
|
||||
"type": "string",
|
||||
"default": "200"
|
||||
},
|
||||
"width": "string",
|
||||
"dataLabels": "bool",
|
||||
"animate": {
|
||||
"type": "bool",
|
||||
"default": true
|
||||
},
|
||||
"legend": {
|
||||
"type": "bool",
|
||||
"default": true
|
||||
},
|
||||
"palette": {
|
||||
"type": "options",
|
||||
"default": "Palette 1",
|
||||
"options": [
|
||||
"Palette 1",
|
||||
"Palette 2",
|
||||
"Palette 3",
|
||||
"Palette 4",
|
||||
"Palette 5",
|
||||
"Palette 6",
|
||||
"Palette 7",
|
||||
"Palette 8",
|
||||
"Palette 9",
|
||||
"Palette 10"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"candlestick": {
|
||||
"description": "Candlestick Chart",
|
||||
"data": true,
|
||||
"props": {
|
||||
"title": "string",
|
||||
"datasource": "tables",
|
||||
"dateColumn": "string",
|
||||
"openColumn": "string",
|
||||
"closeColumn": "string",
|
||||
"highColumn": "string",
|
||||
"lowColumn": "string",
|
||||
"height": {
|
||||
"type": "string",
|
||||
"default": "400"
|
||||
},
|
||||
"width": "string",
|
||||
"animate": {
|
||||
"type": "bool",
|
||||
"default": true
|
||||
},
|
||||
"xAxisLabel": "string",
|
||||
"yAxisLabel": "string",
|
||||
"yAxisUnits": {
|
||||
"type": "options",
|
||||
"default": "Default",
|
||||
"options": [
|
||||
"Default", "Thousands", "Millions"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"datepicker": {
|
||||
|
@ -686,30 +683,6 @@
|
|||
"placeholder": "string"
|
||||
}
|
||||
},
|
||||
"datachart": {
|
||||
"description": "shiny chart",
|
||||
"data": true,
|
||||
"props": {
|
||||
"table": "tables",
|
||||
"type": {
|
||||
"type": "options",
|
||||
"default": "column2d",
|
||||
"options": [
|
||||
"column3d",
|
||||
"line",
|
||||
"area2d",
|
||||
"bar2d",
|
||||
"bar3d",
|
||||
"pie2d",
|
||||
"pie3d",
|
||||
"doughnut2d",
|
||||
"doughnut3d",
|
||||
"pareto2d",
|
||||
"pareto3d"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"name": "Link",
|
||||
"description": "an HTML anchor <a> tag",
|
||||
|
|
|
@ -35,18 +35,15 @@
|
|||
"license": "MIT",
|
||||
"gitHead": "284cceb9b703c38566c6e6363c022f79a08d5691",
|
||||
"dependencies": {
|
||||
"@beyonk/svelte-googlemaps": "^2.2.0",
|
||||
"@budibase/bbui": "^1.50.1",
|
||||
"@budibase/svelte-ag-grid": "^0.0.13",
|
||||
"@fortawesome/fontawesome-free": "^5.14.0",
|
||||
"@svelteschool/svelte-forms": "^0.7.0",
|
||||
"britecharts": "^2.16.1",
|
||||
"d3-selection": "^1.4.2",
|
||||
"apexcharts": "^3.22.1",
|
||||
"fast-sort": "^2.2.0",
|
||||
"flatpickr": "^4.6.6",
|
||||
"fusioncharts": "^3.15.1-sr.1",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"svelte-flatpickr": "^3.1.0",
|
||||
"svelte-fusioncharts": "^1.0.0"
|
||||
"svelte-apexcharts": "^1.0.2",
|
||||
"svelte-flatpickr": "^3.1.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<script>
|
||||
import { chart } from "svelte-apexcharts"
|
||||
|
||||
export let options
|
||||
</script>
|
||||
|
||||
{#if options}
|
||||
<div use:chart={options} />
|
||||
{:else if options === false}
|
||||
<div>Invalid chart options</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
div :global(.apexcharts-legend-series) {
|
||||
display: flex !important;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,154 @@
|
|||
export class ApexOptionsBuilder {
|
||||
formatters = {
|
||||
["Default"]: val => Math.round(val * 100) / 100,
|
||||
["Thousands"]: val => `${Math.round(val / 1000)}K`,
|
||||
["Millions"]: val => `${Math.round(val / 1000000)}M`,
|
||||
}
|
||||
options = {
|
||||
series: [],
|
||||
legend: {
|
||||
show: false,
|
||||
position: "top",
|
||||
horizontalAlign: "right",
|
||||
showForSingleSeries: true,
|
||||
showForNullSeries: true,
|
||||
showForZeroSeries: true,
|
||||
},
|
||||
chart: {
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
zoom: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
formatter: this.formatters.Default,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
setOption(path, value) {
|
||||
if (value == null || value === "") {
|
||||
return this
|
||||
}
|
||||
let tmp = this.options
|
||||
for (let i = 0; i < path.length - 1; i++) {
|
||||
const step = path[i]
|
||||
if (!tmp[step]) {
|
||||
tmp[step] = {}
|
||||
}
|
||||
tmp = tmp[step]
|
||||
}
|
||||
tmp[path[path.length - 1]] = value
|
||||
return this
|
||||
}
|
||||
|
||||
getOptions() {
|
||||
return this.options
|
||||
}
|
||||
|
||||
type(type) {
|
||||
return this.setOption(["chart", "type"], type)
|
||||
}
|
||||
|
||||
title(title) {
|
||||
return this.setOption(["title", "text"], title)
|
||||
}
|
||||
|
||||
color(color) {
|
||||
return this.setOption(["colors"], [color])
|
||||
}
|
||||
|
||||
width(width) {
|
||||
return this.setOption(["chart", "width"], width || undefined)
|
||||
}
|
||||
|
||||
height(height) {
|
||||
return this.setOption(["chart", "height"], height || undefined)
|
||||
}
|
||||
|
||||
xLabel(label) {
|
||||
return this.setOption(["xaxis", "title", "text"], label)
|
||||
}
|
||||
|
||||
yLabel(label) {
|
||||
return this.setOption(["yaxis", "title", "text"], label)
|
||||
}
|
||||
|
||||
categories(categories) {
|
||||
return this.setOption(["xaxis", "categories"], categories)
|
||||
}
|
||||
|
||||
series(series) {
|
||||
return this.setOption(["series"], series)
|
||||
}
|
||||
|
||||
horizontal(horizontal) {
|
||||
return this.setOption(["plotOptions", "bar", "horizontal"], horizontal)
|
||||
}
|
||||
|
||||
dataLabels(dataLabels) {
|
||||
return this.setOption(["dataLabels", "enabled"], dataLabels)
|
||||
}
|
||||
|
||||
animate(animate) {
|
||||
return this.setOption(["chart", "animations", "enabled"], animate)
|
||||
}
|
||||
|
||||
curve(curve) {
|
||||
return this.setOption(["stroke", "curve"], curve)
|
||||
}
|
||||
|
||||
gradient(gradient) {
|
||||
const fill = {
|
||||
type: "gradient",
|
||||
gradient: {
|
||||
shadeIntensity: 1,
|
||||
opacityFrom: 0.7,
|
||||
opacityTo: 0.9,
|
||||
stops: [0, 90, 100],
|
||||
},
|
||||
}
|
||||
return this.setOption(["fill"], gradient ? fill : undefined)
|
||||
}
|
||||
|
||||
legend(legend) {
|
||||
return this.setOption(["legend", "show"], legend)
|
||||
}
|
||||
|
||||
legendPosition(position) {
|
||||
return this.setOption(["legend", "position"], position)
|
||||
}
|
||||
|
||||
stacked(stacked) {
|
||||
return this.setOption(["chart", "stacked"], stacked)
|
||||
}
|
||||
|
||||
labels(labels) {
|
||||
return this.setOption(["labels"], labels)
|
||||
}
|
||||
|
||||
yUnits(units) {
|
||||
return this.setOption(
|
||||
["yaxis", "labels", "formatter"],
|
||||
this.formatters[units || "Default"]
|
||||
)
|
||||
}
|
||||
|
||||
xType(type) {
|
||||
return this.setOption(["xaxis", "type"], type)
|
||||
}
|
||||
|
||||
yTooltip(yTooltip) {
|
||||
return this.setOption(["yaxis", "tooltip", "enabled"], yTooltip)
|
||||
}
|
||||
|
||||
palette(palette) {
|
||||
return this.setOption(
|
||||
["theme", "palette"],
|
||||
palette.toLowerCase().replace(/[\W]/g, "")
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
<script>
|
||||
import LineChart from "./LineChart.svelte"
|
||||
</script>
|
||||
|
||||
<LineChart {...$$props} area />
|
|
@ -1,187 +0,0 @@
|
|||
<script>
|
||||
import {
|
||||
getColorSchema,
|
||||
getChartGradient,
|
||||
notNull,
|
||||
hasProp,
|
||||
} from "./utils.js"
|
||||
import britecharts from "britecharts"
|
||||
import fetchData from "../fetchData.js"
|
||||
import { onMount } from "svelte"
|
||||
import { isEmpty } from "lodash/fp"
|
||||
|
||||
import { select } from "d3-selection"
|
||||
import shortid from "shortid"
|
||||
|
||||
let tooltip
|
||||
const _id = shortid.generate()
|
||||
const chart = britecharts.bar()
|
||||
const chartClass = `bar-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
|
||||
|
||||
let data = []
|
||||
export let datasource = null
|
||||
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 = false
|
||||
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
|
||||
|
||||
onMount(async () => {
|
||||
if (!isEmpty(datasource)) {
|
||||
data = await fetchData(datasource)
|
||||
|
||||
if (schemaIsValid()) {
|
||||
chartContainer = select(`.${chartClass}`)
|
||||
bindChartUIProps()
|
||||
bindChartEvents()
|
||||
chartContainer.datum(data).call(chart)
|
||||
bindChartTooltip()
|
||||
} else {
|
||||
console.error("Bar Chart - Please provide a valid name and value label")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const schemaIsValid = () =>
|
||||
(hasProp(data, "name") || hasProp(data, nameLabel)) &&
|
||||
(hasProp(data, "value") || hasProp(data, valueLabel))
|
||||
|
||||
function bindChartUIProps() {
|
||||
chart.numberFormat(".0f")
|
||||
chart.labelsNumberFormat(".1f")
|
||||
|
||||
if (notNull(color)) {
|
||||
chart.colorSchema(colorSchema)
|
||||
}
|
||||
if (notNull(gradient)) {
|
||||
chart.chartGradient(chartGradient)
|
||||
}
|
||||
if (notNull(xAxisLabel)) {
|
||||
chart.xAxisLabel(xAxisLabel)
|
||||
}
|
||||
if (notNull(yAxisLabel)) {
|
||||
chart.yAxisLabel(yAxisLabel)
|
||||
}
|
||||
if (notNull(betweenBarsPadding)) {
|
||||
chart.betweenBarsPadding(Number(betweenBarsPadding))
|
||||
}
|
||||
if (notNull(enableLabels)) {
|
||||
chart.enableLabels(enableLabels)
|
||||
}
|
||||
if (notNull(hasPercentage)) {
|
||||
chart.hasPercentage(hasPercentage)
|
||||
}
|
||||
if (notNull(hasSingleBarHighlight)) {
|
||||
chart.hasSingleBarHighlight(hasSingleBarHighlight)
|
||||
}
|
||||
if (notNull(labelsMargin)) {
|
||||
chart.labelsMargin(labelsMargin)
|
||||
}
|
||||
if (notNull(height)) {
|
||||
chart.height(height)
|
||||
}
|
||||
if (notNull(highlightBarFunction)) {
|
||||
chart.highlightBarFunction(highlightBarFunction)
|
||||
}
|
||||
if (notNull(width)) {
|
||||
chart.width(width)
|
||||
}
|
||||
if (notNull(isAnimated)) {
|
||||
chart.isAnimated(isAnimated)
|
||||
}
|
||||
if (notNull(isHorizontal)) {
|
||||
chart.isHorizontal(isHorizontal)
|
||||
}
|
||||
if (notNull(yAxisLabelOffset)) {
|
||||
chart.yAxisLabelOffset(yAxisLabelOffset)
|
||||
}
|
||||
if (notNull(xAxisLabelOffset)) {
|
||||
chart.xAxisLabelOffset(Number(xAxisLabelOffset))
|
||||
}
|
||||
if (notNull(labelsNumberFormat)) {
|
||||
chart.labelsNumberFormat(labelsNumberFormat)
|
||||
}
|
||||
if (notNull(valueLabel)) {
|
||||
chart.valueLabel(valueLabel)
|
||||
}
|
||||
if (notNull(locale)) {
|
||||
chart.locale(locale)
|
||||
}
|
||||
if (notNull(nameLabel)) {
|
||||
chart.nameLabel(nameLabel)
|
||||
}
|
||||
if (notNull(numberFormat)) {
|
||||
chart.numberFormat(numberFormat)
|
||||
}
|
||||
if (notNull(labelsSize)) {
|
||||
chart.labelsSize(labelsSize)
|
||||
}
|
||||
if (notNull(xTicks)) {
|
||||
chart.xTicks(xTicks)
|
||||
}
|
||||
if (notNull(yTicks)) {
|
||||
chart.yTicks(yTicks)
|
||||
}
|
||||
if (notNull(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)
|
||||
}
|
||||
|
||||
$: colorSchema = getColorSchema(color)
|
||||
$: chartGradient = getChartGradient(gradient)
|
||||
</script>
|
||||
|
||||
<div bind:this={chartElement} class={chartClass} />
|
|
@ -0,0 +1,99 @@
|
|||
<script>
|
||||
import { onMount } from "svelte"
|
||||
import fetchData, { fetchSchema } from "../fetchData"
|
||||
import { ApexOptionsBuilder } from "./ApexOptionsBuilder"
|
||||
import ApexChart from "./ApexChart.svelte"
|
||||
import { isEmpty } from "lodash/fp"
|
||||
import {
|
||||
closeColumn,
|
||||
dateColumn,
|
||||
highColumn,
|
||||
lowColumn,
|
||||
openColumn,
|
||||
} from "./CandleStickChart.svelte"
|
||||
|
||||
export let _bb
|
||||
export let title
|
||||
export let datasource
|
||||
export let labelColumn
|
||||
export let valueColumns
|
||||
export let xAxisLabel
|
||||
export let yAxisLabel
|
||||
export let height
|
||||
export let width
|
||||
export let color
|
||||
export let dataLabels
|
||||
export let animate
|
||||
export let legend
|
||||
export let stacked
|
||||
export let yAxisUnits
|
||||
export let palette
|
||||
|
||||
const store = _bb.store
|
||||
let options
|
||||
|
||||
// Fetch data on mount
|
||||
onMount(async () => {
|
||||
const allCols = [labelColumn, ...(valueColumns || [])]
|
||||
if (isEmpty(datasource) || allCols.find(x => x == null)) {
|
||||
options = false
|
||||
return
|
||||
}
|
||||
|
||||
// Fetch, filter and sort data
|
||||
const schema = await fetchSchema(datasource.tableId)
|
||||
const result = await fetchData(datasource, $store)
|
||||
const reducer = row => (valid, column) => valid && row[column] != null
|
||||
const hasAllColumns = row => allCols.reduce(reducer(row), true)
|
||||
const data = result
|
||||
.filter(row => hasAllColumns(row))
|
||||
.slice(0, 20)
|
||||
.sort((a, b) => (a[labelColumn] > b[labelColumn] ? 1 : -1))
|
||||
if (!schema || !data.length) {
|
||||
options = false
|
||||
return
|
||||
}
|
||||
|
||||
// Initialise default chart
|
||||
let builder = new ApexOptionsBuilder()
|
||||
.type("bar")
|
||||
.title(title)
|
||||
.width(width)
|
||||
.height(height)
|
||||
.xLabel(xAxisLabel)
|
||||
.yLabel(yAxisLabel)
|
||||
.dataLabels(dataLabels)
|
||||
.animate(animate)
|
||||
.legend(legend)
|
||||
.stacked(stacked)
|
||||
.yUnits(yAxisUnits)
|
||||
.palette(palette)
|
||||
|
||||
// Add data
|
||||
let useDates = false
|
||||
if (datasource.type !== "view" && schema[labelColumn]) {
|
||||
const labelFieldType = schema[labelColumn].type
|
||||
builder = builder.xType(labelFieldType)
|
||||
useDates = labelFieldType === "datetime"
|
||||
}
|
||||
const series = valueColumns.map(column => ({
|
||||
name: column,
|
||||
data: data.map(row => {
|
||||
if (!useDates) {
|
||||
return row[column]
|
||||
} else {
|
||||
return [row[labelColumn], row[column]]
|
||||
}
|
||||
}),
|
||||
}))
|
||||
builder = builder.series(series)
|
||||
if (!useDates) {
|
||||
builder = builder.categories(data.map(row => row[labelColumn]))
|
||||
}
|
||||
|
||||
// Build chart options
|
||||
options = builder.getOptions()
|
||||
})
|
||||
</script>
|
||||
|
||||
<ApexChart {options} />
|
|
@ -1,118 +0,0 @@
|
|||
<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 table
|
||||
|
||||
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 (table) {
|
||||
await fetchData()
|
||||
}
|
||||
chartContainer = select(`.${chartClass}`)
|
||||
bindChartUIProps()
|
||||
bindChartEvents()
|
||||
chartContainer.datum(_data).call(chart)
|
||||
}
|
||||
})
|
||||
|
||||
async function fetchData() {
|
||||
const FETCH_ROWS_URL = `/api/views/all_${table}`
|
||||
const response = await _bb.api.get(FETCH_ROWS_URL)
|
||||
if (response.status === 200) {
|
||||
const json = await response.json()
|
||||
store.update(state => {
|
||||
state[table] = json
|
||||
return state
|
||||
})
|
||||
} else {
|
||||
throw new Error("Failed to fetch rows.", 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 = table ? $store[table] : data
|
||||
|
||||
$: chartGradient = getChartGradient(gradient)
|
||||
$: console.log(chartGradient)
|
||||
</script>
|
||||
|
||||
<div bind:this={chartElement} class={chartClass} />
|
|
@ -1,103 +0,0 @@
|
|||
<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 table
|
||||
|
||||
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 (table) {
|
||||
await fetchData()
|
||||
}
|
||||
chartContainer = select(`.${chartClass}`)
|
||||
bindChartUIProps()
|
||||
chartContainer.datum(_data).call(chart)
|
||||
}
|
||||
})
|
||||
|
||||
async function fetchData() {
|
||||
const FETCH_ROWS_URL = `/api/views/all_${table}`
|
||||
const response = await _bb.api.get(FETCH_ROWS_URL)
|
||||
if (response.status === 200) {
|
||||
const json = await response.json()
|
||||
store.update(state => {
|
||||
state[table] = json
|
||||
return state
|
||||
})
|
||||
} else {
|
||||
throw new Error("Failed to fetch rows.", 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 = table ? $store[table] : data
|
||||
|
||||
$: colorSchema = getColorSchema(color)
|
||||
</script>
|
||||
|
||||
<div bind:this={chartElement} class={chartClass} />
|
|
@ -0,0 +1,74 @@
|
|||
<script>
|
||||
import { onMount } from "svelte"
|
||||
import fetchData, { fetchSchema } from "../fetchData"
|
||||
import { ApexOptionsBuilder } from "./ApexOptionsBuilder"
|
||||
import ApexChart from "./ApexChart.svelte"
|
||||
import { isEmpty } from "lodash/fp"
|
||||
|
||||
export let _bb
|
||||
export let title
|
||||
export let datasource
|
||||
export let dateColumn
|
||||
export let openColumn
|
||||
export let highColumn
|
||||
export let lowColumn
|
||||
export let closeColumn
|
||||
export let xAxisLabel
|
||||
export let yAxisLabel
|
||||
export let height
|
||||
export let width
|
||||
export let animate
|
||||
export let yAxisUnits
|
||||
|
||||
const store = _bb.store
|
||||
let options
|
||||
|
||||
// Fetch data on mount
|
||||
onMount(async () => {
|
||||
const allCols = [dateColumn, openColumn, highColumn, lowColumn, closeColumn]
|
||||
if (isEmpty(datasource) || allCols.find(x => x == null)) {
|
||||
options = false
|
||||
return
|
||||
}
|
||||
|
||||
// Fetch, filter and sort data
|
||||
const schema = await fetchSchema(datasource.tableId)
|
||||
const result = await fetchData(datasource, $store)
|
||||
const reducer = row => (valid, column) => valid && row[column] != null
|
||||
const hasAllColumns = row => allCols.reduce(reducer(row), true)
|
||||
const data = result
|
||||
.filter(row => hasAllColumns(row))
|
||||
.slice(0, 100)
|
||||
.sort((a, b) => (a[dateColumn] > b[dateColumn] ? 1 : -1))
|
||||
if (!schema || !data.length) {
|
||||
options = false
|
||||
return
|
||||
}
|
||||
|
||||
// Initialise default chart
|
||||
let builder = new ApexOptionsBuilder()
|
||||
.type("candlestick")
|
||||
.title(title)
|
||||
.width(width)
|
||||
.height(height)
|
||||
.xLabel(xAxisLabel)
|
||||
.yLabel(yAxisLabel)
|
||||
.animate(animate)
|
||||
.yUnits(yAxisUnits)
|
||||
.yTooltip(true)
|
||||
.xType("datetime")
|
||||
|
||||
// Add data
|
||||
const parseDate = d => (isNaN(d) ? Date.parse(d).valueOf() : parseInt(d))
|
||||
const chartData = data.map(row => ({
|
||||
x: parseDate(row[dateColumn]),
|
||||
y: [row[openColumn], row[highColumn], row[lowColumn], row[closeColumn]],
|
||||
}))
|
||||
builder = builder.series([{ data: chartData }])
|
||||
|
||||
// Build chart options
|
||||
options = builder.getOptions()
|
||||
})
|
||||
</script>
|
||||
|
||||
<ApexChart {options} />
|
|
@ -1,169 +0,0 @@
|
|||
<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}
|
|
@ -1,213 +0,0 @@
|
|||
<script>
|
||||
import { getColorSchema, notNull } from "./utils.js"
|
||||
import fetchData from "../fetchData.js"
|
||||
import Legend from "./Legend.svelte"
|
||||
import britecharts from "britecharts"
|
||||
import { onMount } from "svelte"
|
||||
import { isEmpty } from "lodash/fp"
|
||||
|
||||
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
|
||||
|
||||
let store = _bb.store
|
||||
|
||||
export let customMouseMove = null
|
||||
export let customClick = null
|
||||
|
||||
export let orderingFunction = null
|
||||
|
||||
let data = []
|
||||
export let datasource = {}
|
||||
|
||||
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
|
||||
|
||||
onMount(async () => {
|
||||
if (chart) {
|
||||
if (!isEmpty(datasource)) {
|
||||
let _data = await fetchData(datasource)
|
||||
data = checkAndReformatData(_data)
|
||||
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 && valueKey !== "quantity") {
|
||||
_data = reformatDataKey(_data, valueKey, "quantity")
|
||||
}
|
||||
|
||||
if (nameKey && nameKey !== "name") {
|
||||
_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 clonedRow = { ...d }
|
||||
if (clonedRow[formatKey]) {
|
||||
delete clonedRow[formatKey]
|
||||
}
|
||||
let value = clonedRow[dataKey]
|
||||
if (!ignoreList.includes(dataKey)) {
|
||||
delete clonedRow[dataKey]
|
||||
}
|
||||
clonedRow[formatKey] = value
|
||||
return clonedRow
|
||||
})
|
||||
} 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,5 @@
|
|||
<script>
|
||||
import PieChart from "./PieChart.svelte"
|
||||
</script>
|
||||
|
||||
<PieChart {...$$props} donut />
|
|
@ -1,145 +0,0 @@
|
|||
<script>
|
||||
import { getColorSchema, getChartGradient, notNull, hasProp } from "./utils"
|
||||
import Tooltip from "./Tooltip.svelte"
|
||||
import fetchData from "../fetchData.js"
|
||||
import britecharts from "britecharts"
|
||||
import { onMount } from "svelte"
|
||||
import { select } from "d3-selection"
|
||||
import shortid from "shortid"
|
||||
import { isEmpty } from "lodash/fp"
|
||||
|
||||
const _id = shortid.generate()
|
||||
|
||||
const chart = britecharts.groupedBar()
|
||||
const chartClass = `groupedbar-container-${_id}`
|
||||
const legendClass = `legend-container-${_id}`
|
||||
|
||||
let tooltip = britecharts.tooltip()
|
||||
let tooltipContainer
|
||||
let chartElement = null
|
||||
let chartContainer = null
|
||||
|
||||
export let customClick = null
|
||||
|
||||
let data = []
|
||||
export let datasource = {}
|
||||
export let color = "britecharts"
|
||||
export let height = 200
|
||||
export let width = 200
|
||||
export let margin = null
|
||||
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 tooltipTitle = ""
|
||||
|
||||
const schemaIsValid = () =>
|
||||
(hasProp(data, "name") || hasProp(data, nameLabel)) &&
|
||||
(hasProp(data, "group") || hasProp(data, groupLabel)) &&
|
||||
(hasProp(data, "value") || hasProp(data, valueLabel))
|
||||
|
||||
onMount(async () => {
|
||||
if (!isEmpty(datasource)) {
|
||||
data = await fetchData(datasource)
|
||||
if (schemaIsValid()) {
|
||||
chartContainer = select(`.${chartClass}`)
|
||||
bindChartUIProps()
|
||||
bindChartEvents()
|
||||
chartContainer.datum(data).call(chart)
|
||||
bindTooltip()
|
||||
} else {
|
||||
console.error(
|
||||
"Grouped bar - Please provide valid name, value and group labels"
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function bindTooltip() {
|
||||
tooltipContainer = select(`.${chartClass} .metadata-group`)
|
||||
tooltip.topicLabel("values")
|
||||
tooltip.shouldShowDateInTitle(false)
|
||||
tooltipContainer.datum([]).call(tooltip)
|
||||
}
|
||||
|
||||
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(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)
|
||||
}
|
||||
if (notNull(tooltipTitle)) {
|
||||
tooltip.title(tooltipTitle)
|
||||
} else if (datasource.label) {
|
||||
tooltip.title(datasource.label)
|
||||
}
|
||||
}
|
||||
|
||||
function bindChartEvents() {
|
||||
if (customClick) {
|
||||
chart.on("customClick", customClick)
|
||||
}
|
||||
chart.on("customMouseMove", tooltip.update)
|
||||
chart.on("customMouseOut", tooltip.hide)
|
||||
chart.on("customMouseOver", tooltip.show)
|
||||
}
|
||||
|
||||
$: colorSchema = getColorSchema(color)
|
||||
</script>
|
||||
|
||||
<div bind:this={chartElement} class={chartClass} />
|
|
@ -1,83 +0,0 @@
|
|||
<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 table
|
||||
|
||||
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 (table) {
|
||||
await fetchData()
|
||||
}
|
||||
chartContainer = select(`.${chartClass}`)
|
||||
bindChartUIProps()
|
||||
chartContainer.datum(data).call(chart)
|
||||
}
|
||||
})
|
||||
|
||||
async function fetchData() {
|
||||
const FETCH_ROWS_URL = `/api/views/all_${table}`
|
||||
const response = await _bb.api.get(FETCH_ROWS_URL)
|
||||
if (response.status === 200) {
|
||||
const json = await response.json()
|
||||
store.update(state => {
|
||||
state[table] = json
|
||||
return state
|
||||
})
|
||||
} else {
|
||||
throw new Error("Failed to fetch rows.", 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 = table ? $store[table] : data
|
||||
|
||||
$: colorSchema = getColorSchema(color)
|
||||
</script>
|
||||
|
||||
<div bind:this={chartElement} class={chartClass} />
|
||||
{#if useLegend}
|
||||
<div class={legendClass} />
|
||||
{/if}
|
|
@ -1,86 +0,0 @@
|
|||
<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}
|
||||
style={`width: ${width}px`}
|
||||
class={legendClass} />
|
||||
{/if}
|
|
@ -1,256 +0,0 @@
|
|||
<script>
|
||||
import { getColorSchema, getChartGradient, notNull, hasProp } from "./utils"
|
||||
import fetchData from "../fetchData.js"
|
||||
import britecharts from "britecharts"
|
||||
import { onMount } from "svelte"
|
||||
import { isEmpty } from "lodash/fp"
|
||||
|
||||
import { select } from "d3-selection"
|
||||
import shortid from "shortid"
|
||||
|
||||
const _id = shortid.generate()
|
||||
|
||||
export let datasource = {}
|
||||
|
||||
const chart = britecharts.line()
|
||||
const chartClass = `line-container-${_id}`
|
||||
|
||||
let data = { dataByTopic: [] }
|
||||
|
||||
let chartElement
|
||||
let chartContainer
|
||||
let tooltipContainer
|
||||
|
||||
let tooltip = britecharts.tooltip()
|
||||
|
||||
export let customMouseOver = () => tooltip.show()
|
||||
export let customMouseMove = (
|
||||
dataPoint,
|
||||
topicColorMap,
|
||||
dataPointXPosition,
|
||||
yPosition
|
||||
) => {
|
||||
tooltip.update(dataPoint, topicColorMap, dataPointXPosition, yPosition)
|
||||
}
|
||||
export let customMouseOut = () => tooltip.hide()
|
||||
|
||||
export let customDataEntryClick = null
|
||||
export let customTouchMove = null
|
||||
|
||||
export let color = "britecharts"
|
||||
export let axisTimeCombinations = ""
|
||||
export let grid = "horizontal"
|
||||
export let aspectRatio = 0.5
|
||||
export let width = null
|
||||
export let height = null
|
||||
export let isAnimated = true
|
||||
export let lineCurve = "linear" //see api for possible opts
|
||||
export let lineGradient = null
|
||||
export let locale = "en-GB"
|
||||
export let numberFormat = ""
|
||||
export let shouldShowAllDataPoints = true
|
||||
export let topicLabel = null
|
||||
export let dateLabel = "date"
|
||||
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 yAxisLabelPadding = null
|
||||
export let lines = null //not handled by setting prop
|
||||
export let tooltipThreshold = null
|
||||
export let tooltipTitle = ""
|
||||
export let xTicks = ""
|
||||
export let yTicks = ""
|
||||
|
||||
onMount(async () => {
|
||||
if (!isEmpty(datasource)) {
|
||||
data = await getAndPrepareData()
|
||||
|
||||
if (data.dataByTopic.length > 0) {
|
||||
chartContainer = select(`.${chartClass}`)
|
||||
bindChartUIProps()
|
||||
bindChartEvents()
|
||||
chartContainer.datum(data).call(chart)
|
||||
|
||||
// Hack 🤮 X Axis Label and last tick label gets cut off unless we do this 👇
|
||||
const chartSvg = document.querySelector(`.${chartClass} .britechart`)
|
||||
if (chartSvg) {
|
||||
let height = chartSvg.getAttribute("height")
|
||||
let width = chartSvg.getAttribute("width")
|
||||
height = parseInt(height) + 35
|
||||
width = parseInt(width) + 15
|
||||
chartSvg.setAttribute("height", height)
|
||||
chartSvg.setAttribute("width", width)
|
||||
}
|
||||
|
||||
bindTooltip()
|
||||
} else {
|
||||
console.error(
|
||||
"Line Chart - Please provide valid name, value and topic labels"
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function bindTooltip() {
|
||||
tooltipContainer = select(
|
||||
`.${chartClass} .metadata-group .vertical-marker-container`
|
||||
)
|
||||
tooltip.topicLabel("topics")
|
||||
tooltipContainer.datum([]).call(tooltip)
|
||||
}
|
||||
|
||||
const schemaIsValid = data =>
|
||||
hasProp(data, valueLabel) &&
|
||||
hasProp(data, dateLabel) &&
|
||||
hasProp(data, topicLabel)
|
||||
|
||||
async function getAndPrepareData() {
|
||||
let dataByTopic = []
|
||||
let _data = []
|
||||
|
||||
if (!topicLabel) {
|
||||
topicLabel = "topicName"
|
||||
}
|
||||
|
||||
if (!valueLabel) {
|
||||
valueLabel = "value"
|
||||
}
|
||||
|
||||
if (!dateLabel) {
|
||||
dateLabel = "date"
|
||||
}
|
||||
|
||||
_data = await fetchData(datasource)
|
||||
|
||||
if (schemaIsValid(_data)) {
|
||||
_data.forEach((data, idx, arr) => {
|
||||
let topicName = data[topicLabel]
|
||||
if (!dataByTopic.some(dt => dt.topicName === topicName)) {
|
||||
let d = {
|
||||
topicName,
|
||||
topic: dataByTopic.length + 1,
|
||||
dates: arr
|
||||
.filter(d => d[topicLabel] === topicName)
|
||||
.map(d => ({
|
||||
date: new Date(d[dateLabel]),
|
||||
value: d[valueLabel],
|
||||
}))
|
||||
.sort((a, b) => a.date - b.date),
|
||||
}
|
||||
dataByTopic.push(d)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return { dataByTopic }
|
||||
}
|
||||
|
||||
function bindChartUIProps() {
|
||||
chart.tooltipThreshold(800)
|
||||
chart.aspectRatio(0.5)
|
||||
chart.xAxisCustomFormat("%e %b %Y")
|
||||
chart.xTicks(data.dataByTopic.length)
|
||||
|
||||
if (notNull(color)) {
|
||||
chart.colorSchema(colorSchema)
|
||||
}
|
||||
if (notNull(lineGradient)) {
|
||||
chart.lineGradient(chartGradient)
|
||||
}
|
||||
if (notNull(axisTimeCombinations)) {
|
||||
chart.axisTimeCombinations(axisTimeCombinations)
|
||||
}
|
||||
if (notNull(grid)) {
|
||||
chart.grid(grid)
|
||||
}
|
||||
if (notNull(aspectRatio)) {
|
||||
chart.aspectRatio(aspectRatio)
|
||||
}
|
||||
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(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)
|
||||
}
|
||||
if (notNull(tooltipThreshold)) {
|
||||
chart.tooltipThreshold(tooltipThreshold)
|
||||
}
|
||||
if (notNull(lines)) {
|
||||
chart.lines(lines)
|
||||
}
|
||||
if (notNull(xTicks)) {
|
||||
chart.xTicks(Number(xTicks))
|
||||
}
|
||||
if (notNull(yTicks)) {
|
||||
chart.yTicks(Number(yTicks))
|
||||
}
|
||||
if (notNull(tooltipTitle)) {
|
||||
tooltip.title(tooltipTitle)
|
||||
} else if (datasource.label) {
|
||||
tooltip.title(datasource.label)
|
||||
}
|
||||
}
|
||||
|
||||
function bindChartEvents() {
|
||||
if (customMouseOver) {
|
||||
chart.on("customMouseOver", tooltip.show)
|
||||
}
|
||||
if (customMouseMove) {
|
||||
chart.on("customMouseMove", tooltip.update)
|
||||
}
|
||||
if (customMouseOut) {
|
||||
chart.on("customMouseOut", tooltip.hide)
|
||||
}
|
||||
if (customDataEntryClick) {
|
||||
chart.on("customDataEntryClick", customDataEntryClick)
|
||||
}
|
||||
if (customTouchMove) {
|
||||
chart.on("customTouchMove", customTouchMove)
|
||||
}
|
||||
}
|
||||
|
||||
$: colorSchema = getColorSchema(color)
|
||||
$: chartGradient = getChartGradient(lineGradient)
|
||||
</script>
|
||||
|
||||
<div bind:this={chartElement} class={chartClass} />
|
|
@ -0,0 +1,100 @@
|
|||
<script>
|
||||
import { onMount } from "svelte"
|
||||
import fetchData, { fetchSchema } from "../fetchData"
|
||||
import { ApexOptionsBuilder } from "./ApexOptionsBuilder"
|
||||
import ApexChart from "./ApexChart.svelte"
|
||||
import { isEmpty } from "lodash/fp"
|
||||
|
||||
// Common props
|
||||
export let _bb
|
||||
export let title
|
||||
export let datasource
|
||||
export let labelColumn
|
||||
export let valueColumns
|
||||
export let xAxisLabel
|
||||
export let yAxisLabel
|
||||
export let height
|
||||
export let width
|
||||
export let color
|
||||
export let animate
|
||||
export let dataLabels
|
||||
export let curve
|
||||
export let legend
|
||||
export let yAxisUnits
|
||||
export let palette
|
||||
|
||||
// Area specific props
|
||||
export let area
|
||||
export let stacked
|
||||
export let gradient
|
||||
|
||||
const store = _bb.store
|
||||
let options
|
||||
|
||||
// Fetch data on mount
|
||||
onMount(async () => {
|
||||
const allCols = [labelColumn, ...(valueColumns || [])]
|
||||
if (isEmpty(datasource) || allCols.find(x => x == null)) {
|
||||
options = false
|
||||
return
|
||||
}
|
||||
|
||||
// Fetch, filter and sort data
|
||||
const schema = await fetchSchema(datasource.tableId)
|
||||
const result = await fetchData(datasource, $store)
|
||||
const reducer = row => (valid, column) => valid && row[column] != null
|
||||
const hasAllColumns = row => allCols.reduce(reducer(row), true)
|
||||
const data = result
|
||||
.filter(row => hasAllColumns(row))
|
||||
.slice(0, 100)
|
||||
.sort((a, b) => (a[labelColumn] > b[labelColumn] ? 1 : -1))
|
||||
if (!schema || !data.length) {
|
||||
options = false
|
||||
return
|
||||
}
|
||||
|
||||
// Initialise default chart
|
||||
let builder = new ApexOptionsBuilder()
|
||||
.title(title)
|
||||
.type(area ? "area" : "line")
|
||||
.width(width)
|
||||
.height(height)
|
||||
.xLabel(xAxisLabel)
|
||||
.yLabel(yAxisLabel)
|
||||
.dataLabels(dataLabels)
|
||||
.animate(animate)
|
||||
.curve(curve.toLowerCase())
|
||||
.gradient(gradient)
|
||||
.stacked(stacked)
|
||||
.legend(legend)
|
||||
.yUnits(yAxisUnits)
|
||||
.palette(palette)
|
||||
|
||||
// Add data
|
||||
let useDates = false
|
||||
if (datasource.type !== "view" && schema[labelColumn]) {
|
||||
const labelFieldType = schema[labelColumn].type
|
||||
builder = builder.xType(labelFieldType)
|
||||
useDates = labelFieldType === "datetime"
|
||||
}
|
||||
const series = valueColumns.map(column => ({
|
||||
name: column,
|
||||
data: data.map(row => {
|
||||
if (!useDates) {
|
||||
return row[column]
|
||||
} else {
|
||||
return [row[labelColumn], row[column]]
|
||||
}
|
||||
}),
|
||||
}))
|
||||
builder = builder.series(series)
|
||||
if (!useDates) {
|
||||
builder = builder.categories(data.map(row => row[labelColumn]))
|
||||
}
|
||||
|
||||
// Build chart options
|
||||
options = builder.getOptions()
|
||||
})
|
||||
</script>
|
||||
|
||||
<ApexChart {options} />
|
|
@ -0,0 +1,66 @@
|
|||
<script>
|
||||
import { onMount } from "svelte"
|
||||
import fetchData, { fetchSchema } from "../fetchData"
|
||||
import { ApexOptionsBuilder } from "./ApexOptionsBuilder"
|
||||
import ApexChart from "./ApexChart.svelte"
|
||||
import { isEmpty } from "lodash/fp"
|
||||
|
||||
export let _bb
|
||||
export let title
|
||||
export let datasource
|
||||
export let labelColumn
|
||||
export let valueColumn
|
||||
export let height
|
||||
export let width
|
||||
export let color
|
||||
export let dataLabels
|
||||
export let animate
|
||||
export let legend
|
||||
export let donut
|
||||
export let palette
|
||||
|
||||
const store = _bb.store
|
||||
let options
|
||||
|
||||
// Fetch data on mount
|
||||
onMount(async () => {
|
||||
if (isEmpty(datasource) || !labelColumn || !valueColumn) {
|
||||
options = false
|
||||
return
|
||||
}
|
||||
|
||||
// Fetch, filter and sort data
|
||||
const schema = await fetchSchema(datasource.tableId)
|
||||
const result = await fetchData(datasource, $store)
|
||||
const data = result
|
||||
.filter(row => row[labelColumn] != null && row[valueColumn] != null)
|
||||
.slice(0, 20)
|
||||
.sort((a, b) => (a[labelColumn] > b[labelColumn] ? 1 : -1))
|
||||
if (!schema || !data.length) {
|
||||
options = false
|
||||
return
|
||||
}
|
||||
|
||||
// Initialise default chart
|
||||
let builder = new ApexOptionsBuilder()
|
||||
.title(title)
|
||||
.type(donut ? "donut" : "pie")
|
||||
.width(width)
|
||||
.height(height)
|
||||
.dataLabels(dataLabels)
|
||||
.animate(animate)
|
||||
.legend(legend)
|
||||
.legendPosition("right")
|
||||
.palette(palette)
|
||||
|
||||
// Add data if valid datasource
|
||||
const series = data.map(row => parseFloat(row[valueColumn]))
|
||||
const labels = data.map(row => row[labelColumn])
|
||||
builder = builder.series(series).labels(labels)
|
||||
|
||||
// Build chart options
|
||||
options = builder.getOptions()
|
||||
})
|
||||
</script>
|
||||
|
||||
<ApexChart {options} />
|
|
@ -1,187 +0,0 @@
|
|||
<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 table
|
||||
|
||||
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 (table) {
|
||||
await fetchData()
|
||||
}
|
||||
chartContainer = select(`.${chartClass}`)
|
||||
bindChartUIProps()
|
||||
bindChartEvents()
|
||||
chartContainer.datum(_data).call(chart)
|
||||
bindChartTooltip()
|
||||
}
|
||||
})
|
||||
|
||||
async function fetchData() {
|
||||
const FETCH_ROWS_URL = `/api/views/all_${table}`
|
||||
const response = await _bb.api.get(FETCH_ROWS_URL)
|
||||
if (response.status === 200) {
|
||||
const json = await response.json()
|
||||
store.update(state => {
|
||||
state[table] = json
|
||||
return state
|
||||
})
|
||||
} else {
|
||||
throw new Error("Failed to fetch rows.", 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 = table ? $store[table] : data
|
||||
|
||||
$: colorSchema = getColorSchema(color)
|
||||
</script>
|
||||
|
||||
<div bind:this={chartElement} class={chartClass} />
|
||||
{#if useLegend}
|
||||
<div class={legendClass} />
|
||||
{/if}
|
|
@ -1,103 +0,0 @@
|
|||
<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 table
|
||||
|
||||
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 (table) {
|
||||
await fetchData()
|
||||
}
|
||||
chartContainer = select(`.${chartClass}`)
|
||||
bindChartUIProps()
|
||||
chartContainer.datum(_data).call(chart)
|
||||
}
|
||||
})
|
||||
|
||||
async function fetchData() {
|
||||
const FETCH_ROWS_URL = `/api/views/all_${table}`
|
||||
const response = await _bb.api.get(FETCH_ROWS_URL)
|
||||
if (response.status === 200) {
|
||||
const json = await response.json()
|
||||
store.update(state => {
|
||||
state[table] = json
|
||||
return state
|
||||
})
|
||||
} else {
|
||||
throw new Error("Failed to fetch rows.", 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 = table ? $store[table] : data
|
||||
|
||||
$: aGradient = getChartGradient(areaGradient)
|
||||
$: lGradient = getChartGradient(lineGradient)
|
||||
</script>
|
||||
|
||||
<div bind:this={chartElement} class={chartClass} />
|
||||
{#if useLegend}
|
||||
<div class={legendClass} />
|
||||
{/if}
|
|
@ -1,181 +0,0 @@
|
|||
<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 table
|
||||
|
||||
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 (table) {
|
||||
await fetchData()
|
||||
}
|
||||
chartContainer = select(`.${chartClass}`)
|
||||
bindChartUIProps()
|
||||
bindChartEvents()
|
||||
chartContainer.datum(_data).call(chart)
|
||||
bindChartTooltip()
|
||||
}
|
||||
})
|
||||
|
||||
async function fetchData() {
|
||||
const FETCH_ROWS_URL = `/api/views/all_${table}`
|
||||
const response = await _bb.api.get(FETCH_ROWS_URL)
|
||||
if (response.status === 200) {
|
||||
const json = await response.json()
|
||||
store.update(state => {
|
||||
state[table] = json
|
||||
return state
|
||||
})
|
||||
} else {
|
||||
throw new Error("Failed to fetch rows.", 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 = table ? $store[table] : data
|
||||
|
||||
$: colorSchema = getColorSchema(color)
|
||||
</script>
|
||||
|
||||
<div bind:this={chartElement} class={chartClass} />
|
||||
{#if useLegend}
|
||||
<div class={legendClass} />
|
||||
{/if}
|
|
@ -1,176 +0,0 @@
|
|||
<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 table
|
||||
|
||||
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 (table) {
|
||||
await fetchData()
|
||||
}
|
||||
chartContainer = select(`.${chartClass}`)
|
||||
bindChartUIProps()
|
||||
bindChartEvents()
|
||||
chartContainer.datum(_data).call(chart)
|
||||
// bindChartTooltip()
|
||||
}
|
||||
})
|
||||
|
||||
async function fetchData() {
|
||||
const FETCH_ROWS_URL = `/api/views/all_${table}`
|
||||
const response = await _bb.api.get(FETCH_ROWS_URL)
|
||||
if (response.status === 200) {
|
||||
const json = await response.json()
|
||||
store.update(state => {
|
||||
state[table] = json
|
||||
return state
|
||||
})
|
||||
} else {
|
||||
throw new Error("Failed to fetch rows.", 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 = table ? $store[table] : data
|
||||
|
||||
$: colorSchema = getColorSchema(color)
|
||||
</script>
|
||||
|
||||
<div bind:this={chartElement} class={chartClass} />
|
||||
{#if useLegend}
|
||||
<div class={legendClass} />
|
||||
{/if}
|
|
@ -1,129 +0,0 @@
|
|||
<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 table
|
||||
|
||||
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 (table) {
|
||||
await fetchData()
|
||||
}
|
||||
chartContainer = select(`.${chartClass}`)
|
||||
bindChartUIProps()
|
||||
bindChartEvents()
|
||||
chartContainer.datum(_data).call(chart)
|
||||
bindChartTooltip()
|
||||
}
|
||||
})
|
||||
|
||||
async function fetchData() {
|
||||
const FETCH_ROWS_URL = `/api/views/all_${table}`
|
||||
const response = await _bb.api.get(FETCH_ROWS_URL)
|
||||
if (response.status === 200) {
|
||||
const json = await response.json()
|
||||
store.update(state => {
|
||||
state[table] = json
|
||||
return state
|
||||
})
|
||||
} else {
|
||||
throw new Error("Failed to fetch rows.", 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 = table ? $store[table] : data
|
||||
|
||||
$: colorSchema = getColorSchema(color)
|
||||
</script>
|
||||
|
||||
<div bind:this={chartElement} class={chartClass} />
|
||||
{#if useLegend}
|
||||
<div class={legendClass} />
|
||||
{/if}
|
|
@ -1,41 +0,0 @@
|
|||
<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}
|
|
@ -1,81 +0,0 @@
|
|||
<script>
|
||||
import { notNull } from "./utils"
|
||||
import { onMount } from "svelte"
|
||||
import { select } from "d3-selection"
|
||||
|
||||
import britecharts from "britecharts"
|
||||
|
||||
export const tooltip = britecharts.tooltip()
|
||||
|
||||
export let chartClass = ""
|
||||
let tooltipContainer
|
||||
|
||||
export let axisTimeCombinations = null
|
||||
export let dateCustomFormat = null
|
||||
export let dateFormat = null
|
||||
export let dateLabel = null
|
||||
export let locale = null
|
||||
export let nameLabel = null
|
||||
export let numberFormat = null
|
||||
export let shouldShowDateInTitle = false
|
||||
export let title = "My Tooltip"
|
||||
export let tooltipOffset = null
|
||||
export let topicLabel = "values"
|
||||
export let topicsOrder = null
|
||||
export let valueLabel = null
|
||||
export let xAxisValueType = null
|
||||
|
||||
onMount(() => {
|
||||
tooltipContainer = select(
|
||||
`.${chartClass} .metadata-group .vertical-marker-container`
|
||||
)
|
||||
tooltipContainer.datum([]).call(tooltip)
|
||||
})
|
||||
|
||||
$: if (tooltipContainer) {
|
||||
if (notNull(axisTimeCombinations)) {
|
||||
tooltip.axisTimeCombinations(axisTimeCombinations)
|
||||
}
|
||||
if (notNull(dateCustomFormat)) {
|
||||
tooltip.dateCustomFormat(dateCustomFormat)
|
||||
}
|
||||
if (notNull(dateFormat)) {
|
||||
tooltip.dateFormat(dateFormat)
|
||||
}
|
||||
if (notNull(dateLabel)) {
|
||||
tooltip.dateLabel(dateLabel)
|
||||
}
|
||||
if (notNull(locale)) {
|
||||
tooltip.locale(locale)
|
||||
}
|
||||
if (notNull(nameLabel)) {
|
||||
tooltip.nameLabel(nameLabel)
|
||||
}
|
||||
if (notNull(numberFormat)) {
|
||||
tooltip.numberFormat(numberFormat)
|
||||
}
|
||||
if (notNull(shouldShowDateInTitle)) {
|
||||
tooltip.shouldShowDateInTitle(shouldShowDateInTitle)
|
||||
}
|
||||
if (notNull(title)) {
|
||||
tooltip.title(title)
|
||||
}
|
||||
if (notNull(tooltipOffset)) {
|
||||
tooltip.tooltipOffset(tooltipOffset)
|
||||
}
|
||||
if (notNull(topicLabel)) {
|
||||
tooltip.topicLabel(topicLabel)
|
||||
}
|
||||
if (notNull(topicsOrder)) {
|
||||
tooltip.topicsOrder(topicsOrder)
|
||||
}
|
||||
if (notNull(valueLabel)) {
|
||||
tooltip.valueLabel(valueLabel)
|
||||
}
|
||||
if (notNull(xAxisValueType)) {
|
||||
tooltip.xAxisValueType(xAxisValueType)
|
||||
}
|
||||
|
||||
tooltipContainer.datum([]).call(tooltip)
|
||||
}
|
||||
</script>
|
|
@ -1,14 +1,6 @@
|
|||
import "britecharts/dist/css/britecharts.min.css"
|
||||
|
||||
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"
|
||||
export { default as bar } from "./BarChart.svelte"
|
||||
export { default as line } from "./LineChart.svelte"
|
||||
export { default as pie } from "./PieChart.svelte"
|
||||
export { default as donut } from "./DonutChart.svelte"
|
||||
export { default as area } from "./AreaChart.svelte"
|
||||
export { default as candlestick } from "./CandleStickChart.svelte"
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
<!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="../../../node_modules/britecharts/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>
|
|
@ -1,235 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>HTML Line</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/line.min.js"
|
||||
type="text/javascript"></script> -->
|
||||
|
||||
<script src="../../../node_modules/britecharts/dist/umd/line.min.js" type="text/javascript"></script>
|
||||
<script src="../../../node_modules/britecharts/dist/umd/tooltip.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>
|
||||
<div class="js-line-chart-container line-chart-container card--chart"></div>
|
||||
</article>
|
||||
|
||||
<script>
|
||||
|
||||
const testData = {
|
||||
data: [
|
||||
{
|
||||
amount: 8,
|
||||
audited: new Date("2020-01-01T16:00:00-08:00"),
|
||||
city: "Belfast",
|
||||
name: 1,
|
||||
tableId: "2334751ac0764c1a931bff5b6b6767eb",
|
||||
type: "row",
|
||||
_id: "ceb87054790f480e80512368545755bb",
|
||||
_rev: "2-56e401ebaf59e6310b85fb0c6c2fece5",
|
||||
},
|
||||
{
|
||||
amount: 12,
|
||||
audited: new Date("2020-01-03T16:00:00-08:00"),
|
||||
city: "Belfast",
|
||||
name: 1,
|
||||
tableId: "2334751ac0764c1a931bff5b6b6767eb",
|
||||
type: "row",
|
||||
_id: "0a36103b55124f348a23d10b2f3ed0e3",
|
||||
_rev: "2-50d62530b2edfc63d5fd0b3719dbb286",
|
||||
},
|
||||
{
|
||||
amount: 6,
|
||||
audited: new Date("2020-01-04T16:00:00-08:00"),
|
||||
city: "Belfast",
|
||||
name: 1,
|
||||
tableId: "2334751ac0764c1a931bff5b6b6767eb",
|
||||
type: "row",
|
||||
_id: "68ade2bb94754caa8fc62c7084e3cef7",
|
||||
_rev: "2-a03fe02f3595920adfbcd9c70564fe9d",
|
||||
},
|
||||
{
|
||||
amount: 2,
|
||||
audited: new Date("2020-01-01T16:00:00-08:00"),
|
||||
city: "Dublin",
|
||||
name: 2,
|
||||
tableId: "2334751ac0764c1a931bff5b6b6767eb",
|
||||
type: "row",
|
||||
_id: "2ab6dabf833f4d99b3438fa4353ba429",
|
||||
_rev: "2-45b190489e76842981902cc9f04369ec",
|
||||
},
|
||||
{
|
||||
amount: 16,
|
||||
audited: new Date("2020-01-02T16:00:00-08:00"),
|
||||
city: "Dublin",
|
||||
name: 2,
|
||||
tableId: "2334751ac0764c1a931bff5b6b6767eb",
|
||||
type: "row",
|
||||
_id: "1b2ca36db1724427a98ba95547f946e0",
|
||||
_rev: "2-c43def17ada959948b9af5484ad5b6b7",
|
||||
},
|
||||
{
|
||||
amount: 7,
|
||||
audited: new Date("2020-01-03T16:00:00-08:00"),
|
||||
city: "Dublin",
|
||||
name: 2,
|
||||
tableId: "2334751ac0764c1a931bff5b6b6767eb",
|
||||
type: "row",
|
||||
_id: "d9235d884a224ca68ac30cefdbb8ae53",
|
||||
_rev: "2-695e426a261a25474cbf6b1f069dccb4",
|
||||
},
|
||||
{
|
||||
amount: 3,
|
||||
audited: new Date("2020-01-04T16:00:00-08:00"),
|
||||
city: "Dublin",
|
||||
name: 2,
|
||||
tableId: "2334751ac0764c1a931bff5b6b6767eb",
|
||||
type: "row",
|
||||
_id: "9f8bc39a9cfb4f779da8c998d7622927",
|
||||
_rev: "2-8ae1aff82e1ffc6ffa75f6b9d074e003",
|
||||
},
|
||||
{
|
||||
amount: 4,
|
||||
audited: new Date("2020-01-02T16:00:00-08:00"),
|
||||
city: "London",
|
||||
name: 3,
|
||||
tableId: "2334751ac0764c1a931bff5b6b6767eb",
|
||||
type: "row",
|
||||
_id: "75274e906073493bbf75cda8656e8db0",
|
||||
_rev: "2-6cfc6bb2fccb83c92b50aa5507f2a092"
|
||||
},
|
||||
{
|
||||
amount: 22,
|
||||
audited: new Date("2020-01-06T16:00:00-08:00"),
|
||||
city: "London",
|
||||
name: 3,
|
||||
tableId: "2334751ac0764c1a931bff5b6b6767eb",
|
||||
type: "row",
|
||||
_id: "da3d4b151bc641f4ace487a2314d2550",
|
||||
_rev: "2-ac18490eaa016be0e71bd4c4ea332981",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const topicLabel = "city"
|
||||
const valueLabel = "amount"
|
||||
const dateLabel = "audited"
|
||||
|
||||
function prepareData() {
|
||||
let dataByTopic = []
|
||||
testData.data.forEach((data, idx, arr) => {
|
||||
let topicName = data[topicLabel]
|
||||
if(!dataByTopic.some(dt => dt.topicName === topicName)) {
|
||||
let d = {topicName, topic: dataByTopic.length + 1, dates: arr.filter(d => d[topicLabel] === topicName).map(d => ({date: d[dateLabel], value: d[valueLabel]}))}
|
||||
dataByTopic.push(d)
|
||||
}
|
||||
})
|
||||
return {dataByTopic}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const newData = prepareData()
|
||||
|
||||
const dataByTopic = {
|
||||
dataByTopic: [
|
||||
{
|
||||
topicName: 'San Francisco',
|
||||
topic: 123,
|
||||
dates: [
|
||||
{
|
||||
date: '2017-01-16T16:00:00-08:00',
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
date: '2017-01-16T17:00:00-08:00',
|
||||
value: 2
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
topicName: 'Belfast',
|
||||
topic: 456,
|
||||
dates: [
|
||||
{
|
||||
date: '2017-01-16T16:00:00-08:00',
|
||||
value: 5
|
||||
},
|
||||
{
|
||||
date: '2017-01-16T17:00:00-08:00',
|
||||
value: 8
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const data = {
|
||||
data: [
|
||||
{
|
||||
topicName: "Oakland",
|
||||
name: 2,
|
||||
date: "2017-01-16T16:00:00-08:00",
|
||||
value: 3,
|
||||
},
|
||||
{
|
||||
topicName: "Oakland",
|
||||
name: 2,
|
||||
date: "2017-01-17T16:00:00-08:00",
|
||||
value: 7,
|
||||
},
|
||||
{
|
||||
topicName: "Oakland",
|
||||
name: 2,
|
||||
date: "2017-01-18T16:00:00-08:00",
|
||||
value: 5,
|
||||
},
|
||||
{
|
||||
topicName: "Oakland",
|
||||
name: 2,
|
||||
date: "2017-01-19T16:00:00-08:00",
|
||||
value: 6,
|
||||
},
|
||||
{
|
||||
topicName: "Oakland",
|
||||
name: 2,
|
||||
date: "2017-01-20T16:00:00-08:00",
|
||||
value: 1,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const lineContainer = d3.select('.js-line-chart-container');
|
||||
|
||||
const lineChart = britecharts.line()
|
||||
const tooltip = britecharts.tooltip()
|
||||
|
||||
lineChart.grid("horizontal").aspectRatio(0.5).isAnimated(true).shouldShowAllDataPoints(true)
|
||||
|
||||
lineContainer.datum(newData).call(lineChart);
|
||||
|
||||
const tooltipContainer = d3.select(`.js-line-chart-container .metadata-group .vertical-marker-container`)
|
||||
|
||||
tooltip.title("yeooo")
|
||||
tooltip.topicLabel("topics")
|
||||
lineChart.on("customMouseOver", tooltip.show)
|
||||
lineChart.on("customMouseMove", tooltip.update)
|
||||
lineChart.on("customMouseOut", tooltip.hide)
|
||||
|
||||
|
||||
tooltipContainer.datum([]).call(tooltip)
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,41 +0,0 @@
|
|||
import britecharts from "britecharts"
|
||||
|
||||
export const notNull = value => value || value === false
|
||||
|
||||
export const hasProp = (data, prop) => data.every(d => prop in d)
|
||||
|
||||
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
|
||||
|
||||
export function reformatDataKey(data = [], dataKey = null, formatKey = null) {
|
||||
let ignoreList = ["_id", "_rev", "id"]
|
||||
if (dataKey && data.every(d => d[dataKey])) {
|
||||
return data.map(d => {
|
||||
let clonedRow = { ...d }
|
||||
if (clonedRow[formatKey]) {
|
||||
delete clonedRow[formatKey]
|
||||
}
|
||||
let value = clonedRow[dataKey]
|
||||
if (!ignoreList.includes(dataKey)) {
|
||||
delete clonedRow[dataKey]
|
||||
}
|
||||
clonedRow[formatKey] = value
|
||||
return clonedRow
|
||||
})
|
||||
} else {
|
||||
return data
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
<script>
|
||||
import { onMount } from "svelte"
|
||||
import FusionCharts from "fusioncharts"
|
||||
import Charts from "fusioncharts/fusioncharts.charts"
|
||||
import FusionTheme from "fusioncharts/themes/fusioncharts.theme.fusion"
|
||||
import SvelteFC, { fcRoot } from "svelte-fusioncharts"
|
||||
|
||||
fcRoot(FusionCharts, Charts, FusionTheme)
|
||||
|
||||
export let _bb
|
||||
export let table
|
||||
export let type = "column2d"
|
||||
|
||||
let store = _bb.store
|
||||
|
||||
$: chartConfigs = {
|
||||
type,
|
||||
width: "600",
|
||||
height: "400",
|
||||
dataFormat: "json",
|
||||
dataSource: {
|
||||
data: $store[table] || [],
|
||||
},
|
||||
}
|
||||
|
||||
$: console.log("CHART CONFIGS", chartConfigs)
|
||||
|
||||
async function fetchData() {
|
||||
const FETCH_ROWS_URL = `/api/views/all_${table}`
|
||||
const response = await _bb.api.get(FETCH_ROWS_URL)
|
||||
if (response.status === 200) {
|
||||
const json = await response.json()
|
||||
store.update(state => {
|
||||
state[table] = json
|
||||
return state
|
||||
})
|
||||
} else {
|
||||
throw new Error("Failed to fetch rows.", response)
|
||||
}
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
await fetchData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<div id="container">
|
||||
<SvelteFC {...chartConfigs} />
|
||||
</div>
|
|
@ -14,12 +14,12 @@ export default async function fetchData(datasource, store) {
|
|||
}
|
||||
|
||||
// Fetch table schema so we can check for linked rows
|
||||
if (rows && rows.length) {
|
||||
const table = await fetchTable()
|
||||
const keys = Object.keys(table.schema)
|
||||
if (rows && rows.length && datasource.tableId) {
|
||||
const schema = await fetchSchema(datasource.tableId)
|
||||
const keys = Object.keys(schema)
|
||||
rows.forEach(row => {
|
||||
for (let key of keys) {
|
||||
const type = table.schema[key].type
|
||||
const type = schema[key].type
|
||||
if (type === "link") {
|
||||
row[`${key}_count`] = Array.isArray(row[key]) ? row[key].length : 0
|
||||
} else if (type === "attachment") {
|
||||
|
@ -38,12 +38,6 @@ export default async function fetchData(datasource, store) {
|
|||
return []
|
||||
}
|
||||
|
||||
async function fetchTable() {
|
||||
const FETCH_TABLE_URL = `/api/tables/${datasource.tableId}`
|
||||
const response = await api.get(FETCH_TABLE_URL)
|
||||
return await response.json()
|
||||
}
|
||||
|
||||
async function fetchTableData() {
|
||||
if (!name.startsWith("all_")) {
|
||||
throw new Error("Incorrect table convention - must begin with all_")
|
||||
|
@ -85,3 +79,9 @@ export default async function fetchData(datasource, store) {
|
|||
return row[datasource.fieldName]
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchSchema(id) {
|
||||
const FETCH_TABLE_URL = `/api/tables/${id}`
|
||||
const response = await api.get(FETCH_TABLE_URL)
|
||||
return (await response.json()).schema
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ export { default as text } from "./Text.svelte"
|
|||
export { default as heading } from "./Heading.svelte"
|
||||
export { default as input } from "./Input.svelte"
|
||||
export { default as textfield } from "./Textfield.svelte"
|
||||
|
||||
export { default as button } from "./Button.svelte"
|
||||
export { default as login } from "./Login.svelte"
|
||||
export { default as saveRowButton } from "./Templates/saveRowButton"
|
||||
|
@ -15,7 +14,6 @@ export { default as Navigation } from "./Navigation.svelte"
|
|||
export { default as datagrid } from "./DataGrid/Component.svelte"
|
||||
export { default as dataform } from "./DataForm.svelte"
|
||||
export { default as dataformwide } from "./DataFormWide.svelte"
|
||||
export { default as datachart } from "./DataChart.svelte"
|
||||
export { default as datalist } from "./DataList.svelte"
|
||||
export { default as list } from "./List.svelte"
|
||||
export { default as datasearch } from "./DataSearch.svelte"
|
||||
|
@ -26,5 +24,5 @@ export { default as cardhorizontal } from "./CardHorizontal.svelte"
|
|||
export { default as rowdetail } from "./RowDetail.svelte"
|
||||
export { default as newrow } from "./NewRow.svelte"
|
||||
export { default as datepicker } from "./DatePicker.svelte"
|
||||
export * from "./Chart"
|
||||
export { default as icon } from "./Icon.svelte"
|
||||
export * from "./Chart"
|
||||
|
|
Loading…
Reference in New Issue