2016-05-03 9 views
-1

Я использую один kendoChart для отображения до 10 строк данных.kendoChart: Есть ли способ отобразить несколько рядов различных шкал значений с использованием единственного значения Axis?

Каждая строка представляет данные процесса, которые могут иметь различный контекст и диапазоны min/max, но все линии связаны во времени, категорияAxis. Когда отображается, каждое значениеAxis правильно показывает шкалу для соответствующей строки.

Однако, с 10 линиями, 10 значенийAxes занимают слишком много экрана, чтобы они могли использоваться для моих требований.

Я попытался спрятать все оси, кроме одного, с ожиданием расширения диаграммы, чтобы заполнить пространство, занимаемое скрытыми осями, но это делает не так. Я получаю одиночную ось, окруженную пробелом, и область графика графика остается того же размера.

Я попытался установить все серии для использования одного и того же значения Axis, а затем изменив значениеAxis min/max на активный канал, как было выбрано, нажав элемент легенды. Это расширяет область сюжета по мере необходимости, но удаляет возможность видеть все строки, поскольку масштаб определен для одной строки.

Возможно ли, чтобы kendoChart показывал несколько графиков независимо от одного значенияAxis (например, строка со значениями от 0,5 до 0,7 будет отображаться в масштабе всей диаграммы, а также строка со значениями от 25 до 100, но значениеAxis может отображать любую шкалу.)

ответ

0

Решение, которое я использовал для этой проблемы, - это больше кода, чем я ожидал. Возможно, у других продуктов Telerik есть API для этого.

По существу, я поддерживаю структуру вне kendoChart, которая хранит реальные данные для каждой серии, и эти реальные данные отображаются в ожидаемую шкалу текущего видимого значенияAxis. Функция отображения является стандартным преобразованием из одной шкалы в другую.

ValueAxis «swapped», в зависимости от того, какой элемент легенды нажат, и это событие вызывает перерисовку на диаграмме, где все данные серии отображаются на «активную» ось.

Некоторые фрагменты кода. Серия также описывается как канал.

// 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(); 
}