Custom axes with Sencha 3.1 GXT Charts

Here’s a short idiom for today. If you have a Sencha chart with multiple BarSeries, you can click on the legend by default, which will “exclude” certain values from the recalculation of the y-axis minimum and maximum. We found that there are certain times when Sencha will compute the max range of a chart as a value less than 10, while the axis has 10 tick marks. This leaves some ugly decimal points in the y-axis labels, which just doesn’t make sense in some instances (e.g. you can’t have a fraction of a whole object).

Bad! You can't have a fraction of a device!
Bad! You can’t have a fraction of a device!

In order to get whole numbers here, I added a legend handler which recomputes the axis and sets a minimum value if Sencha would compute a < 10 max for the y-axis. Here's the code snippet:

			legend.addLegendSelectionHandler(new LegendSelectionHandler() {

				@Override
				public void onLegendSelection(LegendSelectionEvent event) {
					if (axis.getTo() < 10) {
						axis.setMaximum(10.0);
					} else {
						axis.setMaximum(Double.NaN);
						axis.setInterval(Double.NaN);
					}
					axis.calcEnds();
					axis.drawAxis(false);
					_chart.redrawSurface();
				}
				
			});

And here's the result:

Screen Shot 2014-04-01 at 2.04.52 PM
Ahh, much better.

Advertisement

Mapping tooltip of different key onto a GXT BarSeries

Here’s a little idiom for when you’re using one key for the value of a stacked bar chart but want to map a different ValueProvider onto your tooltip (or label).

		//Tooltip Config - gets (f) value but if null, just return the int
	    SeriesToolTipConfig<DataPoint> config = new SeriesToolTipConfig<DataPoint>();
	    config.setLabelProvider(new SeriesLabelProvider<DataPoint>() {
	        @Override
	        public String getLabel(DataPoint item, 
	        		ValueProvider<? super DataPoint, ? extends Number> valueProvider) {
	        	String vindex = valueProvider.getPath();
	        	String findex = vindex.replace(ChartModel.CELL_VALUE, ChartModel.CELL_FORMATTED_VALUE);
	        	MapLabelProvider labelProvider = new MapLabelProvider(findex);
	        	String tooltip = labelProvider.getValue(item);
	        	return tooltip == null || tooltip.equals(_chartConstants.emptyLabel()) ? 
	        		  String.valueOf(valueProvider.getValue(item).intValue()) : tooltip;
	        }
	    });
series.setToolTipConfig(config);

By default, Sencha GXT charts only passes in the valueProvider and the data item used to render the stacked bar chart. So what if you want to provider a different value for the tooltip or label? How do you add text? Since be follow the google datatables JSON format, we use a key of “v” in a cell array to represent the numeric value used to generate the chart. We use a key “f” in the same cell array to represent the tooltip.

Here’s what our JSON looks like and here’s the resultant store (After the adapter transforms the data).

{
    "offset": 0,
    "totalCount": 1,
    "items": [
        {
            "title": "Registration Summary",
            "data": {
                "cols": [
                    {
                        "id": "Stacked bar one",
                        "label": "Hamburgers",
                        "type": "number"
                    },
                    {
                        "id": "Stacked bar two",
                        "label": "Fries",
                        "type": "number"
                    }
                ],
                "rows": [
                    {
                        "l": "McDonalds",
                        "c": [
                            {
                                "v": "5",
                                "f": "5 hamburgers sold!"
                            },
                            {
                                "v": "2",
                                "f": "2 fries sold"
                            }
                        ]
                    },
                    {
                        "l": "Burger King",
                        "c": [
                            {
                                "v": "0",
                                "f": "0 hamburgers sold :("
                            },
                            {
                                "v": "3",
                                "f": "3 fries sold"
                            }
                        ]
                    }
... /* More omitted */
                ]
            }
        }
    ]
}

And here’s the resultant store:

[
    {
        v1=2,
        label0=Hamburgers,
        v0=5,
        label1=Fries,
        id1=Stacked bar two,
        type1=number,
        id0=Stacked bar one,
        type0=number,
        f1=2 fries sold,
        l=McDonalds,
        f0=5 hamburgers sold!
    },
    {
        v1=3,
        label0=Hamburgers,
        v0=0,
        label1=Fries,
        id1=Stacked bar two,
        type1=number,
        id0=Stacked bar one,
        type0=number,
        f1=3 fries sold,
        l=9650SIP,
        f0=0 hamburgers sold 😦
    }
... /* more omitted */
]

As you can see, we use v0 – vN to as values to render per bar in our chart, where each of v0 – vN corresponds to 1 stack within the bar. Here’s the resulting tooltip:

Custom tooltip
Custom tooltip