Completed Groupedbar and work on Tooltip
This commit is contained in:
parent
911ba8b7d5
commit
d7e47d67e3
|
@ -1290,15 +1290,6 @@ export default {
|
||||||
_component: "@budibase/standard-components/groupedbar",
|
_component: "@budibase/standard-components/groupedbar",
|
||||||
description: "Groupedbar chart",
|
description: "Groupedbar chart",
|
||||||
icon: "ri-bar-chart-fill",
|
icon: "ri-bar-chart-fill",
|
||||||
presetProps: {
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
name: "2011-01",
|
|
||||||
group: "Direct",
|
|
||||||
value: 0,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
properties: {
|
properties: {
|
||||||
settings: [
|
settings: [
|
||||||
{
|
{
|
||||||
|
@ -1338,11 +1329,6 @@ export default {
|
||||||
key: "aspectRatio",
|
key: "aspectRatio",
|
||||||
control: Input,
|
control: Input,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: "Height",
|
|
||||||
key: "height",
|
|
||||||
control: Input,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: "Grid",
|
label: "Grid",
|
||||||
key: "grid",
|
key: "grid",
|
||||||
|
@ -1359,6 +1345,11 @@ export default {
|
||||||
key: "nameLabel",
|
key: "nameLabel",
|
||||||
control: Input,
|
control: Input,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "Value Label",
|
||||||
|
key: "valueLabel",
|
||||||
|
control: Input,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "Y Ticks",
|
label: "Y Ticks",
|
||||||
key: "yTicks",
|
key: "yTicks",
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/remixicon@2.3.0/fonts/remixicon.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/remixicon@2.3.0/fonts/remixicon.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/britecharts/dist/css/britecharts.min.css" type="text/css" />
|
||||||
|
|
||||||
<link rel='icon' type='image/png' href='/_builder/favicon.png'>
|
<link rel='icon' type='image/png' href='/_builder/favicon.png'>
|
||||||
<link rel='stylesheet' href='/_builder/global.css'>
|
<link rel='stylesheet' href='/_builder/global.css'>
|
||||||
<link rel='stylesheet' href='/_builder/codemirror.css'>
|
<link rel='stylesheet' href='/_builder/codemirror.css'>
|
||||||
|
@ -22,6 +24,10 @@
|
||||||
|
|
||||||
<body id="app">
|
<body id="app">
|
||||||
<script src='/_builder/bundle.js'></script>
|
<script src='/_builder/bundle.js'></script>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.7.4/d3.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/britecharts@2/dist/bundled/britecharts.min.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
|
@ -508,8 +508,7 @@
|
||||||
"color": "string",
|
"color": "string",
|
||||||
"height": "string",
|
"height": "string",
|
||||||
"width": "string",
|
"width": "string",
|
||||||
"margin": "string",
|
"margin":"string",
|
||||||
"aspectRatio": "number",
|
|
||||||
"grid":"string",
|
"grid":"string",
|
||||||
"groupLabel": "string",
|
"groupLabel": "string",
|
||||||
"isAnimated": "bool",
|
"isAnimated": "bool",
|
||||||
|
@ -517,7 +516,6 @@
|
||||||
"nameLabel": "string",
|
"nameLabel": "string",
|
||||||
"valueLabel":"string",
|
"valueLabel":"string",
|
||||||
"yTicks": "string",
|
"yTicks": "string",
|
||||||
"yTickTextOffset": "string",
|
|
||||||
"useLegend": "bool"
|
"useLegend": "bool"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
export let orderingFunction = null
|
export let orderingFunction = null
|
||||||
|
|
||||||
export let data = model ? $store[model] : []
|
let data = []
|
||||||
export let color = "britecharts"
|
export let color = "britecharts"
|
||||||
export let height = 200
|
export let height = 200
|
||||||
export let width = 200
|
export let width = 200
|
||||||
|
@ -47,7 +47,9 @@
|
||||||
export let internalRadius = 25
|
export let internalRadius = 25
|
||||||
export let isAnimated = true
|
export let isAnimated = true
|
||||||
export let radiusHoverOffset = 0
|
export let radiusHoverOffset = 0
|
||||||
export let useLegend = true
|
export let nameKey = null
|
||||||
|
export let valueKey = null
|
||||||
|
// export let useLegend = true
|
||||||
export let horizontalLegend = false
|
export let horizontalLegend = false
|
||||||
export let legendWidth = null
|
export let legendWidth = null
|
||||||
export let legendHeight = null
|
export let legendHeight = null
|
||||||
|
@ -70,19 +72,60 @@
|
||||||
if (chart) {
|
if (chart) {
|
||||||
if (model) {
|
if (model) {
|
||||||
await fetchData()
|
await fetchData()
|
||||||
|
data = checkAndReformatData($store[model])
|
||||||
|
if (data.length === 0) {
|
||||||
|
console.error(
|
||||||
|
"Donut - please provide a valid name and value field for the chart"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chart.emptyDataConfig({
|
chart.emptyDataConfig({
|
||||||
showEmptySlice: true,
|
showEmptySlice: true,
|
||||||
emptySliceColor: "#000000",
|
emptySliceColor: "#F0F0F0",
|
||||||
})
|
})
|
||||||
|
|
||||||
chartContainer = select(`.${chartClass}`)
|
chartContainer = select(`.${chartClass}`)
|
||||||
bindChartUIProps()
|
bindChartUIProps()
|
||||||
bindChartEvents()
|
bindChartEvents()
|
||||||
chartContainer.datum(_data).call(chart)
|
chartContainer.datum(data).call(chart)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function checkAndReformatData(data) {
|
||||||
|
let _data = [...data]
|
||||||
|
|
||||||
|
if (valueKey) {
|
||||||
|
_data = reformatDataKey(_data, valueKey, "quantity")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nameKey) {
|
||||||
|
_data = reformatDataKey(_data, nameKey, "name")
|
||||||
|
}
|
||||||
|
|
||||||
|
return _data.every(d => d.quantity) && _data.every(d => d.name) ? _data : []
|
||||||
|
}
|
||||||
|
|
||||||
|
function reformatDataKey(data = [], dataKey = null, formatKey = null) {
|
||||||
|
let ignoreList = ["_id", "_rev", "id"]
|
||||||
|
if (dataKey && data.every(d => d[dataKey])) {
|
||||||
|
return data.map(d => {
|
||||||
|
let clonedRecord = { ...d }
|
||||||
|
if (clonedRecord[formatKey]) {
|
||||||
|
delete clonedRecord[formatKey]
|
||||||
|
}
|
||||||
|
let value = clonedRecord[dataKey]
|
||||||
|
if (!ignoreList.includes(dataKey)) {
|
||||||
|
delete clonedRecord[dataKey]
|
||||||
|
}
|
||||||
|
clonedRecord[formatKey] = value
|
||||||
|
return clonedRecord
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function bindChartUIProps() {
|
function bindChartUIProps() {
|
||||||
chart.percentageFormat(".0f")
|
chart.percentageFormat(".0f")
|
||||||
|
|
||||||
|
@ -134,7 +177,7 @@
|
||||||
if (notNull(orderingFunction)) {
|
if (notNull(orderingFunction)) {
|
||||||
chart.orderingFunction(orderingFunction)
|
chart.orderingFunction(orderingFunction)
|
||||||
}
|
}
|
||||||
chartContainer.datum(_data).call(chart)
|
chartContainer.datum(data).call(chart)
|
||||||
chartSvg = document.querySelector(`.${chartClass} .britechart`)
|
chartSvg = document.querySelector(`.${chartClass} .britechart`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,17 +202,15 @@
|
||||||
$: if (!width && chartSvg) {
|
$: if (!width && chartSvg) {
|
||||||
width = chartSvg.clientWidth
|
width = chartSvg.clientWidth
|
||||||
chart.width(width)
|
chart.width(width)
|
||||||
chartContainer.datum(_data).call(chart)
|
chartContainer.datum(data).call(chart)
|
||||||
}
|
}
|
||||||
|
|
||||||
$: _data = model ? $store[model] : data
|
|
||||||
|
|
||||||
$: colorSchema = getColorSchema(color)
|
$: colorSchema = getColorSchema(color)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div bind:this={chartElement} class={chartClass} />
|
<div bind:this={chartElement} class={chartClass} />
|
||||||
{#if useLegend}
|
{#if data.length > 0}
|
||||||
<Legend
|
<Legend
|
||||||
bind:legend={legendChart}
|
bind:legend={legendChart}
|
||||||
{colorSchema}
|
{colorSchema}
|
||||||
|
@ -178,6 +219,6 @@
|
||||||
width={legendWidth || width}
|
width={legendWidth || width}
|
||||||
height={legendHeight}
|
height={legendHeight}
|
||||||
{chartClass}
|
{chartClass}
|
||||||
data={_data} />
|
{data} />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
<script>
|
<script>
|
||||||
import { getColorSchema, getChartGradient, notNull } from "./utils"
|
import { getColorSchema, getChartGradient, notNull } from "./utils"
|
||||||
|
import Tooltip from "./Tooltip.svelte"
|
||||||
import britecharts from "britecharts"
|
import britecharts from "britecharts"
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
|
import { select } from "d3-selection"
|
||||||
|
import shortid from "shortid"
|
||||||
/*
|
/*
|
||||||
ISSUES
|
ISSUES
|
||||||
- Renders but seems to be a problem with tooltip hover
|
- Renders but seems to be a problem with tooltip hover
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { select } from "d3-selection"
|
|
||||||
import shortid from "shortid"
|
|
||||||
|
|
||||||
const _id = shortid.generate()
|
const _id = shortid.generate()
|
||||||
|
|
||||||
export let _bb
|
export let _bb
|
||||||
|
@ -33,11 +32,11 @@
|
||||||
export let customMouseOut = () => tooltip.hide()
|
export let customMouseOut = () => tooltip.hide()
|
||||||
export let customClick = null
|
export let customClick = null
|
||||||
|
|
||||||
export let data = []
|
let data = []
|
||||||
export let color = "britecharts"
|
export let color = "britecharts"
|
||||||
export let height = 200
|
export let height = 200
|
||||||
export let width = 200
|
export let width = 200
|
||||||
export let margin = { top: 0, right: 0, bottom: 0, left: 0 }
|
export let margin = null
|
||||||
export let aspectRatio = null
|
export let aspectRatio = null
|
||||||
export let grid = null
|
export let grid = null
|
||||||
export let groupLabel = null
|
export let groupLabel = null
|
||||||
|
@ -51,18 +50,22 @@
|
||||||
export let yAxisLabelOffset = null
|
export let yAxisLabelOffset = null
|
||||||
export let yTicks = null
|
export let yTicks = null
|
||||||
export let yTickTextOffset = null
|
export let yTickTextOffset = null
|
||||||
export let useLegend = true
|
|
||||||
|
$: console.log("DATA", data)
|
||||||
|
|
||||||
|
let chartDrawn = false
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
if (chart) {
|
if (chart) {
|
||||||
if (model) {
|
if (model) {
|
||||||
await fetchData()
|
await fetchData()
|
||||||
|
data = $store[model]
|
||||||
}
|
}
|
||||||
chartContainer = select(`.${chartClass}`)
|
chartContainer = select(`.${chartClass}`)
|
||||||
bindChartUIProps()
|
bindChartUIProps()
|
||||||
// bindChartEvents()
|
bindChartEvents()
|
||||||
chartContainer.datum(data).call(chart)
|
chartContainer.datum(data).call(chart)
|
||||||
// bindChartTooltip()
|
chartDrawn = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -90,6 +93,9 @@
|
||||||
if (notNull(width)) {
|
if (notNull(width)) {
|
||||||
chart.width(width)
|
chart.width(width)
|
||||||
}
|
}
|
||||||
|
if (notNull(margin)) {
|
||||||
|
chart.margin(margin)
|
||||||
|
}
|
||||||
if (notNull(aspectRatio)) {
|
if (notNull(aspectRatio)) {
|
||||||
chart.aspectRatio(aspectRatio)
|
chart.aspectRatio(aspectRatio)
|
||||||
}
|
}
|
||||||
|
@ -131,12 +137,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindChartTooltip() {
|
|
||||||
tooltip = britecharts.miniTooltip()
|
|
||||||
tooltipContainer = select(`.${chartClass} .metadata-group`)
|
|
||||||
tooltipContainer.datum([]).call(tooltip)
|
|
||||||
}
|
|
||||||
|
|
||||||
function bindChartEvents() {
|
function bindChartEvents() {
|
||||||
if (customClick) {
|
if (customClick) {
|
||||||
chart.on("customClick", customClick)
|
chart.on("customClick", customClick)
|
||||||
|
@ -158,6 +158,6 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div bind:this={chartElement} class={chartClass} />
|
<div bind:this={chartElement} class={chartClass} />
|
||||||
{#if useLegend}
|
{#if chartDrawn}
|
||||||
<div class={legendClass} />
|
<Tooltip bind:tooltip {chartDrawn} {chartClass} {data} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
<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 data = []
|
||||||
|
|
||||||
|
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 = null
|
||||||
|
export let title = "My tooltip"
|
||||||
|
export let tooltipOffset = null
|
||||||
|
export let topicLabel = "Topics"
|
||||||
|
export let topicsOrder = null
|
||||||
|
export let valueLabel = null
|
||||||
|
export let xAxisValueType = null
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
tooltipContainer = select(`.${chartClass} .metadata-group`)
|
||||||
|
tooltipContainer.datum([]).call(tooltip)
|
||||||
|
})
|
||||||
|
|
||||||
|
// $: if (chartDrawn) {
|
||||||
|
// tooltipContainer = select(`.${chartClass} .metadata-group`)
|
||||||
|
// 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>
|
|
@ -17,3 +17,23 @@ export const getColorSchema = color =>
|
||||||
|
|
||||||
export const getChartGradient = gradient =>
|
export const getChartGradient = gradient =>
|
||||||
gradient ? colorGradients[gradient] : null
|
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 clonedRecord = { ...d }
|
||||||
|
if (clonedRecord[formatKey]) {
|
||||||
|
delete clonedRecord[formatKey]
|
||||||
|
}
|
||||||
|
let value = clonedRecord[dataKey]
|
||||||
|
if (!ignoreList.includes(dataKey)) {
|
||||||
|
delete clonedRecord[dataKey]
|
||||||
|
}
|
||||||
|
clonedRecord[formatKey] = value
|
||||||
|
return clonedRecord
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue