chart wrapper/line chart dataview problem

455 views
Skip to first unread message

uover82

unread,
Sep 20, 2011, 10:25:43 AM9/20/11
to Google Visualization API
Hi All,

I'm working with a dashboard linking a slider with a line chart
filtering/displaying multiple columns/series.
Things work well/as expected to some extent. However, within certain
filter ranges, the underlying data table seems to begin filtering row
data as well as columns, which is the problem. Here's some related
code snippets:

function onControlStateChange() {
var controlState = slider.getState();
var filteredView =
filterView( dataTable,controlState.lowValue,controlState.highValue );
lineChart.setView( filteredView.toJSON() );
lineChart.draw();
}

function filterView( _table,_min,_max ) {
// filter a data table by min, max column values, producing a
data view.
var validColumns = [ 0 ];
var cellValue;
var valid;
for ( var i = 1;i<_table.getNumberOfColumns();i++ ) {
valid = true;
for ( var j = 0;j<_table.getNumberOfRows() && valid;j++ ) {
cellValue = _table.getValue( j,i );
if ( (cellValue < _min || cellValue > _max) && cellValue !=
null )
valid = false;
}

if ( valid )
validColumns.push( i );
}

var filteredView = new google.visualization.DataView( _table );
filteredView.setColumns( validColumns );

return filteredView;
}

validColumns data appears to remain correct/consistent, while the
underlying data table/chart seems to suffer the problem in some filter
ranges.

Has anyone else experienced this issue and/or know of a remedy?

Thanks

John

Riccardo Govoni ☢

unread,
Sep 20, 2011, 10:34:37 AM9/20/11
to google-visua...@googlegroups.com
Would you mind pasting the code you use to assemble the google.visualization.Dashboard as well, if any?

I suspect you are using a google.visualization.Dashboard linking together the slider with the linechart, _and_ your own onControlStateChange callback.
The former is geared toward performing row filtering (that's the way dashboards work by default), while your code performs the column filtering. The combination of the two is likely to generate the problem you describe.

-- R.



--
You received this message because you are subscribed to the Google Groups "Google Visualization API" group.
To post to this group, send email to google-visua...@googlegroups.com.
To unsubscribe from this group, send email to google-visualizati...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-visualization-api?hl=en.


uover82

unread,
Sep 20, 2011, 11:03:06 AM9/20/11
to Google Visualization API
Certainly, Richardo - thanks for the assistance.

Here's the dashboard code:

function responseHandler(response) {
// Remove the loading message (if exists).
var loadingMsgContainer = document.getElementById('loading');
loadingMsgContainer.style.display = 'none';

if (!gadgetHelper.validateResponse(response)) {
// Default error handling was done, just leave.
return;
}

dataTable = response.getDataTable();

var tx = prefs.getBool("haxis_time_format");

if ( tx )
formatTimeXAxis( dataTable );

var ref = getMaxColumn( dataTable );

// Define a slider control for the y-axis.
slider = new google.visualization.ControlWrapper({
'controlType': 'NumberRangeFilter',
'containerId': 'control1',
'options': {
'filterColumnIndex': ref, 'minValue': 0,
'ui':
{ 'labelStacking':'horizontal','orientation':'vertical','label':'' }
}
});


google.visualization.events.addListener( slider,'statechange',onControlStateChange );

dashboard.bind( slider,lineChart );
dashboard.draw( dataTable );
};

function formatTimeXAxis( _table ) {
// format the x-axis in time-only format.
var v;
var sp;
for ( var i = 0;i<_table.getNumberOfRows();i++ ) {
v = _table.getValue( i,0 );
sp = v.indexOf( ' ' );
if ( sp > 0 ) {
ts = v.substring( sp+1,v.length );
_table.setValue( i,0,ts );
}
}

Also, using the default binding/linkage seems to produce similar
results - filtered rows/columns.

Let me know what you think - thanks

John

On Sep 20, 7:34 am, Riccardo Govoni ☢ <battleho...@gmail.com> wrote:
> Would you mind pasting the code you use to assemble the
> google.visualization.Dashboard as well, if any?
>
> I suspect you are using a google.visualization.Dashboard linking together
> the slider with the linechart, _and_ your own onControlStateChange callback.
> The former is geared toward performing row filtering (that's the way
> dashboards work by default), while your code performs the column filtering.
> The combination of the two is likely to generate the problem you describe.
>
> -- R.
>

Riccardo Govoni ☢

unread,
Sep 20, 2011, 11:17:22 AM9/20/11
to google-visua...@googlegroups.com
Thanks, here's the explanation for the behavior you see.

Dashboards have been designed (in the current released status) to perform row-wise filtering. Therefore the dashboard.bind(slider, lineChart) line instructs the dashboard to filter the datatable row-wise whenever the slider is operated, and to feed the output of said filtering to the line chart.

In addition to that, your code also listens for changes in the slider status and feeds a column-filtered view to the line chart.

There's a race condition issue here (depending on which event handler is invoked first in response to slider changes, either yours or the dashboard one) which results in the weird behavior you experience.

Since you are taking care of manually wiring the slider and the linechart together, you can get rid of :

     dashboard.bind( slider,lineChart );
     dashboard.draw( dataTable );

and replace it with:

slider.draw(dataTable);
lineChart.draw(dataTable);

basically removing all the dashboard management logic (which you don't need since it operates row-wise) and retaining only the control and the linechart which you manually draw and wire together with your onControlStateChange() handler.

Would that work?
-- R.

uover82

unread,
Sep 20, 2011, 2:19:32 PM9/20/11
to Google Visualization API
Hi Richardo - thanks for the help

This doesn't seem to work, unfortunately - dashboard bind/draw seems
to be required for rendering, and wired/commenting the
onControlChange() handler doesn't seem to have any impact.
In any case, the row/column filtering problem remains.

I'll keep working/looking - can you think of any other options?

Thanks

John

On Sep 20, 8:17 am, Riccardo Govoni ☢ <battleho...@gmail.com> wrote:
> Thanks, here's the explanation for the behavior you see.
>
> Dashboards have been designed (in the current released status) to perform
> row-wise filtering. Therefore the dashboard.bind(slider, lineChart) line
> instructs the dashboard to filter the datatable row-wise whenever the slider
> is operated, and to feed the output of said filtering to the line chart.
>
> In addition to that, your code also listens for changes in the slider status
> and feeds a column-filtered view to the line chart.
>
> There's a race condition issue here (depending on which event handler is
> invoked first in response to slider changes, either yours or the dashboard
> one) which results in the weird behavior you experience.
>
> Since you are taking care of manually wiring the slider and the linechart
> together, you can get rid of :
>
>      dashboard.bind( slider,lineChart );
>      dashboard.draw( dataTable );
>
> and replace it with:
>
> slider.draw(dataTable);
> lineChart.draw(dataTable);
>
> basically removing all the dashboard management logic (which you don't need
> since it operates row-wise) and retaining only the control and the linechart
> which you manually draw and wire together with your
> onControlStateChange()handler.
>
> Would that work?
> -- R.
>

Riccardo Govoni ☢

unread,
Sep 21, 2011, 5:16:57 AM9/21/11
to google-visua...@googlegroups.com
Sorry, my bad, I've written my response too soon. ChartWrapper.draw() method does not accept a datatable parameter, so my suggestion to use:

slider.draw(dataTable);
lineChart.draw(dataTable);

is wrong. Instead, I created this example http://jsfiddle.net/nPWYh/ which should accomplish what you want. The slider lets you operate a column-wise filtering of the datatable. The way it works is the following:

- set up a ControlWrapper for the slider and give it the datatable in its 'dataTable' initialization parameter.
- set up a ChartWrapper for the chart and give it the datatable in its 'dataTable' initialization parameter.
- wire up the 'statechange' listener on the control
- do _not_ use google.visualization.Dashboard but just manually draw() both the slider and the chart (for the reasons described above).
- Whenever the statechange event fires, alter the chart 'view' and redraw it (note that to keep the example readable, I use a simplified filtering logic rather than the one you're using.

As said, note that the 'controls' API was initially designed for row-level filtering, so the example goes a bit outside the beaten track. For example, the 'filterColumnIndex' parameter (which would instruct the control which column operate upon) is useless in this scenario, but still required by the API.

-- R.

uover82

unread,
Sep 21, 2011, 3:57:41 PM9/21/11
to Google Visualization API
Hi Richardo,

Your solution works great - thank you for this excellent help!!

John

On Sep 21, 2:16 am, Riccardo Govoni ☢ <battleho...@gmail.com> wrote:
> Sorry, my bad, I've written my response too soon. ChartWrapper.draw() method
> does not accept a datatable parameter, so my suggestion to use:
>
> slider.draw(dataTable);
> lineChart.draw(dataTable);
>
> is wrong. Instead, I created this examplehttp://jsfiddle.net/nPWYh/which
> should accomplish what you want. The slider lets you operate a column-wise
> filtering of the datatable. The way it works is the following:
>
> - set up a ControlWrapper for the slider and give it the datatable in its
> 'dataTable' initialization parameter.
> - set up a ChartWrapper for the chart and give it the datatable in its
> 'dataTable' initialization parameter.
> - wire up the 'statechange' listener on the control
> - do _not_ use google.visualization.Dashboard but just manually draw() both
> the slider and the chart (for the reasons described above).
> - Whenever the statechange event fires, alter the chart 'view' and redraw it
> (note that to keep the example readable, I use a simplified filtering logic
> rather than the one you're using.
>
> As said, note that the 'controls' API was initially designed for row-level
> filtering, so the example goes a bit outside the beaten track. For example,
> the 'filterColumnIndex' parameter (which would instruct the control which
> column operate upon) is useless in this scenario, but still required by the
> API.
>
> -- R.
>

Benjamin Press

unread,
Jun 19, 2012, 6:49:48 PM6/19/12
to google-visua...@googlegroups.com
Okay, I figured out what the problem was. When you were creating the new set of columns to display on the graph, you were cutting off the "Year" column. If, before the for loop, you push the 0th column onto the array, it fixes everything. You also set the iteration to start at the low value, instead of low value minus 1.

On Tuesday, 19 June 2012 16:45:59 UTC-5, Benjamin Press wrote:
Hi there. So I noticed in the interactive example that you linked, that when you touch the slider, the lines on the table go all out of whack. Specifically, I think it's flipping the axis or something. Is this from the code you used? I couldn't figure out where this was happening. I'm trying to do something similar to this(only not using a slider). If you could look into this, I'd be appreciative.

> > > > To unsubscribe from this group, send email to

> > > > For more options, visit this group at
> > > >http://groups.google.com/group/google-visualization-api?hl=en.
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Google Visualization API" group.
> > To post to this group, send email to

> > To unsubscribe from this group, send email to

> > For more options, visit this group at
> >http://groups.google.com/group/google-visualization-api?hl=en.

--
You received this message because you are subscribed to the Google Groups "Google Visualization API" group.
To post to this group, send email to google-visualization-api@googlegroups.com.
To unsubscribe from this group, send email to google-visualization-api+unsub...@googlegroups.com.

Benjamin Press

unread,
Jun 19, 2012, 6:58:46 PM6/19/12
to google-visua...@googlegroups.com
Here's the link to the fixed version.

Reply all
Reply to author
Forward
0 new messages