mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-05 08:09:22 +00:00
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:
@@ -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>
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user