Add line chart and enable multiple data series for all charts

This commit is contained in:
Andrew Kingston 2020-11-03 09:43:45 +00:00
parent b0ee6d4ed3
commit 4f5d12468d
7 changed files with 287 additions and 229 deletions

View File

@ -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: "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",
// 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,
// },
// ],
// },
// },
{
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,
},
// {
// label: "Color",
// key: "color",
// 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,
},
],
},
},
],
},
{

View File

@ -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": {

View File

@ -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",

View File

@ -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)
}
}

View File

@ -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]))
}
}

View File

@ -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} />

View File

@ -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"