Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Baidu map support #64

Merged
merged 12 commits into from Nov 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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.