From 92e1883845868ef702e8bc87193efb20341d00ee Mon Sep 17 00:00:00 2001 From: nikki-kiga <42276368+nikki-kiga@users.noreply.github.com> Date: Tue, 23 Nov 2021 08:23:43 -0800 Subject: [PATCH] Geomap: Add rotation option for markers layer (#41992) * add rotation option for markers layer * add ScalerDimensionEditor --- .../src/components/MatchersUI/utils.ts | 17 +-- .../editors/ScalarDimensionEditor.tsx | 110 ++++++++++++++++++ .../app/features/dimensions/editors/index.ts | 1 + public/app/features/dimensions/index.ts | 1 + public/app/features/dimensions/scalar.test.ts | 94 +++++++++++++++ public/app/features/dimensions/scalar.ts | 59 ++++++++++ public/app/features/dimensions/types.ts | 15 +++ .../panel/geomap/layers/data/StyleEditor.tsx | 78 ++++++++++--- .../panel/geomap/layers/data/markersLayer.tsx | 9 +- .../plugins/panel/geomap/migrations.test.ts | 6 + .../app/plugins/panel/geomap/style/markers.ts | 17 ++- .../app/plugins/panel/geomap/style/types.ts | 13 +++ .../app/plugins/panel/geomap/style/utils.ts | 5 +- .../plugins/panel/geomap/utils/getFeatures.ts | 3 + 14 files changed, 396 insertions(+), 32 deletions(-) create mode 100644 public/app/features/dimensions/editors/ScalarDimensionEditor.tsx create mode 100644 public/app/features/dimensions/scalar.test.ts create mode 100644 public/app/features/dimensions/scalar.ts diff --git a/packages/grafana-ui/src/components/MatchersUI/utils.ts b/packages/grafana-ui/src/components/MatchersUI/utils.ts index 913994a10f0..ccbf9545081 100644 --- a/packages/grafana-ui/src/components/MatchersUI/utils.ts +++ b/packages/grafana-ui/src/components/MatchersUI/utils.ts @@ -68,7 +68,8 @@ export function useFieldDisplayNames(data: DataFrame[], filter?: (field: Field) export function useSelectOptions( displayNames: FrameFieldsDisplayNames, currentName?: string, - firstItem?: SelectableValue + firstItem?: SelectableValue, + fieldType?: string ): Array> { return useMemo(() => { let found = false; @@ -81,11 +82,13 @@ export function useSelectOptions( found = true; } const field = displayNames.fields.get(name); - options.push({ - value: name, - label: name, - icon: field ? getFieldTypeIcon(field) : undefined, - }); + if (!fieldType || fieldType === field?.type) { + options.push({ + value: name, + label: name, + icon: field ? getFieldTypeIcon(field) : undefined, + }); + } } for (const name of displayNames.raw) { if (!displayNames.display.has(name)) { @@ -106,5 +109,5 @@ export function useSelectOptions( }); } return options; - }, [displayNames, currentName, firstItem]); + }, [displayNames, currentName, firstItem, fieldType]); } diff --git a/public/app/features/dimensions/editors/ScalarDimensionEditor.tsx b/public/app/features/dimensions/editors/ScalarDimensionEditor.tsx new file mode 100644 index 00000000000..8d26be77018 --- /dev/null +++ b/public/app/features/dimensions/editors/ScalarDimensionEditor.tsx @@ -0,0 +1,110 @@ +import React, { FC, useCallback } from 'react'; +import { FieldType, GrafanaTheme2, SelectableValue, StandardEditorProps } from '@grafana/data'; +import { ScalarDimensionConfig, ScalarDimensionMode, ScalarDimensionOptions } from '../types'; +import { InlineField, InlineFieldRow, RadioButtonGroup, Select, useStyles2 } from '@grafana/ui'; +import { useFieldDisplayNames, useSelectOptions } from '@grafana/ui/src/components/MatchersUI/utils'; +import { NumberInput } from './NumberInput'; +import { css } from '@emotion/css'; + +const fixedValueOption: SelectableValue = { + label: 'Fixed value', + value: '_____fixed_____', +}; + +const scalarOptions = [ + { label: 'Mod', value: ScalarDimensionMode.Mod, description: 'Use field values, mod from max' }, + { label: 'Clamped', value: ScalarDimensionMode.Clamped, description: 'Use field values, clamped to max and min' }, +]; + +export const ScalarDimensionEditor: FC> = ( + props +) => { + const { value, context, onChange } = props; + + const DEFAULT_VALUE = 0; + + const fieldName = value?.field; + const isFixed = Boolean(!fieldName); + const names = useFieldDisplayNames(context.data); + const selectOptions = useSelectOptions(names, fieldName, fixedValueOption, FieldType.number); + + const styles = useStyles2(getStyles); + + const onSelectChange = useCallback( + (selection: SelectableValue) => { + const field = selection.value; + if (field && field !== fixedValueOption.value) { + onChange({ + ...value, + field, + }); + } else { + const fixed = value.fixed ?? DEFAULT_VALUE; + onChange({ + ...value, + field: undefined, + fixed, + }); + } + }, + [onChange, value] + ); + + const onModeChange = useCallback( + (mode) => { + onChange({ + ...value, + mode, + }); + }, + [onChange, value] + ); + + const onValueChange = useCallback( + (v: number | undefined) => { + onChange({ + ...value, + field: undefined, + fixed: v ?? DEFAULT_VALUE, + }); + }, + [onChange, value] + ); + + const val = value ?? {}; + const mode = value?.mode ?? ScalarDimensionMode.Mod; + const selectedOption = isFixed ? fixedValueOption : selectOptions.find((v) => v.value === fieldName); + return ( + <> +
+ + + + + +