Add line chart and enable multiple data series for all charts
This commit is contained in:
parent
b0ee6d4ed3
commit
4f5d12468d
|
@ -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"
|
||||
|
@ -523,6 +524,11 @@ export default {
|
|||
icon: "ri-bar-chart-fill",
|
||||
properties: {
|
||||
settings: [
|
||||
{
|
||||
label: "Title",
|
||||
key: "title",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Data",
|
||||
key: "datasource",
|
||||
|
@ -530,15 +536,15 @@ export default {
|
|||
},
|
||||
{
|
||||
label: "Label Col.",
|
||||
key: "nameLabel",
|
||||
key: "labelColumn",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Value Col.",
|
||||
key: "valueLabel",
|
||||
label: "Data Cols.",
|
||||
key: "valueColumns",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
control: MultiTableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Y Axis Label",
|
||||
|
@ -550,12 +556,12 @@ export default {
|
|||
key: "xAxisLabel",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Color",
|
||||
key: "color",
|
||||
control: Colorpicker,
|
||||
defaultValue: "#4285f4",
|
||||
},
|
||||
// {
|
||||
// label: "Color",
|
||||
// key: "color",
|
||||
// control: Colorpicker,
|
||||
// defaultValue: "#4285f4",
|
||||
// },
|
||||
{
|
||||
label: "Width",
|
||||
key: "width",
|
||||
|
@ -587,6 +593,13 @@ export default {
|
|||
valueKey: "checked",
|
||||
defaultValue: true,
|
||||
},
|
||||
{
|
||||
label: "Legend",
|
||||
key: "legend",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
@ -693,172 +706,100 @@ export default {
|
|||
// ],
|
||||
// },
|
||||
// },
|
||||
{
|
||||
name: "Line",
|
||||
_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: "Label Col.",
|
||||
key: "labelColumn",
|
||||
dependsOn: "datasource",
|
||||
control: TableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Data Cols.",
|
||||
key: "valueColumns",
|
||||
dependsOn: "datasource",
|
||||
control: MultiTableViewFieldSelect,
|
||||
},
|
||||
{
|
||||
label: "Y Axis Label",
|
||||
key: "yAxisLabel",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "X Axis Label",
|
||||
key: "xAxisLabel",
|
||||
control: Input,
|
||||
},
|
||||
// {
|
||||
// name: "Line",
|
||||
// _component: "@budibase/standard-components/line",
|
||||
// description: "Line chart",
|
||||
// icon: "ri-line-chart-line",
|
||||
// properties: {
|
||||
// settings: [
|
||||
// {
|
||||
// label: "Data",
|
||||
// key: "datasource",
|
||||
// control: TableViewSelect,
|
||||
// },
|
||||
// {
|
||||
// label: "Value Label",
|
||||
// key: "valueLabel",
|
||||
// dependsOn: "datasource",
|
||||
// control: TableViewFieldSelect,
|
||||
// },
|
||||
// {
|
||||
// label: "Topic Label",
|
||||
// key: "topicLabel",
|
||||
// dependsOn: "datasource",
|
||||
// control: TableViewFieldSelect,
|
||||
// },
|
||||
// {
|
||||
// label: "Date Label",
|
||||
// key: "dateLabel",
|
||||
// dependsOn: "datasource",
|
||||
// control: TableViewFieldSelect,
|
||||
// },
|
||||
// {
|
||||
// label: "Colors",
|
||||
// label: "Color",
|
||||
// key: "color",
|
||||
// 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,
|
||||
// },
|
||||
// {
|
||||
// label: "Y Axis Label",
|
||||
// key: "yAxisLabel",
|
||||
// control: Input,
|
||||
// },
|
||||
// {
|
||||
// label: "Show All Datapoints",
|
||||
// key: "shouldShowAllDataPoints",
|
||||
// valueKey: "checked",
|
||||
// control: Checkbox,
|
||||
// },
|
||||
// {
|
||||
// label: "Width",
|
||||
// key: "width",
|
||||
// control: Input,
|
||||
// },
|
||||
// {
|
||||
// label: "Height",
|
||||
// key: "height",
|
||||
// control: Input,
|
||||
// },
|
||||
// {
|
||||
// label: "Is Animated",
|
||||
// key: "isAnimated",
|
||||
// control: Checkbox,
|
||||
// valueKey: "checked",
|
||||
// },
|
||||
// {
|
||||
// label: "Locale",
|
||||
// key: "locale",
|
||||
// control: OptionSelect,
|
||||
// options: ["en-GB", "en-US"],
|
||||
// },
|
||||
// {
|
||||
// label: "X Axis Value Type",
|
||||
// key: "xAxisValueType",
|
||||
// control: OptionSelect,
|
||||
// options: ["date", "numeric"],
|
||||
// },
|
||||
// {
|
||||
// label: "X Axis Format",
|
||||
// key: "xAxisFormat",
|
||||
// control: OptionSelect,
|
||||
// options: [
|
||||
// "day-month",
|
||||
// "minute-hour",
|
||||
// "hour-daymonth",
|
||||
// "month-year",
|
||||
// "custom",
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// label: "X Axis Custom Format",
|
||||
// key: "xAxisCustomFormat",
|
||||
// control: Input,
|
||||
// },
|
||||
// {
|
||||
// label: "Tooltip Title",
|
||||
// key: "tooltipTitle",
|
||||
// control: Input,
|
||||
// },
|
||||
// {
|
||||
// label: "X Ticks",
|
||||
// key: "xTicks",
|
||||
// control: Input,
|
||||
// },
|
||||
// {
|
||||
// label: "Y Ticks",
|
||||
// key: "yTicks",
|
||||
// control: Input,
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// control: Colorpicker,
|
||||
// defaultValue: "#4285f4",
|
||||
// },
|
||||
{
|
||||
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: "Data Labels",
|
||||
key: "dataLabels",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: false,
|
||||
},
|
||||
{
|
||||
label: "Animate",
|
||||
key: "animate",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: true,
|
||||
},
|
||||
{
|
||||
label: "Fill",
|
||||
key: "fill",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: true,
|
||||
},
|
||||
{
|
||||
label: "Legend",
|
||||
key: "legend",
|
||||
control: Checkbox,
|
||||
valueKey: "checked",
|
||||
defaultValue: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
@ -549,9 +549,10 @@
|
|||
"description": "Bar Chart",
|
||||
"data": true,
|
||||
"props": {
|
||||
"title": "string",
|
||||
"datasource": "tables",
|
||||
"nameLabel": "string",
|
||||
"valueLabel": "string",
|
||||
"labelColumn": "string",
|
||||
"valueColumns": "string",
|
||||
"color": {
|
||||
"type": "string",
|
||||
"default": "#4285f4"
|
||||
|
@ -571,52 +572,57 @@
|
|||
"default": true
|
||||
},
|
||||
"xAxisLabel": "string",
|
||||
"yAxisLabel": "string"
|
||||
"yAxisLabel": "string",
|
||||
"legend": {
|
||||
"type": "bool",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"line": {
|
||||
"description": "Line Chart",
|
||||
"data": true,
|
||||
"props": {
|
||||
"title": "string",
|
||||
"datasource": "tables",
|
||||
"labelColumn": "string",
|
||||
"valueColumns": "string",
|
||||
"color": {
|
||||
"type": "string",
|
||||
"default": "#4285f4"
|
||||
},
|
||||
"height": {
|
||||
"type": "number",
|
||||
"default": "400"
|
||||
},
|
||||
"width": "number",
|
||||
"height": "number",
|
||||
"axisTimeCombinations": "string",
|
||||
"color": "string",
|
||||
"grid": {
|
||||
"type": "string",
|
||||
"default": "horizontal"
|
||||
"dataLabels": {
|
||||
"type": "bool",
|
||||
"default": false
|
||||
},
|
||||
"aspectRatio": "number",
|
||||
"dateLabel": "string",
|
||||
"isAnimated": {
|
||||
"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"
|
||||
},
|
||||
"fill": {
|
||||
"type": "bool",
|
||||
"default": true
|
||||
},
|
||||
"legend": {
|
||||
"type": "bool",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"brush": {
|
||||
|
|
|
@ -5,7 +5,7 @@ import postcss from "rollup-plugin-postcss"
|
|||
import { terser } from "rollup-plugin-terser"
|
||||
|
||||
const production = !process.env.ROLLUP_WATCH
|
||||
const lodash_fp_exports = ["isEmpty"]
|
||||
const lodash_fp_exports = ["isEmpty", "sortBy"]
|
||||
|
||||
export default {
|
||||
input: "src/index.js",
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
export class ApexOptionsBuilder {
|
||||
options = {
|
||||
series: [],
|
||||
legend: {
|
||||
show: false,
|
||||
position: "top",
|
||||
horizontalAlign: "right",
|
||||
showForSingleSeries: true,
|
||||
showForNullSeries: true,
|
||||
showForZeroSeries: true,
|
||||
},
|
||||
chart: {
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
setOption(path, value) {
|
||||
|
@ -27,8 +40,12 @@ export class ApexOptionsBuilder {
|
|||
return this.setOption(["chart", "type"], type)
|
||||
}
|
||||
|
||||
title(title) {
|
||||
return this.setOption(["title", "text"], title)
|
||||
}
|
||||
|
||||
color(color) {
|
||||
return this.setOption(["colors"], color)
|
||||
return this.setOption(["colors"], [color])
|
||||
}
|
||||
|
||||
width(width) {
|
||||
|
@ -66,4 +83,25 @@ export class ApexOptionsBuilder {
|
|||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
import { onMount } from "svelte"
|
||||
import { chart } from "svelte-apexcharts"
|
||||
import fetchData from "../fetchData"
|
||||
import { isEmpty } from "lodash/fp"
|
||||
import { isEmpty, sortBy } from "lodash/fp"
|
||||
import { ApexOptionsBuilder } from "./ApexOptionsBuilder"
|
||||
|
||||
export let title
|
||||
export let datasource
|
||||
export let nameLabel
|
||||
export let valueLabel
|
||||
export let labelColumn
|
||||
export let valueColumns
|
||||
export let xAxisLabel
|
||||
export let yAxisLabel
|
||||
export let height
|
||||
|
@ -16,6 +17,7 @@
|
|||
export let horizontal
|
||||
export let dataLabels
|
||||
export let animate
|
||||
export let legend
|
||||
|
||||
let data
|
||||
$: options = getChartOptions(data)
|
||||
|
@ -23,15 +25,16 @@
|
|||
// Fetch data on mount
|
||||
onMount(async () => {
|
||||
if (!isEmpty(datasource)) {
|
||||
data = await fetchData(datasource)
|
||||
const result = (await fetchData(datasource)).slice(0, 20)
|
||||
data = sortBy(row => row[labelColumn])(result)
|
||||
}
|
||||
})
|
||||
|
||||
function getChartOptions(rows = []) {
|
||||
// Initialise default chart
|
||||
let builder = new ApexOptionsBuilder()
|
||||
.title(title)
|
||||
.type("bar")
|
||||
.color(color)
|
||||
.width(width)
|
||||
.height(height)
|
||||
.xLabel(xAxisLabel)
|
||||
|
@ -39,20 +42,19 @@
|
|||
.horizontal(horizontal)
|
||||
.dataLabels(dataLabels)
|
||||
.animate(animate)
|
||||
.legend(legend)
|
||||
|
||||
// Add data if valid datasource
|
||||
if (rows && rows.length) {
|
||||
rows = rows.slice(0, 50)
|
||||
if (!isEmpty(nameLabel) && !isNaN(rows[0][valueLabel])) {
|
||||
builder = builder.series([
|
||||
{
|
||||
name: valueLabel,
|
||||
data: rows.map(row => row[valueLabel]),
|
||||
},
|
||||
])
|
||||
if (valueColumns && valueColumns.length) {
|
||||
const series = valueColumns.map(column => ({
|
||||
name: column,
|
||||
data: rows.map(row => parseFloat(row[column])),
|
||||
}))
|
||||
builder = builder.series(series)
|
||||
}
|
||||
if (!isEmpty(nameLabel)) {
|
||||
builder = builder.categories(rows.map(row => row[nameLabel]))
|
||||
if (!isEmpty(rows[0][labelColumn])) {
|
||||
builder = builder.categories(rows.map(row => row[labelColumn]))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<script>
|
||||
import { onMount } from "svelte"
|
||||
import { chart } from "svelte-apexcharts"
|
||||
import fetchData from "../fetchData"
|
||||
import { isEmpty, sortBy } from "lodash/fp"
|
||||
import { ApexOptionsBuilder } from "./ApexOptionsBuilder"
|
||||
|
||||
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 fill
|
||||
export let legend
|
||||
|
||||
let data = []
|
||||
$: options = getChartOptions(data)
|
||||
|
||||
// Fetch data on mount
|
||||
onMount(async () => {
|
||||
if (!isEmpty(datasource)) {
|
||||
const result = (await fetchData(datasource)).slice(0, 20)
|
||||
data = sortBy(row => row[labelColumn])(result)
|
||||
}
|
||||
})
|
||||
|
||||
function getChartOptions(rows = []) {
|
||||
// Initialise default chart
|
||||
let builder = new ApexOptionsBuilder()
|
||||
.title(title)
|
||||
.type(fill ? "area" : "line")
|
||||
// .color(color)
|
||||
.width(width)
|
||||
.height(height)
|
||||
.xLabel(xAxisLabel)
|
||||
.yLabel(yAxisLabel)
|
||||
.dataLabels(dataLabels)
|
||||
.animate(animate)
|
||||
.curve(curve.toLowerCase())
|
||||
.gradient(fill)
|
||||
.legend(legend)
|
||||
|
||||
// Add data if valid datasource
|
||||
if (rows && rows.length) {
|
||||
if (valueColumns && valueColumns.length) {
|
||||
const series = valueColumns.map(column => ({
|
||||
name: column,
|
||||
data: rows.map(row => parseFloat(row[column])),
|
||||
}))
|
||||
builder = builder.series(series)
|
||||
}
|
||||
if (!isEmpty(rows[0][labelColumn])) {
|
||||
builder = builder.categories(rows.map(row => row[labelColumn]))
|
||||
}
|
||||
}
|
||||
|
||||
// Build chart options
|
||||
return builder.getOptions()
|
||||
}
|
||||
|
||||
$: console.log(options)
|
||||
</script>
|
||||
|
||||
<div use:chart={options} />
|
|
@ -1,2 +1,2 @@
|
|||
export { default as bar } from "./Bar.svelte"
|
||||
export { default as line } from "./Line.svelte"
|
||||
export { default as bar } from "./BarChart.svelte"
|
||||
export { default as line } from "./LineChart.svelte"
|
||||
|
|
Loading…
Reference in New Issue