diff --git a/README.md b/README.md index fb7fb05..e799b7b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,26 @@ -# timeline_map -带有时间轴的中国地图趋势kibana插件 +# kibana-plugin-echarts +Kibana的Echarts图表插件 + +## 基于: + + Kibana 5.2.0 + + Echarts 3.4 + +## 安装方法: +``` bash +cd node/bin +mv npm npm.bak +ln -s ../lib/node_modules/npm/bin/npm-cli.js npm +cd ../.. +vim package.json +在engines配置上面增加echarts +"dependencies": { + "echarts": "3.4.0" + }, + "engines": { + "node": "6.9.0" + } +node/bin/npm update +bin/kibana-plugin install https://github.com/hivefans/kibana-plugin-echarts/files/985443/kibana-plugin-echarts.zip +``` diff --git a/index.js b/index.js new file mode 100644 index 0000000..b928a75 --- /dev/null +++ b/index.js @@ -0,0 +1,7 @@ +export default function (kibana) { + return new kibana.Plugin({ + uiExports: { + visTypes: ['plugins/timeline_map/timeline_map'] + } + }); +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..a385e15 --- /dev/null +++ b/package.json @@ -0,0 +1,10 @@ +{ + "name": "timeline_map", + "version": "0.1.01", + "kibana": { + "version": "5.2.0" + }, + "dependencies": { + "echarts": "3.4.0" + } +} diff --git a/public/echarts_timelinemap.html b/public/echarts_timelinemap.html new file mode 100644 index 0000000..58d197d --- /dev/null +++ b/public/echarts_timelinemap.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/public/echarts_timelinemap.js b/public/echarts_timelinemap.js new file mode 100644 index 0000000..f707a31 --- /dev/null +++ b/public/echarts_timelinemap.js @@ -0,0 +1,78 @@ +import 'plugins/timeline_map/timeline_map.less'; +import 'plugins/timeline_map/echarts_timelinemap_controller'; +import TemplateVisTypeTemplateVisTypeProvider from 'ui/template_vis_type/template_vis_type'; +import VisSchemasProvider from 'ui/vis/schemas'; +import echartsTimelineMapTemplate from 'plugins/timeline_map/echarts_timelinemap.html'; +import echartsTimelineMapParamsTemplate from 'plugins/timeline_map/echarts_timelinemap_editor.html'; + + +// require('ui/registry/vis_types').register(echartsPieProvider); + +function echartsTimelineMapProvider(Private) { + const TemplateVisType = Private(TemplateVisTypeTemplateVisTypeProvider); + const Schemas = Private(VisSchemasProvider); + // we also need to load the controller and used by the template + // require('plugins/kibana-plugin-echarts/echartsPieController'); + + return new TemplateVisType({ + name: 'timeline_map', + title: 'Echarts timeline Map', + icon: 'fa-map-marker', + description: '数据统计中国地图时间轴趋势', + template: echartsTimelineMapTemplate, + params: { + defaults: { + shareYAxis: true, + addTooltip: true, + addLegend: true, + isDonut: false + }, + editor: echartsTimelineMapParamsTemplate + }, + legendPositions: [{ + value: 'left', + text: 'left', + }, { + value: 'right', + text: 'right', + }, { + value: 'top', + text: 'top', + }, { + value: 'bottom', + text: 'bottom', + }], + responseConverter: false, + hierarchicalData: true, + schemas: new Schemas([{ + group: 'metrics', + name: 'metric', + title: 'Y-Axis', + min: 1, + max: 1, + aggFilter: '!geohash_grid', + defaults: [{ + schema: 'metric', + type: 'count', + }] + }, { + group: 'buckets', + name: 'segment', + icon: 'fa fa-scissors', + title: 'X-Axis', + min: 1, + max: 1, + aggFilter: '!geohash_grid' + }, + { + group: 'buckets', + name: 'group', + title: 'Split Area', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + }]) + }); +}; + +export default echartsTimelineMapProvider; diff --git a/public/echarts_timelinemap_controller.js b/public/echarts_timelinemap_controller.js new file mode 100644 index 0000000..e3a520c --- /dev/null +++ b/public/echarts_timelinemap_controller.js @@ -0,0 +1,238 @@ +import echarts from 'echarts/lib/echarts'; +import 'echarts/lib/chart/map'; +import 'echarts/map/js/china'; +// import 'public_function'; + +var module = require('ui/modules').get('timeline_map'); + +module.controller('EchartsTimelineMapController', function ($scope, $element, $rootScope, Private, Notifier) { + var tabifyAggResponse = Private(require('ui/agg_response/tabify/tabify')); + var notify = new Notifier({ location: 'timeline_map/EchartsTimelineMapController'}); + let mychart = echarts.init($element.get(0)); + let rootElement = $element; + let margin = { + top: 10, + right: 10, + bottom: 10, + left: 10 + }; + let width; + let height; + //state.query + var provinces = [ + { name: "anhui", value: "安徽" }, + { name: "beijing", value: "北京" }, + { name: "fujian", value: "福建" }, + { name: "gansu", value: "甘肃" }, + { name: "guangdong", value: "广东" }, + { name: "guangxi", value: "广西" }, + { name: "guizhou", value: "贵州" }, + { name: "hainan", value: "海南" }, + { name: "hebei", value: "河北" }, + { name: "henan", value: "河南" }, + { name: "hubei", value: "湖北" }, + { name: "hunan", value: "湖南" }, + { name: "jilin", value: "吉林" }, + { name: "jiangsu", value: "江苏" }, + { name: "jiangxi", value: "江西" }, + { name: "liaoning", value: "辽宁" }, + { name: "ningxia", value: "宁夏" }, + { name: "qinghai", value: "青海" }, + { name: "shandong", value: "山东" }, + { name: "sanxi", value: "山西" }, + { name: "shanxi", value: "陕西" }, + { name: "shanghai", value: "上海" }, + { name: "sichuan", value: "四川" }, + { name: "tianjin", value: "天津" }, + { name: "xizang", value: "西藏" }, + { name: "xinjiang", value: "新疆" }, + { name: "yunnan", value: "云南" }, + { name: "zhejiang", value: "浙江" }, + { name: "chongqing", value: "重庆" }, + { name: "aomen", value: "澳门" }, + { name: "xianggang", value: "香港" }, + { name: "taiwan", value: "台湾" }, + { name: "heilongjiang", value: "黑龙江" }, + { name: "neimenggu", value: "内蒙古" } + ] + + // 转化省份到汉字 + var convertProvince = function (data) { + for (var i = 0; i < provinces.length; i++) { + if (provinces[i].name == data) { + return provinces[i].value; + } + } + // console.log(data) + return "other"; + } + + var getdateformat = function (timestamp){ + var date = new Date(timestamp); + var Y = date.getFullYear() + '-'; + var M = (date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1) + '-'; + var D = (date.getDate() < 10 ? '0'+(date.getDate()) : date.getDate()) + ' '; + var h = (date.getHours() < 10 ? '0'+(date.getHours()) : date.getHours()) + ':'; + var m = (date.getMinutes() < 10 ? '0'+(date.getMinutes()) : date.getMinutes()); + return Y+M+D+h+m; + } + + + var all={}; + var avgArr=[]; + var tableGroups; + $scope.$watch('esResponse', function(resp) { + if (!resp) { + return; + } + tableGroups = tabifyAggResponse($scope.vis, resp); + tableGroups.tables.forEach(function (table,index) { + var cols = table.columns; + var prov_len=0; + var j=0; + all.dates=[]; + all.options=[]; + avgArr = []; + prov_len=cols[2].aggConfig.params.size; + table.rows.forEach(function (row,i) { + var datestr = row[0]; + var region_name = ""; + region_name = row[2].toString(); + var avg_speed = 0; + avg_speed = row[3]; + avg_speed=avg_speed.toFixed(2); + + if(i%prov_len==0){ + all.dates.push(getdateformat(datestr)); + all.options.push( + { + "series":[{ + "data":[] + }] + } + ); + j=j+1; + } + + avgArr.push(avg_speed); + if(escape(region_name).indexOf("%u")<0) { + region_name = convertProvince(region_name); + } + all.options[j-1].series[0].data.push( + { + name:region_name, + value:avg_speed + } + ) + }); + }); + + var option={}; + option = { + baseOption: { + timeline: { + axisType: 'category', + orient: 'vertical', + autoPlay: true, + inverse: true, + playInterval: 5000, + left: 10, + right: null, + top: 20, + bottom: 20, + width: 120, + height: null, + label: { + emphasis: { + textStyle: { + color: '#fff' + }, + "show":true + }, + normal: { + "show": true + } + }, + symbol: 'none', + lineStyle: { + color: '#555' + }, + checkpointStyle: { + color: '#bbb', + borderColor: '#777', + borderWidth: 2 + }, + controlStyle: { + showNextBtn: true, + showPrevBtn: true, + normal: { + color: '#666', + borderColor: '#666' + }, + emphasis: { + color: '#aaa', + borderColor: '#aaa' + } + }, + data: all.dates + }, + tooltip: { + }, + series: [{ + type: 'map', + name: '数据统计', + map: 'china', + roam: false, + label: { + "emphasis": { + "show": true + }, + "normal": { + "show": true + } + } + }], + animationDurationUpdate: 1000, + animationEasingUpdate: 'quinticInOut', + visualMap: { + min:0, + max: 500, + left: 'right', + top: 'bottom', + text: ['高','低'], + calculable: true, + inRange: { + color: ['#0ba800','#eac736','#d94e5d'] + } + } + }, + options: all.options + }; + + mychart.clear(); + option.baseOption.visualMap.max=Math.max.apply(Math, avgArr); + mychart.setOption(option,true); + width = $(rootElement).width() - margin.left - margin.right; + height = $(rootElement).height() - margin.top - margin.bottom; + mychart.resize({ + option, + width, + height + }); + return notify.timed('Echarts Map Controller', resp); + }); + + // Automatic resizing of graphics + $scope.$watch( + function () { + width = $(rootElement).width() - margin.left - margin.right; + height = $(rootElement).height() - margin.top - margin.bottom; + mychart.resize({ + width, + height + }); + }, + true + ); + }); + diff --git a/public/echarts_timelinemap_editor.html b/public/echarts_timelinemap_editor.html new file mode 100644 index 0000000..b1f7cd3 --- /dev/null +++ b/public/echarts_timelinemap_editor.html @@ -0,0 +1,7 @@ + +
+ +
diff --git a/public/timeline_map.js b/public/timeline_map.js new file mode 100644 index 0000000..a70d8ac --- /dev/null +++ b/public/timeline_map.js @@ -0,0 +1,4 @@ +import visTypes from 'ui/registry/vis_types'; +define(function (require) { + visTypes.register(require('plugins/timeline_map/echarts_timelinemap')); +}); diff --git a/public/timeline_map.less b/public/timeline_map.less new file mode 100644 index 0000000..e5903c3 --- /dev/null +++ b/public/timeline_map.less @@ -0,0 +1,19 @@ +@import (reference) "~ui/styles/mixins.less"; + +.echart-vis { + width: 100%; + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: space-around; + align-items: center; + align-content: space-around; + + .echart-container { + text-align: center; + padding: 1em; + width:100%; + position:relative; + } + +} \ No newline at end of file