I have intention on looking for a specific point in a line chart of MPAndroidChart and then display the the marker to highlight the point after a button is hit. The example given is where the marker is only displayed after touching event which is different in my case. I tried code below but to no avail, can some one please teach me I would appreciate.
Highlight h = new Highlight((int) valIndex, linechart2.getData().getDataSetCount());
linechart2.highlightValue(h, true);
mv2.refreshContent2(valueYAxis.get((int) valIndex), h);
linechart2.getMarkerView();
linechart2.setDrawMarkerViews(true);
linechart2.getData().setHighlightEnabled(true);
// RefreshChart();
linechart2.invalidate();
You can easily highlight values programmatically by using one of the following methods on your Chart object:
highlightValues(Highlight[] highs): Highlights the values at the given indices in the given DataSets. Provide null or an empty array to undo all highlighting.
highlightValue(int xIndex, int dataSetIndex): Highlights the value at the given x-index in the given DataSet. Provide -1 as the x-index or dataSetIndex to undo all highlighting.
It's all in the wiki.
the makerview will show when the point is highlighted, so you can try this
Highlight h = new Highlight((int) valIndex, 0);
mv2.refreshContent2(valueYAxis.get((int) valIndex), h);
linechart2.setMarker(mv2);
linechart2.highlightValue(h);
Related
I have multiple DataSet in line chart and i want to highlight all the Y points with custom overlay image. do we have any function for it ?
If not then
is there any function which can return corresponding pixel values for an entry object ?
Any direction would be appreciated.
Thanks you for reading.
The method is given by getPixelForValues(x,y) in Transform class
val viewPortHandler = ViewPortHandler()
viewPortHandler.setChartDimens(canvas.width.toFloat(),canvas.height.toFloat())
val transformer = Transformer(viewPortHandler)
var mpPointD = transformer.getPixelForValues(x, y)
But the transformation is not working for me with the points I pass but I know that the lib uses it with similar data that I set
I try to find the extrapolated Y value of a point on a androidplot curve.
For example, I have three points in a array: A (0; 0) B (15; 5) C (30; 0).
I displayed in androidplot with smoothing using SplineLineAndPointFormatter.
How can we do to find the Y value of the point N(10; ?)
Look at the example image
Thanks for any help in advance.
First off, you should not use that interpolation method because it uses cubic beziers and will plot false data. I posted a full answer in the linked question back in 2014.
Instead you should use the CatmullRomInterpolator. Once you've switched over to that, you can retrieve the interpolated series by invoking CatmullRomInterpolator.interpolate(XYSeries, Params). You can then retrieve N directly from the interpolated series.
I'm using achartengine in my Android Application, it works well but i have a question.
Is it possible to reverse plot?
I mean in my graph, new values which are added to my XY series with the function add, are added at end of the series, and then the graph is redrawn, so new values appears at right of the graph.
But i want to add my new value at index 0, in order to show on the graph only the last X values.
Sorry if it's not very clear
Thanks
There is no support for inserting data to XYSeries at a given index. However you could get to this behavior by clearing the current data and adding it back, with the new value included. I know this would not be a very optimal way, but it helps you get to your needed behavior.
Edit: I added an add(index, x, y) method in XYSeries. You can download a version including this feature here.
So, i've found a trick:
Dataset is my XYseries and mRenderer my multipleSeriesRenderer
I've changed alignment of the Y axis:
mRenderer.setYAxisAlign(Align.RIGHT, 0);
I've erased automatic labels:
mRenderer.setXLabels(0);
The 0 on the axe X is now a custom label, so every time a new value is added to the graph, I have to change is position:
mRenderer.setXAxisMax(dataset.getItemCount() - 1); mRenderer.addXTextLabel(dataset.getItemCount() - 1, "0");
And to finish, i change the X axis min everytime a new value is added, in order to get a fix scale:
mRenderer.setXAxisMin(dataset.getItemCount() - scale - 1);
I have a for loop that is looping through an array of rectangles as they appear. For each new rectangle that is added to the array a sprite is drawn on top of it. I want each sprite drawn on top of the rectangles to have its own variable that changes the sprite drawing. While on the screen mostly every rectangle should have a different sprite drawn on it ------------------------------------I cant figure out how to give each sprite its own variable with out giving the same one to all of the other sprites. This code ends up drawing the new same sprite on every rectangle. Here is what i have so far..
int arrayplace = 0;
for(Rectangle rain: rectangleArray) {
numberArray.add(arrayPlace, MathUtils.random(3);
//adds a variable to a certain spot on the array
// picks random# within range given
arrayplace++;
if (numberArray.get(arrayPlace)==1){
spritebatch.draw(spriteOne, rain.x, rain.y);
};
if (numberArray.get(arrayPlace)==2){
spritebatch.draw(spriteTwo, rain.x, rain.y);
}
if (numberArray.get(arrayPlace)==3){
spritebatch.draw(spriteThree, rain.x, rain.y);
}
}
The mistake is:
arrayplace++;
You increment arrayplace too early, so it points to an index behind the value you added.
The way random generators work, they generate a series of numbers based on a "seed" value. The first number in the series is going to be the same given the same seed. Are you using your random function correctly? Most likely the value of "10" you are passing to the random method is the seed. Do you need to call some other function to give you the next random number? Check you random function documentation. Here is the Java random doc : http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Random.html#Random(long) Refer to the usage of seed parameter to the constructor and to the method next() or nextInt()
Going further, I think you need to change the "seed" to the random generator every time you enter the loop, instead of using a constant 10.
I guess the reason you are getting the same random number is that you are initializing the class in each loop. so, you are generating the first number which will be the same each time.
Try to initialize MathUtils object outside the for-loop:
MathUtils m = new MathUtils();
And inside the loop, use this line to generate a number:
PointlessRect.x = m.random(10);
Hope this will work
I want to integrate a simple XY line chart in my Activity. While looking for free charting with customization (customizable backgrounds, colors, axis labels), I found two candidates: Achartengine and Adnroidplot. There were some other libraries, but they were not customizable or available only as separate Intents.
I need also support for older Android API (at least 1.6 must be supported).
I tried Achartengine but it failed when I integrated it in a ScrollView. When I was scrolling, the chart became somehow corrupted, it got squeezed and some background elements seemed to drift away.
Then I tried Adnroidplot. At first it did not start on 1.6 because of a Pair class. But I found a fix for the problem on Adnroidplot forum. Everything seemed to work fine, also dynamic updates though custom Observers worked fine. It was a bit hard to customize X axis labels (I needed custom Strings there and not numbers), but with a custom formatter I finally did it.
But then I tried it with real data from a client's database. There were some series of points with equal values. And I was shocked to see that Adnroidplot is not able to draw a horizontal line, it hangs or completely messes up the chart!
Here is the test case, I borrowed it from Adnroidplot Quickstart and did a small modification to make one series with equal values:
pricesPlot = (XYPlot) findViewById(R.id.mySimpleXYPlot);
// Create array of y-values to plot:
Number[] series1Numbers = {7, 7}; // horizontal line expected, got nothing or hang
// Turn the above arrays into XYSeries:
XYSeries series1 = new SimpleXYSeries(
Arrays.asList(series1Numbers), // SimpleXYSeries takes a List so turn our array into a List
ArrayFormat.Y_VALS_ONLY, // Y_VALS_ONLY means use the element index as the x value
"Series1"); // Set the display title of the series
// Create a formatter to use for drawing a series using LineAndPointRenderer:
LineAndPointFormatter series1Format = new LineAndPointFormatter(
Color.rgb(0, 200, 0), // line color
Color.rgb(0, 100, 0), // point color
null); // fill color (optional) <- my app hangs if I add it for a horizontal line
// Add series1 to the xyplot:
pricesPlot.addSeries(series1, series1Format);
// Reduce the number of range labels
pricesPlot.setTicksPerRangeLabel(3);
// By default, AndroidPlot displays developer guides to aid in laying out your plot.
// To get rid of them call disableAllMarkup():
pricesPlot.disableAllMarkup();
I already posted on Adnroidplot forums, but I am not sure how fast they will answer and when the issue will be fixed.
So I hope maybe someone at StackOverflow might know some workaround for it?
Thanks to the developers on Androidplot forums, I now got the solution. The following code is a fragment of my Activity.java file. Unfortunately the final code was later refactored and some pieces moved to a custom datasource and custom XYSeries which I don't have permissions to publish here.
This code worked for Androidplot-core-0.4.4-release.jar, and I'm not sure if it will work with later versions.
// for chart
private XYPlot pricesPlot;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ... other initialisation code omitted for brevity ...
pricesPlot = (XYPlot) findViewById(R.id.mySimpleXYPlot);
// the following code was added as a debug code to test that it works.
// later many things were changed, so take it "as is" - this was the core of the solution
PriceDatesFormat ppf = new PriceDatesFormat();
ppf.Labels = new String[]{
"2011-01",
"2011-05",
"2011-07",
"2011-11",
"2011-07",
"2011-07"
};
pricesPlot.getGraphWidget().setDomainValueFormat(ppf);
// Create two arrays of y-values to plot:
Float [] seriesNumbers = new Float[]{118f, 185f};
Float min = Collections.min(Arrays.asList(seriesNumbers));
Float max = Collections.max(Arrays.asList(seriesNumbers));
pricesPlot.setRangeBoundaries(min - 0.1*min, max + 0.1*max, BoundaryMode.AUTO);// make them a bit wider out of min/max values
I came up with an easy workaround to make sure horizontal lines are shown.
Basically, just graph a 3 point clear Y_VALS_ONLY series before you load your first real plot.
Assuming you have a colors.xml res file, you can create a clear series like this:
Declare this:
Number[] yClear = {0, 1, 0};
LineAndPointFormatter clearFormat;
SimpleXYSeries clear= null;
In your onCreate() or onViewCreated():
clearFormat = new LineAndPointFormatter(getResources().getColor(R.color.transparent), getResources().getColor(R.color.transparent), 0, null);
Then after you set up your plot, just add the clear plot to the graph;
clear = new SimpleXYSeries( Arrays.asList(yClear), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Clear");
yourPlot.addSeries(clear, clearFormat);
I spent hours trying to debug this issue, and it came down to just making life easy and doing it this way.
For those who googled for chart squeezing problems inside ScrollView with AChartEngine this is solution to your problem:
renderer.setInScroll(true);