123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- import { FieldConfigSource, PanelModel, PanelTypeChangedHandler } from '@grafana/data';
- import { AxisPlacement, ScaleDistribution, VisibilityMode } from '@grafana/schema';
- import {
- HeatmapCellLayout,
- HeatmapCalculationMode,
- HeatmapCalculationOptions,
- } from 'app/features/transformers/calculateHeatmap/models.gen';
- import { PanelOptions, defaultPanelOptions, HeatmapColorMode } from './models.gen';
- import { colorSchemes } from './palettes';
- /** Called when the version number changes */
- export const heatmapMigrationHandler = (panel: PanelModel): Partial<PanelOptions> => {
- // Migrating from angular
- if (Object.keys(panel.options).length === 0) {
- return heatmapChangedHandler(panel, 'heatmap', { angular: panel }, panel.fieldConfig);
- }
- return panel.options;
- };
- /**
- * This is called when the panel changes from another panel
- */
- export const heatmapChangedHandler: PanelTypeChangedHandler = (panel, prevPluginId, prevOptions, prevFieldConfig) => {
- if (prevPluginId === 'heatmap' && prevOptions.angular) {
- const { fieldConfig, options } = angularToReactHeatmap({
- ...prevOptions.angular,
- fieldConfig: prevFieldConfig,
- });
- panel.fieldConfig = fieldConfig; // Mutates the incoming panel
- return options;
- }
- // alpha for 8.5+, then beta at 9.0.1
- if (prevPluginId === 'heatmap-new') {
- const { bucketFrame, ...options } = panel.options;
- if (bucketFrame) {
- return { ...options, rowsFrame: bucketFrame };
- }
- return panel.options;
- }
- return {};
- };
- export function angularToReactHeatmap(angular: any): { fieldConfig: FieldConfigSource; options: PanelOptions } {
- const fieldConfig: FieldConfigSource = {
- defaults: {},
- overrides: [],
- };
- const calculate = angular.dataFormat === 'tsbuckets' ? false : true;
- const calculation: HeatmapCalculationOptions = {
- ...defaultPanelOptions.calculation,
- };
- const oldYAxis = { logBase: 1, ...angular.yAxis };
- if (calculate) {
- if (angular.xBucketSize) {
- calculation.xBuckets = { mode: HeatmapCalculationMode.Size, value: `${angular.xBucketSize}` };
- } else if (angular.xBucketNumber) {
- calculation.xBuckets = { mode: HeatmapCalculationMode.Count, value: `${angular.xBucketNumber}` };
- }
- if (angular.yBucketSize) {
- calculation.yBuckets = { mode: HeatmapCalculationMode.Size, value: `${angular.yBucketSize}` };
- } else if (angular.xBucketNumber) {
- calculation.yBuckets = { mode: HeatmapCalculationMode.Count, value: `${angular.yBucketNumber}` };
- }
- if (oldYAxis.logBase > 1) {
- calculation.yBuckets = {
- mode: HeatmapCalculationMode.Count,
- value: +oldYAxis.splitFactor > 0 ? `${oldYAxis.splitFactor}` : undefined,
- scale: {
- type: ScaleDistribution.Log,
- log: oldYAxis.logBase,
- },
- };
- }
- }
- const options: PanelOptions = {
- calculate,
- calculation,
- color: {
- ...defaultPanelOptions.color,
- steps: 128, // best match with existing colors
- },
- cellGap: asNumber(angular.cards?.cardPadding, 2),
- cellRadius: asNumber(angular.cards?.cardRound), // just to keep it
- yAxis: {
- axisPlacement: oldYAxis.show === false ? AxisPlacement.Hidden : AxisPlacement.Left,
- reverse: Boolean(angular.reverseYBuckets),
- axisWidth: asNumber(oldYAxis.width),
- min: oldYAxis.min,
- max: oldYAxis.max,
- unit: oldYAxis.format,
- decimals: oldYAxis.decimals,
- },
- cellValues: {
- decimals: asNumber(angular.tooltipDecimals),
- },
- rowsFrame: {
- layout: getHeatmapCellLayout(angular.yBucketBound),
- },
- legend: {
- show: Boolean(angular.legend.show),
- },
- showValue: VisibilityMode.Never,
- tooltip: {
- show: Boolean(angular.tooltip?.show),
- yHistogram: Boolean(angular.tooltip?.showHistogram),
- },
- exemplars: {
- ...defaultPanelOptions.exemplars,
- },
- };
- if (angular.hideZeroBuckets) {
- options.filterValues = { ...defaultPanelOptions.filterValues }; // min: 1e-9
- }
- // Migrate color options
- const color = angular.color;
- switch (color?.mode) {
- case 'spectrum': {
- options.color.mode = HeatmapColorMode.Scheme;
- const current = color.colorScheme as string;
- let scheme = colorSchemes.find((v) => v.name === current);
- if (!scheme) {
- scheme = colorSchemes.find((v) => current.indexOf(v.name) >= 0);
- }
- options.color.scheme = scheme ? scheme.name : defaultPanelOptions.color.scheme;
- break;
- }
- case 'opacity': {
- options.color.mode = HeatmapColorMode.Opacity;
- options.color.scale = color.scale;
- break;
- }
- }
- options.color.min = color.min;
- options.color.max = color.max;
- return { fieldConfig, options };
- }
- function getHeatmapCellLayout(v?: string): HeatmapCellLayout {
- switch (v) {
- case 'upper':
- return HeatmapCellLayout.ge;
- case 'lower':
- return HeatmapCellLayout.le;
- case 'middle':
- return HeatmapCellLayout.unknown;
- }
- return HeatmapCellLayout.auto;
- }
- function asNumber(v: any, defaultValue?: number): number | undefined {
- if (v == null || v === '') {
- return defaultValue;
- }
- const num = +v;
- return isNaN(num) ? defaultValue : num;
- }
|