diff --git a/client/web/compose/src/components/Chart/Report/GaugeChart.vue b/client/web/compose/src/components/Chart/Report/GaugeChart.vue index 6f5bedf69..13d9113ac 100644 --- a/client/web/compose/src/components/Chart/Report/GaugeChart.vue +++ b/client/web/compose/src/components/Chart/Report/GaugeChart.vue @@ -9,7 +9,7 @@ - + + diff --git a/client/web/compose/src/components/Chart/Report/ReportEdit.vue b/client/web/compose/src/components/Chart/Report/ReportEdit.vue index 626e897f7..8d7b27bab 100644 --- a/client/web/compose/src/components/Chart/Report/ReportEdit.vue +++ b/client/web/compose/src/components/Chart/Report/ReportEdit.vue @@ -142,6 +142,19 @@ :type="defaultValueInputType(d)" /> + + + @@ -246,6 +259,12 @@ + + diff --git a/lib/js/src/compose/types/chart/base.ts b/lib/js/src/compose/types/chart/base.ts index af61dd9ad..290a302ec 100644 --- a/lib/js/src/compose/types/chart/base.ts +++ b/lib/js/src/compose/types/chart/base.ts @@ -252,7 +252,12 @@ export class BaseChart { } defDimension (): Dimension { - return Object.assign({}, { conditions: {}, meta: {} }) + return Object.assign({}, + { + conditions: {}, + meta: {}, + labels: { rotateXAxisLabel: 0 } + }) } defMetrics (): Metric { @@ -270,6 +275,22 @@ export class BaseChart { axisPosition: 'left', labelPosition: 'end', }, + tooltip: {}, + legend: { + position: { + top: '0', + right: '0', + bottom: '0', + left: '0', + }, + }, + offset: { + top: '0', + right: '0', + bottom: '0', + left: '0', + isDefault: true, + }, }) } diff --git a/lib/js/src/compose/types/chart/chart.ts b/lib/js/src/compose/types/chart/chart.ts index 99c2901a2..811d4ebb8 100644 --- a/lib/js/src/compose/types/chart/chart.ts +++ b/lib/js/src/compose/types/chart/chart.ts @@ -105,7 +105,13 @@ export default class Chart extends BaseChart { } const { labels, datasets = [] } = data - const { dimensions: [dimension] = [], yAxis } = reports[0] || {} + const { + dimensions: [dimension] = [], + yAxis, metrics: [metric] = [], + offset, + tooltip: t, + legend: l, + } = reports[0] || {} const hasAxis = datasets.some(({ type }: any) => ['bar', 'line'].includes(type)) const timeDimension = (dimensionFunctions.lookup(dimension) || {}).time @@ -135,6 +141,7 @@ export default class Chart extends BaseChart { interval: 0, overflow: 'truncate', hideOverlap: true, + rotate: yAxis.rotateLabel, }, axisLine: { show: true, @@ -143,7 +150,7 @@ export default class Chart extends BaseChart { nameTextStyle: { align: labelPosition === 'center' ? 'center' : position, padding: labelPosition !== 'center' ? (position === 'left' ? [0, 0, 2, -20] : [0, -20, 2, 0]) : undefined, - } + }, } // If we provide undefined, log scale breaks @@ -156,6 +163,8 @@ export default class Chart extends BaseChart { } } + let pieLegend = {} + options.series = datasets.map(({ type, label, data, fill, tooltip }: any, index: number) => { const { fixed, relative } = tooltip @@ -164,6 +173,30 @@ export default class Chart extends BaseChart { options.tooltip.trigger = 'item' + let lbl = {} + + if (t?.labelsNextToPartition) { + lbl = { show: true } + } else { + lbl = { + show: fixed, + position: 'inside', + align: 'center', + verticalAlign: 'middle', + } + } + + const formatter = t?.formatting + ? t.formatting + : `{a}
{b} : {c}${relative ? ' ({d}%)' : ''}` + + pieLegend = { + top: l?.position?.top || 'auto', + right: l?.position?.right || 'auto', + bottom: l?.position?.bottom || 'auto', + left: l?.position?.left || 'auto', + } + return { z: index, name: label, @@ -172,13 +205,10 @@ export default class Chart extends BaseChart { center: ['50%', '55%'], tooltip: { trigger: 'item', - formatter: `{a}
{b} : {c}${relative ? ' ({d}%)' : ''}`, + formatter, }, label: { - show: fixed, - position: 'inside', - align: 'center', - verticalAlign: 'middle', + ...lbl, fontSize: 14, }, itemStyle: { @@ -196,6 +226,10 @@ export default class Chart extends BaseChart { data: labels.map((name: string, i: number) => { return { name, value: data[i] } }), + top: offset?.isDefault ? 45 : offset?.top, + right: offset?.isDefault ? 25 : offset?.right, + bottom: offset?.isDefault ? 40 : offset?.bottom, + left: offset?.isDefault ? 40 : offset?.left, } } else if (['bar', 'line'].includes(type)) { options.tooltip.trigger = 'axis' @@ -209,15 +243,17 @@ export default class Chart extends BaseChart { interval: 0, overflow: 'truncate', hideOverlap: true, + rotate: dimension.rotateLabel, }, }) } options.grid = { - top: 45, - bottom: 25, - left: 40, - right: 40, + top: offset?.isDefault ? 45 : offset?.top, + right: offset?.isDefault ? 25 : offset?.right, + bottom: offset?.isDefault ? 40 : offset?.bottom, + left: offset?.isDefault ? 40 : offset?.left, + // prevents long labels like dates from being cut off containLabel: true, } @@ -247,8 +283,9 @@ export default class Chart extends BaseChart { fontFamily: 'Poppins-Regular', }, legend: { - show: true, - type: 'scroll', + show: !l?.isHidden, + type: l?.isList ? 'plain' : 'scroll', + ...pieLegend, }, ...options, } diff --git a/lib/js/src/compose/types/chart/util.ts b/lib/js/src/compose/types/chart/util.ts index 8a657ccf4..747e826d6 100644 --- a/lib/js/src/compose/types/chart/util.ts +++ b/lib/js/src/compose/types/chart/util.ts @@ -30,6 +30,7 @@ export interface Dimension { default?: string; skipMissing?: boolean; autoSkip?: boolean; + rotateLabel?: string; } export interface Metric { @@ -55,6 +56,34 @@ export interface YAxis { labelPosition?: string; min?: string; max?: string; + rotateLabel?: string; +} + +export interface ChartOffset { + top?: string; + right?: string; + bottom?: string; + left?: string; + isDefault?: boolean; +} + +export interface Position { + top?: string; + right?: string; + bottom?: string; + left?: string; +} + +export interface Legend { + isHidden?: boolean; + isList?: boolean; + isCustomized?: boolean; + position?: Position; +} + +export interface Tooltip { + formatting?: string; + labelsNextToPartition?: boolean; } export interface Report { @@ -63,6 +92,9 @@ export interface Report { dimensions?: Array; metrics?: Array; yAxis?: YAxis; + tooltip?: Tooltip; + legend?: Legend; + offset?: ChartOffset; } export interface ChartConfig { @@ -212,3 +244,4 @@ const chartUtil = { export { chartUtil, } + diff --git a/locale/en/corteza-webapp-compose/chart.yaml b/locale/en/corteza-webapp-compose/chart.yaml index 3a4065316..6f1359b85 100644 --- a/locale/en/corteza-webapp-compose/chart.yaml +++ b/locale/en/corteza-webapp-compose/chart.yaml @@ -38,6 +38,9 @@ edit: selectedItems: Selected options unselectAllItems: Unselect all noItemsFound: No options found + rotate: + label: Rotate label + description: Labels can be rotated from -90 to 90 degrees. Applied to bar and line charts filter: customize: Customize filter label: Filters @@ -54,7 +57,7 @@ edit: fieldLabel: Field fieldPlaceholder: Select metric field fillArea: Fill area below the line - fixTooltips: Always show tooltips + fixTooltips: Show tooltips function: avg: AVG label: Function @@ -104,6 +107,9 @@ edit: axisOnRight: Place axis on the right side axisScaleFromZero: Always begin axis scale at zero label: Y-axis + rotate: + label: Rotate label + description: Labels can be rotated from -90 to 90 degrees. Applied to bar and line charts labelLabel: Axis label labelPlaceholder: Axis label labelPosition: @@ -116,6 +122,34 @@ edit: maxPlaceholder: Maximum value minLabel: Min value minPlaceholder: Minimum value + additionalConfig: + legend: + label: Legend + hide: Hide legend + showAsList: Show as list + position: + customize: Customize position + top: Top + right: Right + bottom: Bottom + left: Left + valueRange: Values can be set a pixels 20 or as percentages 20% + tooltip: + label: Tooltip + labelNextToChartPartition: Show labels next to chart partition + formatting: + label: Formatting + description: '{a} - metrics field value, {b} - dimension field value, {c} - value of dimension field, {d} - percentage' + placeholder: '{a}
{b} : {c} ({d}%)' + offset: + label: Offset + default: Default offset + position: + top: Top + right: Right + bottom: Bottom + left: Left + valueRange: Values can be set a pixels 20 or as percentages 20% import: 'Import chart(s):' newLabel: 'Create a new chart:' name: Chart name *