-
7 Feb 2012 1:13 PM #1
Line chart with gaps
Line chart with gaps
If a series contains undefined values then ext-js should render this as a gap in the line. There is a partially implemented feature - Ext.data.Field.useNull - which will render gaps at the start or end of a series, but not in the middle. See attached example - tested in ext-js 4.0.7 and 4.1.0-beta-2
-
7 Feb 2012 2:25 PM #2Sencha - Senior Forum Manager
- Join Date
- Mar 2007
- Location
- St. Louis, MO
- Posts
- 33,624
- Vote Rating
- 434
We will look into it. Thank you.
Mitchell Simoens @SenchaMitch
Sencha Inc, Senior Forum Manager
________________
http://www.JSONPLint.com - Source to lint your JSONP!
Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
https://github.com/mitchellsimoens
Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/
Need more help with your app? Hire Sencha Services services@sencha.com
Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is almost in print!
When posting code, please use BBCode's CODE tags.
-
25 Aug 2012 11:56 PM #3
-
23 Nov 2012 5:42 AM #4
null values in graph
null values in graph
has anyone found a workaround to make a line graph skip null values ?
-
23 Nov 2012 8:28 AM #5
-
9 Dec 2012 2:54 PM #6
I wrote a function which can be used as series renderer.
use undefined for null values.
here is how to get it to work:
result will be something like this:Code:function gapHandler(sprite, record, attributes, index, store, dataFieldName){ // Converts path's LineTo to MoveTo on undefined values. var firstUndefinedIndex = new Array(); var offset = new Array(); var lastEmpty = new Array(); if(typeof attributes["path"] == "object"){ for(index1 in store["data"]["items"]){ for(index2 in store["data"]["items"][index1]["data"]){ if(index2 != dataFieldName) continue; if(typeof firstUndefinedIndex[index2] == 'undefined'){ firstUndefinedIndex[index2] = 0; lastEmpty[index2] = "notEmpty"; offset[index2] = 1; } if(store["data"]["items"][index1]["data"][index2] == ""){ if(firstUndefinedIndex[index2] == 0) firstUndefinedIndex[index2] = index1; if(lastEmpty[index2] != "") lastEmpty[index2] = ""; }else { if(firstUndefinedIndex[index2] > 0 && lastEmpty[index2] == ""){ attributes["path"].splice(offset[index2],0,"M"); firstUndefinedIndex[index2] = 0; lastEmpty[index2] = "notEmpty"; offset[index2]= offset[index2] + 3; }else offset[index2]+=2; } } } } return attributes; } var store = Ext.create('Ext.data.JsonStore', { fields: ['name', 'data1', 'data2'], data: [ { 'name': '1', 'data1': 10, 'data2': 12 }, { 'name': '2', 'data1': 7, 'data2': 8 }, { 'name': '3', 'data1': 5, 'data2': undefined }, { 'name': '4', 'data1': undefined, 'data2': 14 }, { 'name': '5', 'data1': undefined, 'data2': 4 }, { 'name': '6', 'data1': 10, 'data2': 12 }, { 'name': '7', 'data1': 7, 'data2': undefined }, { 'name': '8', 'data1': undefined, 'data2': undefined }, { 'name': '9', 'data1': 2, 'data2': undefined }, { 'name': '10', 'data1': 4, 'data2': 10 } ] }); Ext.create('Ext.chart.Chart', { renderTo: Ext.getBody(), width: 500, height: 300, animate: true, store: store, axes: [ { type: 'Numeric', position: 'left', fields: ['data1', 'data2'], label: { renderer: Ext.util.Format.numberRenderer('0,0') }, title: 'Sample Values', grid: true, minimum: 0 }, { type: 'Category', position: 'bottom', fields: ['name'], title: 'Sample Metrics' } ], series: [ { type: 'line', renderer: function(sprite, record, attributes, index, store){ return gapHandler(sprite, record, attributes, index, store, 'data1'); }, highlight: { size: 7, radius: 7 }, axis: 'left', xField: 'name', yField: 'data1', markerConfig: { type: 'cross', size: 4, radius: 4, 'stroke-width': 0 } }, { type: 'line', renderer: function(sprite, record, attributes, index, store){ return gapHandler(sprite, record, attributes, index, store, 'data2'); }, highlight: { size: 7, radius: 7 }, axis: 'left', xField: 'name', yField: 'data2', markerConfig: { type: 'circle', size: 4, radius: 4, 'stroke-width': 0 } } ] });
-
9 Dec 2012 10:47 PM #7
-
11 Dec 2012 11:09 AM #8
I found that if you put boolean false as the value of the data it will not render it and will create a gap in the chart
if you want a point with no data where you want your chart to continue you can put "" as the value:
Code:if(innerRecord.data.value != ""){ if(innerRecord.data.value == -1){ //create a gap items[index][record.data.entityId] = false; } else { items[index][record.data.entityId] = innerRecord.data.value * 1.0; } } else { //just continue the chart items[index][record.data.entityId] = ""; }
-
11 Dec 2012 12:26 PM #9
So it looks like gap issue wasn't a bug after all.
-
11 Dec 2012 9:43 PM #10
Hi @sidoron,
Well, it is a great finding! It appears to be working very well. Here is a simple example.
Example
Code:<!DOCTYPE html> <html> <head> <title>LineSeries Gaps</title> <link type="text/css" rel="stylesheet" href="../resources/css/ext-all.css" /> <script type="text/javascript" src="../ext-all-debug.js"></script> <script type="text/javascript"> Ext.onReady(function () { Ext.create("Ext.chart.Chart", { renderTo: Ext.getBody(), height: 400, width: 400, axes: [{ position: "bottom", title: "X", fields: ["x"], type: "Numeric" }, { position: "left", title: "Y", fields: ["y"], type: "Numeric" }], series: [{ title: "LineSeries", xField: "x", yField: "y", type: "line" }], store: { fields: [{ name: "x" }, { name: "y" }], autoLoad: true, proxy: { type: "memory", data: [{ x: 0, y: 0 }, { x: 25, y: 25 }, { x: 50, y: false }, { x: 75, y: 75 }, { x: 100, y: 100 }] } } }); }); </script> </head> <body> </body> </html>
You found a bug! We've classified it as
EXTJSIV-5302
.
We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.


Reply With Quote