wip
This commit is contained in:
parent
d0fd19a0bc
commit
ab40e3babd
|
@ -9,6 +9,8 @@
|
|||
export let options = []
|
||||
export let getOptionLabel = option => option
|
||||
export let getOptionValue = option => option
|
||||
export let getOptionsIcon = () => null
|
||||
export let getOptionsIconToolip = () => null
|
||||
export let readonly = false
|
||||
export let autocomplete = false
|
||||
export let sort = false
|
||||
|
@ -80,6 +82,8 @@
|
|||
|
||||
<Picker
|
||||
on:loadMore
|
||||
{getOptionsIcon}
|
||||
{getOptionsIconTooltip}
|
||||
{id}
|
||||
{disabled}
|
||||
{readonly}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
export let getOptionLabel = option => option
|
||||
export let getOptionValue = option => option
|
||||
export let getOptionIcon = () => null
|
||||
export let getOptionIconTooltip = () => null
|
||||
export let useOptionIconImage = false
|
||||
export let getOptionColour = () => null
|
||||
export let getOptionSubtitle = () => null
|
||||
|
@ -202,7 +203,7 @@
|
|||
>
|
||||
{#if getOptionIcon(option, idx)}
|
||||
<span class="option-extra icon">
|
||||
{#if useOptionIconImage}
|
||||
{#if useoptioniconimage}
|
||||
<img
|
||||
src={getOptionIcon(option, idx)}
|
||||
alt="icon"
|
||||
|
|
|
@ -9,8 +9,10 @@ import TableSelect from "./controls/TableSelect.svelte"
|
|||
import ColorPicker from "./controls/ColorPicker.svelte"
|
||||
import { IconSelect } from "./controls/IconSelect"
|
||||
import FieldSelect from "./controls/FieldSelect.svelte"
|
||||
import ChartFieldSelect from "./controls/ChartFieldSelect.svelte"
|
||||
import SortableFieldSelect from "./controls/SortableFieldSelect.svelte"
|
||||
import MultiFieldSelect from "./controls/MultiFieldSelect.svelte"
|
||||
import ChartMultiFieldSelect from "./controls/ChartMultiFieldSelect.svelte"
|
||||
import SearchFieldSelect from "./controls/SearchFieldSelect.svelte"
|
||||
import SchemaSelect from "./controls/SchemaSelect.svelte"
|
||||
import SectionSelect from "./controls/SectionSelect.svelte"
|
||||
|
@ -46,7 +48,9 @@ const componentMap = {
|
|||
color: ColorPicker,
|
||||
icon: IconSelect,
|
||||
field: FieldSelect,
|
||||
chartfield: ChartFieldSelect,
|
||||
multifield: MultiFieldSelect,
|
||||
chartmultifield: ChartMultiFieldSelect,
|
||||
searchfield: SearchFieldSelect,
|
||||
options: OptionsEditor,
|
||||
schema: SchemaSelect,
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<script>
|
||||
import { Select } from "@budibase/bbui"
|
||||
import {
|
||||
getDatasourceForProvider,
|
||||
getSchemaForDatasource,
|
||||
} from "dataBinding"
|
||||
import { selectedScreen } from "stores/builder"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
|
||||
export let componentInstance = {}
|
||||
export let value = ""
|
||||
export let placeholder
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
$: datasource = getDatasourceForProvider($selectedScreen, componentInstance)
|
||||
$: schema = getSchemaForDatasource($selectedScreen, datasource).schema
|
||||
$: options = Object.keys(schema || {}).filter(key => {
|
||||
return (
|
||||
schema[key].type !== "json" &&
|
||||
schema[key].type !== "array" &&
|
||||
schema[key].type !== "attachment" &&
|
||||
schema[key].type !== "barcodeqr" &&
|
||||
schema[key].type !== "link" &&
|
||||
schema[key].type !== "bb_reference"
|
||||
);
|
||||
});
|
||||
$: boundValue = getValidValue(value, options)
|
||||
|
||||
const getValidValue = (value, options) => {
|
||||
// Reset value if there aren't any options
|
||||
if (!Array.isArray(options)) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Reset value if the value isn't found in the options
|
||||
if (options.indexOf(value) === -1) {
|
||||
return null
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
const onChange = value => {
|
||||
boundValue = getValidValue(value.detail, options)
|
||||
dispatch("change", boundValue)
|
||||
}
|
||||
|
||||
$: {
|
||||
console.log(options, schema);
|
||||
}
|
||||
</script>
|
||||
|
||||
<Select {placeholder} value={boundValue} on:change={onChange} {options} />
|
|
@ -0,0 +1,48 @@
|
|||
<script>
|
||||
import { Multiselect } from "@budibase/bbui"
|
||||
import { getDatasourceForProvider, getSchemaForDatasource } from "dataBinding"
|
||||
import { selectedScreen } from "stores/builder"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
|
||||
export let componentInstance = {}
|
||||
export let value = ""
|
||||
export let placeholder
|
||||
export let fieldValidator
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
$: datasource = getDatasourceForProvider($selectedScreen, componentInstance)
|
||||
$: schema = getSchemaForDatasource($selectedScreen, datasource).schema
|
||||
|
||||
const getOptions = (schema, fieldValidator) => {
|
||||
if (fieldValidator != null) {
|
||||
return Object.keys(schema || {})
|
||||
}
|
||||
}
|
||||
|
||||
$: options = Object.keys(schema || {}).filter(key => {
|
||||
return (
|
||||
schema[key].type !== "json" &&
|
||||
schema[key].type !== "array" &&
|
||||
schema[key].type !== "attachment" &&
|
||||
schema[key].type !== "barcodeqr" &&
|
||||
schema[key].type !== "link" &&
|
||||
schema[key].type !== "bb_reference"
|
||||
);
|
||||
});
|
||||
$: boundValue = getValidOptions(value, options)
|
||||
|
||||
const getValidOptions = (selectedOptions, allOptions) => {
|
||||
// Fix the hardcoded default string value
|
||||
if (!Array.isArray(selectedOptions)) {
|
||||
selectedOptions = []
|
||||
}
|
||||
return selectedOptions.filter(val => allOptions.indexOf(val) !== -1)
|
||||
}
|
||||
|
||||
const setValue = value => {
|
||||
boundValue = getValidOptions(value.detail, options)
|
||||
dispatch("change", boundValue)
|
||||
}
|
||||
</script>
|
||||
|
||||
<Multiselect {placeholder} value={boundValue} on:change={setValue} {options} />
|
|
@ -0,0 +1,42 @@
|
|||
export const unsupported = Symbol("values-validator-unsupported")
|
||||
export const partialSupport = Symbol("values-validator-partial-support")
|
||||
export const supported = Symbol("values-validator-supported")
|
||||
|
||||
const validatorMap = {
|
||||
chart: (fieldSchema) => {
|
||||
if (
|
||||
fieldSchema.type === "json" ||
|
||||
fieldSchema.type === "array" ||
|
||||
fieldSchema.type === "attachment" ||
|
||||
fieldSchema.type === "barcodeqr" ||
|
||||
fieldSchema.type === "link" ||
|
||||
fieldSchema.type === "bb_reference"
|
||||
) {
|
||||
return {
|
||||
support: unsupported,
|
||||
message: "This field cannot be used as a chart value"
|
||||
}
|
||||
}
|
||||
|
||||
if (fieldSchema.type === "string") {
|
||||
return {
|
||||
support: partialSupport,
|
||||
message: "This field can be used as a chart value, but non-numeric values will not be parsed correctly"
|
||||
}
|
||||
}
|
||||
|
||||
if (fieldSchema.type === "number") {
|
||||
return {
|
||||
support: supported,
|
||||
message: "This field can be used for chart values"
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
support: partialSupport,
|
||||
message: "This field can be used as a chart value, but it may not be parsed correctly"
|
||||
}
|
||||
}
|
||||
};
|
||||
export default validatorMap;
|
||||
|
|
@ -191,6 +191,9 @@
|
|||
// Number fields
|
||||
min: setting.min ?? null,
|
||||
max: setting.max ?? null,
|
||||
|
||||
// Field select settings
|
||||
fieldValidator: setting.fieldValidator,
|
||||
}}
|
||||
{bindings}
|
||||
{componentBindings}
|
||||
|
|
|
@ -1629,10 +1629,11 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "multifield",
|
||||
"type": "chartmultifield",
|
||||
"label": "Data columns",
|
||||
"key": "valueColumns",
|
||||
"dependsOn": "dataProvider",
|
||||
"fieldValidator": "chart",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
|
@ -1787,7 +1788,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "multifield",
|
||||
"type": "chartmultifield",
|
||||
"label": "Data columns",
|
||||
"key": "valueColumns",
|
||||
"dependsOn": "dataProvider",
|
||||
|
@ -1940,7 +1941,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "multifield",
|
||||
"type": "chartmultifield",
|
||||
"label": "Data columns",
|
||||
"key": "valueColumns",
|
||||
"dependsOn": "dataProvider",
|
||||
|
@ -2105,8 +2106,8 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"label": "Data columns",
|
||||
"type": "chartfield",
|
||||
"label": "Data column",
|
||||
"key": "valueColumn",
|
||||
"dependsOn": "dataProvider",
|
||||
"required": true
|
||||
|
@ -2234,7 +2235,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"type": "chartfield",
|
||||
"label": "Data columns",
|
||||
"key": "valueColumn",
|
||||
"dependsOn": "dataProvider",
|
||||
|
@ -2363,28 +2364,28 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"type": "chartfield",
|
||||
"label": "Open column",
|
||||
"key": "openColumn",
|
||||
"dependsOn": "dataProvider",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"type": "chartfield",
|
||||
"label": "Close column",
|
||||
"key": "closeColumn",
|
||||
"dependsOn": "dataProvider",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"type": "chartfield",
|
||||
"label": "High column",
|
||||
"key": "highColumn",
|
||||
"dependsOn": "dataProvider",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"type": "chartfield",
|
||||
"label": "Low column",
|
||||
"key": "lowColumn",
|
||||
"dependsOn": "dataProvider",
|
||||
|
@ -2448,7 +2449,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"type": "chartfield",
|
||||
"label": "Data column",
|
||||
"key": "valueColumn",
|
||||
"dependsOn": "dataProvider",
|
||||
|
@ -5265,7 +5266,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"type": "chartfield",
|
||||
"label": "Data column",
|
||||
"key": "valueColumn",
|
||||
"dependsOn": "dataSource",
|
||||
|
@ -5290,7 +5291,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"type": "chartfield",
|
||||
"label": "Data column",
|
||||
"key": "valueColumn",
|
||||
"dependsOn": "dataSource",
|
||||
|
@ -5315,7 +5316,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "multifield",
|
||||
"type": "chartmultifield",
|
||||
"label": "Data columns",
|
||||
"key": "valueColumns",
|
||||
"dependsOn": "dataSource",
|
||||
|
@ -5362,7 +5363,7 @@
|
|||
},
|
||||
"settings": [
|
||||
{
|
||||
"type": "field",
|
||||
"type": "chartfield",
|
||||
"label": "Value column",
|
||||
"key": "valueColumn",
|
||||
"dependsOn": "dataSource",
|
||||
|
@ -5410,7 +5411,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "multifield",
|
||||
"type": "chartmultifield",
|
||||
"label": "Data columns",
|
||||
"key": "valueColumns",
|
||||
"dependsOn": "dataSource",
|
||||
|
@ -5459,7 +5460,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "multifield",
|
||||
"type": "chartmultifield",
|
||||
"label": "Data columns",
|
||||
"key": "valueColumns",
|
||||
"dependsOn": "dataSource",
|
||||
|
@ -5520,28 +5521,28 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"type": "chartfield",
|
||||
"label": "Open column",
|
||||
"key": "openColumn",
|
||||
"dependsOn": "dataSource",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"type": "chartfield",
|
||||
"label": "Close column",
|
||||
"key": "closeColumn",
|
||||
"dependsOn": "dataSource",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"type": "chartfield",
|
||||
"label": "High column",
|
||||
"key": "highColumn",
|
||||
"dependsOn": "dataSource",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"type": "chartfield",
|
||||
"label": "Low column",
|
||||
"key": "lowColumn",
|
||||
"dependsOn": "dataSource",
|
||||
|
|
|
@ -32,11 +32,12 @@
|
|||
"@spectrum-css/tag": "^3.1.4",
|
||||
"@spectrum-css/typography": "^3.0.2",
|
||||
"@spectrum-css/vars": "^3.0.1",
|
||||
"apexcharts": "^3.22.1",
|
||||
"apexcharts": "^3.45.2",
|
||||
"dayjs": "^1.10.8",
|
||||
"downloadjs": "1.4.7",
|
||||
"html5-qrcode": "^2.2.1",
|
||||
"leaflet": "^1.7.1",
|
||||
"lodash": "^4.17.21",
|
||||
"sanitize-html": "^2.7.0",
|
||||
"screenfull": "^6.0.1",
|
||||
"shortid": "^2.2.15",
|
||||
|
|
|
@ -283,6 +283,9 @@
|
|||
const dependsOnKey = setting.dependsOn.setting || setting.dependsOn
|
||||
const dependsOnValue = setting.dependsOn.value
|
||||
const realDependentValue = instance[dependsOnKey]
|
||||
if (dependsOnValue === undefined && realDependentValue) {
|
||||
return missing
|
||||
}
|
||||
if (dependsOnValue == null && realDependentValue == null) {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -1,25 +1,104 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
import { chart } from "svelte-apexcharts"
|
||||
import Placeholder from "../Placeholder.svelte"
|
||||
import ApexCharts from 'apexcharts'
|
||||
import { Icon } from "@budibase/bbui"
|
||||
import { cloneDeep } from "lodash";
|
||||
|
||||
const { styleable, builderStore } = getContext("sdk")
|
||||
const component = getContext("component")
|
||||
|
||||
export let options
|
||||
/*
|
||||
export let invalid = false
|
||||
|
||||
const parseValue = (value) => {
|
||||
// A value like [10, 11, 12] actually would be output by parseInt as `10`, but this behaviour is odd and not something a
|
||||
// reasonable user would expect.
|
||||
if (Array.isArray(value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const parsedValue = parseInt(value, 10);
|
||||
|
||||
if (Number.isNaN(parsedValue)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return parsedValue
|
||||
}
|
||||
|
||||
const parseOptions = (options) => {
|
||||
const parsedOptions = { series: [], ...cloneDeep(options)}
|
||||
|
||||
// Object form of series, used by most charts
|
||||
if (parsedOptions.series.some(entry => Array.isArray(entry?.data))) {
|
||||
parsedOptions.series = parsedOptions.series.map(entry => ({ ...entry, data: parseValue})parseValue);
|
||||
} else {
|
||||
// Scalar form of series, used by non-axis charts like pie and donut
|
||||
parsedOptions.series = parsedOptions.series.map(parseValue);
|
||||
}
|
||||
|
||||
return parsedOptions;
|
||||
}
|
||||
|
||||
$: parsedOptions = parseOptions(options);
|
||||
*/
|
||||
|
||||
let chartElement;
|
||||
let chart;
|
||||
|
||||
const updateChart = async (newOptions) => {
|
||||
try {
|
||||
await chart?.updateOptions(newOptions)
|
||||
} catch(e) {
|
||||
//console.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
const renderChart = async (newChartElement) => {
|
||||
try {
|
||||
await chart?.destroy()
|
||||
chart = new ApexCharts(newChartElement, options)
|
||||
await chart.render()
|
||||
} catch(e) {
|
||||
//console.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
const isSeriesValid = (series) => {
|
||||
return true
|
||||
}
|
||||
|
||||
$: noData = options == null || options?.series?.length === 0
|
||||
$: hide = noData || !seriesValid
|
||||
|
||||
// Call render chart upon changes to hide, as apex charts has issues with rendering upon changes automatically
|
||||
// if the chart is hidden.
|
||||
$: renderChart(chartElement, hide)
|
||||
$: updateChart(options)
|
||||
$: seriesValid = isSeriesValid(options?.series || [])
|
||||
</script>
|
||||
|
||||
{#if options}
|
||||
{#key options.customColor}
|
||||
<div use:chart={options} use:styleable={$component.styles} />
|
||||
{/key}
|
||||
{:else if $builderStore.inBuilder}
|
||||
<div use:styleable={$component.styles}>
|
||||
<Placeholder />
|
||||
</div>
|
||||
{/if}
|
||||
{#key options?.customColor}
|
||||
<div class:hide use:styleable={$component.styles} bind:this={chartElement} />
|
||||
{#if $builderStore.inBuilder && noData }
|
||||
<div class="component-placeholder" use:styleable={{ ...$component.styles, normal: {}, custom: null, empty: true }}>
|
||||
<Icon name="Alert" color="var(--spectrum-global-color-static-red-600)" />
|
||||
Add rows to your data source to start using your component
|
||||
</div>
|
||||
{:else if $builderStore.inBuilder && !seriesValid}
|
||||
<div class="component-placeholder" use:styleable={{ ...$component.styles, normal: {}, custom: null, empty: true }}>
|
||||
<Icon name="Alert" color="var(--spectrum-global-color-static-red-600)" />
|
||||
Your selected data cannot be displayed in this chart
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{/key}
|
||||
|
||||
<style>
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
div :global(.apexcharts-legend-series) {
|
||||
display: flex !important;
|
||||
text-transform: capitalize;
|
||||
|
@ -59,4 +138,25 @@
|
|||
) {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.component-placeholder {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
color: var(--spectrum-global-color-gray-600);
|
||||
font-size: var(--font-size-s);
|
||||
padding: var(--spacing-xs);
|
||||
gap: var(--spacing-s);
|
||||
}
|
||||
|
||||
/* Common styles for all error states to use */
|
||||
.component-placeholder :global(mark) {
|
||||
background-color: var(--spectrum-global-color-gray-400);
|
||||
padding: 0 4px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.component-placeholder :global(.spectrum-Link) {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -7,6 +7,9 @@ export class ApexOptionsBuilder {
|
|||
}
|
||||
this.options = {
|
||||
series: [],
|
||||
noData:{
|
||||
text: "no data to show"
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
position: "top",
|
||||
|
@ -99,7 +102,8 @@ export class ApexOptionsBuilder {
|
|||
}
|
||||
|
||||
series(series) {
|
||||
return this.setOption(["series"], series)
|
||||
const foo = this.setOption(["series"], series)
|
||||
return foo;
|
||||
}
|
||||
|
||||
horizontal(horizontal) {
|
||||
|
@ -161,6 +165,15 @@ export class ApexOptionsBuilder {
|
|||
)
|
||||
}
|
||||
|
||||
candleStick() {
|
||||
//this.options.xaxis.convertedCatToNumeric = false;
|
||||
this.options.xaxis.labels.formatter = (epoch) => {
|
||||
return (new Date(epoch)).toDateString();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
clearXFormatter() {
|
||||
delete this.options.xaxis.labels
|
||||
return this
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
import { ApexOptionsBuilder } from "./ApexOptionsBuilder"
|
||||
import ApexChart from "./ApexChart.svelte"
|
||||
import { get } from "lodash";
|
||||
|
||||
export let title
|
||||
export let dataProvider
|
||||
|
@ -71,9 +72,8 @@
|
|||
|
||||
// Fetch data
|
||||
const { schema, rows } = dataProvider
|
||||
const reducer = row => (valid, column) => valid && row[column] != null
|
||||
const hasAllColumns = row => allCols.reduce(reducer(row), true)
|
||||
const data = rows.filter(row => hasAllColumns(row)).slice(0, 100)
|
||||
|
||||
const data = rows.slice(0, 100)
|
||||
if (!schema || !data.length) {
|
||||
return null
|
||||
}
|
||||
|
@ -105,11 +105,21 @@
|
|||
}
|
||||
useDates = labelFieldType === "datetime"
|
||||
}
|
||||
const series = valueColumns.map(column => ({
|
||||
const series = (valueColumns ?? []).map(column => ({
|
||||
name: column,
|
||||
data: data.map(row => {
|
||||
if (!useDates) {
|
||||
return row[column]
|
||||
const value = get(row, column);
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Number.isNaN(parseInt(value, 10))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return value;
|
||||
} else {
|
||||
return [row[labelColumn], row[column]]
|
||||
}
|
||||
|
|
|
@ -76,14 +76,16 @@
|
|||
.animate(animate)
|
||||
.yUnits(yAxisUnits)
|
||||
.yTooltip(true)
|
||||
.xType("datetime")
|
||||
//.xType("datetime")
|
||||
.candleStick()
|
||||
|
||||
// Add data
|
||||
//const parseDate = d => d
|
||||
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]],
|
||||
}))
|
||||
const chartData = data.map(row => ([
|
||||
parseDate(row[dateColumn]),
|
||||
row[openColumn], row[highColumn], row[lowColumn], row[closeColumn]
|
||||
]))
|
||||
builder = builder.series([{ data: chartData }])
|
||||
|
||||
// Build chart options
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
import { ApexOptionsBuilder } from "./ApexOptionsBuilder"
|
||||
import ApexChart from "./ApexChart.svelte"
|
||||
import { get } from "lodash";
|
||||
|
||||
// Common props
|
||||
export let title
|
||||
|
@ -80,9 +81,7 @@
|
|||
|
||||
// Fetch, filter and sort data
|
||||
const { schema, rows } = dataProvider
|
||||
const reducer = row => (valid, column) => valid && row[column] != null
|
||||
const hasAllColumns = row => allCols.reduce(reducer(row), true)
|
||||
const data = rows.filter(row => hasAllColumns(row))
|
||||
const data = rows
|
||||
if (!schema || !data.length) {
|
||||
return null
|
||||
}
|
||||
|
@ -112,11 +111,21 @@
|
|||
builder = builder.xType(labelFieldType)
|
||||
useDates = labelFieldType === "datetime"
|
||||
}
|
||||
const series = valueColumns.map(column => ({
|
||||
const series = (valueColumns ?? []).map(column => ({
|
||||
name: column,
|
||||
data: data.map(row => {
|
||||
if (!useDates) {
|
||||
return row[column]
|
||||
const value = get(row, column);
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Number.isNaN(parseInt(value, 10))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return value;
|
||||
} else {
|
||||
return [row[labelColumn], row[column]]
|
||||
}
|
||||
|
|
20
yarn.lock
20
yarn.lock
|
@ -6605,6 +6605,11 @@
|
|||
js-yaml "^3.10.0"
|
||||
tslib "^2.4.0"
|
||||
|
||||
"@yr/monotone-cubic-spline@^1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz#7272d89f8e4f6fb7a1600c28c378cc18d3b577b9"
|
||||
integrity sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==
|
||||
|
||||
"@zerodevx/svelte-json-view@^1.0.7":
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@zerodevx/svelte-json-view/-/svelte-json-view-1.0.7.tgz#abf3efa71dedcb3e9d16bc9cc61d5ea98c8d00b1"
|
||||
|
@ -6907,7 +6912,7 @@ anymatch@^3.0.3, anymatch@~3.1.2:
|
|||
normalize-path "^3.0.0"
|
||||
picomatch "^2.0.4"
|
||||
|
||||
apexcharts@^3.19.2, apexcharts@^3.22.1:
|
||||
apexcharts@^3.19.2:
|
||||
version "3.37.1"
|
||||
resolved "https://registry.yarnpkg.com/apexcharts/-/apexcharts-3.37.1.tgz#50443d302fc7fc72aace9c6c4074baae017c6950"
|
||||
integrity sha512-fmQ5Updeb/LASl+S1+mIxXUFxzY0Fa7gexfCs4o+OPP9f2NEBNjvybOtPrah44N4roK7U5o5Jis906QeEQu0cA==
|
||||
|
@ -6919,6 +6924,19 @@ apexcharts@^3.19.2, apexcharts@^3.22.1:
|
|||
svg.resize.js "^1.4.3"
|
||||
svg.select.js "^3.0.1"
|
||||
|
||||
apexcharts@^3.45.2:
|
||||
version "3.48.0"
|
||||
resolved "https://registry.yarnpkg.com/apexcharts/-/apexcharts-3.48.0.tgz#cf0e18f4551b04a242d81942c965c15547f5f1b6"
|
||||
integrity sha512-Lhpj1Ij6lKlrUke8gf+P+SE6uGUn+Pe1TnCJ+zqrY0YMvbqM3LMb1lY+eybbTczUyk0RmMZomlTa2NgX2EUs4Q==
|
||||
dependencies:
|
||||
"@yr/monotone-cubic-spline" "^1.0.3"
|
||||
svg.draggable.js "^2.2.2"
|
||||
svg.easing.js "^2.0.0"
|
||||
svg.filter.js "^2.0.2"
|
||||
svg.pathmorphing.js "^0.1.3"
|
||||
svg.resize.js "^1.4.3"
|
||||
svg.select.js "^3.0.1"
|
||||
|
||||
apidoc@0.50.4:
|
||||
version "0.50.4"
|
||||
resolved "https://registry.yarnpkg.com/apidoc/-/apidoc-0.50.4.tgz#52ff8fb4d067a73faf544455031f44459bd68d75"
|
||||
|
|
Loading…
Reference in New Issue