Oct 23, 2014, 8:18 PM
[CLOSED] Line Series Chart with null values & axis scaling
Hello,
I need to be able to show gaps of data in a line series on a chart. I followed this thread for a workaround that sets null values in the data to false:
http://forums.ext.net/showthread.php...e-chart-series
This works as far as showing the gaps, but the y-axis of the chart does not scale properly. I checked the ExtJS javascript, and it is defaulting the false as a 0 in the part of the code that calculates the axis range.
Here is the example copied from that thread above -- in this example the y-axis should not start from 0.
Here is the full override I used. Please let me know if you know of a better way to address this issue.
I need to be able to show gaps of data in a line series on a chart. I followed this thread for a workaround that sets null values in the data to false:
http://forums.ext.net/showthread.php...e-chart-series
This works as far as showing the gaps, but the y-axis of the chart does not scale properly. I checked the ExtJS javascript, and it is defaulting the false as a 0 in the part of the code that calculates the axis range.
Here is the example copied from that thread above -- in this example the y-axis should not start from 0.
<%@ Page Language="C#" %>
<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (!X.IsAjaxRequest)
{
Store s = this.Chart1.GetStore();
s.DataSource = new object[]
{
new
{
x = 0,
y = 100
},
new
{
x = 25,
y = 75
},
new
{
x = 50,
y = ""
},
new
{
x = 75,
y = 75
},
new
{
x = 100,
y = 100
}
};
}
}
</script>
<!DOCTYPE html>
<html>
<head runat="server">
<title>Ext.NET v2 Example</title>
</head>
<body>
<form runat="server">
<ext:ResourceManager runat="server" />
<ext:Chart
ID="Chart1"
runat="server"
Width="400"
Height="400">
<Store>
<ext:Store ID="Store1" runat="server">
<Model>
<ext:Model runat="server">
<Fields>
<ext:ModelField Name="x" />
<ext:ModelField Name="y">
<Convert Handler="if (value === '') { return false; } return value;" />
</ext:ModelField>
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<Axes>
<ext:NumericAxis Title="X" Fields="x" Position="Bottom" />
<ext:NumericAxis Title="Y" Fields="y" Position="Left" />
</Axes>
<Series>
<ext:LineSeries Titles="Chart" XField="x" YField="y" />
</Series>
</ext:Chart>
</form>
</body>
</html>
The only workaround I could come up with is to override the getRange function of Ext.chart.axis.Axis. I changed the following (see line 114 below):if (isNaN(value) {
continue;
}
to this:
if (isNaN(value) || value===false) {
continue;
}
Here is the full override I used. Please let me know if you know of a better way to address this issue.
Ext.override(Ext.chart.axis.Axis, {
getRange: function () {
var me = this,
chart = me.chart,
store = chart.getChartStore(),
data = store.data.items,
series = chart.series.items,
position = me.position,
axes,
seriesClasses = Ext.chart.series,
aggregations = [],
min = Infinity, max = -Infinity,
vertical = me.position === 'left' || me.position === 'right' || me.position === 'radial',
i, ln, ln2, j, k, dataLength = data.length, aggregates,
countedFields = {},
allFields = {},
excludable = true,
fields, fieldMap, record, field, value;
fields = me.fields;
for (j = 0, ln = fields.length; j < ln; j++) {
allFields[fields[j]] = true;
}
for (i = 0, ln = series.length; i < ln; i++) {
if (series[i].seriesIsHidden) {
continue;
}
if (!series[i].getAxesForXAndYFields) {
continue;
}
axes = series[i].getAxesForXAndYFields();
if (axes.xAxis && axes.xAxis !== position && axes.yAxis && axes.yAxis !== position) {
continue;
}
if (seriesClasses.Bar && series[i] instanceof seriesClasses.Bar && !series[i].column) {
fields = vertical ? Ext.Array.from(series[i].xField) : Ext.Array.from(series[i].yField);
} else {
fields = vertical ? Ext.Array.from(series[i].yField) : Ext.Array.from(series[i].xField);
}
if (me.fields.length) {
for (j = 0, ln2 = fields.length; j < ln2; j++) {
if (allFields[fields[j]]) {
break;
}
}
if (j == ln2) {
continue;
}
}
if (aggregates = series[i].stacked) {
if (seriesClasses.Bar && series[i] instanceof seriesClasses.Bar) {
if (series[i].column != vertical) {
aggregates = false;
excludable = false;
}
}
else if (!vertical) {
aggregates = false;
excludable = false;
}
}
if (aggregates) {
fieldMap = {};
for (j = 0; j < fields.length; j++) {
if (excludable && series[i].__excludes && series[i].__excludes[j]) {
continue;
}
if (!allFields[fields[j]]) {
Ext.Logger.warn('Field `' + fields[j] + '` is not included in the ' + position + ' axis config.');
}
allFields[fields[j]] = fieldMap[fields[j]] = true;
}
aggregations.push({
fields: fieldMap,
positiveValue: 0,
negativeValue: 0
});
} else {
if (!fields || fields.length == 0) {
fields = me.fields;
}
for (j = 0; j < fields.length; j++) {
if (excludable && series[i].__excludes && series[i].__excludes[j]) {
continue;
}
allFields[fields[j]] = countedFields[fields[j]] = true;
}
}
}
for (i = 0; i < dataLength; i++) {
record = data[i];
for (k = 0; k < aggregations.length; k++) {
aggregations[k].positiveValue = 0;
aggregations[k].negativeValue = 0;
}
for (field in allFields) {
value = record.get(field);
if (me.type == 'Time' && typeof value == "string") {
value = Date.parse(value);
}
if (isNaN(value) || value===false) {
continue;
}
if (value === undefined) {
value = 0;
} else {
value = Number(value);
}
if (countedFields[field]) {
if (min > value) {
min = value;
}
if (max < value) {
max = value;
}
}
for (k = 0; k < aggregations.length; k++) {
if (aggregations[k].fields[field]) {
if (value >= 0) {
aggregations[k].positiveValue += value;
if (max < aggregations[k].positiveValue) {
max = aggregations[k].positiveValue;
}
if (min > 0) {
min = 0;
}
} else {
aggregations[k].negativeValue += value;
if (min > aggregations[k].negativeValue) {
min = aggregations[k].negativeValue;
}
if (max < 0) {
max = 0;
}
}
}
}
}
}
if (!isFinite(max)) {
max = me.prevMax || 0;
}
if (!isFinite(min)) {
min = me.prevMin || 0;
}
if (typeof min === 'number') {
min = Ext.Number.correctFloat(min);
}
if (typeof max === 'number') {
max = Ext.Number.correctFloat(max);
}
if (min != max && (max != Math.floor(max) || min != Math.floor(min))) {
min = Math.floor(min);
max = Math.floor(max) + 1;
}
if (!isNaN(me.minimum)) {
min = me.minimum;
}
if (!isNaN(me.maximum)) {
max = me.maximum;
}
if (min >= max) {
min = Math.floor(min);
max = min + 1;
}
return { min: min, max: max };
}
});
Last edited by Daniil; Oct 25, 2014 at 6:58 AM.
Reason: Please use [CODE] tags, [CLOSED]