echarts 数据转换


echarts 数据转换

                           

官网:Handbook - Apache ECharts

应用:给定数据集以及转换方法,生成一个新的数据集,使用新的数据集绘制图表    

                             

              

***********************

dataset 属性配置

                    

id:数据集id,默认不指定

source:原始数据

dimensions:维度名

sourceHeader:第一行或者列是否是维度名,可选值:null(自动探测)、true、false

transform:转换方法

fromDatasetIndex:transform方法使用的dataset(index指定)

fromDatasetId:transform方法使用的dataset(id指定)

fromTransformResult:获取transform方法产生的result(一般在transform产生多个结果时使用)

                      

source 属性:可以使用三种形式设置

# 二维数组:第一行或者列是维度名、也可以直接是数据
[
    ['product', '2015', '2016', '2017'],
    ['Matcha Latte', 43.3, 85.8, 93.7],
    ['Milk Tea', 83.1, 73.4, 55.1],
    ['Cheese Cocoa', 86.4, 65.2, 82.5],
    ['Walnut Brownie', 72.4, 53.9, 39.1]
]

# key-value对象数组,key是维度名
[
    {product: 'Matcha Latte', count: 823, score: 95.8},
    {product: 'Milk Tea', count: 235, score: 81.4},
    {product: 'Cheese Cocoa', count: 1042, score: 91.2},
    {product: 'Walnut Brownie', count: 988, score: 76.9}
]

# key value数组,key为维度名
{
    'product': ['Matcha Latte', 'Milk Tea', 'Cheese Cocoa', 'Walnut Brownie'],
    'count': [823, 235, 1042, 988],
    'score': [95.8, 81.4, 91.2, 76.9]
}

                  

transform:数据转换方法

type:转换类型,内置:filter、sort,也可引入外部转换器
config:转换配置
print:是否将转换结果打印出来,默认false

# 数据过滤
option = {
  dataset: [
    {
      source: [
        ['Product', 'Sales', 'Price', 'Year'],
        ['Cake', 123, 32, 2011],
        ['Latte', 231, 14, 2011],
        ['Tofu', 235, 5, 2011],
        ['Milk Tee', 341, 25, 2011],
        ['Porridge', 122, 29, 2011],
        ['Cake', 143, 30, 2012],
        ['Latte', 201, 19, 2012],
        ['Tofu', 255, 7, 2012],
        ['Milk Tee', 241, 27, 2012],
        ['Porridge', 102, 34, 2012],
        ['Cake', 153, 28, 2013],
        ['Latte', 181, 21, 2013],
        ['Tofu', 395, 4, 2013],
        ['Milk Tee', 281, 31, 2013],
        ['Porridge', 92, 39, 2013],
        ['Cake', 223, 29, 2014],
        ['Latte', 211, 17, 2014],
        ['Tofu', 345, 3, 2014],
        ['Milk Tee', 211, 35, 2014],
        ['Porridge', 72, 24, 2014]
      ]
    },
    {
      transform: {
        type: 'filter',
        config: { dimension: 'Year', '=': 2011 }  //过滤出'Year'为2011的所有数据项
      }
    }
  ],
  series: {
    type: 'pie',
    datasetIndex: 1
  }
}


# 数据排序
option = {
  dataset: [
    {
      dimensions: ['name', 'age', 'profession', 'score', 'date'],
      source: [
        [' Hannah Krause ', 41, 'Engineer', 314, '2011-02-12'],
        ['Zhao Qian ', 20, 'Teacher', 351, '2011-03-01'],
        [' Jasmin Krause ', 52, 'Musician', 287, '2011-02-14'],
        ['Li Lei', 37, 'Teacher', 219, '2011-02-18'],
        [' Karle Neumann ', 25, 'Engineer', 253, '2011-04-02'],
        [' Adrian Groß', 19, 'Teacher', null, '2011-01-16'],
        ['Mia Neumann', 71, 'Engineer', 165, '2011-03-19'],
        [' Böhm Fuchs', 36, 'Musician', 318, '2011-02-24'],
        ['Han Meimei ', 67, 'Engineer', 366, '2011-03-12']
      ]
    },
    {
      transform: {
        type: 'sort',
        config: { dimension: 'score', order: 'asc' }   //按score排序
      }
    }
  ],
  series: {
    type: 'bar',
    datasetIndex: 1
  }
};

                      

transform config说明

数字比较操作符:>、>=、=、!=、<、<=
字符串比较操作符:=、!=
正则匹配操作符:regex

逻辑比较操作符:and、or、not
# and、or支持多个比较条件、not后面只能有一个比较条件

解析器:time、trim、number
time:把原始值解析成时间戳( timestamp )后再做比较,如果不能解析则转换为NAN
trim:如果原始数据是字符串,则把字符串两端的空格(全角半角)和换行符去掉
      如果不是字符串,还保持为原始数据
number:强制把原始数据转成数值,如果不能转换,则解析为NAN
        默认情况下,数字字符串会直接转换为数字
        含尾缀的字符串(20%、20px等)要转换为数字,需使用parser:'number'

# 示例
    {
      transform: {
        type: 'filter',     //过滤出Year 2013的数据
        config: { dimension: 'Year', value: 2013 }
      }
    }

    {
      transform: {
        type: 'filter',     //过滤出Year 2013的数据
        config: { dimension: 'Year', '=': 2013 }
      }
    }

    {
      transform: {
        type: 'filter',     //过滤出Year 2013的数据(维度名索引从0开始)
        config: { dimension: 0, value: 2013 }
      }
    }


# transform 链式调用
    {
      transform: [
        {
          type: 'filter',
          config: { dimension: 'Product', value: 'Tofu' }
        },
        {
          type: 'sort',
          config: { dimension: 'Year', order: 'desc' }
        }                   //先过滤出Product为Tofu的产品,在根据Year降序排序
      ]
    }


# 逻辑运算
    {
      transform: {
        type: 'filter',
        config: {
          and: [
            { dimension: 'Year', '=': 2011 },
            { dimension: 'Price', '>=': 20, '<': 30 }
          ]
        }                  //过滤出2011年价格大于等于20、小于30的产品
      }
    }

and与如下等价
    {
      transform: {
        type: 'filter',
        config: [
          { dimension: 'Year', '=': 2011 },
          { dimension: 'Price', '>=': 20, '<': 30 }
        ]      //过滤出2011年价格大于等于20、小于30的产品
      }
    }

    {
      transform: {
        type: 'filter',
        config: {
          or: [
            { dimension: 'Price', '<': 20 },
            { dimension: 'Price', '>': 30 }
          ]
        }                  //过滤出2011年价格小于20,或者大于30的产品
      }
    }

    {
      transform: {
        type: 'filter',
        config: {
          not: { dimension: 'Price', '<': 20 }
        }                  //过滤出2011年价格不小于20的产品
      }
    }


# 逻辑嵌套
transform: {
  type: 'filter',
  config: {
    or: [{
      and: [{
        dimension: 'Price', '>=': 10, '<': 20
      }, {
        dimension: 'Sales', '<': 100
      }, {
        not: { dimension: 'Product', '=': 'Tofu' }
      }]
    }, {
      and: [{
        dimension: 'Price', '>=': 10, '<': 20
      }, {
        dimension: 'Sales', '<': 100
      }, {
        not: { dimension: 'Product', '=': 'Cake' }
      }]
    }]
  }
}


# 解析器使用
    {
      transform: {
        type: 'filter',
        config: {
          dimension: 'Date',
          '>=': '2012-05',
          '<': '2012-06',
          parser: 'time'
        }  //过滤出时间大于等于2012-05、小于2012-06的数据
      }
    }

                   

transform输出多个结果

# fromTransformResult单独使用:使用transform生成的指定结果
option = {
  dataset: [
    {
      source: [          //dataset index为0
        ...
      ]
    },
    {
      transform: {       //dataset index为1
        type: 'boxplot'
      }                  //boxplot transform生成2份数据:
                         //result[0]:boxplot series需要的数据
                         //result[1]:离群点数据
                         //当其他dataset、series使用该数据集时,默认使用result[0]
                         //若其他dataset想使用result[1],需指定fromDatasetResult:1
                         //若其他series想使用result[1],需先创建一个使用result[1]的数据集,series在使用新建的数据集
    },
    {
      fromDatasetIndex: 1,    //dataset index为2,使用dataset 1中的数据
      fromTransformResult: 1  //使用transform转换生成的result[1]
    }
  ],

  xAxis: {
    type: 'category'
  },
  yAxis: {},

  series: [
    {
      name: 'boxplot',
      type: 'boxplot',
      datasetIndex: 1   //使用transform转换生成的result[0]
    },
    {
      name: 'outlier',
      type: 'scatter',
      datasetIndex: 2   //使用transform转换生成的result[1]
    }
  ]
};


# fromTransformResult、transform同时使用:使用上游transform生成的指定结果
{
  fromDatasetIndex: 1,
  fromTransformResult: 1,
  transform: {
    type: 'sort',
    config: { dimension: 2, order: 'desc' }
  }
}

                               

transform使用外部转换器:先注册,使用时添加命名空间

<script src="/echarts/ecStat.min.js"></script>          //导入ecStat js脚本
echarts.registerTransform(ecStat.transform.regression); //注册转换方法

const data = [
    ...
];
option = {
  dataset: [
    {
      source: data
    },
    {
      transform: {
        type: 'ecStat:regression'   //引用外部转换器需要设置命名空间:esStat
                                    //内置转换器(filter、sort)不需要
      }
    }
  ],

  ...
};

                           

                                  

                                 

***********************

示例

                    

过滤年度分布数据  

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="/echarts/echarts.min.js"></script>
  <script src="/jquery/jquery-3.6.0.min.js"></script>
  <script type="text/javascript">
    $(function (){
      const myChart = echarts.init($("#con")[0]);

      // 指定图表的配置项和数据
      const option = {
        title: {
          left: 'center',
          text: '中国神华营业总收入季度分布图',
          textStyle: {
            color: '#b28'
          }
        },
        tooltip: {},
        legend: {
          left: 'right',
          top: '10',
          orient: 'vertical',
          data:['一季度','二季度','三季度','四季度']
        },
        dataset: [
          {
            source: [
              ['quarter', 'income', 'year'],
              ['一季度', 510.8, 2020],
              ['二季度', 539.2, 2020],
              ['三季度', 611, 2020],
              ['四季度', 672, 2020],
              ['一季度', 570.1, 2019],
              ['二季度', 593.9, 2019],
              ['三季度', 614, 2019],
              ['四季度', 641, 2019],
            ]
          },
          {
            transform:{
              type: 'filter',
              config: {dimension: 'year', value: '2020'}
            }      //过滤2020季度分布数据
          },
          {
            transform:{
              type: 'filter',
              config: {dimension: 'year', value: '2019'}
            }      //过滤2019季度分布数据
          }
        ],
        series: [
          {
            name: '中国神华2020',
            type: 'pie',
            center: ['25%','50%'],  //圆心横坐标、纵坐标
            radius: '40%',
            datasetIndex: 1,
            encode: {
              itemName: 0,        //数据项名称,在legend中展示
              value: 1
            },
            label: {
              show: false
            }
          },
          {
            name: '中国神华2019',
            type: 'pie',
            center: ['75%','50%'],   //圆心横坐标、纵坐标
            radius: '40%',
            datasetIndex: 2,
            encode: {
              itemName: 0,         //数据项名称,在legend中展示
              value: 1
            },
            label: {
              show: false
            }
          }
        ]
      };

      myChart.setOption(option);
    })
  </script>
</head>
<body>
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<div id="con" style="width: 500px;height:300px;"></div>
</body>
</html>

                   

                         

使用外部转换器(指数线性回归)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="/echarts/echarts.min.js"></script>
  <script src="/echarts/ecStat.min.js"></script>
  <script src="/jquery/jquery-3.6.0.min.js"></script>
  <script type="text/javascript">
    $(function (){
      echarts.registerTransform(ecStat.transform.regression);

      const myChart = echarts.init($("#con")[0]);

      const option = {
        dataset: [
          {
            source: [
              [1, 4862.4],
              [2, 5294.7],
              [3, 5934.5],
              [4, 7171.0],
              [5, 8964.4],
              [6, 10202.2],
              [7, 11962.5],
              [8, 14928.3],
              [9, 16909.2],
              [10, 18547.9],
              [11, 21617.8],
              [12, 26638.1],
              [13, 34634.4],
              [14, 46759.4],
              [15, 58478.1],
              [16, 67884.6],
              [17, 74462.6],
              [18, 79395.7]
            ]
          },
          {
            transform: {
              type: 'ecStat:regression',
              config: {
                method: 'exponential'
              }
            }
          }
        ],
        title: {
          text: '1981 - 1998 gross domestic product GDP (trillion yuan)',
          subtext: 'By ecStat.regression',
          sublink: 'https://github.com/ecomfe/echarts-stat',
          left: 'center'
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'cross'
          }
        },
        xAxis: {
          splitLine: {
            lineStyle: {
              type: 'dashed'
            }
          }
        },
        yAxis: {
          splitLine: {
            lineStyle: {
              type: 'dashed'
            }
          }
        },
        series: [
          {
            name: 'scatter',
            type: 'scatter',
            datasetIndex: 0
          },
          {
            name: 'line',
            type: 'line',
            smooth: true,
            datasetIndex: 1,
            symbolSize: 0.1,
            symbol: 'circle',
            label: { show: true, fontSize: 16 },
            labelLayout: { dx: -20 },
            encode: { label: 2, tooltip: 1 }
          }
        ]
      };

      myChart.setOption(option);
    })
  </script>
</head>
<body>
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<div id="con" style="width: 600px;height:400px;"></div>
</body>
</html>

                   

                                 

                                              

Guess you like

Origin blog.csdn.net/weixin_43931625/article/details/121150118