I have a LineSeries
RadCartesianChartView chart = new RadCartesianChartView(context);
CartesianChartGrid cartesianChartGrid = new CartesianChartGrid();
cartesianChartGrid.setMajorYLinesRenderMode(GridLineRenderMode.INNER_AND_LAST);
cartesianChartGrid.setMajorXLinesRenderMode(GridLineRenderMode.INNER_AND_LAST);
cartesianChartGrid.setLineThickness(1);
cartesianChartGrid.setLineColor(Color.CYAN);
chart.setGrid(cartesianChartGrid);
LineSeries series = new LineSeries();
series.setStrokeColor(Color.GRAY);
But line is shown continuous without any point denoting the data point.
How can I show circles as data points on line.
To show the data points you have to add some methods in series.
series.setShowLabels(true);
And in case you need you can format labels in any java format you need
series.setLabelFormat("%.0f");
Hope it helps
Related
I have created an android application similar to Not Tetris 2 using Libgdx with Box2d.
It can successfully remove a slice from the world, which obviously involves duplicating several bodies and destroying/creating fixtures. However, seemingly at random, a body with a 2x2 fixture will appear. The body and fixture are displayed using information related to the objects around it when it is created, so I narrowed its creation down to the following function:
Body duplicateBody(Body original){
BodyDef d = new BodyDef();
d.position.set(original.getPosition());
d.angle = original.getAngle();
d.linearVelocity.set(original.getLinearVelocity());
d.angularVelocity = original.getAngularVelocity();
Body dup = world.createBody(d);
dup.setType(BodyDef.BodyType.DynamicBody);
return dup;
}
I use this function in 2 different contexts:
Making a copy of the body if a "slice" cuts one in two -- I then transfer the fixtures which are below to it.
When a fixture is below the line then it is added to a body created for ones below
Making a copy of the body when groups of fixtures are separated
I commented out the code responsible for the third instance and still had the 2x2 boxes spawning, so here are the functions relevant to the others:
...
if (below && !above) {
//copy fixture, add copy to lower body and remove original
Body top = fixture.getBody();
FixtureDef n = new FixtureDef();
PolygonShape s = new PolygonShape();
s.set(getLocalVerticesOfFixture(fixture));
n.shape = s;
n.density = fixture.getDensity();
//create lower body if a lower one doesn't already exist
if (!topBottomPairs.containsKey(top)) {
Body dup = duplicateBody(top);
topBottomPairs.put(top, dup);
}
//delete fixture
remove.add(fixture);
Fixture f = topBottomPairs.get(top).createFixture(n);
s.dispose();
}
...
if (below && above) {
//copy fixture, add copy to lower body, but keep original on upper as it needs to split
FixtureDef n = new FixtureDef();
PolygonShape s = new PolygonShape();
s.set(getLocalVerticesOfFixture(fixture));
n.shape = s;
n.density = fixture.getDensity();
Body top = fixture.getBody();
//create lower body if a lower one doesn't already exist
if (!topBottomPairs.containsKey(top)) {
Body dup = duplicateBody(top);
topBottomPairs.put(top, dup);
}
Fixture second = topBottomPairs.get(top).createFixture(n);
s.dispose();
}
....
private Vector2[] getLocalVerticesOfFixture(Fixture fixture) {
PolygonShape shape = ((PolygonShape) fixture.getShape());
Vector2[] localVertices = new Vector2[shape.getVertexCount()];
for (int i = 0; i < shape.getVertexCount(); i++) {
localVertices[i] = new Vector2();
shape.getVertex(i, localVertices[i]);
}
return localVertices;
}
I also have this remove fixture function which runs on all fixtures I want to remove:
private void smartDeleteFixture(Fixture f){
f.getBody().destroyFixture(f);
if(f.getBody().getFixtureList().size == 0){
world.destroyBody(f.getBody());
}
}
Nowhere do I create vertices, let alone a fixture of a 2x2 shape. I was wondering if this duplication function has any flaws, or if I stumbled upon some "default shape" that box2d uses.
Edit: I have removed anything not related to the manipulation of box2d bodies. Hope that helps
Deleted this question as I decided to perform a major recode and hoped that would fix my problem. It did not, but I figured out the cause.
I looked through box2d and found a couple instances of code similar to this in the polygon shape class:
if (n < 3)
{
// Polygon is degenerate.
b2Assert(false);
SetAsBox(1.0f, 1.0f);
return;
}
These instances check the number of vertices after various operations and turn the shape into a 2x2 box if there are fewer than 3. One of these operations makes the shape convex. Another checks if vertices are close together (closer than 0.0025f), deleting one if so.
In my case, the problem was simple. Some of my vertices were less than 0.0025f from each other, resulting in them being deleted, the vert count dropping below 3, an assertion being ignored, and then my shape being turned into a 2x2 box. I hope this helps someone out.
Below is my simple code for a line chart. If I use this code but only have one Entry, one point shows on the graph, which is good. If I add any more, like I have below, nothing at all shows, unless I add "newchart.animateX(3000);, in which case the chart shows for 3000ms and then disappears.... what gives?
LineChart newchart = (LineChart) findViewById(R.id.chart);
ArrayList<Entry> YAxis = new ArrayList<>();
Entry startingtemp = new Entry(0,3);
Entry next = new Entry(1,6);
YAxis.add(next);
YAxis.add(startingtemp);
LineDataSet temps = new LineDataSet(YAxis, "fuck");
ArrayList<ILineDataSet> dataSets = new ArrayList<>();
dataSets.add(temps);
LineData data = new LineData(dataSets);
newchart.setData(data);
newchart.animateX(3000);
newchart.invalidate();
Okay, the reason it wasn't working was because I added an x value of 1 before 0. when i switched the order in which i added the two entrys to the array, it started working fine.
GraphViewData[] data = new GraphViewData[numElements];
for (int c = 0; c<numElements; c++) {
data[c] = new GraphViewData(c+1, pvalueArray[c]);
}
GraphView graphView = new LineGraphView(this, Captionname);
GraphViewSeries graphViewSeries = new GraphViewSeries(data);
I am populating a graph as above, my array contains values set to 2 decimal places.
When I use the graph on my app, the Y axis goes up to 3 decimal places. Can I force it to be 2?
I am using version 3.1.3. I don't really want to upgrade and have to change loads of code.
How do I use DefaultLabelFormatter? - Sorry I can't add a comment as I'm new!
I have had to upgrade to version 4 then I can use
NumberFormat nf = NumberFormat.getInstance();
nf.setMinimumFractionDigits(1);
nf.setMinimumIntegerDigits(2);
graph.getGridLabelRenderer().setLabelFormatter(new DefaultLabelFormatter(nf, nf));
Now stuck on how to add data from my array!!!
(I fixed some issues with saving and loading regarding my previous posts)
I am saving some data (mydata) and the date as strings (dates_Strings).
In graph activity I load data and dates.And I convert dates_Strings to dates in order to use them in the plot.
Now , while entering some data for example "1","2","3" in 10/05/13 I am getting the following image.
All good until now.
If I try to enter some more data ("3,4,7") in another date (13/05/13) I am getting this image.
The dates are superimposed.
The MainActivity :
The code:
//copy the dates_asString to date (Dates) in order to use them in TimeSeries
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy",Locale.US);
Date convertedDate;
try{
for (int k=0;k<mydata.size();k++){
convertedDate = formatter.parse(dates_Strings.get(k));
date.clear();
date.add(convertedDate);
Log.d("line","convertedDate :"+convertedDate);
}
}catch ...
//TimeSeries series = new TimeSeries("Showing data");
//for (int i=0;i<mydata.size();i++){
// series.add(i,mydata.get(i));
//}
XYSeries series = new XYSeries("Showing data");
for (int i=0;i<mydata.size();i++){
series.add(i,mydata.get(i));
}
XYMultipleSeriesDataset dataset=new XYMultipleSeriesDataset();
dataset.addSeries(series);
XYSeriesRenderer renderer =new XYSeriesRenderer();
renderer.setColor(Color.YELLOW);
...
XYMultipleSeriesRenderer mRenderer =new XYMultipleSeriesRenderer();
mRenderer.addSeriesRenderer(renderer);
...
mRenderer.setXRoundedLabels(false);
mRenderer.setXLabels(0);
//mRenderer.setXAxisMax(mydata.size());
for (int i=0;i<mydata.size();i++){
mRenderer.addXTextLabel(i,dates_Strings.get(i));
}
I put in setXAxisMax the value 14/05/2013 and I entered data in 10/05 and 13/05 for example.
When I use setXAxisMin the plot is completely empty.
Another weird problem occurs if I don't use setXAxisMax . I enter "1" and "2" as data but the plot shows the "2" (second data) in two points. :
------------------UPDATE----------------------------------------
Ok, I think the problem lies during saving the data in the file.
The user enters some data (mydata) in an edittext field and then presses the save button which saves that data together with the current date.
For example , user enters "1" and presses "save".
user enters "2" and presses "save".
So, I have data "1" and "2" in the same date (08/05/13).
I want to save one instance of the date (because it is the same date) in order to have one point (date) in x axis and 2 points (1 and 2) in y axis.
I am saving as:
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
for (int i=0;i<mydata.size();i++){
bw.write(mydata.get(i)+","+dates_Strings.get(i)+"\n");
}
I thought sth like:
for (int i=1;i<mydata.size();i++){
bw.write(mydata.get(i)+",");
while (!(dates_Strings.get(i).equals(dates_Strings.get(i-1))))
bw.write(dates_Strings.get(i)+"\n");
}
but it saves only the last entered data..
This looks like a wrong usage of the TimeSeries. You are calling series.add(i, something) where something is mydata.get(i) in your code. This means that the method add(double x, double y) inherited by TimeSeries from XYSeries is called, so x in your case ranges between 0 and mydata.size() - 1.
Just make sure you are correctly calling the add(Date x, double value) method in TimeSeries.
Basically i want to draw a graph where x-axis gives you the date and y axis gives u the count
I am getting data from server and parsing it in my two array's one is for count and other is for date
i am getting values in two array like this
SoapObject o=(SoapObject)p2.getProperty(xx);
UserCallStatusBean ld=new UserCallStatusBean();
if(o.getProperty("Month").toString().equals("anyType{}")){
ld.setDuration("");
}
else{
ld.setDuration(o.getProperty("Month").toString());
}
ld.setCount(Integer.parseInt(o.getProperty("Count").toString()));
CallStatus.add(ld);
GraphViewData o1=new GraphViewData(_iLoopCounter,Double.parseDouble(o.getProperty("Count").toString()));
String o2=new String(o.getProperty("Month").toString());
//String o2=new String(String.valueOf(_iLoopCounter));
arrData[xx]=o1;
arrXaxis[xx]=o2;
_iLoopCounter++;
After Getting the Value in two array i use Graph View Demo to create a grapg like
setContentView(R.layout.graphs);
// init example series data
exampleSeries = new GraphViewSeries(arrData);
// graph with dynamically genereated horizontal and vertical labels
GraphView graphView;
graphView = new BarGraphView(
this,"");
graphView.addSeries(exampleSeries); // data
graphView.setScalable(true);
graphView.setScrollable(true);
graphView.setViewPort(2,6);
graphView.setScrollable(true);
graphView.setHorizontalLabels(arrXaxis);
graphView.setGravity(Gravity.CENTER);
graphView.setBaselineAlignedChildIndex(4);
//graphView.setHorizontalLabels(labels);
LinearLayout layout = (LinearLayout) findViewById(R.id.graph1);
layout.addView(graphView);
Now My issue of concern is i am getting value of count on y-axis but i am also getting count of date on x-axis instead i want to show the date on x-axis
I Have read various articles to get string value on x-axis ,finded one to use Cutom lavel formatter , But didnt knw how to use so what i can do to get x-axis ? (Date Value)
I hope u understands ,Expecting Answer Pleasue will b aLl Mine
Thanks in advance