migrations.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import { cloneDeep } from 'lodash';
  2. import { FieldConfigSource, PanelModel, PanelTypeChangedHandler, Threshold, ThresholdsMode } from '@grafana/data';
  3. import { ResourceDimensionMode } from 'app/features/dimensions';
  4. import { MarkersConfig } from './layers/data/markersLayer';
  5. import { getMarkerAsPath } from './style/markers';
  6. import { defaultStyleConfig } from './style/types';
  7. import { GeomapPanelOptions, TooltipMode } from './types';
  8. import { MapCenterID } from './view';
  9. /**
  10. * This is called when the panel changes from another panel
  11. */
  12. export const mapPanelChangedHandler: PanelTypeChangedHandler = (panel, prevPluginId, prevOptions, prevFieldConfig) => {
  13. // Changing from angular/worldmap panel to react/openlayers
  14. if (prevPluginId === 'grafana-worldmap-panel' && prevOptions.angular) {
  15. const { fieldConfig, options } = worldmapToGeomapOptions({
  16. ...prevOptions.angular,
  17. fieldConfig: prevFieldConfig,
  18. });
  19. panel.fieldConfig = fieldConfig; // Mutates the incoming panel
  20. return options;
  21. }
  22. return {};
  23. };
  24. export function worldmapToGeomapOptions(angular: any): { fieldConfig: FieldConfigSource; options: GeomapPanelOptions } {
  25. const fieldConfig: FieldConfigSource = {
  26. defaults: {},
  27. overrides: [],
  28. };
  29. const options: GeomapPanelOptions = {
  30. view: {
  31. id: MapCenterID.Zero,
  32. },
  33. controls: {
  34. showZoom: true,
  35. mouseWheelZoom: Boolean(angular.mouseWheelZoom),
  36. },
  37. basemap: {
  38. type: 'default', // was carto
  39. name: 'Basemap',
  40. },
  41. layers: [
  42. // TODO? depends on current configs
  43. ],
  44. tooltip: { mode: TooltipMode.Details },
  45. };
  46. let v = asNumber(angular.decimals);
  47. if (v) {
  48. fieldConfig.defaults.decimals = v;
  49. }
  50. // Convert thresholds and color values
  51. if (angular.thresholds && angular.colors) {
  52. const levels = angular.thresholds.split(',').map((strVale: string) => {
  53. return Number(strVale.trim());
  54. });
  55. // One more color than threshold
  56. const thresholds: Threshold[] = [];
  57. for (const color of angular.colors) {
  58. const idx = thresholds.length - 1;
  59. if (idx >= 0) {
  60. thresholds.push({ value: levels[idx], color });
  61. } else {
  62. thresholds.push({ value: -Infinity, color });
  63. }
  64. }
  65. fieldConfig.defaults.thresholds = {
  66. mode: ThresholdsMode.Absolute,
  67. steps: thresholds,
  68. };
  69. }
  70. v = asNumber(angular.initialZoom);
  71. if (v) {
  72. options.view.zoom = v;
  73. }
  74. // mapCenter: 'Europe',
  75. // mapCenterLatitude: 46,
  76. // mapCenterLongitude: 14,
  77. //
  78. // Map center (from worldmap)
  79. const mapCenters: any = {
  80. '(0°, 0°)': MapCenterID.Zero,
  81. 'North America': 'north-america',
  82. Europe: 'europe',
  83. 'West Asia': 'west-asia',
  84. 'SE Asia': 'se-asia',
  85. 'Last GeoHash': MapCenterID.Coordinates, // MapCenterID.LastPoint,
  86. };
  87. options.view.id = mapCenters[angular.mapCenter as any];
  88. options.view.lat = asNumber(angular.mapCenterLatitude);
  89. options.view.lon = asNumber(angular.mapCenterLongitude);
  90. return { fieldConfig, options };
  91. }
  92. function asNumber(v: any): number | undefined {
  93. const num = +v;
  94. return isNaN(num) ? undefined : num;
  95. }
  96. export const mapMigrationHandler = (panel: PanelModel): Partial<GeomapPanelOptions> => {
  97. const pluginVersion = panel?.pluginVersion ?? '';
  98. // before 8.3, only one layer was supported!
  99. if (pluginVersion.startsWith('8.1') || pluginVersion.startsWith('8.2')) {
  100. const layers = panel.options?.layers;
  101. if (layers?.length === 1) {
  102. const layer = panel.options.layers[0];
  103. if (layer?.type === 'markers' && layer.config) {
  104. // Moving style to child object
  105. const oldConfig = layer.config;
  106. const config: MarkersConfig = {
  107. style: cloneDeep(defaultStyleConfig),
  108. showLegend: Boolean(oldConfig.showLegend),
  109. };
  110. if (oldConfig.size) {
  111. config.style.size = oldConfig.size;
  112. }
  113. if (oldConfig.color) {
  114. config.style.color = oldConfig.color;
  115. }
  116. if (oldConfig.fillOpacity) {
  117. config.style.opacity = oldConfig.fillOpacity;
  118. }
  119. const symbol = getMarkerAsPath(oldConfig.shape);
  120. if (symbol) {
  121. config.style.symbol = {
  122. fixed: symbol,
  123. mode: ResourceDimensionMode.Fixed,
  124. };
  125. }
  126. return { ...panel.options, layers: [{ ...layer, config }] };
  127. }
  128. }
  129. }
  130. return panel.options;
  131. };