PDA

View Full Version : [CLOSED] Line Series Chart with null values & axis scaling



tylert
Oct 23, 2014, 8:18 PM
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?25817-CLOSED-Handle-null-values-in-line-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 };
}
});

Daniil
Oct 24, 2014, 5:31 AM
Hi @tylert,

I don't think there is better solution. So, you are good with overriding.

To be honest, if you are going to use Charts a lot, then "Ext.override" will be your good friend:)

There is some thread you might be interested to read through.
http://www.sencha.com/forum/showthread.php?258745

tylert
Oct 24, 2014, 2:35 PM
Daniil,

Thanks. Yes, I had seen that ExtJS 5 includes a new chart package -- I assume they will be included in Ext.NET 3.0. I'm looking forward to making the switch.

Tyler

Daniil
Oct 25, 2014, 6:57 AM
At this point, the new Charts package might be not included into Ext.NET v3 Beta, but it will be included to the finale 3.0 release for absolute sure.

I have not played a lot yet with the new Charts, though I hope very much it is better than the old package:)