feat: Dashboard Config Option (#4617)

- #4589 

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

- **New Features**
- Enhanced dashboard panel configuration with new options for line
thickness, label positioning, symbol visibility, and line interpolation.
- Introduced new icons for visual representation of chart options,
including Linear, NoSymbol, Smooth, StepBefore, StepAfter, and
StepMiddle.

- **Bug Fixes**
- Improved error handling and validation for dashboard panel
configurations.

- **Documentation**
- Added new localization entries for enhanced user interface labels
related to dashboard features.

These updates significantly improve the customization and usability of
dashboard panels, providing users with greater flexibility in
visualizing their data.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
ktx-vaidehi
2024-10-29 10:54:33 +05:30
committed by GitHub
parent eeecb3f130
commit f6c0fc8940
11 changed files with 606 additions and 25 deletions
+38
View File
@@ -196,6 +196,8 @@ pub struct PanelConfig {
#[serde(skip_serializing_if = "Option::is_none")]
decimals: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
line_thickness: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
top_results: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
top_results_others: Option<bool>,
@@ -204,6 +206,12 @@ pub struct PanelConfig {
#[serde(skip_serializing_if = "Option::is_none")]
axis_border_show: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
label_option: Option<LabelOption>,
#[serde(skip_serializing_if = "Option::is_none")]
show_symbol: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
line_interpolation: Option<LineInterpolation>,
#[serde(skip_serializing_if = "Option::is_none")]
legend_width: Option<LegendWidth>,
base_map: Option<BaseMap>,
map_view: Option<MapView>,
@@ -427,3 +435,33 @@ pub struct LegendWidth {
#[serde(skip_serializing_if = "Option::is_none")]
pub unit: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ToSchema)]
pub struct LabelOption {
#[serde(skip_serializing_if = "Option::is_none")]
pub position: Option<LabelPosition>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rotate: Option<f64>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "lowercase")]
pub enum LineInterpolation {
Smooth,
Linear,
#[serde(rename = "step-start")]
StepStart,
#[serde(rename = "step-end")]
StepEnd,
#[serde(rename = "step-middle")]
StepMiddle,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "lowercase")]
pub enum LabelPosition {
Top,
Inside,
InsideTop,
InsideBottom
}
@@ -190,7 +190,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
:display-value="`${
dashboardPanelData.data.config.unit
? unitOptions.find(
(it) => it.value == dashboardPanelData.data.config.unit
(it) => it.value == dashboardPanelData.data.config.unit,
)?.label
: 'Default'
}`"
@@ -348,7 +348,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
handleBlur(
dashboardPanelData.data.config.map_symbol_style.size_by_value,
1,
'min'
'min',
)
"
:label="t('dashboard.minimum')"
@@ -379,7 +379,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
handleBlur(
dashboardPanelData.data.config.map_symbol_style.size_by_value,
100,
'max'
'max',
)
"
:label="t('dashboard.maximum')"
@@ -409,7 +409,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
handleBlur(
dashboardPanelData.data.config.map_symbol_style,
2,
'size_fixed'
'size_fixed',
)
"
:label="t('dashboard.fixedValue')"
@@ -678,7 +678,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<q-toggle
v-if="
['area', 'line', 'area-stacked'].includes(
dashboardPanelData.data.type
dashboardPanelData.data.type,
)
"
v-model="dashboardPanelData.data.config.connect_nulls"
@@ -691,7 +691,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<q-input
v-if="
['area', 'line', 'area-stacked', 'bar', 'stacked'].includes(
dashboardPanelData.data.type
dashboardPanelData.data.type,
)
"
v-model="dashboardPanelData.data.config.no_value_replacement"
@@ -767,7 +767,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
dashboardPanelData.layout.currentQueryIndex
].config,
1,
'weight_fixed'
'weight_fixed',
)
"
:label="t('common.weight')"
@@ -895,10 +895,197 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/>
<div class="space"></div>
<q-select
v-if="
[
'area',
'area-stacked',
'bar',
'h-bar',
'line',
'scatter',
'stacked',
'h-stacked',
].includes(dashboardPanelData.data.type)
"
outlined
v-model="dashboardPanelData.data.config.label_option.position"
:options="labelPositionOptions"
dense
:label="t('dashboard.labelPosition')"
class="showLabelOnTop selectedLabel"
stack-label
emit-value
:display-value="`${
dashboardPanelData.data.config.label_option.position
? labelPositionOptions.find(
(it) =>
it.value ==
dashboardPanelData.data.config.label_option.position,
)?.label
: 'None'
}`"
data-test="dashboard-config-label-position"
>
</q-select>
<div class="space"></div>
<q-input
v-if="
[
'area',
'area-stacked',
'bar',
'h-bar',
'line',
'scatter',
'stacked',
'h-stacked',
].includes(dashboardPanelData.data.type)
"
v-model.number="dashboardPanelData.data.config.label_option.rotate"
:label="t('dashboard.labelRotate')"
color="input-border"
bg-color="input-bg"
class="q-py-md showLabelOnTop"
stack-label
outlined
filled
dense
label-slot
:type="'number'"
placeholder="0"
@update:model-value="
(value: any) =>
(dashboardPanelData.data.config.label_option.rotate =
value !== '' ? value : 0)
"
data-test="dashboard-config-label-rotate"
>
</q-input>
<div class="space"></div>
<q-select
v-if="
['area', 'area-stacked', 'line'].includes(
dashboardPanelData.data.type,
)
"
outlined
v-model="dashboardPanelData.data.config.show_symbol"
:options="showSymbol"
dense
:label="t('dashboard.showSymbol')"
class="showLabelOnTop selectedLabel"
stack-label
emit-value
:display-value="`${
dashboardPanelData.data.config.show_symbol
? showSymbol.find(
(it: any) =>
it.value == dashboardPanelData.data.config.show_symbol,
)?.label
: 'No'
}`"
data-test="dashboard-config-show_symbol"
>
<template v-slot:option="scope">
<q-item v-bind="scope.itemProps">
<q-item-section avatar style="height: 20px">
<q-icon>
<component :is="scope.opt.iconComponent"></component>
</q-icon>
</q-item-section>
<q-item-section>
<q-item-label>{{ scope.opt.label }}</q-item-label>
</q-item-section>
</q-item>
</template>
</q-select>
<div class="space"></div>
<q-select
v-if="
['area', 'area-stacked', 'line'].includes(
dashboardPanelData.data.type,
)
"
outlined
v-model="dashboardPanelData.data.config.line_interpolation"
:options="lineInterpolationOptions"
dense
:label="t('dashboard.lineInterpolation')"
class="showLabelOnTop selectedLabel"
stack-label
emit-value
:display-value="`${
dashboardPanelData.data.config.line_interpolation
? lineInterpolationOptions.find(
(it: any) =>
it.value == dashboardPanelData.data.config.line_interpolation,
)?.label
: 'smooth'
}`"
data-test="dashboard-config-line_interpolation"
>
<template v-slot:option="scope">
<q-item v-bind="scope.itemProps">
<q-item-section avatar>
<q-icon>
<component :is="scope.opt.iconComponent"></component>
</q-icon>
</q-item-section>
<q-item-section>
<q-item-label>{{ scope.opt.label }}</q-item-label>
</q-item-section>
</q-item>
</template>
</q-select>
<div class="space"></div>
<q-input
v-if="
!promqlMode &&
!dashboardPanelData.data.queries[
dashboardPanelData.layout.currentQueryIndex
].customQuery &&
['area', 'area-stacked', 'line'].includes(
dashboardPanelData.data.type,
)
"
v-model.number="dashboardPanelData.data.config.line_thickness"
:value="1.5"
:min="0"
@update:model-value="
(value: any) =>
(dashboardPanelData.data.config.line_thickness =
typeof value == 'number' && value >= 0 ? value : 1.5)
"
label="Line Thickness"
color="input-border"
bg-color="input-bg"
class="q-py-sm showLabelOnTop"
stack-label
outlined
filled
dense
label-slot
placeholder="Default: 1.5"
:type="'number'"
data-test="dashboard-config-line_thickness"
>
</q-input>
<div class="space"></div>
<Drilldown
v-if="
!['html', 'markdown', 'geomap', 'maps'].includes(
dashboardPanelData.data.type
dashboardPanelData.data.type,
)
"
:variablesData="variablesData"
@@ -1020,6 +1207,13 @@ import ValueMapping from "./ValueMapping.vue";
import MarkLineConfig from "./MarkLineConfig.vue";
import CommonAutoComplete from "@/components/dashboards/addPanel/CommonAutoComplete.vue";
import CustomDateTimePicker from "@/components/CustomDateTimePicker.vue";
import LinearIcon from "@/components/icons/dashboards/LinearIcon.vue";
import NoSymbol from "@/components/icons/dashboards/NoSymbol.vue";
import Smooth from "@/components/icons/dashboards/Smooth.vue";
import StepBefore from "@/components/icons/dashboards/StepBefore.vue";
import StepAfter from "@/components/icons/dashboards/StepAfter.vue";
import StepMiddle from "@/components/icons/dashboards/StepMiddle.vue";
import { markRaw } from "vue";
export default defineComponent({
components: {
@@ -1028,15 +1222,21 @@ export default defineComponent({
CommonAutoComplete,
MarkLineConfig,
CustomDateTimePicker,
LinearIcon,
NoSymbol,
Smooth,
StepBefore,
StepAfter,
StepMiddle,
},
props: ["dashboardPanelData", "variablesData"],
setup(props) {
const dashboardPanelDataPageKey = inject(
"dashboardPanelDataPageKey",
"dashboard"
"dashboard",
);
const { dashboardPanelData, promqlMode } = useDashboardPanelData(
dashboardPanelDataPageKey
dashboardPanelDataPageKey,
);
const { t } = useI18n();
@@ -1100,6 +1300,24 @@ export default defineComponent({
if (!dashboardPanelData.data.config.table_dynamic_columns) {
dashboardPanelData.data.config.table_dynamic_columns = false;
}
// by default, use label_option position as null and rotate as 0
if (!dashboardPanelData.data.config.label_option) {
dashboardPanelData.data.config.label_option = {
position: null,
rotate: 0,
};
}
// by default, set show_symbol as false
if (!dashboardPanelData.data.config.show_symbol) {
dashboardPanelData.data.config.show_symbol = false;
}
// by default, set line interpolation as smooth
if (!dashboardPanelData.data.config.line_interpolation) {
dashboardPanelData.data.config.line_interpolation = "smooth";
}
});
const legendWidthValue = computed({
@@ -1246,6 +1464,70 @@ export default defineComponent({
value: "custom",
},
];
const labelPositionOptions = [
{
label: t("dashboard.none"),
value: null,
},
{
label: t("dashboard.top"),
value: "top",
},
{
label: t("dashboard.inside"),
value: "inside",
},
{
label: t("dashboard.insideTop"),
value: "insideTop",
},
{
label: t("dashboard.insideBottom"),
value: "insideBottom",
},
];
const showSymbol = [
{
label: t("dashboard.no"),
value: false,
iconComponent: markRaw(NoSymbol),
},
{
label: t("dashboard.yes"),
value: true,
iconComponent: markRaw(LinearIcon),
},
];
const lineInterpolationOptions = [
{
label: t("dashboard.smooth"),
value: "smooth",
iconComponent: markRaw(Smooth),
},
{
label: t("dashboard.linear"),
value: "linear",
iconComponent: markRaw(LinearIcon),
},
{
label: t("dashboard.stepBefore"),
value: "step-start",
iconComponent: markRaw(StepBefore),
},
{
label: t("dashboard.stepAfter"),
value: "step-end",
iconComponent: markRaw(StepAfter),
},
{
label: t("dashboard.stepMiddle"),
value: "step-middle",
iconComponent: markRaw(StepMiddle),
},
];
const isWeightFieldPresent = computed(() => {
const layoutFields =
dashboardPanelData.data.queries[
@@ -1289,8 +1571,8 @@ export default defineComponent({
label: it.name,
value: it.name,
};
}
)
},
),
);
const timeShifts = [];
@@ -1341,6 +1623,9 @@ export default defineComponent({
symbolOptions,
legendsPositionOptions,
unitOptions,
labelPositionOptions,
showSymbol,
lineInterpolationOptions,
isWeightFieldPresent,
setUnit,
handleBlur,
@@ -0,0 +1,22 @@
<template>
<svg
width="116"
height="87"
viewBox="0 0 116 87"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M5.5 81L58.5 5.5L111 81" stroke="currentColor" stroke-width="4" />
<circle cx="59" cy="6" r="6" fill="currentColor" />
<circle cx="110" cy="81" r="6" fill="currentColor" />
<circle cx="6" cy="81" r="6" fill="currentColor" />
</svg>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "LinearIcon",
});
</script>
@@ -0,0 +1,19 @@
<template>
<svg
width="86"
height="90"
viewBox="0 0 86 90"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M2.5 83L31.5 6.5L59 83L83.5 6.5" stroke="currentColor" stroke-width="4" />
</svg>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "NoSymbol",
});
</script>
@@ -0,0 +1,26 @@
<template>
<svg
width="132"
height="84"
viewBox="0 0 132 84"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.07188 78C2.5731 -18.122 127.973 -20.5371 125.976 78"
stroke="currentColor"
stroke-width="4"
/>
<circle cx="66" cy="6" r="6" fill="currentColor" />
<circle cx="126" cy="78" r="6" fill="currentColor" />
<circle cx="6" cy="78" r="6" fill="currentColor" />
</svg>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "Smooth",
});
</script>
@@ -0,0 +1,40 @@
<template>
<svg
width="91"
height="83"
viewBox="0 0 91 83"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M85 76V5.5H44V76H5" stroke="currentColor" stroke-width="4" />
<circle
cx="6"
cy="6"
r="6"
transform="matrix(-1 0 0 1 50 0)"
fill="currentColor"
/>
<circle
cx="6"
cy="6"
r="6"
transform="matrix(-1 0 0 1 12 70)"
fill="currentColor"
/>
<circle
cx="6"
cy="6"
r="6"
transform="matrix(-1 0 0 1 91 71)"
fill="currentColor"
/>
</svg>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "StepAfter",
});
</script>
@@ -0,0 +1,22 @@
<template>
<svg
width="91"
height="83"
viewBox="0 0 91 83"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M6 76V5.5H47V76H86" stroke="currentColor" stroke-width="4" />
<circle cx="47" cy="6" r="6" fill="currentColor" />
<circle cx="85" cy="76" r="6" fill="currentColor" />
<circle cx="6" cy="77" r="6" fill="currentColor" />
</svg>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "StepBefore",
});
</script>
@@ -0,0 +1,33 @@
<template>
<svg
width="82"
height="83"
viewBox="0 0 82 83"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M80 77V6.5H39V77H0" stroke="currentColor" stroke-width="4" />
<circle
cx="6"
cy="6"
r="6"
transform="matrix(-1 0 0 1 65 0)"
fill="currentColor"
/>
<circle
cx="6"
cy="6"
r="6"
transform="matrix(-1 0 0 1 26 71)"
fill="currentColor"
/>
</svg>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "StepMiddle",
});
</script>
+7
View File
@@ -48,10 +48,17 @@ const getDefaultDashboardPanelData: any = () => ({
unit: null,
unit_custom: null,
decimals: 2,
line_thickness: 1.5,
top_results: null,
top_results_others: false,
axis_width: null,
axis_border_show: false,
label_option: {
position: null,
rotate: 0,
},
show_symbol: false,
line_interpolation: "smooth",
legend_width: {
value: null,
unit: "px",
+17 -1
View File
@@ -582,6 +582,8 @@
"showBorder": "Show Axis Border",
"legendsPositionLabel": "Legends Positions",
"unitLabel": "Unit",
"labelPosition": "Value Position",
"labelRotate": "Value Rotate",
"basemapLabel": "Base Map",
"customunitLabel": "Custom Unit",
"currencyDollar": "Currency - Dollar ($)",
@@ -657,7 +659,21 @@
"scheduledReports": "Scheduled Reports",
"newReport": "New Report",
"scheduledDashboards": "Scheduled Dashboards",
"panelHeight": "Panel Height"
"panelHeight": "Panel Height",
"none": "None",
"inside": "Inside",
"insideTop": "Inside Top",
"insideBottom": "Inside Bottom",
"top": "Top",
"showSymbol": "Show Symbol",
"yes": "Yes",
"no": "No",
"lineInterpolation": "Line Interpolation",
"linear": "Linear",
"smooth": "Smooth",
"stepBefore": "Step Before",
"stepAfter": "Step After",
"stepMiddle": "Step Middle"
},
"panel": {
"header": "Panel",
+85 -12
View File
@@ -722,6 +722,12 @@ export const convertSQLData = async (
// inverse data for h-stacked and h-bar
inverse: ["h-stacked", "h-bar"].includes(panelSchema.type),
name: index == 0 ? panelSchema.queries[0]?.fields?.x[index]?.label : "",
label: {
show:
panelSchema.config?.label_option?.position != null,
position: panelSchema.config?.label_option?.position || "None",
rotate: panelSchema.config?.label_option?.rotate || 0,
},
nameLocation: "middle",
nameGap: 25,
nameTextStyle: {
@@ -830,7 +836,7 @@ export const convertSQLData = async (
series: [],
};
const defaultSeriesProps = getPropsByChartTypeForSeries(panelSchema.type);
const defaultSeriesProps = getPropsByChartTypeForSeries(panelSchema);
// Now set the series values as per the chart data
// Override any configs if required as per the chart type
@@ -897,11 +903,19 @@ export const convertSQLData = async (
const data = missingValueData.filter(
(it: any) => it[key1] == key
);
const seriesObj = {
//only append if yaxiskeys length is more than 1
name:
yAxisKeys.length == 1 ? key : key + " (" + yAxisName + ")",
...defaultSeriesProps,
label: {
show:
panelSchema.config?.label_option?.position != null,
position:
panelSchema.config?.label_option?.position || "None",
rotate: panelSchema.config?.label_option?.rotate || 0,
},
// markLine if exist
markLine: {
silent: true,
@@ -928,6 +942,12 @@ export const convertSQLData = async (
name: panelSchema?.queries[0]?.fields?.y.find(
(it: any) => it.alias == key
)?.label,
label: {
show:
panelSchema.config?.label_option?.position != null,
position: panelSchema.config?.label_option?.position || "None",
rotate: panelSchema.config?.label_option?.rotate || 0,
},
// color:
// panelSchema.queries[0]?.fields?.y.find(
// (it: any) => it.alias == key,
@@ -1021,6 +1041,12 @@ export const convertSQLData = async (
name: panelSchema?.queries[0]?.fields?.y.find(
(it: any) => it.alias == key
)?.label,
label: {
show:
panelSchema.config?.label_option?.position != null,
position: panelSchema.config?.label_option?.position || "None",
rotate: panelSchema.config?.label_option?.rotate || 0,
},
// color:
// panelSchema.queries[0]?.fields?.y.find(
// (it: any) => it.alias == key,
@@ -1053,6 +1079,12 @@ export const convertSQLData = async (
// ?.color || "#5960b2",
opacity: 0.8,
...defaultSeriesProps,
label: {
show:
panelSchema.config?.label_option?.position != null,
position: panelSchema.config?.label_option?.position || "None",
rotate: panelSchema.config?.label_option?.rotate || 0,
},
// markLine if exist
markLine: {
silent: true,
@@ -1094,6 +1126,12 @@ export const convertSQLData = async (
animation: false,
data: getMarkLineData(panelSchema),
},
label: {
show:
panelSchema.config?.label_option?.position != null,
position: panelSchema.config?.label_option?.position || "None",
rotate: panelSchema.config?.label_option?.rotate || 0,
},
data: getAxisDataFromKey(key),
barMinHeight: 1,
};
@@ -1296,6 +1334,12 @@ export const convertSQLData = async (
const seriesObj = {
name: key,
...defaultSeriesProps,
label: {
show:
panelSchema.config?.label_option?.position != null,
position: panelSchema.config?.label_option?.position || "None",
rotate: panelSchema.config?.label_option?.rotate || 0,
},
// markLine if exist
markLine: {
silent: true,
@@ -1357,6 +1401,7 @@ export const convertSQLData = async (
{
...defaultSeriesProps,
name: panelSchema?.queries[0]?.fields?.y[0].label,
data: zValues
.map((it: any, index: any) => {
return xAxisZerothPositionUniqueValue.map(
@@ -1506,6 +1551,12 @@ export const convertSQLData = async (
const seriesObj = {
name: key,
...defaultSeriesProps,
label: {
show:
panelSchema.config?.label_option?.position != null,
position: panelSchema.config?.label_option?.position || "None",
rotate: panelSchema.config?.label_option?.rotate || 0,
},
// markLine if exist
markLine: {
silent: true,
@@ -2231,8 +2282,8 @@ const largestLabel = (data: any) => {
* @param {string} type - The type of chart.
* @return {Object} - The properties for the given chart type.
*/
const getPropsByChartTypeForSeries = (type: string) => {
switch (type) {
const getPropsByChartTypeForSeries = (panelSchema: any) => {
switch (panelSchema.type) {
case "bar":
return {
type: "bar",
@@ -2243,10 +2294,18 @@ const getPropsByChartTypeForSeries = (type: string) => {
return {
type: "line",
emphasis: { focus: "series" },
smooth: true,
showSymbol: false,
smooth:
panelSchema.config?.line_interpolation === "smooth" ||
panelSchema.config?.line_interpolation == null,
step: ["step-start", "step-end", "step-middle"].includes(
panelSchema.config?.line_interpolation,
)
// TODO: replace this with type integrations
? panelSchema.config.line_interpolation.replace("step-", "")
: false,
showSymbol: panelSchema.config?.show_symbol ?? false,
areaStyle: null,
lineStyle: { width: 1.5 },
lineStyle: { width: panelSchema.config?.line_thickness ?? 1.5 },
};
case "scatter":
return {
@@ -2304,11 +2363,18 @@ const getPropsByChartTypeForSeries = (type: string) => {
case "area":
return {
type: "line",
smooth: true,
smooth:
panelSchema.config?.line_interpolation === "smooth" ||
panelSchema.config?.line_interpolation == null,
step: ["step-start", "step-end", "step-middle"].includes(
panelSchema.config?.line_interpolation,
)
? panelSchema.config.line_interpolation.replace("step-", "")
: false,
emphasis: { focus: "series" },
areaStyle: {},
showSymbol: false,
lineStyle: { width: 1.5 },
showSymbol: panelSchema.config?.show_symbol ?? false,
lineStyle: { width: panelSchema.config?.line_thickness ?? 1.5 },
};
case "stacked":
return {
@@ -2336,14 +2402,21 @@ const getPropsByChartTypeForSeries = (type: string) => {
case "area-stacked":
return {
type: "line",
smooth: true,
smooth:
panelSchema.config?.line_interpolation === "smooth" ||
panelSchema.config?.line_interpolation == null,
step: ["step-start", "step-end", "step-middle"].includes(
panelSchema.config?.line_interpolation,
)
? panelSchema.config.line_interpolation.replace("step-", "")
: false,
stack: "Total",
areaStyle: {},
emphasis: {
focus: "series",
},
showSymbol: false,
lineStyle: { width: 1.5 },
showSymbol: panelSchema.config?.show_symbol ?? false,
lineStyle: { width: panelSchema.config?.line_thickness ?? 1.5 },
};
case "metric":
return {