AChartEngine in thread - achartengine

I'm using AChartengine in my project. I'm showing users charts with database data.
I'm using actually 1.0.0 version of AChartEngine.
I wanted to change showing charts function in my app to threads.
Everything works but ... I've got a problem. Chart showed by runnable thread has no zooming possibilities.
On handler I've checked the GraphicalView if it is enabled. And it is. I tried so many options. Is this the AChartEngine issue?
I'm using this renderer options:
renderer.setXLabels(7);
renderer.setYLabels(10);
renderer.setLegendHeight(60);
renderer.setShowGrid(true);
renderer.setXLabelsAlign(Align.CENTER);
renderer.setYLabelsAlign(Align.RIGHT);
renderer.setZoomButtonsVisible(false);
renderer.setZoomEnabled(true);
renderer.setExternalZoomEnabled(true);
renderer.setApplyBackgroundColor(true);
renderer.setBackgroundColor(Color.WHITE);
renderer.setLabelsColor(Color.BLACK);
renderer.setMarginsColor(Color.WHITE);
renderer.setChartTitle("");
renderer.setMargins(new int[] { 15, AChartMarginLeft, 20, 15 });
renderer.setPanLimits(new double[] { x.get(0)[0].getTime(),
x.get(0)[(ileC - 1)].getTime() + (1 * 24 * 60 * 60 * 1000),
minvalY, maxY });
renderer.setZoomLimits(new double[] { x.get(0)[0].getTime(),
x.get(0)[(ileC - 1)].getTime() + (1 * 24 * 60 * 60 * 1000),
minvalY, maxY });
renderer.setPointSize(4);
renderer.setShowAxes(false);
renderer.setAxisTitleTextSize(AChartAxisTitleTextSize);
renderer.setLabelsTextSize(AChartsetLabelsTextSize);
renderer.setLegendTextSize(AChartsetLegendTextSize);
So zooming is enabled.
mChartView in handler is showing that mChartView has zoom enabled.
private final Handler myHandler = new Handler();
final Runnable updateRunnable = new Runnable() {
public void run() {
Log.d("updateRunnable","RUNNABLE");
if (mRenderer.isZoomEnabled()) {
Log.d("ZOOM ENABLED","ENABLED");
} else {
Log.d("NO","NO ZOOMING");
}
}
};
SOLUTION
Edit:
I found answer to my question. I tried so many things. It wasn't zoom/pan margins.
I moved this part from thread to handler and now zooming works. If this part was in thread the chart was OK but like I said zooming hasn't been working.
mChartView = ChartFactory.getBarChartView(getApplicationContext(),
ChartFunctions.buildBarDataset(titles, values),
renderer,type.DEFAULT);

You are setting some zoom limits that seem to be exactly your chart values range. This means that you cannot zoom outside that range.

Related

Very slow hover interactions in OpenLayers 3 with any browser except Chrome

I have two styles of interactions, one highlights the feature, the second places a tooltop with the feature name. Commenting both out, they're very fast, leave either in, the map application slows in IE and Firefox (but not Chrome).
map.addInteraction(new ol.interaction.Select({
condition: ol.events.condition.pointerMove,
layers: [stationLayer],
style: null // this is actually a style function but even as null it slows
}));
$(map.getViewport()).on('mousemove', function(evt) {
if(!dragging) {
var pixel = map.getEventPixel(evt.originalEvent);
var feature = null;
// this block directly below is the offending function, comment it out and it works fine
map.forEachFeatureAtPixel(pixel, function(f, l) {
if(f.get("type") === "station") {
feature = f;
}
});
// commenting out just below (getting the feature but doing nothing with it, still slow
if(feature) {
target.css("cursor", "pointer");
$("#FeatureTooltip").html(feature.get("name"))
.css({
top: pixel[1]-10,
left: pixel[0]+15
}).show();
} else {
target.css("cursor", "");
$("#FeatureTooltip").hide();
}
}
});
I mean this seems like an issue with OpenLayers-3 but I just wanted to be sure I wasn't overlooking something else here.
Oh yeah, there's roughly 600+ points. Which is a lot, but not unreasonably so I would think. Zooming-in to limit the features in view definitely helps. So I guess this is a # of features issue.
This is a known bug and needs more investigation. You can track progress here: https://github.com/openlayers/ol3/issues/4232.
However, there is one thing you can do to make things faster: return a truthy value from map.forEachFeatureAtPixel to stop checking for features once one was found:
var feature = map.forEachFeatureAtPixel(pixel, function(f) {
if (f.get('type') == 'station') {
return feature;
}
});
i had same issue, solved a problem by setInterval, about this later
1) every mouse move to 1 pixel fires event, and you will have a quee of event till you stop moving, and the quee will run in calback function, and freezes
2) if you have an objects with difficult styles, all element shown in canvas will take time to calculate for if they hit the cursor
resolve:
1. use setInterval
2. check for pixels moved size from preview, if less than N, return
3. for layers where multiple styles, try to simplify them by dividing into multiple ones, and let only one layer by interactive for cursor move
function mouseMove(evt) {
clearTimeout(mm.sheduled);
function squareDist(coord1, coord2) {
var dx = coord1[0] - coord2[0];
var dy = coord1[1] - coord2[1];
return dx * dx + dy * dy;
}
if (mm.isActive === false) {
map.unByKey(mm.listener);
return;
}
//shedules FIFO, last pixel processed after 200msec last process
const elapsed = (performance.now() - mm.finishTime);
const pixel = evt.pixel;
const distance = squareDist(mm.lastP, pixel);
if (distance > 0) {
mm.lastP = pixel;
mm.finishTime = performance.now();
mm.sheduled = setTimeout(function () {
mouseMove(evt);
}, MIN_ELAPSE_MSEC);
return;
} else if (elapsed < MIN_ELAPSE_MSEC || mm.working === true) {
// console.log(`distance = ${distance} and elapsed = ${elapsed} mesc , it never should happen`);
mm.sheduled = setTimeout(function () {
mouseMove(evt);
}, MIN_ELAPSE_MSEC);
return;
}
//while multithreading is not working on browsers, this flag is unusable
mm.working = true;
let t = performance.now();
//region drag map
const vStyle = map.getViewport().style;
vStyle.cursor = 'default';
if (evt.dragging) {
vStyle.cursor = 'grabbing';
}//endregion
else {
//todo replace calback with cursor=wait,cursor=busy
UtGeo.doInCallback(function () {
checkPixel(pixel);
});
}
mm.finishTime = performance.now();
mm.working = false;
console.log('mm finished', performance.now() - t);
}
In addition to #ahocevar's answer, a possible optimization for you is to utilize the select interaction's select event.
It appears that both the select interaction and your mousemove listener are both checking for hits on the same layers, doing double work. The select interaction will trigger select events whenever the set of selected features changes. You could listen to it, and show the popup whenever some feature is selected and hide it when not.
This should reduce the work by half, assuming that forEachFeatureAtPixel is what's hogging the system.

Fixed min and max dynamic time ticks in chart

I'm currently working on a graph, which should visualise a fixed time frame. I want to have the start and end of the timeframe fixed on the width of the graph and want to set a custom amount of ticks in between, depending on the timeframe.
I tried to find something in the highcharts docu, but it seems there is nothing for gwt as "tickpositioner" or "tickpositions" for javascript would do.
Has anybody an idea how to approach a solution in gwt to achieve this behaviour please?
I found a solution where i set the tickpositioner in the JSONObject and implement the function in javascript. Mind the "positions.info" because due to the tickpositioner function, label predefined label formatting gets lost.
void setXaxisTicks(XAxis xAxis, Long start, Long end) {
JSONObject options = xAxis.getOptions();
options.put("tickPositioner", null);
configureXAxis(options.getJavaScriptObject(), start, end);
}
private native void configureXAxis(JavaScriptObject javaScriptObject, Number start, Number end) /*-{
javaScriptObject.tickPositioner = function () {
var positions = [],
tick = Math.floor(start),
increment = Math.ceil((end - start));
for (tick; tick - increment <= end; tick += increment) {
positions.push(tick);
}
tLen = positions.length;
positions.info = {
unitName: "minute",
higherRanks: {},
totalRange: positions[tLen - 1] - positions[0]
};
return positions;
};
}-*/;

Set the minimum grid resolution in AChartEngine?

I am using AchartEngine library to plot the measurements from a sensor. The values are in the order of 1E-6.
When I try to plot the values they are shown correctly but as I zoom the plot, the maximum resolution I can see in the x Labels is in the order of 1E-4. I am using following code to change the number of labels:
mRenderer.setXLabels(20);
mRenderer.setYLabels(20);
I am also changing the range of the y axis, but the resolution remains unchanged. Has anyone found this problem before?
EDIT
I do not have enough reputation to post images, but the following link shows the chartview that I am getting.
https://dl.dropboxusercontent.com/u/49921111/measurement1.png
What I want is to have more grid lines between 3.0E-5 and 4.0E-5. Unfortunately I have not found how to do that. I also tried changing the renderer pan, initial range of the plot and zoom limits. all without sucess. I was thinking the only option left would be to override some of the draw methods but I have no clue how to do that.
I Have digged into the source code of AChartEngine and found the problem that it has when small numbers are to be plotted. It is in a static function used to draw labels by every chart:
private static double[] computeLabels(final double start, final double end,
final int approxNumLabels) {
// The problem is right here in this condition.
if (Math.abs(start - end) < 0.000001f) {
return new double[] { start, start, 0 };
}
double s = start;
double e = end;
boolean switched = false;
if (s > e) {
switched = true;
double tmp = s;
s = e;
e = tmp;
}
double xStep = roundUp(Math.abs(s - e) / approxNumLabels);
// Compute x starting point so it is a multiple of xStep.
double xStart = xStep * Math.ceil(s / xStep);
double xEnd = xStep * Math.floor(e / xStep);
if (switched) {
return new double[] { xEnd, xStart, -1.0 * xStep };
}
return new double[] { xStart, xEnd, xStep };
}
So this function basically takes the start (minimum) and and end (maximum) values of the plot and the aproximate number of labels. Then it rounds the values and computes the step of the grid (xStep). If the difference between start and end is too small (0.000001f) then the start and end are the same and the step is 0. That is why its not showing any labels in between this small values nor any grid lines!. So I just need to change the 0.000001f with a smaller number or with a variable in order to control the resolution of the grid. I hope this can help someone.

Manipulating Opacity in Blackberry 5

I am building a news ticker that needs to be implemented on Blackberry 5. When transitioning from one element to the next, I am looking at a fade out/fade in transition. Mostly because I am having trouble finding resources on creating animations in the Blackberry 5 reference.
the basic flow I am looking at is:
public void updateUI() {
//fade out
//set values
//fade in
}
So far I have all the UI elements contained inside a HorizontalFieldManager. I have tried digging through the Field and Graphics documents, but did not find what I was looking for.
Keep in mind, supporting Blackberry 5 is the client's requirement, not mine.
You need to handle animations explicitly, using a timer for transitions.
My typical solution is something like this (inside the paint() method):
final long time = System.currentTimeMillis();
final int alpha;
if (startFadeIn != 0) {
alpha = (int) Math.min((time - startFadeIn) / SPEED, 255);
if (alpha < 255) {
invalidate();
}
} else if (startFadeOut != 0) {
alpha = (int) Math.max(255 + (startFadeOut - time) / SPEED, 0);
if (alpha > 0) {
invalidate();
}
} else {
alpha = 255;
}
graphics.setGlobalAlpha(alpha);
It burns some CPU cycles (for a short time), but it works.

How to correctly calculate FPS in XNA?

I wrote a component to display current FPS.
The most important part of it is:
public override void Update(GameTime gameTime)
{
elapseTime += (float)gameTime.ElapsedRealTime.TotalSeconds;
frameCounter++;
if (elapseTime > 1)
{
FPS = frameCounter;
frameCounter = 0;
elapseTime = 0;
}
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
spriteBatch.Begin();
spriteBatch.DrawString(font, "FPS " + ((int)FPS).ToString(), position, color, 0, origin, scale, SpriteEffects.None, 0);
spriteBatch.End();
base.Draw(gameTime);
}
In most cases it works ok, but recently I had a problem.
When I put following code into Update method of game strange thing starts to happen.
if (threadPath == null || threadPath.ThreadState != ThreadState.Running)
{
ThreadStart ts = new ThreadStart(current.PathFinder.FindPaths);
threadPath = new Thread(ts);
threadPath.Priority = ThreadPriority.Highest;
threadPath.Start();
}
Main idea of this code is to run pathFinding algorithm in different thread all the time.
By strange things I mean that sometimes FPS drasticly decreases, this is obvious, but displayed FPS changes more often than once a second. If I understand this code FPS can't change more often than once a second.
Can someone explain me what's going on?
Edit 26.03.2010
I've posted also code of Draw method.
Edit 31.03.2010 Answers to Venesectrix questions
1) are you running with a fixed or variable time step?
IsFixedTimeStep and SynchronizeWithVerticalRetrace is set to true.
2)Were you moving the XNA window around when this occurred?
No
3)Did the XNA window have focus?
Yes
4) How noticeable was it (ie, updating so fast you can't read it, or just barely updating more than a second)?
I was able to read updates, FPS was updating ~3 times a second.
5) And all of this only happens with the thread code in there?
Yes
Shawn Hargreaves has a great post about this here. The first difference I see between his code and yours is the fact that you reset your elapseTime to 0 each time, which will lose some time, whereas Shawn just subtracts 1 second from his elapsedTime. Also, Shawn uses ElapsedGameTime instead of ElapsedRealTime. He updates his frameCounter in the Draw function instead of the Update function as well.
As far as why he uses ElapsedRealTime, he explains it in a comment after the post:
> Surely 1 / gameTime.ElapsedRealTime.TotalSeconds
> will therefore give the current framerate.
That will tell you how long it was
since the previous call to Update, but
that is not the same thing as your
framerate!
a) If the game is dropping frames,
Update will be called more frequently
in order to catch up. You want to time
the number of actual draws that are
taking place, not just these extra
catch-up logic frames.
b) The time for a single Update can
fluctuate widely, so the figure you
get out of that will be too flickery
to be easily readable.
I would try his component, and see if it works for you. The post is pretty old, and I think you will have to change LoadGraphicsContent to LoadContent and UnloadGraphicsContent to UnloadContent, as another one of the comments points out.
Here is how I do it and with this method:
You average over n Frames
You can use it with any initialization method you choose
It should be easy to read and follow
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace _60fps
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SpriteFont OutputFont;
float Fps = 0f;
private const int NumberSamples = 50; //Update fps timer based on this number of samples
int[] Samples = new int[NumberSamples];
int CurrentSample = 0;
int TicksAggregate = 0;
int SecondSinceStart = 0;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
graphics.SynchronizeWithVerticalRetrace = false;
int DesiredFrameRate = 60;
TargetElapsedTime = new TimeSpan(TimeSpan.TicksPerSecond / DesiredFrameRate);
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
OutputFont = Content.Load<SpriteFont>("MessageFont");
}
protected override void UnloadContent()
{/* Nothing to do */}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Escape))
this.Exit();
base.Update(gameTime);
}
private float Sum(int[] Samples)
{
float RetVal = 0f;
for (int i = 0; i < Samples.Length; i++)
{
RetVal += (float)Samples[i];
}
return RetVal;
}
private Color ClearColor = Color.FromNonPremultiplied(20, 20, 40, 255);
protected override void Draw(GameTime gameTime)
{
Samples[CurrentSample++] = (int)gameTime.ElapsedGameTime.Ticks;
TicksAggregate += (int)gameTime.ElapsedGameTime.Ticks;
if (TicksAggregate > TimeSpan.TicksPerSecond)
{
TicksAggregate -= (int)TimeSpan.TicksPerSecond;
SecondSinceStart += 1;
}
if (CurrentSample == NumberSamples) //We are past the end of the array since the array is 0-based and NumberSamples is 1-based
{
float AverageFrameTime = Sum(Samples) / NumberSamples;
Fps = TimeSpan.TicksPerSecond / AverageFrameTime;
CurrentSample = 0;
}
GraphicsDevice.Clear(ClearColor);
spriteBatch.Begin();
if (Fps > 0)
{
spriteBatch.DrawString(OutputFont, string.Format("Current FPS: {0}\r\nTime since startup: {1}", Fps.ToString("000"), TimeSpan.FromSeconds(SecondSinceStart).ToString()), new Vector2(10,10), Color.White);
}
spriteBatch.End();
base.Draw(gameTime);
}
}
}
As for:
"but the question why displayed FPS was changing more often than once a second is still open"
The difference between ElapsedGameTime and ElapsedRealTime is that "ElapsedGameTime" is the amount of time since the last time you entered the Update or Draw statement (depending on which "gameTime" you're using - the one from Update or the one from Draw).
ElapsedRealTime is the time since the game started. Because of this, it increases linearly as the game continues to run. Indeed, after 1 second, you'll update every frame because your logic looked like this:
(Let's assume you were running 4 fps for the sake of easy explanation):
Frame 1: ElapsedRealTime: 0.25. Running total now: 0.25
Frame 2: ElapsedRealTime: 0.5 Running total now: 0.75
Frame 3: ElapsedRealTime: 0.75 Running total now: 1.5
Running total greater than 1!!! Show FPS!
Set Running total = 0
Frame 4: ElapsedRealTime: 1.00 Running total now: 1.0
Running total greater than 1!!! Show FPS!
Now that you've fixed the counter, you should now only be getting Elapsed Game Time changes of a steady 0.25 so the progression now moves:
Frame 1: ElapsedGameTime: 0.25. Running total now: 0.25
Frame 2: ElapsedGameTime: 0.25 Running total now: 0.50
Frame 3: ElapsedGameTime: 0.25 Running total now: 0.75
Frame 4: ElapsedGameTime: 0.25 Running total now: 1.00
Running total greater than 1!!! Show FPS!
Set Running total = 0
Frame 5: ElapsedGameTime: 0.25. Running total now: 0.25
Frame 6: ElapsedGameTime: 0.25 Running total now: 0.50
Frame 7: ElapsedGameTime: 0.25 Running total now: 0.75
Frame 8: ElapsedGameTime: 0.25 Running total now: 1.00
Running total greater than 1!!! Show FPS!
Set Running total = 0
Which is what you're expecting. In short, now that you corrected the first problem, you should have corrected the second too and "why" is explained above.
As an aside ... you should avoid setting the thread priority. By assigning the highest thread priority to what should be a background thread, you could end up starving the main thread of cpu time because the scheduler would give priority to threadPath
Are you actively checking if IsRunningSlowly is being changed? Even with IsFixedTimeStep to true, if your program isn't able to do as many Updates as it expects, it will call it more frequently.
A way I have mitigated this before is by directly calling ResetElapsedTime() instead of keeping track of it yourself.
Not sure if that'll work for you though. I did notice that when i was debugging the previous issue I had, it wouldn't call the extra Updates, probably a 'feature' when debugging.
You should run your fps counter under the draw method
Hi guys if you want to show your real framerate you have to implement framerate counter to method Draw, because XNA do it like this:
"If your computer can't serve the method Update it suspend Draw method and instead of that it serve the Update method"

Resources