2016-05-03 2 views
-1

私は、最大10行のデータを表示するために単一のkendoChartを使用しています。kendoChart:単一のvalueAxisを使用して、複数の異なる値のスケールを表示する方法はありますか?

各行は、幅広く異なるコンテキストと最小/最大範囲を持つ可能性のあるプロセスデータを表しますが、すべての行は時間的に関連しています(categoryAxis)。表示されると、各valueAxisは対応する行の縮尺を正しく示します。

しかし、10行の場合、10個のValueAxesが画面のあまりにも多くを占めています。

隠し軸が占めるスペースを埋めるためにグラフが拡張されることを期待して、1つを除いてすべての軸を隠そうとしましたが、 は発生しません。私は空白のスペースに囲まれた孤独な軸を取得し、グラフのプロット領域は同じサイズのままです。

すべてのシリーズを同じvalueAxisを使用し、 凡例アイテムをクリックして選択したアクティブなチャンネルごとにmax/minを変更することを試みました。これにより、必要に応じてプロット領域が拡大されますが、縮尺が1行に限定されているため、すべての線を表示する機能が削除されます。

kendoChartでは、単一のvalueAxisから独立して複数のプロットを表示できます(たとえば、0.5〜0.7の値を持つ行は、完全なグラフ領域に拡大表示され、25〜100の値を持つ行も同様です)。 valueAxisにはどちらかのスケールが表示されることがあります)。

答えて

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(); 
} 
関連する問題