I have a program android use graph view but default label graph view using int number like 1, 2 or 3. I wanna change the label from 1, 2, 3 to A, B, C horizontal label like this http://prntscr.com/bwxclx
My code like this
GraphView bar_graph = (GraphView) findViewById(R.id.graph);
BarGraphSeries<DataPoint> bar_series = new BarGraphSeries<DataPoint>(new DataPoint[] {
new DataPoint(0, 0),
new DataPoint(1, 7), // 1st war
new DataPoint(1.5, 0),
new DataPoint(2, 5), // 2nd war
new DataPoint(2.5, 0),
new DataPoint(3, 8), // 3rd war
new DataPoint(3.5, 0),
new DataPoint(4, 0)
});
Anyone can help me how to change label 1, 2, 3 to A, B, C
You can set labels statically using StaticLabelsFormatter().
In my case below, the "plotArrayX" is an array containing the values I want. They can be text, numbers or empty.
I've used it to generate timestamps set at.
The code below is kotlin, but it's quite simlar to java.
val staticLabelsFormatter = StaticLabelsFormatter(graph)
staticLabelsFormatter.setHorizontalLabels(plotArrayX)
graph.getGridLabelRenderer().setLabelFormatter(staticLabelsFormatter)
my actual X axis datapoints are just an incremented integer. The labels are then automatically exchanged with the static ones in the final view.
Related
Hi all I am just trying out a simple XY Plot with AndroidPlot. I am having trouble figuring out how to change the label colours for the domain and range. Examples online say to use:
plot.getGraphWidget().getDomainLabelPaint().setColor(my_colour);
plot.getDomainLabelWidget().getLabelPaint().setColor(my_colour);
However this does not compile for me. Can anyone suggest what I need to use? (I have also tried using getGraph() instead of getGraphWidget() )
I'm also trying to set margin space between the graph and domain labels, and also space between graph and range labels if anyone has a suggestion for that.
plot = (XYPlot) findViewById(R.id.plot);
plot.setPlotMargins(0, 0, 0, 0);
plot.getBackgroundPaint().setColor(Color.WHITE);
plot.setBorderStyle(XYPlot.BorderStyle.NONE, null, null);
plot.getGraph().getBackgroundPaint().setColor(Color.WHITE);
plot.getGraph().getGridBackgroundPaint().setColor(Color.WHITE);
plot.getGraph().getDomainOriginLinePaint().setColor(Color.TRANSPARENT);
plot.getGraph().getRangeOriginLinePaint().setColor(Color.TRANSPARENT);
// create a couple arrays of y-values to plot:
final Number[] domainLabels = {1, 10, 20, 6, 7, 8, 9, 10, 13, 14};
Number[] series1Numbers = {1, 4, 2, 8, 4, 16, 8, 32, 16, 64};
// turn the above arrays into XYSeries':
// (Y_VALS_ONLY means use the element index as the x value)
XYSeries series1 = new SimpleXYSeries(
Arrays.asList(series1Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series1");
// create formatters to use for drawing a series using LineAndPointRenderer
// and configure them from xml:
LineAndPointFormatter series1Format = new LineAndPointFormatter();
series1Format.setPointLabelFormatter(new PointLabelFormatter());
series1Format.configure(getApplicationContext(),
R.xml.line_point_formatter_with_labels);
LineAndPointFormatter series2Format = new LineAndPointFormatter();
series2Format.setPointLabelFormatter(new PointLabelFormatter());
series2Format.configure(getApplicationContext(),
R.xml.line_point_formatter_with_labels_2);
// add an "dash" effect to the series2 line:
series2Format.getLinePaint().setPathEffect(
new DashPathEffect(new float[]{
// always use DP when specifying pixel sizes, to keep things consistent across devices:
PixelUtils.dpToPix(20),
PixelUtils.dpToPix(15)}, 0));
plot.addSeries(series1, series1Format);
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM).setFormat(new Format() {
#Override
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
int i = Math.round(((Number) obj).floatValue());
return toAppendTo.append(domainLabels[i]);
}
#Override
public Object parseObject(String source, ParsePosition pos) {
return null;
}
});
Looks like you found the answer to your text color problem.
As far as adjusting the spacing between your graph and the domain / range labels, as of Androidplot 1.x that's controlled by the graph's line label insets. For example, to adjust the relative positioning of range labels on the left edge of the graph:
programmatically:
// move line labels away from the graph by 5dp:
plot.getGraph().getLineLabelInsets().setLeft(PixelUtils.dpToPix(-5));
xml param:
ap:lineLabelInsetLeft="-5dp"
I have a screen on my app that display the following graph:
Is there a way to change my legend so that it can say what each color represents? Currently I can get the blue square to show up but it doesn't represent any of the numbers. Here is the code I'm using when creating the graph:
GraphView graph = (GraphView) findViewById(R.id.graph);
BarGraphSeries<DataPoint> series = new BarGraphSeries<DataPoint>(new DataPoint[]{
new DataPoint(1, personal),
new DataPoint(2, fun),
new DataPoint(3, work),
new DataPoint(4, food),
new DataPoint(5, commute),
new DataPoint(6,bills)
});
graph.setTitle("Expenses");
graph.addSeries(series);
graph.getLegendRenderer().setVisible(true);
graph.getLegendRenderer().setAlign(LegendRenderer.LegendAlign.TOP);
series.setValueDependentColor(new ValueDependentColor<DataPoint>() {
#Override
public int get(DataPoint data) {
return Color.rgb((int) data.getX() * 255 / 4, (int) Math.abs(data.getY() * 255 / 6), 100);
}
});
series.setSpacing(50);
series.setDrawValuesOnTop(true);
series.setValuesOnTopColor(Color.RED);
backToMainMenu();
}
I don't think you need to customize the legend. The LegendRenderer class uses the title of each series of data to display what the bars on the chart represent.
series.setTitle("This will display in the legend.");
However, you only have one series of data in this example. If you must have labels in the legend for each bar, I suggest adding multiple series with different titles to your chart. Each series will have its own title and color.
// Each series represents one bar.
BarGraphSeries<DataPoint> series1 = new BarGraphSeries<DataPoint>(new DataPoint[]{ new DataPoint(1, personal)});
BarGraphSeries<DataPoint> series2 = new BarGraphSeries<DataPoint>(new DataPoint[]{ new DataPoint(2, fun)});
BarGraphSeries<DataPoint> series3 = new BarGraphSeries<DataPoint>(new DataPoint[]{ new DataPoint(3, work)});
BarGraphSeries<DataPoint> series4 = new BarGraphSeries<DataPoint>(new DataPoint[]{ new DataPoint(4, food)});
BarGraphSeries<DataPoint> series5 = new BarGraphSeries<DataPoint>(new DataPoint[]{ new DataPoint(5, commute)});
BarGraphSeries<DataPoint> series6 = new BarGraphSeries<DataPoint>(new DataPoint[]{ new DataPoint(6, bills)});
// Add titles to be displayed in the legend.
series1.setTitle("personal");
series2.setTitle("fun");
series3.setTitle("work");
series4.setTitle("food");
series5.setTitle("commute");
series6.setTitle("bills");
// Add color to your bars.
series1.setColor(Color.rbg(1,2,3));
series2.setColor(Color.rbg(4,5,6));
series3.setColor(Color.rbg(7,8,9));
series4.setColor(Color.rbg(0,1,2));
series5.setColor(Color.rbg(3,4,5));
series6.setColor(Color.rbg(6,7,8));
// Add each series to your graph.
graph.addSeries(series1);
graph.addSeries(series2);
graph.addSeries(series3);
graph.addSeries(series4);
graph.addSeries(series5);
graph.addSeries(series6);
// Display the legend.
graph.getLegendRenderer().setVisible(true);
you could use a custom legend renderer and extend the default implementation.
https://github.com/jjoe64/GraphView/blob/master/src/main/java/com/jjoe64/graphview/LegendRenderer.java
Or you disable the legend in graphview, use a FrameLayout and overlay the graph with your very own views for your legend
I have a graph that is not a real time graph, i want to add the x-axis and y-axis from the data that i have.
GraphView line_graph = (GraphView) findViewById(R.id.graph3);
LineGraphSeries<DataPoint> line_series =
new LineGraphSeries<DataPoint>(new DataPoint[] {
new DataPoint(0, 0),
new DataPoint(1, 5),
new DataPoint(2, 3),
new DataPoint(3, 2),
new DataPoint(4, 6)
});
line_graph.addSeries(line_series);
i was just testing the graph with the above points. And now i have an array received from database using JSON, i want to use them as the x-axis data and y-axis data. Just like array[oddNumber] as x-axis data, array[evenNumber] as y-axis data. Is there any way to do that?
Get your JSON data and convert it in Integer array like xAxis and yAxis.
Now do like this,
Integer[] xAxis = new Integer[]{0, 1, 2, 3, 4};
Integer[] yAxis = new Integer[]{0, 5, 3, 2, 6};
GraphView line_graph = (GraphView) findViewById(R.id.graph3);
DataPoint[] dataPoints = new DataPoint[xAxis.length];
for (int i = 0; i < xAxis.length; i++)
{
dataPoints[i] = new DataPoint(xAxis[i],yAxis[i]);
}
LineGraphSeries<DataPoint> line_series =
new LineGraphSeries<DataPoint>(dataPoints);
line_graph.addSeries(line_series);
Note: Length of xAxis and yAxis array must be same.
I created a simple game where move the objects from one place to another and each moves increment count of moves in score table. After all objects are moved correct I want set opacity to screen and slowly resizing score from initial size(e.g. 15px) to whole screen(e.g. 50px). I load font like this:
FontFactory.setAssetBasePath("font/");
final ITexture mainFontTexture = new BitmapTextureAtlas(activity.getTextureManager(), 256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
font = FontFactory.createStrokeFromAsset(activity.getFontManager(), mainFontTexture, activity.getAssets(), "font.ttf", 15, true, Color.WHITE, 2, Color.BLACK);
font.load();
In createScene() method I create HUD with text and I initial text:
Int mMoves = 0;
HUD gameHUD = new HUD();
Text mText = new Text(25, 25, font, "Moves: " + "123456789", getVertexBufferObjectManager());
And each moves set text with actual moves count:
mText.setText("Moves: " + mMoves++);
And when level was complete I don't know how can I resize this text. I mean something like scale with transition in CSS3..
Thanks for all comments
You can set the size of the text by using the setscale function.
If you just want to set the size use the following :
Example : mText.setScale(1.5f);
You can also use Entity modifiers to create an animation:
ScaleModifier scale = new ScaleModifier(1f, 1f, 1.1f);
LoopEntityModifier loop = new LoopEntityModifier(scale);
mText.registerEntityModifier(loop);
This will give a animation effect re-sizing the text in a loop.
I'm trying to make a BarChart using achartengine, but so far, I haven't been able to get rid of the following effect : bar width is only correctly displayed when values are on the edge of the screen, but at startup, bars are much bigger and sometimes even hide the bar's value. Could this have something to do with my data set not being a continued serie of x values ? I have one point at x=17 then then next value is at x=24, and it seems the changing bar width happens between these 2 values. Can someone assist in making this graph look good ?
Thanks in advance for your help !
[The graph being shown on fragment's start]
[The graph being shown when scrolling to the left]
CODE TO MAKE THE GRAPH :
XYSeries xySerie = new XYSeries("Climb Level Statistics");
XYSeriesRenderer serieRenderer;
XYMultipleSeriesDataset mDataset = new XYMultipleSeriesDataset();
XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();
//Adding data to XYSerie and adding XYSerie to mDataset
//stats is an int[] containing level id, value for the level, level id, ...
//example of dataset used for image shown above: {17, 4, 24, 3, 25, 7, 26, 10, 27, 4}
int statsSize = stats.size();
double routeLevel;
double climbsQuantity;
for (int counter = 0; counter<statsSize; counter++){
routeLevel = stats.get(counter);
counter++;
climbsQuantity = stats.get(counter);
xySerie.add(routeLevel, climbsQuantity);
}
mDataset.addSeries(xySerie);
//Setting series renderer properties and adding it to the mRenderer
serieRenderer = new XYSeriesRenderer();
serieRenderer.setChartValuesTextSize(28);
serieRenderer.setDisplayChartValues(true);
mRenderer.addSeriesRenderer(serieRenderer);
//Setting main renderer properties
mRenderer.setApplyBackgroundColor(true);
mRenderer.setMarginsColor(Color.argb(0x00, 0x01, 0x01, 0x01));
mRenderer.setBackgroundColor(Color.TRANSPARENT);
mRenderer.setLabelsTextSize(15);
mRenderer.setMargins(new int[] { 30, 30, 30, 30 });
mRenderer.setZoomButtonsVisible(false);
mRenderer.setPanLimits(new double[]{0,48, 0, 5000});
mRenderer.setBarSpacing(1.5);
mRenderer.setLabelsTextSize(28);
mRenderer.setLabelsColor(Color.BLACK);
mRenderer.setXLabels(0);
mRenderer.setXLabelsColor(Color.BLACK);
String[] routeLevels = context.getResources().getStringArray(R.array.route_levels);
int routeLevelsSize = routeLevels.length;
for (int x=1;x<routeLevelsSize+1;x++){
mRenderer.addXTextLabel(x, routeLevels[x-1]);
}
mRenderer.setYLabels(0);
mRenderer.setYAxisMin(0);
mRenderer.setShowLegend(false);
mRenderer.setZoomEnabled(false);
mRenderer.setZoomEnabled(false, false);
mRenderer.setPanEnabled(true, false);
GraphicalView graphView = ChartFactory.getBarChartView(context, mDataset, mRenderer, BarChart.Type.STACKED);
graphView.setBackgroundColor(Color.argb(255, 247, 247, 247));
I was able to resolve the changing bar width issue by ensuring the serie was a "perfect" suite for x values, changing
this : {17, 4, 24, 3, 25, 7, 26, 10, 27, 4}
to this : {17, 4, 18, 0, 19, 0, 20, 0, 21, 0, 22, 0, 23, 0, 24, 3, 25, 7, 26, 10, 27, 4}
To achieve that, I modified my first for loop to check for missing x values :
for (int x = 0; x<statsSize; x++){
routeLevel = currentLevel;
x++;
currentLevel++;
climbsQuantity = stats.get(x);
xySerie.add(routeLevel, climbsQuantity);
//if not at the last x/y couple of the array, fill the blanks in the serie
if (x<statsSize-1){
while (stats.get(x+1)>currentLevel){
routeLevel = currentLevel;
climbsQuantity = 0;
xySerie.add(routeLevel, climbsQuantity);
currentLevel++;
}
}
}
Now the bar width doesn't change at all when I scroll. This is more a workaround, though, because now the "filling" couples I added are all showing 0 as value, which I find a bit odd. If I find a way to hide these 0 values, I'll edit my answer...
CURRENT APPEARANCE OF THE GRAPH
First of all, you can set the visible area by changing the X axis min and max:
renderer.setXAxisMin(min);
renderer.setXAxisMax(max);
For changing the bars width, you have a few options.
If your dataset contain more than one element per series then I suggest you use renderer.setBarSpacing().
If there is only one element in your series then you can use renderer.setBarWidth().