OpenLayers在地图上显示统计图,饼图线状图柱状图,修复统计图跳动的问题
Openlayers | ol.js | v5.3.0 |
Highcharts | highcharts.js | v7.0.1 |
jquery | jquery-3.3.1.js | v3.3.1 |
显示效果
地图放大缩小对统计图的大小无影响
以饼状图为例
1、添加地图,并渲染统计图所在的点位,
vector是渲染feature需要用的图层,一定要保证在所有图层的最前方,否则渲染的feature会被遮盖,(地图量算时由于这个问题搞了一上午)
sourceMeasure = new ol.source.Vector({ wrapX: false }); vector = new ol.layer.Vector({ source: sourceMeasure, style: new ol.style.Style({ fill: new ol.style.Fill({ color: 'rgba(255, 255, 0, 0.2)' }), stroke: new ol.style.Stroke({ color: '#ffcc33', width: 2 }), image: new ol.style.Circle({ radius: 7, fill: new ol.style.Fill({ color: '#ffaa33' }) }) }) }); map = new ol.Map({ controls: ol.control.defaults({ attribution: false }), target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }), vector ], view: new ol.View({ projection: 'EPSG:3857', center: ol.proj.transform([121, 37], 'EPSG:4326', 'EPSG:3857'), //center: [121, 37], zoom: 6 }) }); DrawPoint();
2、画点的方法
function DrawPoint() { for (var i = 0; i < dataPie.length; i++) { var d = dataPie[i]; var pt = ol.proj.transform([d.x, d.y], 'EPSG:4326', 'EPSG:3857'); var point = new ol.geom.Point(pt); var feature = new ol.Feature(point); sourceMeasure.addFeature(feature); } }
3、添加统计图
下面是原始的方法,可以显示统计图,但是初始位置不对,但是稍微拖动下地图,位置又跳到对的位置了,没找到问题,换成了后面的方法2
//方法1
//$("#addPieChart").on("click", function () { // clearChartOverlay(); // for (var i = 0; i < dataPie.length; i++) { // var d = dataPie[i]; // var pt = ol.proj.transform([d.x, d.y], 'EPSG:4326', 'EPSG:3857'); // var domid = "chart" + guid(); // $("#chart").append("<div id='" + domid + "'></div>"); // var chart = new ol.Overlay({ // id: domid, // position: pt, // positioning: "bottom-center", // element: document.getElementById(domid), // offset: [0, 18], // stopEvent: false //overlay也支持滚珠放大缩小 // }); // map.addOverlay(chart); // addPieChart(domid, d, 100); // overlayId.push(domid); // } //});
可能是因为对Overlay的element做了设置解决的这个问题,比较玄学
//方法2
$("#addPieChart").on("click", function () { clearChartOverlay(); for (var i = 0; i < dataPie.length; i++) { var d = dataPie[i]; var pt = ol.proj.transform([d.x, d.y], 'EPSG:4326', 'EPSG:3857'); var domid = "chart" + guid(); $("#chart").append("<div id='" + domid + "'></div>"); addPieChart(domid, d, 100); var chart = new ol.Overlay({ id: domid, element: document.getElementById(domid), positioning: "bottom-center", //统计图和渲染点位的位置关系 offset: [0, 18],//如果统计图相对于点位又偏移,可以通过此属性将统计图移回来 stopEvent: false //overlay也支持滚珠放大缩小 }); map.addOverlay(chart); var element = chart.getElement(); chart.setPosition(pt); //使用下面的方法显示Overlay,可避免初始位置不对,拖动一下地图跳动的问题 $(element).popover({ placement: 'top', animation: false }); $(element).popover('show'); overlayId.push(domid); } });
移除所有用来显示统计图的Overlay,和饼图的方法,highcharts里很多,想要别的风格可以去看highcharts的api
/** * 移除统计图所使用的Overlay * */ function clearChartOverlay() { for (var i = 0; i < overlayId.length; i++) { map.removeOverlay(map.getOverlayById(overlayId[i])); } } function addPieChart(domid, data, size) { $('#' + domid).highcharts({ chart: { backgroundColor: 'rgba(255, 255, 255, 0)', plotBorderColor: null, plotBackgroundColor: null, plotBackgroundImage: null, plotBorderWidth: null, plotShadow: false, width: size, height: size }, tooltip: { pointFormat: '<b>{point.percentage:.1f}%</b>' }, credits: { enabled: false }, title: { text: '' }, plotOptions: { pie: { dataLabels: { enabled: false } } }, series: [{ type: 'pie', name: data.name, data: data.data }] }); }
4、差不多就这么多,线状图和柱状图都类似,下面是完成代码
html
@{ ViewBag.Title = "StatisticalChart"; Layout = "~/Views/Shared/_Layout.cshtml"; } @Styles.Render("~/Content/openlayers") <div id="map" class="map"> </div> <div class="tool"> <button id="addPieChart">添加饼图</button> <button id="addLineChart">添加线状图</button> <button id="addColumnChart">添加柱状图</button> </div> <div style="display: none;" id="chart"> </div> @Scripts.Render("~/bundles/openlayers") <script src="~/Scripts/openlayers/MapStatisticalChart.js"></script> <script src="~/Scripts/Highcharts/highcharts.js"></script> <script type="text/javascript"> $(document).ready(function () { init(); }); </script>
js
/* *地图上显示统计图 */ //地图渲染的两个对象 var vector; var sourceMeasure; //x,y表示渲染的位置,如果是点图层好说,如果是面或者线,需要获取中心点 var overlayId = []; var dataPie = [{ name: "乌鲁木齐", x: 87.5758285931, y: 43.7822116460, data: [ { name: '男', y: 40.0, color: "#5ab1ef" }, { name: '女', y: 60.0, color: "#d87a80" } ] }, { name: "拉萨", x: 91.1629975040, y: 29.7104204643, data: [ { name: '男', y: 45.0, color: "#5ab1ef" }, { name: '女', y: 55.0, color: "#d87a80" } ] }, { name: "北京", x: 116.4575803581078, y: 40.04054437977018, data: [ { name: '男', y: 35.0, color: "#5ab1ef" }, { name: '女', y: 65.0, color: "#d87a80" } ] }, { name: "兰州", x: 103.584297498, y: 36.1190864503, data: [ { name: '男', y: 44.0, color: "#5ab1ef" }, { name: '女', y: 56.0, color: "#d87a80" } ] }]; var map; function init() { sourceMeasure = new ol.source.Vector({ wrapX: false }); vector = new ol.layer.Vector({ source: sourceMeasure, style: new ol.style.Style({ fill: new ol.style.Fill({ color: 'rgba(255, 255, 0, 0.2)' }), stroke: new ol.style.Stroke({ color: '#ffcc33', width: 2 }), image: new ol.style.Circle({ radius: 7, fill: new ol.style.Fill({ color: '#ffaa33' }) }) }) }); map = new ol.Map({ controls: ol.control.defaults({ attribution: false }), target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }), vector ], view: new ol.View({ projection: 'EPSG:3857', center: ol.proj.transform([121, 37], 'EPSG:4326', 'EPSG:3857'), //center: [121, 37], zoom: 6 }) }); DrawPoint(); $("#addPieChart").on("click", function () { clearChartOverlay(); for (var i = 0; i < dataPie.length; i++) { var d = dataPie[i]; var pt = ol.proj.transform([d.x, d.y], 'EPSG:4326', 'EPSG:3857'); var domid = "chart" + guid(); $("#chart").append("<div id='" + domid + "'></div>"); addPieChart(domid, d, 100); var chart = new ol.Overlay({ id: domid, element: document.getElementById(domid), positioning: "bottom-center", offset: [0, 18], stopEvent: false //overlay也支持滚珠放大缩小 }); map.addOverlay(chart); var element = chart.getElement(); chart.setPosition(pt); //使用下面的方法显示Overlay,可避免初始位置不对,拖动一下地图跳动的问题 $(element).popover({ placement: 'top', animation: false }); $(element).popover('show'); overlayId.push(domid); } }); $("#addLineChart").on("click", function () { clearChartOverlay(); for (var i = 0; i < dataLine.length; i++) { var d = dataLine[i]; var pt = ol.proj.transform([d.x, d.y], 'EPSG:4326', 'EPSG:3857'); var domid = "chart" + guid(); //$("#chart").append("<div id='" + domid + "'></div>"); //var chart = new ol.Overlay({ // id: domid, // position: pt, // positioning: "bottom-center", // element: document.getElementById(domid), // stopEvent: false //overlay也支持滚珠放大缩小 //}); //map.addOverlay(chart); //addLineChart(domid, d.data, 200, 150); //overlayId.push(domid); $("#chart").append("<div id='" + domid + "'></div>"); var chart = new ol.Overlay({ id: domid, positioning: "bottom-center", element: document.getElementById(domid), stopEvent: false //overlay也支持滚珠放大缩小 }); map.addOverlay(chart); addLineChart(domid, d.data, 200, 150); var element = chart.getElement(); chart.setPosition(pt); //使用下面的方法显示Overlay,可避免初始位置不对,拖动一下地图跳动的问题 $(element).popover({ placement: 'top', animation: false }); $(element).popover('show'); overlayId.push(domid); } }); $("#addColumnChart").on("click", function () { clearChartOverlay(); for (var i = 0; i < dataColumn.length; i++) { var d = dataColumn[i]; var pt = ol.proj.transform([d.x, d.y], 'EPSG:4326', 'EPSG:3857'); var domid = "chart" + guid(); $("#chart").append("<div id='" + domid + "'></div>"); var chart = new ol.Overlay({ id: domid, positioning: "bottom-center", element: document.getElementById(domid), offset: [0, 5], stopEvent: false //overlay也支持滚珠放大缩小 }); map.addOverlay(chart); addColumnChart(domid, d.data, 80, 80); var element = chart.getElement(); chart.setPosition(pt); //使用下面的方法显示Overlay,可避免初始位置不对,拖动一下地图跳动的问题 $(element).popover({ placement: 'top', animation: false }); $(element).popover('show'); overlayId.push(domid); } }); } /** * 移除统计图所使用的Overlay * */ function clearChartOverlay() { for (var i = 0; i < overlayId.length; i++) { map.removeOverlay(map.getOverlayById(overlayId[i])); } } function addPieChart(domid, data, size) { $('#' + domid).highcharts({ chart: { backgroundColor: 'rgba(255, 255, 255, 0)', plotBorderColor: null, plotBackgroundColor: null, plotBackgroundImage: null, plotBorderWidth: null, plotShadow: false, width: size, height: size }, tooltip: { pointFormat: '<b>{point.percentage:.1f}%</b>' }, credits: { enabled: false }, title: { text: '' }, plotOptions: { pie: { dataLabels: { enabled: false } } }, series: [{ type: 'pie', name: data.name, data: data.data }] }); } var dataLine = [{ name: "乌鲁木齐", x: 87.5758285931, y: 43.7822116460, data: [ { name: '安装,实施人员', series: [ { x: 2010, y: 1234 }, { x: 2011, y: 1234 } ], color: "#5ab1ef" }, { name: '工人', series: [ { x: 2010, y: 245 }, { x: 2011, y: 3454 } ], color: "#d87a80" } ] }, { name: "拉萨", x: 91.1629975040, y: 29.7104204643, data: [ { name: '安装,实施人员', series: [ { x: 2010, y: 1234 }, { x: 2011, y: 124 }, { x: 2012, y: 0 } ], color: "#5ab1ef" }, { name: '工人', series: [ { x: 2010, y: 245 }, { x: 2011, y: 0 }, { x: 2012, y: 3454 } ], color: "#d87a80" } ] }]; function addLineChart(domid, data, width, height) { var categoriesX = []; var seriesValue = []; for (var i = 0; i < data.length; i++) { var value = []; for (var j = 0; j < data[i].series.length; j++) { categoriesX.push(data[i].series[j].x); value.push(data[i].series[j].y); } seriesValue.push({ "name": data[i].name, "data": value }); } $('#' + domid).highcharts({ chart: { backgroundColor: 'rgba(255, 255, 255, 0.8)', borderRadius: 20, plotBorderColor: null, plotBackgroundColor: null, plotBackgroundImage: null, plotBorderWidth: null, plotShadow: false, width: width, height: height }, credits: { enabled: false }, title: { text: '' }, yAxis: { visible: false, title: { text: '' } }, xAxis: { categories: categoriesX, crosshair: true }, legend: { enabled: false }, plotOptions: { series: { label: { connectorAllowed: false } }, line: { dataLabels: { enabled: true, formatter: function () { return '<b>' + this.point.y + '</b><br>'; } } } }, series: seriesValue, responsive: { rules: [{ condition: { maxWidth: 500 }, chartOptions: { legend: { layout: 'horizontal', align: 'center', verticalAlign: 'bottom' } } }] } }); } var dataColumn = [{ name: "乌鲁木齐", x: 87.5758285931, y: 43.7822116460, data: [ { name: '安装,实施人员', series: [ { x: 2011, y: 1234 } ], color: "#5ab1ef" }, { name: '工人', series: [ { x: 2011, y: 3454 } ], color: "#d87a80" } ] }, { name: "拉萨", x: 91.1629975040, y: 29.7104204643, data: [ { name: '安装,实施人员', series: [ { x: 2012, y: 123 } ], color: "#5ab1ef" }, { name: '工人', series: [ { x: 2012, y: 3454 } ], color: "#d87a80" } ] }, { name: "北京", x: 116.4575803581078, y: 40.04054437977018, data: [ { name: '安装,实施人员', series: [ { x: 2014, y: 252 } ], color: "#5ab1ef" }, { name: '工人', series: [ { x: 2014, y: 324 } ], color: "#d87a80" } ] }, { name: "兰州", x: 103.584297498, y: 36.1190864503, data: [ { name: '安装,实施人员', series: [ { x: 2013, y: 2341 } ], color: "#5ab1ef" }, { name: '工人', series: [ { x: 2013, y: 2341 } ], color: "#d87a80" } ] }]; function addColumnChart(domid, data, width, height) { var categoriesX = []; var seriesValue = []; for (var i = 0; i < data.length; i++) { var value = []; for (var j = 0; j < data[i].series.length; j++) { categoriesX.push(data[i].series[j].x); value.push(data[i].series[j].y); } seriesValue.push({ "name": data[i].name, "data": value }); } $('#' + domid).highcharts({ chart: { backgroundColor: 'rgba(255, 255, 255, 0)', borderRadius: 20, plotBorderColor: null, plotBackgroundColor: null, plotBackgroundImage: null, plotBorderWidth: null, plotShadow: false, width: width, height: height, type: 'column' }, credits: { enabled: false }, title: { text: '' }, yAxis: { visible: false, title: { text: '' } }, xAxis: { visible: false, categories: categoriesX, crosshair: true }, legend: { enabled: false }, plotOptions: { series: { label: { connectorAllowed: false } }, line: { dataLabels: { enabled: true, formatter: function () { return '<b>' + this.point.y + '</b><br>'; } } } }, series: seriesValue, responsive: { rules: [{ condition: { maxWidth: 500 }, chartOptions: { legend: { layout: 'horizontal', align: 'center', verticalAlign: 'bottom' } } }] } }); } function DrawPoint() { for (var i = 0; i < dataPie.length; i++) { var d = dataPie[i]; var pt = ol.proj.transform([d.x, d.y], 'EPSG:4326', 'EPSG:3857'); var point = new ol.geom.Point(pt); var feature = new ol.Feature(point); sourceMeasure.addFeature(feature); } }
引用的资料包括:https://blog.csdn.net/gisshixisheng/article/details/50926948,https://blog.csdn.net/henrystern/article/details/81149015