How could we achieve Synchronized charts in Android.
For my web page I've used Highcharts API. Is there any similar thing for Android. I've checked various libraries mentioned here but didn't find any which will match the requirement.
I don't want combined charts like this and this. I'm looking for Synchronized charts.
Is there any library which will meet the requirement or Should I go with webView (It's a worst case for me)
Is it possible with MPAndroidChart?
EDIT:
Resultant chart should be like the Charts given in highcharts page
Sample:
UPDATE
Motto is not just to draw the 3 charts. The Aim is to synchronize them. Synchronise means all the 3 charts have same x-axis(values), on click at any point in these charts the plot at that particular point should be highlighted in all the charts. I'm sure I didn't explain it properly. Kindly check this link and hover the graph
when clicked on chart 1 get the X and Y points and highlight them on chart 2. Same with 2nd chart.
lineChart1.setOnChartValueSelectedListener(new OnChartValueSelectedListener()
{
#Override
public void onValueSelected(Entry e, Highlight h)
{
lineChart2.highlightValue(e.getX(),e.getY(),0,false);
}
#Override
public void onNothingSelected()
{
}
});
lineChart2.setOnChartValueSelectedListener(new OnChartValueSelectedListener()
{
#Override
public void onValueSelected(Entry e, Highlight h)
{
lineChart1.highlightValue(e.getX(),e.getY(),0,false);
}
#Override
public void onNothingSelected() {
}
});
NOTE set the last argument to false so that it doesn't call the listener again and again. If this is not set then it results to deadlock.
The sample app has a good display of the features available to you "out of the box" with MPAndroidChart.
As you can see, there is an example of multiple charts inside a ListView which seems to be close to your requirement.
Likewise, the source code is available on GitHub for you to inspect and see if it has the available classes and methods for you to do what you want out of the box.
At the same time, you should understand that it is often unrealistic to expect to find a library that will exactly suit an unusual requirement from mere configuration alone. Free and open source libraries often provision for extension and customisation and MPAndroidChart is no exception. As a professional software engineer, or as an aspiring one, you should be willing and prepared to program that yourself.
In your particular case, it seems you want some kind of co-ordination between the charts. So if you click on one of them then the MarkerView appears on all at the same xIndex in the DataSet.
To attempt this, you would start by looking at the code for OnChartGestureListener. A solution can be obtained through using event-driven programming. You would set up 3 implementations of OnChartGestureListener which would use events to transmit the current gesture to a mediator who then triggers the same gestures on the other two charts. For example, inside OnChartGestureListener there is a method to implement called:
void onChartScale(MotionEvent var1, float var2, float var3);
Your implementation would look something like this:
#Override
void onChartScale(MotionEvent var1, float var2, float var3) {
//transmit event to mediator
//handle event for this chart
}
If this is too difficult then you will have to stick with Highcharts inside a WebView as you have cogently suggested yourself. However, be aware that the performance inside the WebView will not be as good as using a library that renders to canvas directly.
In short, it is possible, although difficult, to accomplish what you want using MPAndroidChart and no "out-of-the-box" solution is available.
You can surely make it using MPAndroidCharts library.
Go for 1> LineChart (with legend, simple design) for Speed
2> LineChart (cubic lines) / (gradient fill) for Elevation , Heart
While Using gradientFill apply this to eliminate dashed line and draw a straight line:
lineDataSet.enableDashedLine(0f, 0f, 0f);
lineDataSet.enableDashedHighlightLine(0f, 0f, 0f);
Related
I'm starting to develop a game in libgdx, and I'm wondering what the best practice is for the following situation. There are two things that I'm trying to do at the moment: move a menu (sprite) into place, and pan the camera to the player sprite. My idea to accomplish these things is to have an 'action_stack' ArrayList in the render() function. The ArrayList would contain 'Action' instances. Each Action instance would have a step() function, which would be over-ridden. In the render() function, I would iterate through action_stack, and fire each elements' step() function. So, to accomplish moving the menu into place, I would create the class:
public class MenuAnim1 implements Action {
private int targetX;
private int targetY;
private Sprite menu;
public MenuAnim1() {
//set initial sprite and position
}
public Step() (
//move this.menu towards targetX and targetY
//draw the sprite
//if not at target position, do nothing
//if at target position, remove this object from action_stack
}
}
...and put an instance into the action_stack:
MenuAnim1 menuAnim1 = new MenuAnim1();
action_stack.add(menuAnim1);
Sorry if my Java is bad, I'm not super familiar with it. Anyways, my question is: is this even good practice? What do people normally do? Is there a better way to do what I'm describing above?
I have never used Actions, but your idea is good. If you want them to be time dependant (and thus fps independant), be sure to use the time that has passed since the last frame to the current, also known as delta or deltaTime. You can get it like this:
Gdx.graphics.getDeltaTime();
so, to make your action move the sprite, for example, to the right, this would do the trick:
speed = 10; //It will move 10 units per second.
delta = Gdx.graphics.getDeltaTime();
menu.translateX(speed*delta);
(Sprite#translateX)
Firstly, thanks for your time.
How do I use Box2D Sensors on the EdgeShape(s) to determine a collision condition with the Ball, then use said condition to increment a score variable?
I am creating a Pong clone using Box2D via libGDX! I have found great examples and tutorials from iforce2d and Ray Wenderlich, however, they are written in languages and libraries that I am not familiar with at the moment. Trying to comprehend and convert the code is not working for me. If code or a link to a Java/libGDX rendition of Sensor use could be provided, I would be much obliged.
I am receiving contacts in my code, but I do not yet understand the recipe for the algorithm that would ignore contact with the paddle rectangles and arena boundary, but increment a score variable upon collision with the left or right EdgdeShape sensors.
I have scavenged the web for two weeks in an effort to find bits and pieces of useful information to hack together a solution before posting to SO, however, I am officially stumped on this one. I could use some guidance.
i don't know how far you came with your efforts and never worked with libgdx, but the way to go is something like this:
fixture.setUserData() (could be body) to recognize the single bodies you have (outLeft, outRight, paddleLeft, paddleRight, ball) - this could be any useful information from Integers to the whole game object instance, what ever you need
set your left/right boundaries as sensor fixture.setSensor(true) - afaik this has to be set to not let the boundaries induct a collision
implement your contact listeners endContact(Contact contact) (or begin contact, like you want it) call and request the fixtures A and B from the contact object with contact.getFixtureA/B() and determine if the given collision is relevant for your needs e.g.:
-
public void endContact(Contact contact) {
Fixture fixtureA = contact.getFixtureA();
Fixture fixtureB = contact.getFixtureB();
Object userDataA = fixtureA.getBody().getUserData();
Object userDataB = fixtureB.getBody().getUserData();
// check if one is ball
if (userDataA instanceof Ball) {
checkBallCollision(userDataB);
} else if (userDataB instanceof Ball) {
checkBallCollision(userDataA);
}
}
private void checkBallCollision(Object userData) {
if (userData instanceof outLeft) {
//add points to right player
} else if (userData instanceof outRight) {
//add points to left player
}
}
-4. add your ContactListener to your World.setContactListener()
as said, i'm not 100% sure that this will work, never used it in libgdx, just some smaller experiments with andengines box2d extension, but in fact it should be the same for both engines. here is another link handling sensors in andengine: http://www.matim-dev.com/creating-sensors.html
Libreoffice (and other apps like Latex) allows you to use some kind of script language to show really cool mathematical formulas.
I need to use a view (probably a textView) that will be able to shows such formulas, and fractions in particular.
For example "x over y" would look like:
x
-
y
and so on.
Is there any such solution for this on Android? Maybe a library (with license similar to Apache or better) that allows you to write such things?
You could easily extend the view class and replicate this with two TextViews and an ImageView. Probably not the most efficient way of doing this but certainly pretty easy.
Some sudo code but you get the idea..
public class FractionView extends View {
private TextView top;
private Textview bottom;
private ImageView line;
public FractionView(Context context) {
// instantiate the views
}
// TODO add methods to update the text, possibly update positions as well, more stuff?
}
I am trying to add some visual indication, that there are no more pages in the desired fling direction in the ViewPager. However I am struggling to find a place, where to put relevant code.
I have tried extending ViewPager class with following code, but the Toast is not displaying (ev.getOrientation() returns always 0). I have also tried the same with history points, but ev.getHistorySize() returns also 0.
What am I missing?
Class example:
public class CustomViewPager extends ViewPager {
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* #see android.support.v4.view.ViewPager#onTouchEvent(android.view.MotionEvent)
*/
#Override
public boolean onTouchEvent(MotionEvent ev) {
boolean result = super.onTouchEvent(ev);
switch (ev.getAction() & MotionEventCompat.ACTION_MASK) {
case MotionEvent.ACTION_MOVE:
if (ev.getOrientation() > 0) {
Toast.makeText(getContext(), "left", 0).show();
}
}
return result;
}
}
If you look at the v4 support library you will see there's a class used by ViewPager called EdgeEffectCompat (this provides the glow effect when you reach the beginning or end of a view pager in ICS+) If you look at the implementation in the compat library you will see that it has an if-statement to see if the build version is 14+ (ICS) or not. If it is, then it ends up eventually (if you trace long enough) using the normal EdgeEffect class that was inroduced in ICS. Otherwise it uses BaseEdgeEffectImpl which basically has nothing in it.
If you want, you can make your own custom ViewPager that uses EdgeEffect of your own. You can look at the android source code to see how they implemented EdgeEffect here which you can pretty much copy (just make sure to copy the overscroll_edge and overscroll_glow drawables in the AOSP /res/drawable directories to your own project since they are internal to android) or go ahead and create your own version.
Good luck.
(By the way, that's how they create the cool looking edge tilt effect in the launcher menu on ICS... so you can pretty much be as creative as you want with this ;)
I was trying to get the exact same effect that was asked in this question. I struggle with it and then I read #wnafee answer (I couldn't do it with out it).
But then I struggle to implement what was sound pretty simple from the answer.
I had so much trouble with implementing it, that I might didn't understand the answer correctly, but there were too many issues of inaccessible APIs since I wasn't working in the same package of the Compatibility library.
After I tried some approaches (none of them succeeded, and they were pretty complicated) I went to a slightly different direction, and now it works like a charm. I used some reflection, for the ones who never used it, don't worry it is really the basic of reflection.
I'm not sure if it's the best solution out there, but it worked for me, so if you would like to use it you are welcome. Please read Wnafee example since it explains some of the stuff that I did.
In order to accomplish this task you should just follow my three parts solution. (Will take you between 3-10 minutes)
Part I:
As Wnafee said I just made my own EdgeEffect class by copy paste the source code from here,
(just make sure to copy the overscroll_edge and overscroll_glow
drawables in the AOSP /res/drawable directories to your own project
since they are internal to android)
I only did 2 really small changes:
I declare that the class extends EdgeEffectCompat (I called my class EdgeEffectForEarlyVersions). public class EdgeEffectForEarlyVersions extends EdgeEffectCompat. The reason for doing this change is that the mLeftEdge and mRightEdge are of the type EdgeEffectCompat.
At the first line of the constructor of "my" new class I added a call to the parent constructor super(context);. Since there is no default constructor to EdgeEffectCompat you have to Explicitly call the constructor.
Part II
Besides that I wrote the another function. The purpose of the function is that in case of an early version (before ICS) we would like to use the EdgeEffectForEarlyVersions that we just copied. In order to get that purpose I used reflection.
This is the function:
private static void changeEdgeEffectCompactOnEarlyVersions(ViewPager viewPager, Context context)
{
/* In case that the version is earlier than 14 there is only empty implementation for the edge effect, therefore we change it.
* for more information look on the following links:
* 1. http://stackoverflow.com/questions/10773565/visual-indication-of-over-scroll-in-android
* 2. http://grepcode.com/file/repo1.maven.org/maven2/com.google.android/support-v4/r7/android/support/v4/view/ViewPager.java#ViewPager.0mLeftEdge
* 3. http://grepcode.com/file/repo1.maven.org/maven2/com.google.android/support-v4/r7/android/support/v4/widget/EdgeEffectCompat.java#EdgeEffectCompat
*/
if (Build.VERSION.SDK_INT < 14)
{
try
{
Class<ViewPager> viewPagerClass = ViewPager.class;
//Get the left edge field, since it is private we used getDeclaredField and not getDeclared
Field leftEdge = viewPagerClass.getDeclaredField("mLeftEdge");
leftEdge.setAccessible(true);
//Get the right edge field, since it is private we used getDeclaredField and not getDeclared
Field rightEdge = viewPagerClass.getDeclaredField("mRightEdge");
rightEdge.setAccessible(true);
EdgeEffectForEarlyVersions leftEdgeEffect = new EdgeEffectForEarlyVersions(context);
EdgeEffectForEarlyVersions rightEdgeEffect = new EdgeEffectForEarlyVersions(context);
//Set the mLeftEdge memeber of viewPager not to be the default one, but to be "our" edgeEffect
leftEdge.set(viewPager, leftEdgeEffect);
//Set the mRightEdge memeber of viewPager not to be the default one, but to be "our" edgeEffect
rightEdge.set(viewPager, rightEdgeEffect);
}
catch (Exception ex)
{
Log.e("refelection", ex.getMessage());
}
}
}
Part III
Now all there is left to do, is to call that function after you have the ViewPager Instance and nothing more.
I Hope it will help someone.
wnafee explained the solution well but for the lazy among us, i made an actual working implementation quite some time ago.
https://github.com/inovex/ViewPager3D
And if you just want overscroll take a look here:
https://github.com/inovex/ViewPager3D/issues/1
You have a lot of options, you can show a Toast, display a Dialog, make a TextView or image to appear over your UI, etc. Or because you know the amount of View items in the ViewPager, you could add different View at positions 0 and/or n + 1 with the message and make it bounce to the last View that actually contains your data.
You could implement:
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
public void onPageSelected(int position) {
//TODO If position is the 0 or n item, add a view at 0 or at n+1 to indicate there is no more pages with data.
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// TODO Show a Toast, View or do anything you want when position = your first/last item;
}
public void onPageScrollStateChanged(int state) {
}
});
just to complement #goBeepit dev answer when you create your own edgeffect class and you extend from EdgeEffectCompat some methods requires to be boolean. you can change those methods to boolean type and make then return true in any case, this way everything works fine
You can overload the setUserVisibleHint(boolean) function in your fragments. Pseudo code:
void setUserVisibleHint(boolean isVisibleToUser) {
// If this fragment is becoming visible
if (isVisibleToUser == true) {
// Check if it is the last fragment in the viewpager
if (indexOfThis == getActivity().indexOfLast) {
// Display right limit reached
Toast(..., "No more Frags to right",...)
}
// Check if it is the first fragment in the viewpager
else if (indexOfThis == getActivity().indexOfFirst) {
// Display Left Limit reached
Toast(..., "No more Frags to left",...)
}
}
}
I have not used this function for this purpose, but have used it for other reasons and it does fire appropriately. Hope this helps...
I've implemented a bounce back effect based on Renard's ViewPager3D: https://stackoverflow.com/a/17425468/973379
Usually with ViewPager, one uses a PagerAdapter such as FragmentPagerAdapter or FragmentStatePagerAdapter to flood the ViewPager with contents(your content are going to be views).
Now, when you use a PagerAdapter, you have one method called getCount(), http://developer.android.com/reference/android/support/v4/view/PagerAdapter.html#getCount%28%29 ,which will give you the size of the content.
Since you now, know the size you can easily display a message with an if control statement.
Try this code : http://developer.android.com/reference/android/support/v4/view/ViewPager.html
Note: I dont think you need a custom ViewPager. You will also need to understand Fragments for ViewPager. Look at samples in ApiDemos. Its a great source.
Here is my problem: I am using AFreeChart to display a chart in my activity. The reason why I used AFreeChart was because I first finished this chart with JFreeChart, and, realized after that, it wasn't compatible with Android.
So, with AFreeChart, I could create the same chart with exactly the same code, but I don't know how to display it on a View.
Here I am creating the chart:
private void creerGraphique(){
//Here I have the creation of the DateSet
AFreeChart chart = ChartFactory.createXYLineChart(
"Mois", // Title
"Jours", // x-axis Label
"Repetitions", // y-axis Label
graph, // Dataset
PlotOrientation.VERTICAL, // Plot Orientation
true, // Show Legend
true, // Use tooltips
false // Configure chart to generate URLs?
);
}
Here I want to use it:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.graphique);
this.stockTableau();
this.creerGraphique();
//HERE: How can I display it since it's already created
}
I downloaded the AFreeChart demo code, but a function which wasn't on the package was used, and so, I couldn't use it too.
I thank you for your help.
PS: I'm not an english, so I hope my problem is clear, do not hesitate to ask me more details.
Have you looked at the sample in AFreeChart? It's quite straight forward, look at what they did for this chart for instance :
http://code.google.com/p/afreechart/source/browse/trunk/afreechart_sample/src/org/afree/chart/demo/view/PieChartDemo01View.java
They extend a DemoView which is basically an Android View with a setChart method, and pass the chart to the View.
So either extend DemoView or create you own equivalent if you don't need everything that's in it and follow the sample !
Good luck.
It is also worth noting that using the code you've pasted above, it would be helpful to call the chart's draw() method when you want it to draw.
As a simple example, if you were using a SurfaceView, you could create a method something like the following:
private void drawChart(AFreeChart chart, ChartRenderingInfo info) {
getHolder.lockCanvas();
chart.draw(canvas, area, info);
getHolder().unlockCanvasAndPost(canvas);
}
Where 'canvas' and 'area' have been set.
This is useful if you are looking to do a very simple implementation where you don't want to use the DemoView discussed above.