Annotating points on line graph with JFreeChart? - annotations

I'm using JFreeChart to make a line graph. There are some points that I want to mark, or annotate, with circles of different sizes. I tried ShapeAnnotation, but even after I addAnnotation, it's not visible. I was able to make a pointer annotation, though.
Here's the relevant code:
XYShapeAnnotation annotation = new XYShapeAnnotation(new Ellipse2D.Float(100.0f, 100.0f, 100.0f, 100.0f), new BasicStroke(1.0f), Color.blue);
XYPointerAnnotation pointer = new XYPointerAnnotation("arrow", 0.5,0.5,0.0);
xyDataset.addSeries(series1); //
xyDataset.addSeries(series2); // random lists of numbers
xyDataset.addSeries(series3); //
JFreeChart chart = ChartFactory.createXYLineChart ("XYLine Chart using JFreeChart","Age","Weight",xyDataset,PlotOrientation.VERTICAL,true,true,false);
chart.getXYPlot().addAnnotation(pointer);
chart.getXYPlot().addAnnotation(annotation);
I think I should have more code to make the ellipse annotation visible because I never specified coordinates like I did with the pointer. I went through the JFreeChart API and couldn't find it. Help?

It's hard to say why your XYShapeAnnotation fails without seeing your data; an sscce would help. As a starting point, you might look at the examples here and here for comparison.

Related

Using Block class on viewportlayout in devDept.Eyeshot

I loaded a cadfile in which a lot of lines are drawn. I want to make a rectangle region, using 4 vertices(X, Y Coordinate value) so that I can click the region not just one point.
I found Block class in devDept.Eyshot but I don't know how to use it. Please give any ideas or c# code example for me.
You don't need block to do that. You used the correct word and that is Region. A Region is a visual entity that has many vertices. It's technically a polygon. If you want you can use the simple method :
var width = 10d;
var height = 10d;
var region = devDept.Eyeshot.Entities.Region.CreateRectangle(width, height, true);
viewport.Entities.Add(region);
When you use the method to get the entities under mouse, the whole surface of the region is taken into account. It works perfectly

Where did the drawBackground hook go? Or why is my last point the wrong color

To try and solve this problem, I started looking into writing a plugin for flot to do what I needed. It looked surprisingly straight-forward, but I have run into a minor snag. I First used the draw hook to draw my axis (note: I'm aware this code needs some error checking to make sure the origin isn't off the chart)
function draw(plot, ctx) {
var offset = plot.getPlotOffset();
var origin = plot.pointOffset({ x: 0, y: 0 });
ctx.moveTo(offset.left, origin.top);
ctx.lineTo(plot.width() + offset.left, origin.top);
ctx.stroke();
ctx.moveTo(origin.left, offset.top);
ctx.lineTo(origin.left, plot.height() + offset.top);
ctx.stroke();
}
And this works, with 2 small snags. The first and most important is that for some reason it makes the very last point of my data series change color! See here:
The point in the upper right-hand corner has turned black. By stepping through the code I can observe that this only happens when the axes are drawn. Before my draw code is called, the point is the correct color. So I think it has something to do with the drawing on the first "stroke". For some reason it seems to then apply the black color to the last point. Any idea on how to fix this?
The second problem is that this code is called only after flot has draw everything else (including the data points) which means that my lines appear on top of points instead of underneath them. This is only a problem for those two points that are very close to the vertical axis. Looking at the flot documentation, it mentions a drawBackground hook, but this doesn't seem to actually exist. I tried using it and it complained the drawBackground was null. So what happened? And is there a better place to hook into and draw my axes? I want to draw after flot has worked out the size of the plot area and before it draws the first series of data points.
What's currently on the website API documentation does not match the newest released version (0.7). In order to use the backgroundDraw hook, you'll need a newer version of flot, directly from their github repository. The newest version is fine, but anything after this commit would be workable.

Determine/Save the position of text in matlab

I plotted few points using scatter and then label them using text. The position of these labels are same as the position of the points + some offset. Some of these text label overlap with each other and hence I moved them interactively (using mouse). I can check the new position of each of these text individually using property editor. However this is very time-consuming. Is there a better way to get the coordinates of all these text-label?
You can use findobj to get handles to text objects that are children of the current axes (or another handle... your choice):
text_handles = findobj('parent',gca,'type','text');
Then you can get the positions of these text objects:
positions = get(text_handles,'position');
You may need to do a bit more work to associate each text object with its data point - I suggest taking advantage of the property system, perhaps via the UserData field, for this, though there are many options.
If you want to do it easily later do this in your plots, for example:
h=text(2.9,7.5,'MyText');
This will put "MyText" at position 2.9, and 7.5.
Then to change the position use:
set(h,'Position',[2.5 7]);
This will change the position to 2.5 and 7.
Later if you need to see tthe position of text again use:
get(h);
Hope this helps.

Highlight a single plot symbol on a line - Core Plot

I'm making an iPhone app that uses Core Plot at one point in the application. I'm drawing a graph using a CPTScatterPlot and along the line I have CPTPlotSymbol plot symbols.
the graph is looking really good after some customizing but what I want to do is give the user a bit better visual representation of where exactly on the graph the current material is referring to.
I would like to "highlight" individual plot symbols along my line. I have the location on the xAxis of the point I want to manipulate. I have not been able to find any example of this or even a suggestion that it's possible, it seems to be possible for pie charts and bar plots though.
If it is not possible to change or manipulate the actual plot symbol at a point I'm quite happy to simply draw something over the symbol. If so, is there a way to get the x,y coordinates (in relation to the screen) of each plot symbol? Or will I have to calculate that from my data? My data varies a_lot so I'm simply auto resizing the plot area at the moment.
thanks!
You can implement the -symbolForScatterPlot:recordIndex: datasource method to customize the plot symbol at each point. Return nil if you don't want a symbol drawn at the given index. The Mac version of CPTTestApp (in the Core Plot examples folder) has a plot symbol demo that shows how to use this method.

asp.net charts: Legend overlapping with X-axis

I am creating a Chart (DataVisualization.Charting.Chart) programmatically, which is a Stacked Bar chart.
I am also adding Legend entries programmatically to it. I want to show the Legend at the bottom of the chart.
But, while doing so, the Legend overlapps with the X-axis of the chart.
Here is the code I am using:
Private Function GetLegend(ByVal legendName As String, ByVal s As Single) As System.Windows.Forms.DataVisualization.Charting.Legend
Dim objLegend As System.Windows.Forms.DataVisualization.Charting.Legend = New System.Windows.Forms.DataVisualization.Charting.Legend()
objLegend.Name = legendName
objLegend.Font = New System.Drawing.Font("Verdana", s)
objLegend.IsDockedInsideChartArea = False
objLegend.Docking = Docking.Bottom
Return objLegend
End Function
Below statement adds that Legend to the chart
_msChart.Legends.Add(GetLegend("SomeValue1", 10.0F))
Any idea, what is missing? I want to show the legend at the bottom only, but it should not overlapp with the X-axis.
I had the same problem today. Try adding:
objLegend.Position.Auto = true
objLegend.DockedToChartArea = "yourChartAreaName"
That did not help me but I found on the net that this might be helpful (and clean solution).
What actually worked for me was moving chart area to make space for legend so it no longer overlaps. My legend was on top so this code worked for me:
chart.ChartAreas[0].Position.Y = 15
You can try resizing it instead, forcing it to be for example 20 pixels shorter than chart.Size.
Hope this helps.
I had an overlapping legend/chart area problem as well but none of the other suggestions here seemed to make any difference. I think the problem stems from legend text wrapping to two lines and the sizing algorithms not taking account of this.
The ideas here got me thinking more clearly about the problem though, and I was able control the size and position of the chart area using the following.
Chart1.ChartAreas[0].InnerPlotPosition = new ElementPosition(15, 5, 90, 75);
There's not much intellisense on those parameters, but as well as I could deduce, the parameters are all percentages of the total chart area (I initially thought they might be pixel values and got some very odd results). So what I've written above would set the plot area to start at 15% in from the left edge of the chart image and 5% down from the top, and have a width of 90% and a height of 75%.