directory

1. Comparison of chart libraries

2. Geojson World map dataset and Chinese translation

3. Implement world map with Highcharts (including detailed code)

Four, the realization of the process of stepping on the pit

5. Exploration and solution of the forbidden click event in Highcharts Legend


During the development of the project, there was a need to mark the corresponding parameters in the corresponding countries on the world map. The final result is shown in the following figure, which is in line with the requirements. I’m going to write down the implementation and some of the problems that I’ve encountered in the process of implementation to release.

1. Comparison of chart libraries

When it comes to the world map, we should quickly think of several chart libraries.

(1) Echarts: This library is familiar to us. ECharts, an open source visualization library using JavaScript, can run smoothly on PC and mobile devices, compatible with most of the current browser (IE8/9/10/11, Chrome, Firefox, Safari, etc.), the underlying dependency on vector graphics library ZRender, Provides intuitive, interactive and highly customizable data visualization charts.

Specific features and related introduction to view website: echarts.apache.org/zh/feature…. “, the introduction is very detailed.

(2) Highcharts: Highcharts is a chart library written in pure JavaScript, which can add interactive charts to Web sites or Web applications in a very simple and convenient way. When writing map-related content this time, I just know that Highcharts series software includes Highcharts JS, Highstock JS and Highmaps JS, all of which are PURE HTML5 chart libraries written in JavaScript.

Very good to use, but it is part of the function to charge, before use to let the company to help you buy the corresponding function for commercial use.

Similarly, specific to view the content of the website: www.highcharts.com.cn/docs/start-…

(3) G2: G2 is a set of graphical syntax based on visual coding. It is data-driven and has a high degree of ease of use and extensibility. Users do not need to pay attention to various tedious implementation details, and a variety of interactive statistical charts can be constructed by a single statement.

Specific content can be viewed on the official website: www.yuque.com/antv/g2-doc…

(4) D3: d3.js is a JavaScript library based on data manipulation documents. D3 helps you bring your data to life using HTML, SVG, and CSS. D3’s emphasis on Web standards gives you the full power of a modern browser without tying yourself to a proprietary framework, combining powerful visual components and a data-driven approach to DOM manipulation.

For details, see the official website: d3js.org/

Comparison of chart libraries:

www.cnblogs.com/duole/p/110… This article summarizes nearly 20 chart libraries

DataV AntV Echarts Highcharts D3js
features (1) DataV is a Vue based data visualization component library (also available in React version of course) (2) provides SVG borders and decorations for improving the visual effect of pages (3) provides common charts such as line charts, etc (1) AntV is a new generation of data visualization solution for Ant Financial, which is committed to providing a set of simple, convenient, professional, reliable and unlimited best practices for data visualization. (2) G2 itself is a graph grammar, the simplicity and flexibility is that after you learn this grammar, you can get what you think and express it in a graph. His difficulty is that simplicity and flexibility are built upon learning the grammar, and G2 is not positioned as an out-of-the-box framework. ECharts is a pure Javascript chart library that runs smoothly on PC and mobile devices and is compatible with most current browsers (IE8/9/10/11, Chrome, Firefox, Safari, etc.). The bottom layer relies on the lightweight Canvas class library ZRender, which provides intuitive, vivid, interactive and highly personalized data visualization charts. Make data visualization more simple and compatible with IE6+, perfect support for mobile terminal, rich chart type, convenient and fast HTML5 interactive chart library D3js is a JavaScript library that can manipulate documents based on data. It helps you display data using HTML, CSS, SVG and Canvas. D3 follows existing Web standards, runs independently in modern browsers without the need for any other framework, and combines powerful visual components to drive DOM operations. D3.js is a free JavaScript library that helps you create images using data. The tool enables you to connect arbitrary data to the document Object Model (DOM) and then apply data-driven transformations to the document. Through the DOM programming API, programmers can access documents as objects.
The official address datav.jiaminghi.com/guide/ antv.vision/zh Echarts.apache.org/zh/index.ht… www.highcharts.com.cn/docs/how-to… d3js.org/
Charge is Ali free Ali Department free Baidu open source free For commercial use in the United States, there is a fee free

2. Geojson World map dataset and Chinese translation

The official data set address provided by Highcharts is img.hcharts.cn/mapdata/

How to use data sets and data set field parsing? www.highcharts.com.cn/docs/mapdat…

As mentioned above, Highcharts series software includes three software: Highcharts JS, Highstock JS and Highmaps JS. When implementing maps, use Highmaps, a charting plugin for maps that inherits from Highcharts. In addition to displaying geographic area color blocks based on values, Highmaps supports other geographic elements such as line segments (which can represent roads, rivers, and so on), points (cities, points of interest, and so on).

Using Highmaps:www.highcharts.com.cn/docs/highma…

Introduction of Highcharts scheme: www.highcharts.com.cn/docs/instal…

(1) What is Geojson data? (introduced from mp.weixin.qq.com/s/gBkQi1dV3… , this article is very detailed, you can directly jump to the article to see the relevant content)

  1. Geojson is used to express and store geographic data in JSON syntax. It is a subset of JSON, but it is not used exclusively for JS.
  2. A map has geographic information about mountains, rivers, oceans and so on. Then how to describe a river? At this point, use the geoJSON format file to depict.
  3. Geojson is not necessary. Geojson is just a set of specifications that various parsers use to parse and generate the corresponding scenery. We can make our own specifications to achieve this, but it is not compatible and we need to write our own rendering parsers.

(2) Detailed introduction of Geojson?

1. Basic structure

{// We can include dots, lines, and surface, a large collection "type": "FeatureCollection", // we can define this as a geoJSON file, and we can use other values here.Copy the code

Later on we see a line like “Type “: “FeatureCollection” that indicates that this file is a GeoJSON specification file

2. Describe the dot data on a Feature map

{"type": "FeatureCollection", "features": [{"type": "Feature", // indicates that the object is an element "properties": {}, // coordinates: {// coordinates: {// coordinates: {// coordinates: {// coordinates: {// coordinates: [105.380859375, 31.57853542647338] // The default value is longitude and latitude.Copy the code

3. Describe ** benefits in the recollection of several points

  1. Writing concise
  2. These point styles can be shared
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": Coordinates "MultiPoint", // MultiPoint, that is, to draw several consecutive points of the same shape "coordinates": [[105.380859375, 31.57853542647338], [105.580859375, 31.52853542647338]]}},]}Copy the code

4. Describe a line (LineString)

  1. I’m going to draw each of these points, but they’re going to join together to form a line
  2. Line data on the map
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": "LineString", // here all the points will join together to form a line "coordinates": [105.6005859375, 30.65681556429287], [107.95166015624999, 31.98944183792288], [109.3798828125, 30.031055426540206], [107.7978515625, 29.935895213372444]]}},]}Copy the code

5. MultiLineString description

  1. Here the second and the first lines, they can be separated and they don’t go end to end.
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": "MultiLineString", "coordinates": [[105.6005859375, 30.65681556429287], [107.95166015624999, 31.98944183792288], [109.3798828125, 30.031055426540206], [107.7978515625, 29.935895213372444], [109.3798828125, 30.031055426540206], [107.1978515625, 31.235895213372444]]]}},]}Copy the code

6. Describe a Polygon

  1. The first point and the last point must be the same in order to complete the closed loop!!
  2. The format of a 3d array needs to be noticed
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": "Polygon", // notice here is the three-dimensional array "coordinates": [[106.10595703125, 33.33970700424026], [106.32568359375, 32.41706632846282], [108.03955078125, 32.2313896627376], [108.25927734375, 33.15594830078649], [106.10595703125, 33.33970700424026]]}},]}Copy the code

7. Polygon inside a Face

  1. A single ‘Polygon’ with multiple shapes in it will appear hollow, like a Boolean operation, so that the circled countries can be described on a map
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": "Polygon", "coordinates": [[-39.7265625, -3.162455530237848], [127.96875, -3.162455530237848], [127.96875, 74.1160468394894], [-39.7265625, 74.1160468394894], [-39.7265625, -3.162455530237848], [-22.5, 15.961329081596647] [110.74218749999999, 15.961329081596647], [70.8446726342528], [-22.5, 70.8446726342528], [-22.5, 15.961329081596647]]]}}]}Copy the code

The effect is as follows:

8. Describe the advantages of MultiPolygon:

  1. Writing concise
  2. These point styles can be shared
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": "MultiPolygon", "coordinates": [[[[-39.7265625, -3.162455530237848, [127.96875, -3.162455530237848], [127.96875, 74.1160468394894], [-39.7265625, 74.1160468394894], [-39.7265625, -3.162455530237848], [[-22.5, 15.961329081596647], [110.74218749999999, 15.961329081596647], [70.8446726342528], [-22.5, 70.8446726342528], [-22.5, 15.961329081596647]]]]}}]}Copy the code

If it overlaps, the color is overlaid, as shown in the figure below:

9. Describing a group (Geometries)

  1. For example, if we want to represent a particular landscape then we can make that landscape data independent
{"type": "FeatureCollection", "features": [{// Can include points, lines, a separate collection "type": "GeometryCollection", "geometries": {"coordinates": "coordinates", "coordinates": [108.62, 31.02819]}, {"coordinates": "coordinates", "coordinates": [108.62, 31.02819]}, {"coordinates": "coordinates", "coordinates": [[108.896484375, 30.1071178870], [108.2184375, 30.91717870], [109.5184375, 31.2175780]]}]}Copy the code

10. Different properties

{" type ":" FeatureCollection ", "the features" : [{" type ":" Feature ", "properties" : {/ / special attribute "stroke" : "#fa9661", // Width: 4.1; // Width: 0.7; // Opacity: 0.7; "#9e290c", // fill color "fill-opacity": 0.7 // fill color opacity}, "coordinates": {"type": "Point", // paint "coordinates": [105.380859375, 31.57853542647338]}},]}Copy the code

3. Implement world map with Highcharts (including detailed code)

ECharts Demo:blog.csdn.net/wangcunhuaz implementation map…

Someone else’s implementation Demo (to record creating a world map with Highmaps) : blog.csdn.net/qq_42282789…

Ge.json rendering of maps in Echarts: juejin.cn/post/697123…

Used in the Vue Highcharts:blog.jianshukeji.com/highcharts/…

Highcharts – Highmaps dynamic incoming city name: www.bbsmax.com/A/A2dmZGABz…

Highcharts achieve official DEMO:jshare.com.cn/mapdata/CN4 world map…

Chinese translation of country names in the Geojson World map data set provided by Highcharts

Among them, the country name I need to show is Chinese, but many data sets are all English, so the country name is translated in a unified way, mainly according to the language translation package provided by ** for comparison processing. If you need this document, please contact me.

Translation resources are as follows:

World map specific implementation code:

HTML code:

<! <div id="container"> <div id="container">Copy the code

Js code:

Import template from './ template-. HTML 'import './style.less' // Import {WORLDDATA} from './world' import Highmaps from 'highcharts/modules/map' Highmaps(window.highcharts) let  WorldMapComponent = { name: 'worldmap', props: { worldMapData: { type: Array, default: function () { return {} } } }, data () { return { worldData: WORLDDATA } }, watch: { worldMapData (data) { this.initMapData(data) } }, methods: { initMapData (resData) { var mapdata = this.worldData var data = [] resData.length && resData.forEach(element => { mapdata.features.length && mapdata.features.forEach(md => { if (mapdata.features) { if (element.geo.includes(md.properties['name'])) { let color = '' switch (element.level) { case 'a': color = '#67cc02' break case 'b': color = '#ffe100' break case 'c': color = '#fab011' break case 'd': color = '#ff523f' break } data.push({ 'hc-key': md.properties['hc-key'], value: element.counts, color: $('#container').highcharts('Map', {mapNavigation: {enabled: true, buttonOptions: {mapNavigation: {enabled: true, buttonOptions: {verticalAlign: 'bottom'}}, colorAxis: {verticalAlign: 'bottom'}}, // stops: [/ / [0, window. Highcharts. GetOptions (.) colors [5]], / / [0.5, Windows. Highcharts. GetOptions (.) colors [4]], [0.75, / / window.Highcharts.getOptions().colors[3]], // [1, window.Highcharts.getOptions().colors[13]] // ] dataClasses: [{ from: -1, to: 0, color: '#67cc02', name: 'a' }, { from: 0, to: 1, color: '#ffe100', name: 'b' }, { from: 2, to: 3, name: 'c', color: '#fab011' }, { from: 3, to: 4, name: 'd, color: '#ff523f' }] }, tooltip: { formatter: function () { let str = '' this.point.colorArr.forEach((item, Index) => {console.log(item) // eslint-disable-next-line STR += '<span style="color: ${item}"> ${this.point. ValueArr [index]}</b><br> '}) // eslint-disable-next-line return 'location: <b>${this.point. Name}</b><br>${STR} '}}, title: {text: null}, // Remove the watermark of highcharts credits: {enabled: false }, series: [{ data: data, mapData: mapdata, joinBy: 'hc-key', name: 'abcd', states: { hover: { color: '#a4edba' } }, dataLabels: { enabled: false, format: '{point.name}' } }] }) } }, template } WorldMapComponent.install = function (Vue) { Vue.component(this.name, WorldMapComponent) } export default WorldMapComponentCopy the code

Four, the realization of the process of stepping on the pit

Error: Uncaught Error: Highcharts Error #16

Solution reference: blog.csdn.net/w926498/art…

Uncaught TypeError: (Intermediate value)(intermediate value)(…) Is not a funtion: solution reference: blog.csdn.net/xubuhui/art…

(3) After the implementation of the world map, there is no problem in the local operation, but when deployed online, there is an error:

Uncaught TypeError: Array.prototype.forEach called on null or undefined at highcharts.js
Copy the code

At that time, however, from the error report, I thought that empty data was not processed, so I processed all the places involving the array, redeployed, and the result was the same error.

Finally, it was found that the problem was highcharts version. The local version was 6.2.0, but the online version was 6.0.7 after the deployment. The online version was replaced, and the problem was solved.

(4) Legend changed from long to round

// control legend colorAxis: {// control legend is a gradient // min: 0, // stops: [/ / [0, window. Highcharts. GetOptions (.) colors [5]], / / [0.5, Windows. Highcharts. GetOptions (.) colors [4]], [0.75, / / window.Highcharts.getOptions().colors[3]], // [1, window.Highcharts.getOptions().colors[13]] // ] dataClasses: [{ from: -1, to: 0, color: '#67cc02', name: 'low risk'}, {from: 0, to: 1, color: '#ffe100', name: 'mid risk'}, {from: 2, to: 3, name: 'mid risk'}, 'high-risk' color: '# fab011'}, {the from: 3,, 4, name: 'crisis', color:' # ff523f '}},Copy the code

(5) The watermark of Highcharts is not displayed:

// Remove watermark from highcharts credits: {enabled: false},Copy the code

5. Exploration and solution of the forbidden click event in Highcharts Legend

I didn’t notice this before, but there was a bug in the test. Indeed, after doing this, clicking on the legend below, only the image corresponding to the click will be dimmed, but nothing will change on the icon, which is definitely not a good idea.

How to solve this problem, I explored for a long time. The initial direction was how to relate to the data in the chart and make corresponding changes after clicking, so I watched a lot of demo from the official website.

Such as this: www.highcharts.com.cn/demo/highma… I didn’t do anything special with the demo name, so clicking on the little circle will change the UI.

And this: jshare.com.cn/highmaps/hh…

And this: jshare.com.cn/highmaps/I4…

I noticed that they didn’t do a separate special treatment, so I probably don’t have to do it here. But mine didn’t work.

And then I realized that I had a different set of properties than I had in the previous demos. This is a reworked map of the world.

I this figure prototype is like this: www.highcharts.com.cn/demo/highma…

The legend is obviously not the same as the one I’m using now, and in the image above, the world map does not change after clicking on the legend. Now I have a legend of the dot with the following code added. So far, THAT’s what I think it is.

Coloryellow: [{name: 'critical ', color: '#ff523f'}, {name:' critical ', color: '#ff523f'}, {name: 'critical ', color: '#fab011'}, {color: '# ffe100' name: 'moderate'}, {color: # 67 cc02, name: 'low-risk'}},Copy the code

At this point I changed direction, can you control the legend, can’t trigger the click event. Indeed, there is an API for this problem, legendItemClick. It is used in both the official website and many people’s introduction, but it is not effective after I add it.

That’s what most people do, but mine didn’t work.

PlotOptions: {series: {events: {legendItemClick: Function (even){return false //return trueCopy the code

There is also an official legendItemClick event for colorAxis, but the same is true. It wasn’t in effect when I dealt with it. The official is introduced: api.highcharts.com/highcharts/…

Now this problem is finally solved, is to see some students define the method, gave me inspiration, the introduction of students such as the link: blog.csdn.net/weixin_4386…

When I used it, it worked, preventing the event from triggering.

/ / custom Legend event window. Highcharts. Wrap (window. Highcharts. Legend. Prototype, 'renderItem', function (proceed, item) { proceed.call(this, Item) var element = item.legendgroup.element = function() {return false}})Copy the code

Looked at the official website, the original is to provide a secondary extension of an API.

Refunction with Prototype

JavaScript is very powerful at dynamically changing the behavior of scripts. Within Highcharts we created a utility function, wrap, which adds its own business code before or after the execution of the existing prototype function. Its construction and parameters are described as follows:

Highcharts.wrap(object obj, String methodName, function callback)

  • Obj: The parent object of the function to be encapsulated
  • MethodName: the function name
  • Callback: callback function

Where the original function is passed to the wrapper function as the first argument, and the other arguments to the original function are passed to the wrapper function after the first argument. Here is the sample code:

H.wrap(H.Series.prototype, 'drawGraph', Function (proceed) {console. Log ("We are about to draw the graph: ", this.graph); / / perform the original function (proceed), the arguments for the primitive function parameters (the first parameter is the original function) proceed. Apply (this, Array. Prototype. Slice. The call (the arguments, 1)); Console. log("We just finished drawing the graph: ", this.graph); });Copy the code