Teach you to make data visualization projects and dynamically simulate flight routes

If you are Xiaobai, this set of information can help you become a big bull. If you have rich development experience, this set of information can help you break through the bottleneck
2022web full set of video tutorial front-end architecture H5 vue node applet Video + data + code + interview questions.

Data visualization Preface: https://blog.csdn.net/diviner_s/article/details/115933789
Final effect drawing of the project:

This blog is a summary and record of the project completed after learning teacher pink. It is only for communication and reference. Copyright, reprint, please mark the original author!
In addition, the technologies included in the project include html, css, js, jQuery, ajax, websocket, koa, etc.

Article catalogue

Simulated flight route

This dynamic simulated flight route shows the dynamic transition map from Zhengzhou to other cities.

What I share today is the dynamic route from Zhengzhou to other regions simulated on "reversing the big earth". Does it look nice!!!

Data preprocessing

The coordinates are attached to a custom Echarts layer object, that is, our Henan layer,

Import this file:
<script src="js/echarts-map-henan.js"></script>

1. Storage of longitude and latitude coordinates of map

Firstly, the coordinates of the ecarts map need to be stored in a geoCoord attribute. It is a JS dictionary object, which is composed of key / value pairs. The key represents the name of the point, and the value represents its coordinates. It is composed of longitude and latitude. It is an array.

    var geoCoordMap = {
      // It consists of key / value pairs: location name / longitude and latitude coordinates
      Shanghai: [121.4648, 31.2891],
      Dongguan: [113.8953, 22.901],
      doy : [118.7073, 37.5513],
      Zhongshan: [113.4229, 22.478],
      Linfen: [111.4783, 36.1615],Linyi: [118.3118, 35.2936],Dandong: [124.541, 40.4242],Lishui: [119.5642, 28.1854],Urumqi: [87.9236, 43.5883],Foshan: [112.8955, 23.1097],Baoding: [115.0488, 39.0948],Lanzhou: [103.5901, 36.3043],Baotou: [110.3467, 41.4899],Beijing: [116.4551, 40.2539],the north sea: [109.314, 21.6211],Nanjing: [118.8062, 31.9208],Nanning: [108.479, 23.1152],Nanchang: [116.0046, 28.6633],Nantong: [121.1023, 32.1625],Xiamen: [118.1689, 24.6478],Taizhou: [121.1353, 28.6688],Hefei: [117.29, 32.0581],Hohhot: [111.4124, 40.4901],Xianyang: [108.4131, 34.8706],Harbin: [127.9688, 45.368],Tangshan: [118.4766, 39.6826],Jiaxing: [120.9155, 30.6354],da tong: [113.7854, 39.8035],Dalian: [122.2229, 39.4409],Tianjin: [117.4219, 39.4189],Taiyuan: [112.3352, 37.9413],Weihai: [121.9482, 37.1393],Ningbo: [121.5967, 29.6466],Baoji: [107.1826, 34.3433],Suqian: [118.5535, 33.7775],Changzhou: [119.4543, 31.5582],Guangzhou: [113.5107, 23.2196],Langfang: [116.521, 39.0509],Yan'an: [109.1052, 36.4252],Zhangjiakou: [115.1477, 40.8527],Xuzhou: [117.5208, 34.3268],Texas: [116.6858, 37.2107],Huizhou: [114.6204, 23.1647],Chengdu: [103.9526, 30.7617],Yangzhou: [119.4653, 32.8162],Chengde: [117.5757, 41.4075],Lhasa: [91.1865, 30.1465],Wuxi: [120.3442, 31.5527],sunshine: [119.2786, 35.5023],Kunming: [102.9199, 25.4663],Hangzhou: [119.5313, 29.8773],Zaozhuang: [117.323, 34.8926],city in Guangxi: [109.3799, 24.9774],Zhuzhou: [113.5327, 27.0319],Wuhan: [114.3896, 30.6628],Shantou: [117.1692, 23.3405],Jiangmen: [112.6318, 22.1484],Shenyang: [123.1238, 42.1216],Cangzhou: [116.8286, 38.2104],Heyuan: [114.917, 23.9722],Quanzhou: [118.3228, 25.1147],Taian: [117.0264, 36.0516],Taizhou: [120.0586, 32.5525],Jinan: [117.1582, 36.8701],Jining: [116.8286, 35.3375],Haikou: [110.3893, 19.8516],Zibo: [118.0371, 36.6064],Huai'an: [118.927, 33.4039],Shenzhen: [114.5435, 22.5439],Qingyuan: [112.9175, 24.3292],Wenzhou: [120.498, 27.8119],Weinan: [109.7864, 35.0299],Huzhou: [119.8608, 30.7782],Xiangtan: [112.5439, 27.7075],Binzhou: [117.8174, 37.4963],Weifang: [119.0918, 36.524],Yantai: [120.7397, 37.5128],Yuxi: [101.9312, 23.8898],Zhuhai: [113.7305, 22.1155],ynz : [120.2234, 33.5577],Panjin: [121.9482, 41.0449],Shijiazhuang: [114.4995, 38.1006],Fuzhou: [119.4543, 25.9222],qinghuangdao: [119.2126, 40.0232],Shaoxing: [120.564, 29.7565],Liaocheng: [115.9167, 36.4032],Zhaoqing: [112.1265, 23.5822],Zhoushan: [122.2559, 30.2234],Suzhou: [120.6519, 31.3989],Laiwu prefecture level city in Shandong: [117.6526, 36.2714],Heze: [115.6201, 35.2057],Yingkou: [122.4316, 40.4297],Huludao: [120.1575, 40.578],Hengshui: [115.8838, 37.7161],Quzhou: [118.6853, 28.8666],Xining: [101.4038, 36.8207],Xi'an: [109.1162, 34.2004],Guiyang: [106.6992, 26.7682],Lianyungang: [119.1248, 34.552],Xingtai: [114.8071, 37.2821],Handan: [114.4775, 36.535],Zhengzhou: [113.4668, 34.6234],erdos: [108.9734, 39.2487],Chongqing: [107.7539, 30.1904],Jinhua: [120.0037, 29.1028],Tongchuan: [109.0393, 35.1947],Yinchuan: [106.3586, 38.1775],Zhenjiang: [119.4763, 31.9702],Changchun: [125.8154, 44.2584],Changsha: [113.0823, 28.2568],CiH : [112.8625, 36.4746],Yangquan: [113.4778, 38.0951],Qingdao: [120.4651, 36.3373],Shaoguan: [113.7964, 24.7028],Aksu Region: [80.2671, 41.1749],Anyang: [114.352482, 36.103442],Hebi: [114.295444, 35.748236],Puyang: [115.041299, 35.768234],Xinxiang: [113.883991, 35.302616],Jiaozuo: [113.238266, 35.23904],Jiyuan: [112.590047, 35.090378],Sanmenxia: [111.194099, 34.777338],Luoyang: [112.434468, 34.663041],Zhengzhou: [113.665412, 34.757975],Kaifeng: [114.341447, 34.797049],Shangqiu: [115.650497, 34.437054],Xu Chang: [113.826063, 34.022956],Pingdingshan: [113.307718, 33.735241],Luohe: [114.026405, 33.575855],Zhoukou: [114.649653, 33.620357],Nanyang: [112.540918, 32.999082],Zhumadian: [114.024736, 32.980169],Xinyang: [114.075031, 32.123274],
    };

2. Route planning

What is planned here is the route for graduates from Zhengzhou to work in other cities (virtual data)
Array [start point end point, number of people]

    //Route start end, number of people
    var XAData = [
      [{ name: "Zhengzhou" }, { name: "Zhengzhou", value: 79 }],
      [{ name: "Zhengzhou" }, { name: "Luoyang", value: 6 }],
      [{ name: "Zhengzhou" }, { name: "Zhoukou", value: 14 }],
      [{ name: "Zhengzhou" }, { name: "Anyang", value: 10 }],
      [{ name: "Zhengzhou" }, { name: "Zhumadian", value: 3 }],
      [{ name: "Zhengzhou" }, { name: "Xinxiang", value: 11 }],
      [{ name: "Zhengzhou" }, { name: "Hebi", value: 15 }],
      [{ name: "Zhengzhou" }, { name: "Kaifeng", value: 3 }],
      [{ name: "Zhengzhou" }, { name: "Pingdingshan", value: 12 }],
      [{ name: "Zhengzhou" }, { name: "Shangqiu", value: 2 }],
      [{ name: "Zhengzhou" }, { name: "Xinyang", value: 6 }],
      [{ name: "Zhengzhou" }, { name: "Xu Chang", value: 21 }],
      [{ name: "Zhengzhou" }, { name: "Jiaozuo", value: 11 }],
      [{ name: "Zhengzhou" }, { name: "Beijing", value: 2 }],
      [{ name: "Zhengzhou" }, { name: "Hangzhou", value: 23 }],
      [{ name: "Zhengzhou" }, { name: "Xiamen", value: 1 }],
      [{ name: "Zhengzhou" }, { name: "Suzhou", value: 12 }],
      [{ name: "Zhengzhou" }, { name: "Wuhan", value: 8 }],
      [{ name: "Zhengzhou" }, { name: "Chongqing", value: 14 }],
      [{ name: "Zhengzhou" }, { name: "Shanghai", value: 22 }],
      [{ name: "Zhengzhou" }, { name: "Shenzhen", value: 18 }],
      [{ name: "Zhengzhou" }, { name: "Huizhou", value: 4 }]
    ];

3. Define convertata array

Note: here, the location name in the route planning is converted into longitude and latitude and stored in the array [longitude and latitude are found in the key value pair in the longitude and latitude array of the map, and the value is found through the key]

// push in line start end place longitude and latitude
    var convertData = function (data) {
      var res = [];
      for (var i = 0; i < data.length; i++) {
        var dataItem = data[i];

        var fromCoord = geoCoordMap[dataItem[0].name];// Longitude and latitude acquisition of starting point
        var toCoord = geoCoordMap[dataItem[1].name];// Acquisition of longitude and latitude of target point
        if (fromCoord && toCoord) { //When both longitude and latitude are sometimes, push the key value pair into the res array
          res.push({
            fromName: dataItem[0].name,//Name of departure place
            toName: dataItem[1].name,//Target location name
            coords: [fromCoord, toCoord],//Store the longitude and latitude of the starting point and the longitude and latitude of the target point in the coords array
            value: dataItem[1].value//Save value
          });
          //res array format [[{fromName: "Zhengzhou"}, {toName: "Zhengzhou"}, {coords: [[113.665412, 34.757975],[113.665412, 34.757975]]}, {value: 79}], [...],...]

        }
      }
      return res;
    };

Special effect settings

The above route consists of three layers:

  • Red line dynamic effects

  • Arrow movement effect

  • Coordinate point effect (ripple effect)

Look at the code diagram:

Overall effect:

For these three layers, we need to use the zlevel function to configure the layer, and the code below has comments.
js code, do not understand the configuration function, see the label behind!

    //Arrow style
    var planePath =
      "path://M482.73408 403.02592a40.96 40.96 0 0 1 59.71968-1.90464l144.81408 144.7936a40.96 40.96 0 1 1-57.91744 57.9584l-115.79392-115.8144-115.95776 115.95776a40.96 40.96 0 0 1-57.91744-57.93792l143.0528-143.0528z";
    //var planePath = 'arrow';
    var color = ["#a6c84c", "#ffa022", "#46bee9 "]; / / color of the route
    var series = [];
    [
      ["Zhengzhou", XAData]
    ].forEach(function (item, i) {
      console.log(item[0])
      series.push(
        {//Red line dynamic effects
          name: item[0] + " Top1",//At this time, item[0] stores Zhengzhou, that is, the name is "Zhengzhou Top1"
          type: "lines",
          zlevel: 1, //Zlevel is used for Canvas layering. Graphs with different zlevel values will be placed in different canvases, and those with large values are above those with small values.
          effect: {
            show: true,//Show special effects
            period: 6,//The period of the animation, in seconds.
            trailLength: 0.7,//The length of the effect's wake. Take the value from 0 to 1. The larger the value, the longer the wake.
            color: "red", //Arrow arrow color
            symbolSize: 3//The marker size at both ends of the line can be specified separately by an array or uniformly by a single
          },
          lineStyle: {
            normal: {
              color: color[i],
              width: 0,// Flight path width  
              curveness: 0.2//The curvature of the edge supports values from 0 to 1. The greater the value, the greater the curvature.
            }
          },
          data: convertData(item[1])
        },
        {//Arrow move dynamic route
          name: item[0] + " Top2",
          type: "lines",
          zlevel: 2,//ditto
          symbol: ["none", "arrow"],//Graphic category of element
          symbolSize: 10,
          effect: {
            show: true,//Show special effects
            period: 6,//The period of the animation, in seconds.
            trailLength: 0,//The length of the effect's wake. Take the value from 0 to 1. The larger the value, the longer the wake.
            symbol: planePath,//The style of the arrow is defined in front.
            symbolSize: 11//This refers to the size of the arrow,
          },
          lineStyle: {
            normal: {
              color: color[i],
              width: 1,// Flight path width  
              opacity: 0.6,
              curveness: 0.2//The curvature of the edge supports values from 0 to 1. The greater the value, the greater the curvature.
            }
          },
          data: convertData(item[1])
        },
        {//Coordinate point effect setting
          name: item[0] + " Top3",
          type: "effectScatter",//Bubble chart with ripple effect animation
          coordinateSystem: "geo",//Use geographic coordinate system
          zlevel: 2,//The control layer is displayed before and after, and the one with large value is above the one with small value (overlay).
          rippleEffect: {//Configuration related to ripple effect.
            brushType: "stroke"//Set to ripple effect
          },
          label: {
            normal: {
              show: false,
              position: "right",
              formatter: "{b}"
            }
          },
          symbolSize: function (val) {
            return 10;
          },
          itemStyle: {
            normal: {
              color: color[i]
            },
            emphasis: {
              areaColor: "#2B91B7"
            }
          },
          data: item[1].map(function (dataItem) {
            return {
              name: dataItem[1].name,
              value: geoCoordMap[dataItem[1].name].concat([dataItem[1].value])
            };
          })
        }
      );
    });

option settings

	var myChart = echarts.init(document.querySelector(".map .chart"));
    var option = {
      tooltip: {//When the mouse is placed on the route, the prompt box is displayed
        trigger: "item",
        formatter: function (params, ticket, callback) {
          if (params.seriesType == "effectScatter") {
            return "city:" + params.data.name + "<br />Number of persons:" + params.data.value[2];
          } else if (params.seriesType == "lines") {
            return (
              params.data.fromName + "---->" + params.data.toName +
              "<br />Number of persons:" + params.data.value
            );
          } else {
            return params.name;
          }
        }
      },
      legend: {//Legend component settings in the lower right corner 
        orient: "vertical",//Layout orientation of legend list
        top: "bottom",
        left: "right",
        data: ["Zhengzhou Top1"],
        textStyle: {
          color: "#fff"
        },
        selectedMode: "multiple"
      },
      geo: {
        map: "henan",//The ecarts library used here is Henan layer!
        label: {
          // emphasis: {
          show: true,
          color: "#fff"
          // }
        },
        // Enlarge the map of Henan by 1.2 times
        zoom: 1.2,
        roam: true,
        // Whether to turn on mouse zoom and pan roaming. Not on by default. If you only want to turn on zoom or pan, you can set it to 'scale' or 'move'. Set true to enable all
        itemStyle: {
          normal: {
            // The background color of the map
            areaColor: "rgba(20, 41, 87,0.6)",
            borderColor: "#195BB9",
            borderWidth: 1
          },
          emphasis: {//Corresponding mouse hover effect
            areaColor: "#2B91B7"
          }
        }
      },
      series: series//The front series array has been configured
    };
    myChart.setOption(option);

Each route has a starting point. The type is lines, and then the effect attribute is added to increase the motion effect. The idea is realized through screen coordinate conversion.

Keywords: Javascript Front-end html Interview echarts

Added by atoboldon on Sun, 20 Feb 2022 22:54:55 +0200