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",
|
||||
description: "Groupedbar chart",
|
||||
icon: "ri-bar-chart-fill",
|
||||
presetProps: {
|
||||
data: [
|
||||
{
|
||||
name: "2011-01",
|
||||
group: "Direct",
|
||||
value: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
properties: {
|
||||
settings: [
|
||||
{
|
||||
|
@ -1338,11 +1329,6 @@ export default {
|
|||
key: "aspectRatio",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Height",
|
||||
key: "height",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Grid",
|
||||
key: "grid",
|
||||
|
@ -1359,6 +1345,11 @@ export default {
|
|||
key: "nameLabel",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Value Label",
|
||||
key: "valueLabel",
|
||||
control: Input,
|
||||
},
|
||||
{
|
||||
label: "Y Ticks",
|
||||
key: "yTicks",
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
<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='stylesheet' href='/_builder/global.css'>
|
||||
<link rel='stylesheet' href='/_builder/codemirror.css'>
|
||||
|
@ -22,6 +24,10 @@
|
|||
|
||||
<body id="app">
|
||||
<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>
|
||||
|
||||
</html>
|
|
@ -509,7 +509,6 @@
|
|||
"height": "string",
|
||||
"width": "string",
|
||||
"margin":"string",
|
||||
"aspectRatio": "number",
|
||||
"grid":"string",
|
||||
"groupLabel": "string",
|
||||
"isAnimated": "bool",
|
||||
|
@ -517,7 +516,6 @@
|
|||
"nameLabel": "string",
|
||||
"valueLabel":"string",
|
||||
"yTicks": "string",
|
||||
"yTickTextOffset": "string",
|
||||
"useLegend": "bool"
|
||||
}
|
||||
},
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
export let orderingFunction = null
|
||||
|
||||
export let data = model ? $store[model] : []
|
||||
let data = []
|
||||
export let color = "britecharts"
|
||||
export let height = 200
|
||||
export let width = 200
|
||||
|
@ -47,7 +47,9 @@
|
|||
export let internalRadius = 25
|
||||
export let isAnimated = true
|
||||
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 legendWidth = null
|
||||
export let legendHeight = null
|
||||
|
@ -70,19 +72,60 @@
|
|||
if (chart) {
|
||||
if (model) {
|
||||
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({
|
||||
showEmptySlice: true,
|
||||
emptySliceColor: "#000000",
|
||||
emptySliceColor: "#F0F0F0",
|
||||
})
|
||||
|
||||
chartContainer = select(`.${chartClass}`)
|
||||
bindChartUIProps()
|
||||
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() {
|
||||
chart.percentageFormat(".0f")
|
||||
|
||||
|
@ -134,7 +177,7 @@
|
|||
if (notNull(orderingFunction)) {
|
||||
chart.orderingFunction(orderingFunction)
|
||||
}
|
||||
chartContainer.datum(_data).call(chart)
|
||||
chartContainer.datum(data).call(chart)
|
||||
chartSvg = document.querySelector(`.${chartClass} .britechart`)
|
||||
}
|
||||
|
||||
|
@ -159,17 +202,15 @@
|
|||
$: if (!width && chartSvg) {
|
||||
width = chartSvg.clientWidth
|
||||
chart.width(width)
|
||||
chartContainer.datum(_data).call(chart)
|
||||
chartContainer.datum(data).call(chart)
|
||||
}
|
||||
|
||||
$: _data = model ? $store[model] : data
|
||||
|
||||
$: colorSchema = getColorSchema(color)
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<div bind:this={chartElement} class={chartClass} />
|
||||
{#if useLegend}
|
||||
{#if data.length > 0}
|
||||
<Legend
|
||||
bind:legend={legendChart}
|
||||
{colorSchema}
|
||||
|
@ -178,6 +219,6 @@
|
|||
width={legendWidth || width}
|
||||
height={legendHeight}
|
||||
{chartClass}
|
||||
data={_data} />
|
||||
{data} />
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
<script>
|
||||
import { getColorSchema, getChartGradient, notNull } from "./utils"
|
||||
import Tooltip from "./Tooltip.svelte"
|
||||
import britecharts from "britecharts"
|
||||
import { onMount } from "svelte"
|
||||
|
||||
import { select } from "d3-selection"
|
||||
import shortid from "shortid"
|
||||
/*
|
||||
ISSUES
|
||||
- Renders but seems to be a problem with tooltip hover
|
||||
*/
|
||||
|
||||
import { select } from "d3-selection"
|
||||
import shortid from "shortid"
|
||||
|
||||
const _id = shortid.generate()
|
||||
|
||||
export let _bb
|
||||
|
@ -33,11 +32,11 @@
|
|||
export let customMouseOut = () => tooltip.hide()
|
||||
export let customClick = null
|
||||
|
||||
export let data = []
|
||||
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 margin = null
|
||||
export let aspectRatio = null
|
||||
export let grid = null
|
||||
export let groupLabel = null
|
||||
|
@ -51,18 +50,22 @@
|
|||
export let yAxisLabelOffset = null
|
||||
export let yTicks = null
|
||||
export let yTickTextOffset = null
|
||||
export let useLegend = true
|
||||
|
||||
$: console.log("DATA", data)
|
||||
|
||||
let chartDrawn = false
|
||||
|
||||
onMount(async () => {
|
||||
if (chart) {
|
||||
if (model) {
|
||||
await fetchData()
|
||||
data = $store[model]
|
||||
}
|
||||
chartContainer = select(`.${chartClass}`)
|
||||
bindChartUIProps()
|
||||
// bindChartEvents()
|
||||
bindChartEvents()
|
||||
chartContainer.datum(data).call(chart)
|
||||
// bindChartTooltip()
|
||||
chartDrawn = true
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -90,6 +93,9 @@
|
|||
if (notNull(width)) {
|
||||
chart.width(width)
|
||||
}
|
||||
if (notNull(margin)) {
|
||||
chart.margin(margin)
|
||||
}
|
||||
if (notNull(aspectRatio)) {
|
||||
chart.aspectRatio(aspectRatio)
|
||||
}
|
||||
|
@ -131,12 +137,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
function bindChartTooltip() {
|
||||
tooltip = britecharts.miniTooltip()
|
||||
tooltipContainer = select(`.${chartClass} .metadata-group`)
|
||||
tooltipContainer.datum([]).call(tooltip)
|
||||
}
|
||||
|
||||
function bindChartEvents() {
|
||||
if (customClick) {
|
||||
chart.on("customClick", customClick)
|
||||
|
@ -158,6 +158,6 @@
|
|||
</script>
|
||||
|
||||
<div bind:this={chartElement} class={chartClass} />
|
||||
{#if useLegend}
|
||||
<div class={legendClass} />
|
||||
{#if chartDrawn}
|
||||
<Tooltip bind:tooltip {chartDrawn} {chartClass} {data} />
|
||||
{/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 =>
|
||||
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