我正在使用一个kendoChart来显示多达10行数据。
每一行代表可能具有广泛不同的上下文和最小/最大范围的过程数据,但所有行都在时间上相关,类别为.Axis。显示时,每个valueAxis都会正确显示相应行的比例。
但是,对于10行,10个值的值占用了太多的屏幕,无法满足我的要求。
我试图隐藏除了一个轴之外的所有轴,期望图表会扩展以填充隐藏轴所占用的空间,但是 不会发生。我得到一个被空白区域包围的孤立轴,图表的绘图区域保持相同的大小。
我尝试将所有系列设置为使用相同的valueAxis,然后通过单击选择的活动通道更改valueAxis min / max 传奇项目。这会根据需要扩展绘图区域,但会删除查看所有行的功能,因为刻度特定于一行。
kendoChart是否可以独立于单个valueAxis显示多个绘图(例如,值在0.5和0.7之间的行将显示为缩放到整个图表区域,因此一行的值将介于25和100之间,但是valueAxis可能会显示scale。)
答案 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();
}