Skip to content

Commit

Permalink
Add Baidu map support (#64)
Browse files Browse the repository at this point in the history
* add bmap support

* Create EChartsPanel.tsx

fix script bug

* Add Baidu map support

* Add Baidu map support

* Update Types

* Update Yarn and remove package lock

* Minor updates. Fix CI.

* Update types, utils, constants

* Update Baidu Maps

* Fix Tests

* Update maps dashboard

Co-authored-by: huishanjiang <47376191+huishanjiang@users.noreply.github.com>
Co-authored-by: Mikhail <mikhail@volkovlabs.io>
  • Loading branch information
3 people committed Nov 13, 2022
1 parent fd8f933 commit e4a6e9e
Show file tree
Hide file tree
Showing 14 changed files with 642 additions and 404 deletions.
116 changes: 116 additions & 0 deletions provisioning/dashboards/maps.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/components/EChartsPanel/EChartsPanel.test.tsx
Expand Up @@ -6,7 +6,7 @@ import { EChartsPanel } from './EChartsPanel';
/**
* Skip Register Maps
*/
jest.mock('../../utils', () => ({
jest.mock('../../maps', () => ({
registerMaps: () => {
return;
},
Expand Down
14 changes: 12 additions & 2 deletions src/components/EChartsPanel/EChartsPanel.tsx
@@ -1,15 +1,17 @@
import 'echarts-liquidfill';
import 'echarts-gl';
import 'echarts/extension/bmap/bmap';
import * as echarts from 'echarts';
import echartsStat from 'echarts-stat';
import React, { useEffect, useRef, useState } from 'react';
import { css, cx } from '@emotion/css';
import { AlertErrorPayload, AlertPayload, AppEvents, PanelProps } from '@grafana/data';
import { getAppEvents, locationService } from '@grafana/runtime';
import { Alert, useTheme2 } from '@grafana/ui';
import { Map } from '../../constants';
import { loadBaidu, registerMaps } from '../../maps';
import { getStyles } from '../../styles';
import { PanelOptions } from '../../types';
import { registerMaps } from '../../utils';

/**
* Properties
Expand Down Expand Up @@ -79,7 +81,7 @@ export const EChartsPanel: React.FC<Props> = ({ options, data, width, height, re
useEffect(() => {
initChart();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [options.renderer]);
}, [options.renderer, options.map]);

/**
* Resize
Expand Down Expand Up @@ -137,6 +139,14 @@ export const EChartsPanel: React.FC<Props> = ({ options, data, width, height, re
'notifyError',
options.getOption
);

/**
* Load Baidu Maps
*/
if (options.map === Map.BMAP && !(window as any).BMap) {
loadBaidu(options.baidu);
}

chart.setOption(
func(data, theme, chart, echarts, ecStat, replaceVariables, locationService, notifySuccess, notifyError)
);
Expand Down
8 changes: 7 additions & 1 deletion src/constants/default.ts
@@ -1,5 +1,5 @@
import { PanelOptions } from '../types';
import { Renderer } from './echarts';
import { Map, Renderer } from './echarts';
import { Format } from './editor';

/**
Expand Down Expand Up @@ -83,4 +83,10 @@ export const DefaultOptions: PanelOptions = {
getOption,
renderer: Renderer.CANVAS,
editor: { height: 600, format: Format.AUTO },
map: Map.DEFAULT,
baidu: {
url: 'https://api.map.baidu.com/api',
key: '',
callback: 'bmapReady',
},
};
16 changes: 16 additions & 0 deletions src/constants/echarts.ts
Expand Up @@ -13,3 +13,19 @@ export const RendererOptions = [
{ value: Renderer.CANVAS, label: 'Canvas' },
{ value: Renderer.SVG, label: 'SVG' },
];

/**
* ECharts Map
*/
export enum Map {
DEFAULT = 'json',
BMAP = 'bmap',
}

/**
* Echarts Map Options
*/
export const MapOptions = [
{ value: Map.DEFAULT, label: 'JSON' },
{ value: Map.BMAP, label: 'Baidu' },
];
30 changes: 30 additions & 0 deletions src/maps.ts
@@ -0,0 +1,30 @@
import * as echarts from 'echarts';
import { BaiduOptions } from 'types';

/**
* Register maps
*/
export const registerMaps = () => {
console.log('Maps Loaded');

const maps = require.context('./maps', false, /\.json/);
maps.keys().map((m: string) => {
const matched = m.match(/\.\/([0-9a-zA-Z_]*)\.json/);
if (!matched) {
return;
}

echarts.registerMap(matched[1], maps(m));
});
};

/**
* Load Baidu Maps
*/
export const loadBaidu = (baidu: BaiduOptions) => {
const script = document.createElement('script');
script.type = 'text/javascript';
script.src = `${baidu.url}?v=3.0&ak=${baidu.key}&callback=${baidu.callback}`;

document.body.appendChild(script);
};
4 changes: 3 additions & 1 deletion src/module.test.ts
Expand Up @@ -4,7 +4,7 @@ import { plugin } from './module';
/**
* Skip Register Maps
*/
jest.mock('./utils', () => ({
jest.mock('./maps', () => ({
registerMaps: () => {
return;
},
Expand All @@ -26,6 +26,7 @@ describe('plugin', () => {
addCustomEditor: jest.fn().mockImplementation(() => builder),
addSliderInput: jest.fn().mockImplementation(() => builder),
addRadio: jest.fn().mockImplementation(() => builder),
addTextInput: jest.fn().mockImplementation(() => builder),
};

/**
Expand All @@ -39,5 +40,6 @@ describe('plugin', () => {
expect(builder.addCustomEditor).toHaveBeenCalled();
expect(builder.addSliderInput).toHaveBeenCalled();
expect(builder.addRadio).toHaveBeenCalled();
expect(builder.addTextInput).toHaveBeenCalled();
});
});
82 changes: 58 additions & 24 deletions src/module.ts
@@ -1,22 +1,60 @@
import { PanelPlugin } from '@grafana/data';
import { EChartsEditor, EChartsPanel } from './components';
import { DefaultOptions, FormatOptions, RendererOptions } from './constants';
import { DefaultOptions, FormatOptions, Map, MapOptions, RendererOptions } from './constants';
import { PanelOptions } from './types';

/**
* Panel Plugin
*/
export const plugin = new PanelPlugin<PanelOptions>(EChartsPanel).setPanelOptions((builder) => {
builder.addRadio({
path: 'renderer',
name: 'Renderer',
description:
'Canvas is more suitable for charts with a large number of elements. SVG has less memory usage, no blur when using the browser zoom.',
settings: {
options: RendererOptions,
},
defaultValue: DefaultOptions.renderer,
});
builder
.addRadio({
path: 'renderer',
name: 'Renderer',
description:
'Canvas is more suitable for charts with a large number of elements. SVG has less memory usage, no blur when using the browser zoom.',
settings: {
options: RendererOptions,
},
defaultValue: DefaultOptions.renderer,
})
.addRadio({
path: 'map',
name: 'Maps',
settings: {
options: MapOptions,
},
defaultValue: DefaultOptions.map,
});

/**
* Baidu
*/
builder
.addTextInput({
path: 'baidu.url',
name: 'URL',
defaultValue: DefaultOptions.baidu.url,
showIf: (config) => config.map === Map.BMAP,
category: ['Baidu'],
})
.addTextInput({
path: 'baidu.key',
name: 'Access Key',
description:
'Set Access Key to use Baidu Maps. You can get it from https://lbsyun.baidu.com/apiconsole/key#/home',
defaultValue: DefaultOptions.baidu.key,
showIf: (config) => config.map === Map.BMAP,
category: ['Baidu'],
})
.addTextInput({
path: 'baidu.callback',
name: 'Callback',
description: 'Name of the Callback function.',
defaultValue: DefaultOptions.baidu.callback,
showIf: (config) => config.map === Map.BMAP,
category: ['Baidu'],
});

/**
* Editor
Expand All @@ -40,20 +78,16 @@ export const plugin = new PanelPlugin<PanelOptions>(EChartsPanel).setPanelOption
},
defaultValue: DefaultOptions.editor.format,
category: ['Editor'],
})
.addCustomEditor({
id: 'getOption',
path: 'getOption',
name: 'Function',
description: 'Should return parameters and data for setOptions().',
defaultValue: DefaultOptions.getOption,
editor: EChartsEditor,
category: ['Editor'],
});

/**
* Function
*/
builder.addCustomEditor({
id: 'getOption',
path: 'getOption',
name: 'setOptions() Function',
description: 'Should return parameters and data for setOptions().',
defaultValue: DefaultOptions.getOption,
editor: EChartsEditor,
category: ['Function'],
});

return builder;
});
25 changes: 25 additions & 0 deletions src/types/baidu.ts
@@ -0,0 +1,25 @@
/**
* Baidu Options
*/
export interface BaiduOptions {
/**
* URL
*
* @type {string}
*/
url: string;

/**
* Access Key
*
* @type {string}
*/
key: string;

/**
* Callback Function
*
* @type {string}
*/
callback: string;
}
20 changes: 20 additions & 0 deletions src/types/editor.ts
@@ -0,0 +1,20 @@
import { Format } from '../constants';

/**
* Editor Options
*/
export interface EditorOptions {
/**
* Height
*
* @type {number}
*/
height: number;

/**
* Format
*
* @type {Format}
*/
format: Format;
}
3 changes: 3 additions & 0 deletions src/types/index.ts
@@ -0,0 +1,3 @@
export * from './baidu';
export * from './editor';
export * from './panel';
23 changes: 11 additions & 12 deletions src/types.ts → src/types/panel.ts
@@ -1,4 +1,6 @@
import { Format, Renderer } from './constants';
import { Map, Renderer } from '../constants';
import { BaiduOptions } from './baidu';
import { EditorOptions } from './editor';

/**
* Options
Expand All @@ -20,25 +22,22 @@ export interface PanelOptions {

/**
* Editor
*
* @type {EditorOptions}
*/
editor: EditorOptions;
}

/**
* Editor Options
*/
export interface EditorOptions {
/**
* Height
* Type
*
* @type {number}
* @type {Map}
*/
height: number;
map: Map;

/**
* Format
* Baidu
*
* @type {Format}
* @type {BaiduOptions}
*/
format: Format;
baidu: BaiduOptions;
}
16 changes: 0 additions & 16 deletions src/utils.ts

This file was deleted.

0 comments on commit e4a6e9e

Please sign in to comment.