kendoChart:有没有办法使用单个valueAxis显示多个不同的值标度系列?

时间:2016-05-03 15:30:47

标签: telerik kendo-chart telerik-charting

我正在使用一个kendoChart来显示多达10行数据。

每一行代表可能具有广泛不同的上下文和最小/最大范围的过程数据,但所有行都在时间上相关,类别为.Axis。显示时,每个valueAxis都会正确显示相应行的比例。

但是,对于10行,10个值的值占用了太多的屏幕,无法满足我的要求。

我试图隐藏除了一个轴之外的所有轴,期望图表会扩展以填充隐藏轴所占用的空间,但是 不会发生。我得到一个被空白区域包围的孤立轴,图表的绘图区域保持相同的大小。

我尝试将所有系列设置为使用相同的valueAxis,然后通过单击选择的活动通道更改valueAxis min / max 传奇项目。这会根据需要扩展绘图区域,但会删除查看所有行的功能,因为刻度特定于一行。

kendoChart是否可以独立于单个valueAxis显示多个绘图(例如,值在0.5和0.7之间的行将显示为缩放到整个图表区域,因此一行的值将介于25和100之间,但是valueAxis可能会显示scale。)

1 个答案:

答案 0 :(得分:0)

我用于解决此问题的解决方案的代码比我预期的要多。也许Telerik的其他产品都有这方面的API。

基本上,我在kendoChart之外维护一个结构,用于存储每个系列的实际数据,并且这个实际数据被映射到当前可见valueAxis的预期比例。映射函数是从一个尺度到另一个尺度的标准变换。

valueAxis被交换'取决于单击哪个图例项,该事件触发图表上的重绘,其中所有系列数据都映射到“活动”项目。轴。

一些代码段。系列也被描述为一个频道。

// The data structure.
this._channelDescriptors.push({
    fullName: ch.fullName || "",
    axisTitle: (ch.fullName + axisEUString) || "",
    axisFont: ch.axisFont || "",
    axisColor: ch.color || "#000000",
    realData: [],
    minData: Number.MAX_VALUE,
    maxData: Number.MIN_VALUE
});

// This event causes the switching of valueAxis for all members of the series.
$("#" + chartID).kendoChart({
    // Other kendoChart configurations
    //
    legendItemClick: function (e) {
        var idx = e.seriesIndex;
        sncTrender.updateAxis(idx);
        e.preventDefault();
    },
    tooltip: {
        visible: true,
        template: "#=series.name# : #=kendo.format('{0:N4}', dataItem.realValue)#<br />#=kendo.format('{0:MM-dd HH:mm:ss.fff}', dataItem.Time)#",
    },
    //
    // Other kendoChart configurations
});

// All code snippets are members of a wrapper object.
updateAxis: function (ch) {
    if (this.series[ch].visible) {
        this.setAxis(ch);
    }
},

// Every series is set to the same valueAxis via the selected series' valueAxis.name property.
setAxis: function (ch) {
    var i,
        channel = this._channelDescriptors[ch];
    this._currentChannel = ch;
    for (i = 0; i < this.series.length; i++) {
        this.series[i].axis = this._channelDescriptors[ch].fullName;
    }
    // Set the active valueAxis properties. This is the only axis visible maintained for the chart.
    this.valueAxis.name = channel.fullName;
    this.valueAxis.title.text = channel.axisTitle;
    this.valueAxis.title.font = channel.axisFont;
    this.valueAxis.line.color = channel.axisColor;
},

// The mapping occurs here, and the transform calculation is this line
//    Y: (yRange * (chDesc.realData[k].realValue - newMin) / newRange) + this.valueAxis.min,
//
updateChart: function (allTrends) {
    // ...
    timeStamps = trendDataResponse.curve.Timestamp;
    t1 = trendArgs.t1;
    t2 = trendArgs.t2;
    xValues = trendDataResponse.curve.X;
    yValues = trendDataResponse.curve.Y;
    pointCount = xValues.length;
    min = Number.MAX_VALUE;
    max = Number.MIN_VALUE;
    categoryTimes = [pointCount];
    newData = [];
    for (l = 0; l < pointCount; l++) {
        min = Math.min(min, yValues[l]);
        max = Math.max(max, yValues[l]);
        ts = new Date(timeStamps[l]);
        categoryTimes[l] = ts;
        // The Y data will be plotted on the chart, but the cursor tooltip will
        // use the realValue data. In this way, the series can be visible regardless of
        // the valueAxis scaling, but the actual data is also available. Refer to the
        // tooltip template.
        newData.push({ X: xValues[l], Y: yValues[l], realValue: yValues[l], Time: ts });
    }

    // Real data for each channel is stored in channelDescriptors.
    chDesc = this._channelDescriptors[channelID];
    chDesc.realData = newData;
    chDesc.minData = min;
    chDesc.maxData = max;

    // The valueAxis min/max is set only for the 'active' series.
    if (this._currentChannel === channelID) {
        this.categoryAxis.categories = categoryTimes;
        yRange = max - min;
        scaleAdjustment = yRange * SNC.CONST_yAxisScaleAdjustmentFactor;
        this.valueAxis.min = min - scaleAdjustment;
        this.valueAxis.max = max + scaleAdjustment;
    }
    }
    // Scale curves to current axis.
    // Use real data for the current series.
    for (j = 0; j < this.series.length; ++j) {
    chDesc = this._channelDescriptors[j];
    if (j === this._currentChannel) {
        this.series[j].data = chDesc.realData;
        continue;
    }

    // Use mapped data for all other series.
    recalcData = [];
    newMin = chDesc.minData;
    newMax = chDesc.maxData;
    newRange = newMax - newMin;
    rangeAdjustment = newRange * SNC.CONST_yAxisScaleAdjustmentFactor;
    newMin = newMin - rangeAdjustment;
    newMax = newMax + rangeAdjustment;
    for (k = 0; k < chDesc.realData.length; ++k) {
        recalcData.push({
            X: chDesc.realData[k].X,
            Y: (yRange * (chDesc.realData[k].realValue - newMin) / newRange) + this.valueAxis.min,
            realValue: chDesc.realData[k].realValue,
            Time: chDesc.realData[k].Time,
        });
    }
    this.series[j].data = recalcData;
    }
    chart.redraw();
}