Jfree chart Find Subplot - jfreechart

This may sound very basic as a question, but i am stuck in JFreechart use.
Let me lay out my problem :
I have a CombinedDomainXYPlot to which I add my subplots as and when required.
I have used my custom JPopup menu and have included a menu item that is intended to provide user the facility to delete a particular subplot
I am assuming that one can find a subplot using findSubplot method of the main plot. I am able to get mouse positions but not able to do anything with PlotRenderingInfo that's required as input.
Would appreciate some help.

You can get a List of subplots using getSubplots(). To learn which subplot was clicked, examine the ChartMouseEvent that was sent from the ChartPanel, as suggested here.
Addendum: Here's a simple implementation of ChartMouseListener that will show each ChartEntity as it is clicked.
ChartPanel panel = ...
panel.addChartMouseListener(new ChartMouseListener() {
#Override
public void chartMouseClicked(ChartMouseEvent e) {
System.out.println(e.getEntity().getClass());
}
#Override
public void chartMouseMoved(ChartMouseEvent event) {}
});

Related

Layout of Text in Components

I have a couple of questions on text layout in Codenameone I can't seem to find answers to in the docs, videos or forums.
Is it possible to break, wrap text into multiple lines based on the text, such as a newline "\n", or can this only be done by creating a label for each line.
Also is it possible to rotate buttons / labels by 90 degrees, so that text is rotated, I see graphics can be rotated but not sure about how to do for components or text within them.
Any hints of tips would be appreciated. Thanks
Use Spanlabel for multiline label
Use the following code to rotate a button
public class RotatedButton extends Button {
#Override
public void paint(Graphics g) {
g.rotate((float)(Math.PI/4.0), getAbsoluteX(), getAbsoluteY());
super.paint(g);
g.resetAffine();
}
}
RotatedButton btn = new RotatedButton();
btn.setText("Hi");

JFreechart stop unzoom when drag left

How do I stop JFreechart from unzooming when I drag left?
thxs.
I made an assumption (based on your short question) that you want to disable the "zoom restore" feature when invoked by the mouse being dragged to the left.
If so, you simply need to override the restoreAutobounds() method like this:
JFreeChart chart = /* create your chart here*/
// add the chart to the panel and override
// the zoom restore behavior
chartPanel = new ChartPanel(chart){
#Override
public void restoreAutoBounds(){
// Do nothing
}
};
Or, event better is to extend the ChartPanel object and override it there.
NOTE: the zoom out feature will still be available from the context menu of the chart so the user still has meaningful ways to zoom out

printing with silverlight the same image multiple time

I have an image an a textbox. the user enters into the textbox the number of copies (N) and clicks print. The printer prints the photo N times (3 photos per page, one under the other).
Hiw would you do something like that? Do I need to first generate a silverlight page?
Silverlight has a really simple to use Printing API. I have recently been using it and learnt how to do so using the tutorial Melodatron listed, and this one over at the Visiblox site. This is specific to their charting library but I still found it very useful.
I am assuming that you only have 1 image to print at a time here, let me know if you have more. First, you need to set up a grid or something similar to put your photos in. You will need N number of rows in this grid. You'll have to do this in code behind as you have a certain number of rows you'd like to create, but this can easily be achieved by something like this:
Grid grid = new Grid();
// Set the column and row definitions
for (int i = 0; i < Number of rows; i++)
{
grid.RowDefinitions.Add(new RowDefinition());
}
That should set up your grid that you need. After you have the grid, you need to populate it with the images that you have. This is pretty straightforward, the only issue will be that your image can't be used multiple times - i.e. the image that you already have can only appear on the grid once. You will have to duplicate it in order to place it on the grid multiple times. I'm not sure how you are creating your images, but you could possibly create a new image based on the source path of the existing image? There is a thread on how to do this here. You'll need to give more details if you need help with that.
// Set the column and row definitions
for (int i = 0; i < Number of rows; i++)
{
// Duplicate your existing image here.
Image image = new Image();
grid.Children.Add(image);
Grid.SetRow(image, i);
}
All of the code above should be in this method:
private void printDocument_PrintPage(object sender, PrintPageEventArgs e)
{
//Code from above...
e.PageVisual = grid;
}
In the button event handler where you wish to print, do this:
private void Button_Click(object sender, RoutedEventArgs e)
{
PrintDocument printDocument = new PrintDocument();
printDocument.PrintPage += new EventHandler<PrintPageEventArgs>(printDocument_PrintPage);
printDocument.Print("TITLE");
}
Hope this helps!
There's a pretty good tutorial (link below) with an example and source code on advanced printing techniques in Silverlight.
You will need to create the layout as a custom control, which should not be so difficult, but you won't need to display it.
http://www.silverlightshow.net/items/Advanced-printing-in-Silverlight-4.aspx
Hopefully this gets you started in the right direction.

Pausing between operations

I am trying to build a simple memory game. Clicking on a card that has not been "flipped" simply "flips" the card over (revealing the underside of the image).
When a card is already showing and a second card is flipped over, I would like to pause for one second. Then, if the card that was flipped over matches the first card, I remove it from the board, if it does not match, I would like to flip both cards back to their hidden stage.
I have the "flipping" coded, I just want to know how I can pause it for one second after the second card is flipped.
I've tried:
System.Threading.Thread.Sleep(1000)
and
Dispatcher.BeginInvoke(() => System.Threading.Thread.Sleep(1000));
But it doesn't work like I want. This is my first WP7 and Silverlight project, so not sure what I'm doing wrong.
Any advise would be greatly appreaciated!
use the DispatcherTimer class:
var timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0,0,0,1);
timer.Tick += SomeTickMethod;
timer.Start();
private void SomeTickMethod(obejct sender, EventArgs e) {
FlipBackCards();
//remember to stop it :)
((DispatcherTimer)sender).Stop();
}
then in your Tick method you flip over the card. You could make the timer a class member in which case (based on some of your own logic) you could Stop() the timer from firing at any time.
Hope that helps
(note I quickly just typed up this code, may not be 100%, should be close)

How can I change the way InkCanvas draws?

I've searched for examples for this, but the ones I've ran across seem to focus on simpler stuff like setting the InkCanvas DefaultDrawingAttributes such as Width, Height, Color etc. Doesn't seem like there's a lot of material for this.
For example, if I hold down the mouse button I can see it drawing lines. What if I want to draw ellipses instead of lines, or draw ellipses around sampled points between the start and end of the line?
I know I can get new points with the StrokeCollected event, but beyond that I have no idea where to go. This guy seemed like he got msdn's code working, but I couldn't do it. I only know how to build the interface using XAML, and there doesn't seem to be a sample either.
edit
Created a StrokeCollection class variable called thisIsNotNice, initialized in the constructor and did this:
private void InkCanvas_StrokeCollected(object sender, InkCanvasStrokeCollectedEventArgs e)
{
myInkCanvas.Strokes = thisIsNotNice;
foreach (StylusPoint p in e.Stroke.StylusPoints)
{
StylusPointCollection spc = new StylusPointCollection();
spc.Add(p);
Stroke s = new Stroke(spc);
s.DrawingAttributes.Height = 3;
s.DrawingAttributes.Width = 3;
thisIsNotNice.Add(s);
}
e.Handled = true;
}
But it doesn't work as it should. The ellipses are drawn, but the lines drawn by the mouse are still there. Also, for some reason, the first time it works as it should, drawing just the ellipses, but afterward it draws both the ellipses and the lines. But, if I do this instead:
private void InkCanvas_StrokeCollected(object sender, InkCanvasStrokeCollectedEventArgs e)
{
myInkCanvas.Strokes = new System.Windows.Ink.StrokeCollection();
e.Handled = true;
}
The lines aren't kept on the screen. So, I don't understand why they aren't being erased in the above code.
If I do this:
private void InkCanvas_StrokeCollected(object sender, InkCanvasStrokeCollectedEventArgs e)
{
foreach (Stroke s in myInkCanvas.Strokes)
System.Diagnostics.Trace.WriteLine(s);
e.Handled = true;
}
I can also see that the canvas contains the line strokes.
While erasing the strokes after they have been added to the collection is far from ideal, it at least does what I want. I could set up the line color to be the same of the background, but then I wouldn't be able to retrieve just the ellipses. I could copy them to a separate collection too, but that's just awful.
It sounds like you want to customize the way strokes appear on your inkCanvas. There are two separate things to consider here:
1) The way they look as the ink flows off the pen, before it is lifted (the DynamicRenderer, who runs on another thread to ensure that ink is always fast, is responsible for this. It sounds like you're happy with your solution to this already.
2) The way the eventual stroke sitting on the canvas looks. To customize this you might try subclassing Stroke, overriding:
protected override void DrawCore(DrawingContext drawingContext, DrawingAttributes drawingAttributes);
Each time you get a strokeCollected (and here's the same horrible thing you were worried about but there you go), you remove the incoming stroke from the canvas and replace it with your custom implementation, stealing the stroke data from the incoming one.
Your implementation of DrawCore would look something like (pseudocode):
foreach(sp in this.StylusPoints)
drawingContext.DrawEllipse(RADIUS, sp.X, sp.Y)
And so as not to get the lines that normally happen you would not call base.DrawCore(context,attributes) at any point.

Resources