echarts 风向 风速曲线

数据格式1效果

 数据格式2效果

 数据格式2  真实数据(每半小时一个数据)效果

 

 vue.js项目该部分源代码:

  <div id="windspeedandDirection" style="100%"></div>
  this.initWindspeedandDirection("windspeedandDirection",data);
      initWindspeedandDirection(id,data){
            let chartElement = document.getElementById(id);
            chartElement.style.height = '260px';
            let chart = echarts.init(chartElement);
            chart.dispose();
            chart = echarts.init(chartElement);
            //数据格式1
            // var data2 = [
            //     [
            //         1483488000000, //时间戳
            //         6.19,//风速
            //         159.4 //角度
            //     ],
            //     [
            //         1483574400000,
            //         6.19,
            //         8.31
            //     ],
            //     [
            //         1483660800000,
            //         3.19,
            //         37.77
            //     ],
            //     [
            //         1483747200000,
            //         6.19,
            //         340
            //     ],
            //     [
            //         1483833600000,
            //         6.19,
            //         79.235
            //     ],
            //     [
            //         1483920000000,
            //         11.19,
            //         286.8
            //     ],
            //     [
            //         1484006400000,
            //         17.19,
            //         193.71
            //     ]
            // ];
            //数据格式2
            // var data2 = [
            //     [
            //         '2020-9-1 13:15:31', //年月日时分秒
            //         6.19,//风速
            //         159.4 //角度
            //     ],
            //     [
            //         '2020-9-1 14:15:31',
            //         6.19,
            //         8.31
            //     ],
            //     [
            //         '2020-9-1 15:15:31',
            //         3.19,
            //         37.77
            //     ],
            //     [
            //         '2020-9-1 16:15:31',
            //         6.19,
            //         340
            //     ],
            //     [
            //         '2020-9-1 17:15:31',
            //         6.19,
            //         79.235
            //     ],
            //     [
            //         '2020-9-1 18:15:31',
            //         11.19,
            //         286.8
            //     ],
            //     [
            //         '2020-9-1 19:15:31',
            //         17.19,
            //         193.71
            //     ]
            // ];

           

            //只显示小时和分钟数据 方式1  同时设置xAxis type: 'category'
            let data2 =data.map(function (item) {
                    return [item['TIMESTAMP'],item['WS_Avg'],item['WD']];
             });
             //只显示小时和分钟数据 方式2  同时设置xAxis type: 'category',问题:formatTime只返回小时和分钟部分,但X轴重复会出现曲线首尾相连。
            // let data2 =data.map(function (item) {
            //         return [util.formatTime (new Date(item['TIMESTAMP'])),item['WS_Avg'],item['WD']];
            //  });
            //只显示小时和分钟数据 方式3  同时设置xAxis type: 'time',  tooltip-formatter方法,缺点X轴设置为time类型,时间间隔无法控制。
             console.log(id,data,data2);
           
  

            //console.log('data',data)
            //console.log('data2',data2)
            //dims对象保存数组的维度,方便从data数组中取数据
            var dims = {
                time: 0, //时间的维度是0
                windSpeed: 1,//风速的维度是1
                R: 2 //角度(0-360)的维度是2
            };
            let that=this;
            var option = {
                tooltip: {
                    trigger: 'axis',
                    // formatter: function (params) { //时间戳转年月日
                    //     return [
                    //         echarts.format.formatTime('yyyy-MM-dd', params[0].value[dims.time])
                    //         + ' ' + echarts.format.formatTime('hh:mm', params[0].value[dims.time]),
                    //         '风速:' + params[0].value[dims.windSpeed],
                    //         '风向:' + params[0].value[dims.R]
                    //     ].join('<br>');
                    // }
                    formatter: function (params) {
                        return [
                           params[0].value[dims.time],
                            '风速(m/s):' + params[0].value[dims.windSpeed],
                            '风向(度):' + params[0].value[dims.R],
                            '风向:' + util.formatWindDirection(params[0].value[dims.R])
                        ].join('<br>');
                    }
            
                },
                grid: {
                    top: 50,
                    left: 45,
                    right: '4%',
                    bottom: '2%',
                    containLabel: true
                },
                xAxis: {
                    /*
                       ecnarts文档-配置项: xAxis. type 
                        坐标轴类型。
                        可选:
                        'value' 数值轴,适用于连续数据。
                        'category' 类目轴,适用于离散的类目数据。为该类型时类目数据可自动从 series.data 或 dataset.source 中取,或者可通过 xAxis.data 设置类目数据。
                        'time' 时间轴,适用于连续的时序数据,与数值轴相比时间轴带有时间的格式化,在刻度计算上也有所不同,例如会根据跨度的范围来决定使用月,星期,日还是小时范围的刻度。
                        'log' 对数轴。适用于对数数据。
                    */
                    //type: 'value',
                    type: 'category',
                    //type: 'time',
                    //data: xAxisData,
                    splitLine:{
                        show:false//去掉网格中的垂直线
                    },
                    boundaryGap:false,
                     axisLabel:{  
                        //interval: 0,  //坐标轴刻度标签的显示间隔.设置成 0 强制显示所有标签。设置为 1,隔一个标签显示一个标签。
                         //rotate: 45,//倾斜度 -90 至 90 默认为0
                        // textStyle: {
                        //     fontWeight: "bold",  //加粗
                        //     color: "#000000"   //黑色
                        // },
                        formatter:function(date1,index){
                            //console.log('formatter',date1,index);
                            let date=null;
                                if (date1) {
                                    if (typeof (date1) === 'string') {
                                        date = new Date(date1.replace(/-/g, '/'));
                                    }else{
                                         date = new Date(date1);
                                    }
                                    // const y = date.getFullYear();
                                    // let m = date.getMonth() + 1;
                                    // m = m < 10 ? '0' + m : m;
                                    // let d = date.getDate();
                                    // d = d < 10 ? ('0' + d) : d;
                                    let h = date.getHours();
                                    h = h < 10 ? '0' + h : h;
                                    let mi = date.getMinutes();
                                    mi = mi < 10 ? '0' + mi : mi;
                              
                                    return h+ ':' + mi;
                                    
                                } else {
                                    return null;
                                }
                        }
                    }

                    // axisPointer:{
                    //     label:{
                    //         formatter: function(data){
                    //             console.log('xAxis',data)
                    //             return "10";
                    //         }   
                    //     } 
                    // }
                },
                yAxis: [{ 
                    name: '风速(m/s)',

                }],

                series: [
                    
                    {
                    /*echarts文档-配置项: series-custom
                      custom 系列需要开发者自己提供图形渲染的逻辑。这个渲染逻辑一般命名为 renderItem
                    */
                    type: 'custom', 
                    renderItem: this.renderArrow, 
                    /*echarts文档-配置项:series-line.encode
                        可以定义 data 的哪个维度被编码成什么。比如:
                        encode: {
                        x: [3, 1, 5],      // 表示维度 3、1、5 映射到 x 轴。
                        y: 2,              // 表示维度 2 映射到 y 轴。
                        tooltip: [3, 2, 4] // 表示维度 3、2、4 会在 tooltip 中显示。
                        }
                    */
                    encode: {
                        x: dims.time,
                        y: dims.windSpeed
                    },
                    data: data2,
                    /*
                        series-custom. z 
                        自定义图组件的所有图形的z值。控制图形的前后顺序。z值小的图形会被z值大的图形覆盖。
                        z相比zlevel优先级更低,而且不会创建新的 Canvas。
                    */
                    z: 10
                }, 
                {
                    type: 'line',
                    symbol: 'none', //不显示点
                    smooth: true, //这句就是让曲线变平滑的
                    connectNulls: true,//断点连接
                    encode: { 
                        x: dims.time,
                        y: dims.windSpeed
                    },
                    lineStyle: {
                        normal: {
                            color: 'rgb(148, 192, 90)',
                            //type: 'dotted'
                        }
                    },
                    data: data2,
                    z: 3
                }]
            };
 
            //console.log('option',option);
            chart.setOption(option);
            chart.resize();
            this[id] = chart;
        },

        onresizeAir(){
            let idArr=['windspeedandDirection'];
            for(let i=0;i<idArr.length;i++){
                
                let id=idArr[i];
                let chartElement = document.getElementById(id);
                chartElement.style.height = (window.innerHeight -139)/3+'px';  //window.innerHeight浏览器高度
               
                this.resizeChart(this[id]);
                //  console.log('ceshi1',(window.innerHeight -123)/3);
                //   console.log('chartElement',chartElement)
                //    console.log('that[id]',that[id])

            }
           },


 mounted () {
           let that=this;
      
        setTimeout(function(){
              that.onresizeAir();
          }, 400);    
        window.addEventListener('resize', () => {
             that.onresizeAir(); 
        }, false)
  
     
    },



         renderArrow(param, api) {
        /*
            echarts文档-配置项: series-custom. renderItem
            对于 data 中的每个数据项(为方便描述,这里称为 dataItem),会调用此 renderItem 函数。

            renderItem 函数提供了两个参数:

            params:包含了当前数据信息和坐标系的信息。
            api:是一些开发者可调用的方法集合。
            renderItem 函数须返回根据此 dataItem 绘制出的图形元素的定义信息,参见 renderItem.return。

            一般来说,renderItem 函数的主要逻辑,是将 dataItem 里的值映射到坐标系上的图形元素。这一般需要用到 renderItem.arguments.api 中的两个函数:

            api.value(...),意思是取出 dataItem 中的数值。例如 api.value(0) 表示取出当前 dataItem 中第一个维度的数值。
            api.coord(...),意思是进行坐标转换计算。例如 var point = api.coord([api.value(0), api.value(1)]) 表示 dataItem 中的数值转换成坐标系上的点。
            有时候还需要用到 api.size(...) 函数,表示得到坐标系上一段数值范围对应的长度。

            返回值中样式的设置可以使用 api.style(...) 函数,他能得到 series.itemStyle 中定义的样式信息,以及视觉映射的样式信息。也可以用这种方式覆盖这些样式信息:api.style({fill: 'green', stroke: 'yellow'})。

        
        */
             //数据参数顺序
            var dims = {
                time: 0,
                windSpeed: 1,
                R: 2
            };
             var arrowSize = 12;
           
             var point = api.coord([
                 api.value(dims.time),
                 api.value(dims.windSpeed)
             ]);
             let rotationData= api.value(dims.R);
            //  console.log('param',param);
            //  console.log('api',api);
            //  console.log('point',point);

             let obj={
                 type: 'path',
                 shape: {
                     pathData: 'M 146.5 230 L 141.298 239.011 L 146.5 219.595 L 151.702 239.011 Z',//绘制图形
                     //'M31 16l-15-15v9h-26v12h26v9z',
                     x: -arrowSize / 2,
                     y: -arrowSize / 2,
                      arrowSize,
                     height: arrowSize
                 },
                 rotation: -rotationData*(Math.PI/180),
                 //echarts文档-配置项: series-custom.renderItem.return_path. rotation
                 //旋转(rotation):默认值是 0。表示旋转的弧度值。正值表示逆时针旋转。
                 //1) 角度转换为弧度公式:弧度=角度*(π /180 )
                 //2)弧度转换为角度公式: 角度=弧度*(180/π)
                 //平移(position):默认值是 [0, 0]。表示 [横向平移的距离, 纵向平移的距离]。右和下为正值。
                 position: point,
                 style: api.style({
                     stroke: 'rgb(102, 0, 204)',//图形颜色
                     lineWidth: 1
                 })
                 
             };
             //console.log('obj',obj);
             return obj
         },

  



一些格式转换方法(时间转换、风速转风力、风向度数转文字、四舍五入保留2位小数)
util.formatDate = function (date) {
    if (date) {
        if (typeof (date) === 'string') {
            date = new Date(date.replace(/-/g, '/'));
        }
        const y = date.getFullYear();
        let m = date.getMonth() + 1;
        m = m < 10 ? '0' + m : m;
        let d = date.getDate();
        d = d < 10 ? ('0' + d) : d;
        return y + '-' + m + '-' + d;
    } else {
        return null;
    }
};

util.formatDateTime = function (date) {
    //console.log('formatDateTime',date)
    if (date) {
        if (typeof (date) === 'string') {
            date = new Date(date.replace(/-/g, '/'));
        }
        const y = date.getFullYear();
        let m = date.getMonth() + 1;
        m = m < 10 ? '0' + m : m;
        let d = date.getDate();
        d = d < 10 ? ('0' + d) : d;
        let h = date.getHours();
        h = h < 10 ? '0' + h : h;
        let mi = date.getMinutes();
        mi = mi < 10 ? '0' + mi : mi;
        return y + '-' + m + '-' + d + ' ' + h + ':' + mi;
    } else {
        return null;
    }
};

util.formatHourMinutes = function (date) {
    if (date) {
        if (typeof (date) === 'string') {
            date = new Date(date.replace(/-/g, '/'));
        }
        const y = date.getFullYear();
        let m = date.getMonth() + 1;
        m = m < 10 ? '0' + m : m;
        let d = date.getDate();
        d = d < 10 ? ('0' + d) : d;
        let h = date.getHours();
        h = h < 10 ? '0' + h : h;
        let mi = date.getMinutes();
        mi = mi < 10 ? '0' + mi : mi;
        return h + ':' + mi;
    } else {
        return null;
    }
};
util.formatTime = function (date) {
    if (date) {
        if (typeof (date) === 'string') {
            date = new Date(date.replace(/-/g, '/'));
        }
        const y = date.getFullYear();
        let m = date.getMonth() + 1;
        m = m < 10 ? '0' + m : m;
        let d = date.getDate();
        d = d < 10 ? ('0' + d) : d;
        let h = date.getHours();
        h = h < 10 ? '0' + h : h;
        let mi = date.getMinutes();
        mi = mi < 10 ? '0' + mi : mi;
        return h + ':' + mi;
    } else {
        return null;
    }
};

util.formatTwoDecimalPlaces= function  (val) {
    
   
        if (val==undefined||val==null||typeof (val) !== 'number'){ return null; }
       
        let v2=100;
        return Math.round(val * v2) / v2;



 
};

     /**
     * 根据日期字符串获取星期几
     * @param dateString 日期字符串(如:2020-05-02)
     * @returns {String|Null}
     */
    util.formatWeek= function(dateString) {
         //dateString="2020-11-27 10:10:03.378";
        if(dateString){
            let date = new Date(dateString);
            //console.log('getWeek',date,dateString, date.getFullYear(),date.getMonth(),date.getDate(),date.getHours(),date.getMinutes(),date.getSeconds(),date.getMilliseconds(),date.getDay())
            return "" + "日一二三四五六".charAt(date.getDay());
        }else{
            return null;
        }

    };

    /**
     * 风向 角度转文字
     * @param data 向角(如:1.34)
     * @returns {Number}
     */
    util.formatWindDirection= function(data) {
       if(data){

        let val  =parseInt((data/22.5)+0.5)
        //let arr= ["N","NNE","NE","ENE","E","ESE", "SE", "SSE","S","SSW","SW","WSW","W","WNW","NW","NNW"]
        let arr2=["","东北偏北","东北","东北偏东","","东南偏东", "东南", "东南偏南","","西南偏南","西南","西南偏西","西","西北偏西","西北","西北偏北"]
        let name=  arr2[(val % 16)];
        //console.log('name',name);
       return name;
        
       }else{
           return null;
       }

   };

     /**
     * 风力 m/s转等级
     * @param data 向角(如:1.34)
     * @returns {Number}
     */
    util.formatWindGrades= function(data) {
        if(data){
         let arr=["无风","软风","轻风","微风","和风","清风","强风","劲风(疾风)","大风","烈风","狂风","暴风","台风","台风","强台风","强台风","超强台风","超强台风","超强台风","超强台风"];
         let gradeArr=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18];
         let arr2=[0.3,1.6,3.4,5.5,8.0,10.8,13.9,17.2,20.8,24.5,28.5,32.7,37.9,41.5,46.2,51.0,56.1,61.3,69.4];
         let name= "";
         let grade="";
        if(data<arr2[0]){
            name=arr[0];
            grade=gradeArr[0];
        }else if(data<arr2[1]){
            name=arr[1];
            grade=gradeArr[1];
        }else if(data<arr2[2]){
            name=arr[2];
            grade=gradeArr[2];
        }else if(data<arr2[3]){
            name=arr[3];
            grade=gradeArr[3];
        }else if(data<arr2[4]){
            name=arr[4];
            grade=gradeArr[4];
        }else if(data<arr2[5]){
            name=arr[5];
            grade=gradeArr[5];
        }else if(data<arr2[6]){
            name=arr[6];
            grade=gradeArr[6];
        }else if(data<arr2[7]){
            name=arr[7];
            grade=gradeArr[7];
        }else if(data<arr2[8]){
            name=arr[8];
            grade=gradeArr[8];
        }else if(data<arr2[9]){
            name=arr[9];
            grade=gradeArr[9];
        }else if(data<arr2[10]){
            name=arr[10];
            grade=gradeArr[10];
        }else if(data<arr2[11]){
            name=arr[11];
            grade=gradeArr[11];
        }else if(data<arr2[12]){
            name=arr[12];
            grade=gradeArr[12];
        }else if(data<arr2[13]){
            name=arr[13];
            grade=gradeArr[13];
        }else if(data<arr2[14]){
            name=arr[14];
            grade=gradeArr[14];
        }else if(data<arr2[15]){
            name=arr[15];
            grade=gradeArr[15];
        }else if(data<arr2[16]){
            name=arr[16];
            grade=gradeArr[16];
        }else if(data>=arr2[17]){
            name=arr[17];
            grade=gradeArr[17];
        }
        //console.log('name',name);
        return {name:name,grade:grade};
        }else{
            return null;
        }
 
    };


export default util;
 

 参考来源: 

https://www.cnblogs.com/w2011/p/11277147.html

从该文档知道怎么做,但很多地方没注释不明白意思。

http://www.weather.com.cn/weather1d/101121201.shtml

中国天气网 F12  获取绘制箭头图形的编码和颜色

如果想显示风力等级曲线,可以用formatWindGrades方法 把风速转换为风力等级

原文地址:https://www.cnblogs.com/hao-1234-1234/p/14166962.html