Bar chart in aChartEngine in Android - java

I am working on graph chart using aChartEngine, the problem faced is that the although graph are generating, problem is graph is not coming as per need inside the view, how to fix it ??
When selecting Bar from drop down
After Zooming Out and panning(by interacting with graph)
Here is my code
private static XYMultipleSeriesDataset getBarDataset(int rightAnswers, int wrongAnswers)
{
String[] labels={"right","wrong"};
List<Double> values = new ArrayList<Double>();
values.add((double) rightAnswers);
values.add((double) wrongAnswers);
XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
for (int i = 0; i < titles.length; i++)
{
XYSeries series = new XYSeries(titles[i]);
series.add(i,values.get(i));
dataset.addSeries(i,series);
}
return dataset;
}
2)Renderer
protected static XYMultipleSeriesRenderer buildBarRenderer(int[] colors) {
XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
renderer.addXTextLabel(0, "right");
renderer.addXTextLabel(1, "wrong");
renderer.setChartTitle("Results");
int length = colors.length;
SimpleSeriesRenderer r = new SimpleSeriesRenderer();
r.setColor(colors[0]);
renderer.addSeriesRenderer(r);
r = new SimpleSeriesRenderer();
r.setColor(colors[1]);
renderer.addSeriesRenderer(r);
renderer.setScale(10);
renderer.setXLabels(0);
renderer.setApplyBackgroundColor(true);
renderer.setBackgroundColor(Color.WHITE);
renderer.setAxesColor(Color.CYAN);
renderer.setBarWidth(30);
return renderer;
}
3) the view
ChartFactory.getBarChartView(context, getBarDataset(rightAnswers, wrongAnswers), buildBarRenderer(new int[]{Color.GREEN,Color.RED}), Type.DEFAULT);
Query
1) How to fix the position and exact panned graph
2) Can we have 3d effect on bars??How??
3) Is there any other library simpler compared to aChartEngine??

To solve the problem of having bar inside the graph we need to specify X-axis and Y-axis min and max based on your minimum and maximum values,eg; for the renderer, you need
renderer.setXAxisMin(-1);
renderer.setXAxisMax(wrongAnswers);
renderer.setYAxisMax(10);
renderer.setYAxisMin(0);
so the final result comes out to be

Related

Achartengine display values inside the series areas and horizontal legend

I have tried the following with the default renderer
CategorySeries series = new CategorySeries("First test");
int numSlide = portions.length;
for (int i = 0; i < numSlide; i++){
series.add(seriesNames[i]+" ("+portions[i]+" %)", portions[i]);
}
DefaultRenderer defaultRenderer = new DefaultRenderer();
SimpleSeriesRenderer simpleSeriesRenderer = null;
for (int i = 0; i < numSlide; i++){
simpleSeriesRenderer = new SimpleSeriesRenderer();
simpleSeriesRenderer.setColor(colors[i]);
simpleSeriesRenderer.setChartValuesFormat(new DecimalFormat("###,###,##0.0"));
defaultRenderer.addSeriesRenderer(simpleSeriesRenderer);
}
defaultRenderer.setInScroll(true);
defaultRenderer.setZoomButtonsVisible(false);
defaultRenderer.setZoomEnabled(true);
defaultRenderer.setLabelsTextSize(18); //value size
defaultRenderer.setLabelsColor(R.color.primary_dark);
defaultRenderer.setShowLegend(false);
defaultRenderer.setClickEnabled(true);
defaultRenderer.setPanEnabled(true);
defaultRenderer.setShowLabels(true);
defaultRenderer.setShowLegend(true);
//return the pie chart view
return ChartFactory.getPieChartView(context, series, defaultRenderer);
Now the above produces
What am looking forward to get is to have the percentage values eg: 2% inside the chart area something which looks like this
How do i get the percentage values to be displayed inside the charts?
You want to display values and hide labels. Do that like so in your renderer:
defaultRenderer.setShowLabels(false);
defaultRenderer.setDisplayValues(true);
Also, your series names should probably not contain the values, so change the following line
series.add(seriesNames[i]+" ("+portions[i]+" %)", portions[i]);
to
series.add(seriesNames[i], portions[i]);

UnfoldingMaps add MarkerList after initialization

I'm writing an application where I show markers on a map using the library Unfolding Maps.
The application lets the user choose a year and depending on that value other markers are shown. This works perfect, but when the user selects another year I can't seem to get the other markers shown.
I've tried to completely renew the map but after that first time it doesn't redraw a map.
Besides that I've tried to add a MarkerManager to the map but then I get errors of OpenGL.
setup function:
public void setup() {
/*
* Provincies, set zoom to 10
*/
size(1000, 800, OPENGL);
this.map = new UnfoldingMap(this, new Microsoft.RoadProvider());
map.zoomAndPanTo(belgie, 8);
map.setPanningRestriction(belgie, 1);
map.setZoomRange(8, 8);
drawOtherMarker();
//map.getMarkerManager(markerRemarck.get(keyM)).enableDrawing();
MapUtils.createDefaultEventDispatcher(this, map);
}
function that creates the MarkerManager and adds it to the map
private void createMarkers(ArrayList<double[]> dataMarker) {
float size = 0;
int i = 0;
ListIterator<double[]> dataIt = dataMarker.listIterator();
ArrayList<SimplePointMarker> markList = new ArrayList<SimplePointMarker>();
while (dataIt.hasNext()) {
double[] element = dataIt.next();
SimplePointMarker point = new SimplePointMarker(new Location(
element[0], element[1]));
if (element[2] > 1000)
size = 120;
else if (element[2] > 100)
size = 60;
else if (element[2] > 10)
size = 30;
else
size = 20;
point.setRadius(size);
point.setColor(color(64,64,64,100));
point.setStrokeColor(color(178,34,34));
point.setStrokeWeight(30);
point.setStrokeWeight(0);
point.setId(Integer.toString(i++));
markList.add(point);
}
MarkerManager man = new MarkerManager(markList);
map.addMarkerManager(man);
}
When the map is drawn and another set of markers must be drawn the following function is called:
public void drawOtherMarker(){
if(!markerRemarck.containsKey(keyM)){
markerRemarck.put(keyM, totalMark++);
createMarkers(dataMarkerProvince);
}
if(dataMarkerTown != null){
markerRemarck.put(keyM + "city", totalMark++);
createMarkers(dataMarkerTown);
}
for(int i = 0; i < totalMark;++i)
map.getMarkerManager(i).disableDrawing();
map.getMarkerManager(markerRemarck.get(keyM)).enableDrawing();
}
another function brings in the data required to make the markers. I just don't seem to manage to add a MarkerManager after the first draw.
EDIT
This map is placed inside a JPanel. And the years are choosen with the help of a JComboBox. Once a year is chosen the "dataMarker" variable containing the information for creating markers is updated
thanks in advance for helping me out.

Adding ladels to graphic data to XYPlot, XYShapeRenderer

i'm using jfreechart, and i need to add labels to my series data. There are bold dots on graphic and they need labels... Following code does not work.
XYSeries series = new XYSeries("Average Size");
series.add(.60, .70);
XYDataset xyDataset = new XYSeriesCollection(series);
XYItemRenderer rend = new XYShapeRenderer();
XYItemLabelGenerator generator = new XYItemLabelGenerator() {
#Override
public String generateLabel(XYDataset xyd, int i, int i1) {
return "Some label?";
}
};
//SeriesItemLabelGenerator
rend.setBaseItemLabelGenerator(generator);
rend.setBaseItemLabelsVisible(true);
ItemLabelPosition pos = new ItemLabelPosition(ItemLabelAnchor.CENTER, TextAnchor.TOP_LEFT);
rend.setBasePositiveItemLabelPosition(pos);
I think the problem is that XYShapeRenderer(http://www.jfree.org/jfreechart/api/javadoc/src-html/org/jfree/chart/renderer/xy/XYShapeRenderer.html), which extends AbstractXYItemRenderer, does not implement ItemLabelGenerator logic yet.
So, or you will need to use another Renderer.
For example, XYLineAndShapeRenderer(http://www.jfree.org/jfreechart/api/javadoc/src-html/org/jfree/chart/renderer/xy/XYLineAndShapeRenderer.html) implements it:
// draw the item label if there is one...
if (isItemLabelVisible(series, item)) {
drawItemLabel(g2, orientation, dataset, series, item, xx, yy,(y1 < 0.0));
}
Or you will need to extend XYShapeRenderer yourself and add the label drawing logic, using any of the other Renderer's source code as an example.

JfreeChart - How to hide item from legend - Problem of colors

I would like to hide items from legend in Jfreechart and I've tried this code
jFreeChart: How to hide items from legend?
It works but something strange happened : the colors of the legend items do not match to the right data anymore. In other words, in the graph, a piece of data appears in yellow for example but the legend corresponding to this item appears in another color. In fact, the colors in the legend have been mixed.
Besides, when I try to display both old and new legends, there is no problem of colors but when I make the old legend invisible, the problem of mixed color appears. Obviously, I would like not to display the old legend.
Working code =>
LegendItemCollection legendItemsOld = localCombinedDomainXYPlot.getLegendItems();
final LegendItemCollection legendItemsNew = new LegendItemCollection();
for(int i = 0; i<4; i++){
legendItemsNew.add(legendItemsOld.get(i));
}
LegendItemSource source = new LegendItemSource() {
LegendItemCollection lic = new LegendItemCollection();
{lic.addAll(legendItemsNew);}
public LegendItemCollection getLegendItems() {
return lic;
}
};
localJFreeChart.addLegend(new LegendTitle(source));
ChartUtilities.applyCurrentTheme(localJFreeChart);
localJFreeChart.getLegend().setVisible(true); ///////////////////
Not working code =>
LegendItemCollection legendItemsOld = localCombinedDomainXYPlot.getLegendItems();
final LegendItemCollection legendItemsNew = new LegendItemCollection();
for(int i = 0; i<4; i++){
legendItemsNew.add(legendItemsOld.get(i));
}
LegendItemSource source = new LegendItemSource() {
LegendItemCollection lic = new LegendItemCollection();
{lic.addAll(legendItemsNew);}
public LegendItemCollection getLegendItems() {
return lic;
}
};
localJFreeChart.addLegend(new LegendTitle(source));
ChartUtilities.applyCurrentTheme(localJFreeChart);
localJFreeChart.getLegend().setVisible(false); ///////////////////
Based on this thread, you might try adding a null element to replace the unwanted legend item. The other approach appears to elide unwanted items, but I'm not sure if you're doing the same. To clarify, consider posting an sscce that demonstrates the problem. One of the org.jfree.chart.demo classes may be a suitable starting point.

JFreeChart : obtain data source value on mouse click

I have a JFreeChart instance that displays process memory status, initialized as follows:
m_data = new TimeSeriesCollection();
TimeSeries vmsize = new TimeSeries("VMSize");
TimeSeries resident = new TimeSeries("Resisdent");
TimeSeries shared = new TimeSeries("Shared memory");
TimeSeries code = new TimeSeries("Code");
TimeSeries data = new TimeSeries("Data");
m_data.addSeries(vmsize);
m_data.addSeries(resident);
m_data.addSeries(shared);
m_data.addSeries(code);
m_data.addSeries(data);
JFreeChart chart = ChartFactory.createTimeSeriesChart("Memory usage", "Time", "Size", m_data, true, true, false);
m_chart = new ChartPanel(chart);
Later I add values to each TimeSeries in the TimeSeriesCollection. I would like to somehow know - when the user clicks on the Chart - either what time associated with that columm, or even better - what is the index of the value.
I looked at the JFreeChart and ChartMouseListener classes, but I could not figure out how to do that (also the documentation of JFreeChart is annoyingly scarce, I guess they are trying to get people to buy their developer's guide).
if you click dead on the item, the event.getEntity() function returns XYItem and then from there onwards
XYItemEntity xyitem=(XYItemEntity) event.getEntity(); // get clicked entity
XYDataset dataset = (XYDataset)xyitem.getDataset(); // get data set
System.out.println(xyitem.getItem()+" item of "+xyitem.getSeriesIndex()+"series");
System.out.println(dataset.getXValue(xyitem.getSeriesIndex(), xyitem.getItem()));
System.out.println(dataset.getYValue(xyitem.getSeriesIndex(), xyitem.getItem()));
Comparable comparable=dataset.getSeriesKey(0);
XYPlot xyplot = (XYPlot) event.getChart().getPlot();
System.out.println(xyplot.getRangeCrosshairValue());
however incase you do not click on the item itself but your crosshair is set to auto lock on data, in such case the crosshair will move to nearest item but since the item has not been clicked, you will not be able to get the XYItem and hence you cannot know the series and item index, to solve this problem there is this code below, it should be put in the catch clause while the above mentioned code should be in try clause
first define a function which will take crosshair value at domain and range and also Xydataset, this functions returns an inner class object that groups item index and series index
public static SeriesAndItemIndex getItemIndex(double domainVal,double rangeVal,XYDataset xydataset){
Comparable comparable;
int indexOf;
for(int i=0;i<xydataset.getSeriesCount();i++){
comparable = xydataset.getSeriesKey(i);
indexOf=xydataset.indexOf(comparable);
for(int j=0 ; j<xydataset.getItemCount(indexOf);j++){
double x=xydataset.getXValue(indexOf, j);
double y=xydataset.getYValue(indexOf, j);
if(x == domainVal && y==rangeVal){
return new SeriesAndItemIndex(j,indexOf);//return item index and series index
}
}
}
return null;
}
private static class SeriesAndItemIndex{ ///inner CLASS to group series and item clicked index
public int itemIndex;
public int seriesIndex;
public SeriesAndItemIndex(int i,int s){
itemIndex=i;
seriesIndex=s;
}
#Override
public String toString(){
return "itemIndex="+itemIndex+",seriesIndex="+seriesIndex;
}
}
how to use it?
try{......code block from the top
}catch(Exception e){
Object source=event.getSource();
JFreeChart chartpanel=(JFreeChart)source;
XYPlot xyplot = (XYPlot) chartpanel.getPlot();
XYDataset xydataset= xyplot.getDataset();
double d=xyplot.getDomainCrosshairValue(); //get crosshair X value
double r =xyplot.getRangeCrosshairValue(); //get crosshair y value
SeriesAndItemIndex index=getItemIndex(d,r,xydataset);
if(index != null){
System.out.println(index.toString());
}
}
hmm should work, if you replace the last two lines by something like this:
ChartPanel panel=new ChartPanel(ChartFactory.createTimeSeriesChart("Memory usage", "Time", "Size", m_data, true, true, false)));
panel.addChartMouseListener(new ChartMouseListener(){
void chartMouseClicked(ChartMouseEvent e){
[...do something on click...]
}
void chartMouseMoved(ChartMouseEvent e){
[...do something on move...]
}
});
return panel;

Categories

Resources