Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

无法使用`series.sampling`选项, 使用后就会抛出异常 #8017

Closed
qqj1228 opened this Issue Mar 25, 2018 · 1 comment

Comments

Projects
None yet
1 participant
@qqj1228
Copy link

qqj1228 commented Mar 25, 2018

One-line summary [问题简述]

无法使用series.sampling选项, 使用后就会抛出异常

Version & Environment [版本及环境]

  • ECharts version [ECharts 版本]: 3.8.5
  • Browser version [浏览器类型和版本]: Chrome, 59.0.3071.115
  • OS Version [操作系统类型和版本]: win10 pro, 1709, 16299.309
    另外我是在electron环境里运行的,electron版本:1.8.3

Expected behaviour [期望结果]

可以正常使用series.sampling选项

ECharts option [ECharts配置项]

// 这是初始化option,运行时会再传入下面的option
option = {
        legend: {
            data: ['盖侧', '轴侧'],
        },
        grid: [{
            top: '10%',
            height: '24%',
            left: '5%',
            right: '5%',
        }, {
            top: '40%',
            height: '24%',
            left: '5%',
            right: '5%',
        }, {
            top: '70%',
            height: '24%',
            left: '5%',
            right: '5%',
        }],
        xAxis: [{
            type: 'value',
            name: 'θ°',
            axisPointer: {triggerTooltip: false},
            min: 0,
            max: 360,
            splitNumber: 6,
            minInterval: 60,
            maxInterval: 180,
        }, {
            gridIndex: 1,
            type: 'value',
            name: 'θ°',
            axisPointer: {triggerTooltip: false},
            min: 0,
            max: 360,
            splitNumber: 6,
            minInterval: 60,
            maxInterval: 180,
        }, {
            gridIndex: 2,
            type: 'value',
            name: 'θ°',
            axisPointer: {triggerTooltip: false},
            min: 0,
            max: 360,
            splitNumber: 6,
            minInterval: 60,
            maxInterval: 180,
        }],
        yAxis: [{
            type: 'value',
            name: 'h(mm)',
            nameLocation: 'middle',
            nameGap: 30,
        }, {
            gridIndex: 1,
            type: 'value',
            name: 'v(m/s)',
            nameLocation: 'middle',
            nameGap: 30,
        }, {
            gridIndex: 2,
            type: 'value',
            name: 'p(MPa)',
            nameLocation: 'middle',
            nameGap: 30,
        }],
        series: [{
            name: '盖侧',
            type: 'line',
            showSymbol: false,
            sampling: 'max',                          // <===============sampling选项
            dimensions: ['theta', 'h', 'v', 'p'],
            encode: {
                x: 'theta',
                y: 'h',
                tooltip: ['h', 'v', 'p'],
            },
        }, {
            name: '盖侧',
            type: 'line',
            xAxisIndex: 1,
            yAxisIndex: 1,
            showSymbol: false,
            tooltip: {show: false},
            dimensions: ['theta', 'h', 'v', 'p'],
            encode: {
                x: 'theta',
                y: 'v',
            },
        }, {
            name: '盖侧',
            type: 'line',
            xAxisIndex: 2,
            yAxisIndex: 2,
            showSymbol: false,
            tooltip: {show: false},
            dimensions: ['theta', 'h', 'v', 'p'],
            encode: {
                x: 'theta',
                y: 'p',
            },
        }, {
            name: '轴侧',
            type: 'line',
            showSymbol: false,
            dimensions: ['theta', 'h', 'v', 'p'],
            encode: {
                x: 'theta',
                y: 'h',
                tooltip: ['h', 'v', 'p'],
            },
        }, {
            name: '轴侧',
            type: 'line',
            xAxisIndex: 1,
            yAxisIndex: 1,
            showSymbol: false,
            tooltip: {show: false},
            dimensions: ['theta', 'h', 'v', 'p'],
            encode: {
                x: 'theta',
                y: 'v',
            },
        }, {
            name: '轴侧',
            type: 'line',
            xAxisIndex: 2,
            yAxisIndex: 2,
            showSymbol: false,
            tooltip: {show: false},
            dimensions: ['theta', 'h', 'v', 'p'],
            encode: {
                x: 'theta',
                y: 'p',
            },
        }],
}

// 运行时再传入该option
    const option = {
        tooltip: {trigger: 'axis'},
        axisPointer: {
            link: {xAxisIndex: 'all'},
        },
        series: [{
            data: plotData.head,
        }, {
            data: plotData.head,
        }, {
            data: plotData.head,
        }, {
            data: plotData.crank,
        }, {
            data: plotData.crank,
        }, {
            data: plotData.crank,
        }],
    };

// 绘图数据, 每个数组含有大概4000~5000个数据点
plotData = {
    head: ['theta', 'h', 'v', 'p'],
    crank: ['theta', 'h', 'v', 'p'],
}

Other comments [其他信息]

运行时会报错:TypeError: Cannot read property 'length' of undefined
是在lib/data/list.js文件内的listProto.downSample函数出错,第900行

listProto.downSample = function (dimension, rate, sampleValue, sampleIndex) {
  var list = cloneListForMapAndSample(this, [dimension]);
  var storage = this._storage;
  var targetStorage = list._storage;
  var originalIndices = this.indices;
  var indices = list.indices = [];
  var frameValues = [];
  var frameIndices = [];
  var frameSize = Math.floor(1 / rate);
  var dimStore = targetStorage[dimension];
  var len = this.count(); // Copy data from original data

  for (var i = 0; i < storage[dimension].length; i++) {         // <======就是这句
    targetStorage[dimension][i] = storage[dimension][i];
  }

上面的storage[dimension].lengthdimension"Y",但是storage里只有{theta: [], h: [], v: [], p: []}
也就是说dimension应该是"h"而不是"Y"

@qqj1228

This comment has been minimized.

Copy link
Author

qqj1228 commented Mar 25, 2018

简单跟踪了一下,文件:lib/processor/dataSample.js,第79行

function _default(seriesType, ecModel, api) {
  ecModel.eachSeriesByType(seriesType, function (seriesModel) {
    var data = seriesModel.getData();
    var sampling = seriesModel.get('sampling');
    var coordSys = seriesModel.coordinateSystem; // Only cartesian2d support down sampling

    if (coordSys.type === 'cartesian2d' && sampling) {
      var baseAxis = coordSys.getBaseAxis();
      var valueAxis = coordSys.getOtherAxis(baseAxis);  // <====该函数返回的就是valueAxis.dim
      var extent = baseAxis.getExtent(); // Coordinste system has been resized

      var size = extent[1] - extent[0];
      var rate = Math.round(data.count() / size);

      if (rate > 1) {
        var sampler;

        if (typeof sampling === 'string') {
          sampler = samplers[sampling];
        } else if (typeof sampling === 'function') {
          sampler = sampling;
        }

        if (sampler) {
          data = data.downSample(valueAxis.dim, 1 / rate, sampler, indexSampler); // 调用参数不对
          seriesModel.setData(data);
        }
      }
    }
  }, this);
}

上面注释的那句调用data.downSample函数的第一个参数valueAxis.dim有问题,其值为"Y"
var valueAxis = coordSys.getOtherAxis(baseAxis);直接把valueAxis.dim赋值为"Y"
lib/coord/cartesian/Cartesian2D.js第75行

  /**
   * Get other axis
   * @param {module:echarts/coord/cartesian/Axis2D} axis
   */
  getOtherAxis: function (axis) {
    return this.getAxis(axis.dim === 'x' ? 'y' : 'x');
  }

按照我的理解不是应该把encode里的"Y"映射成"h"吗?

@100pah 100pah closed this in f5a9111 Mar 25, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.