i'm using jfreechart, and i need to add labels to my series data. There are bold dots on graphic and they need labels... Following code does not work.
XYSeries series = new XYSeries("Average Size");
series.add(.60, .70);
XYDataset xyDataset = new XYSeriesCollection(series);
XYItemRenderer rend = new XYShapeRenderer();
XYItemLabelGenerator generator = new XYItemLabelGenerator() {
#Override
public String generateLabel(XYDataset xyd, int i, int i1) {
return "Some label?";
}
};
//SeriesItemLabelGenerator
rend.setBaseItemLabelGenerator(generator);
rend.setBaseItemLabelsVisible(true);
ItemLabelPosition pos = new ItemLabelPosition(ItemLabelAnchor.CENTER, TextAnchor.TOP_LEFT);
rend.setBasePositiveItemLabelPosition(pos);
I think the problem is that XYShapeRenderer(http://www.jfree.org/jfreechart/api/javadoc/src-html/org/jfree/chart/renderer/xy/XYShapeRenderer.html), which extends AbstractXYItemRenderer, does not implement ItemLabelGenerator logic yet.
So, or you will need to use another Renderer.
For example, XYLineAndShapeRenderer(http://www.jfree.org/jfreechart/api/javadoc/src-html/org/jfree/chart/renderer/xy/XYLineAndShapeRenderer.html) implements it:
// draw the item label if there is one...
if (isItemLabelVisible(series, item)) {
drawItemLabel(g2, orientation, dataset, series, item, xx, yy,(y1 < 0.0));
}
Or you will need to extend XYShapeRenderer yourself and add the label drawing logic, using any of the other Renderer's source code as an example.
Related
I'm using JFreeChart to graph some data, and I've set it up so that the graph shows my standard error for each point as such:
The label shows the Y value for each point, but I'd like to be able to show the Y value for the standard errors as well. Furthermore, is there a way to make it so this data only shows up if hovered over with the mouse?
This is the code I use to add both the error and the labels:
XYErrorRenderer renderer = new XYErrorRenderer();
renderer.setBaseLinesVisible(true);
renderer.setBaseShapesVisible(true);
renderer.setBaseItemLabelGenerator(new StandardXYItemLabelGenerator("{2}",
NumberFormat.getNumberInstance(),NumberFormat.getNumberInstance()));
renderer.setBaseItemLabelsVisible(true);
chart.getXYPlot().setRenderer(renderer);
Thanks in advance.
XYErrorRenderer inherits its implementation of drawItemLabel() from the abstract parent, which knows nothing about the error bars. You'll need to override drawItem() in a custom renderer subclass to draw the extra labels. The source for drawItemLabel() may serve as a guide.
Addendum: A less ambitious alternative would be to display the error range in a tooltip. The custom StandardXYToolTipGenerator below specifies a custom format string and overrides createItemArray() to supply the relevant y values from the dataset. As your XYDataset is a YIntervalSeriesCollection, you can cast it as shown below.
renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator(
"{0}: {1}…{2}", NumberFormat.getInstance(), NumberFormat.getInstance()) {
#Override
protected Object[] createItemArray(XYDataset data, int series, int item) {
YIntervalSeriesCollection d = (YIntervalSeriesCollection) data;
Object[] result = new Object[3];
double y = d.getYValue(series, item);
result[0] = getYFormat().format(y);
double min = d.getStartYValue(series, item);
result[1] = getYFormat().format(min);
double max = d.getEndYValue(series, item);
result[2] = getYFormat().format(max);
return result;
}
});
I'm trying to display formatted Strings within JFreeChart's legend.
The APIAPI shows support for this, but however I cannot get it to display.
The aim is to get superscripts, subscripts displayed in jfreecharts legend..
I've written my own renderer and overriden the following:
#Override
public LegendItem getLegendItem(int datasetIndex, int series) {
LegendItem legendItem = super.getLegendItem(datasetIndex, series);
AttributedString attString = new AttributedString("s14");
attString.addAttribute(TextAttribute.FONT, new Font(Font.SANS_SERIF, Font.PLAIN, 10));
attString.addAttribute(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUB, 1,3);
Shape shape = getLegendBar();
Paint paint = getBaseFillPaint();
legendItem = new LegendItem(attString, null, null, null, shape, paint);
return legendItem;
}
But this shows only "s14" as normal string. I need to get the "14" to display in subscript.
Does anyone know, what I am doing wrong or how to achieve this ?
I am working on graph chart using aChartEngine, the problem faced is that the although graph are generating, problem is graph is not coming as per need inside the view, how to fix it ??
When selecting Bar from drop down
After Zooming Out and panning(by interacting with graph)
Here is my code
private static XYMultipleSeriesDataset getBarDataset(int rightAnswers, int wrongAnswers)
{
String[] labels={"right","wrong"};
List<Double> values = new ArrayList<Double>();
values.add((double) rightAnswers);
values.add((double) wrongAnswers);
XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
for (int i = 0; i < titles.length; i++)
{
XYSeries series = new XYSeries(titles[i]);
series.add(i,values.get(i));
dataset.addSeries(i,series);
}
return dataset;
}
2)Renderer
protected static XYMultipleSeriesRenderer buildBarRenderer(int[] colors) {
XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
renderer.addXTextLabel(0, "right");
renderer.addXTextLabel(1, "wrong");
renderer.setChartTitle("Results");
int length = colors.length;
SimpleSeriesRenderer r = new SimpleSeriesRenderer();
r.setColor(colors[0]);
renderer.addSeriesRenderer(r);
r = new SimpleSeriesRenderer();
r.setColor(colors[1]);
renderer.addSeriesRenderer(r);
renderer.setScale(10);
renderer.setXLabels(0);
renderer.setApplyBackgroundColor(true);
renderer.setBackgroundColor(Color.WHITE);
renderer.setAxesColor(Color.CYAN);
renderer.setBarWidth(30);
return renderer;
}
3) the view
ChartFactory.getBarChartView(context, getBarDataset(rightAnswers, wrongAnswers), buildBarRenderer(new int[]{Color.GREEN,Color.RED}), Type.DEFAULT);
Query
1) How to fix the position and exact panned graph
2) Can we have 3d effect on bars??How??
3) Is there any other library simpler compared to aChartEngine??
To solve the problem of having bar inside the graph we need to specify X-axis and Y-axis min and max based on your minimum and maximum values,eg; for the renderer, you need
renderer.setXAxisMin(-1);
renderer.setXAxisMax(wrongAnswers);
renderer.setYAxisMax(10);
renderer.setYAxisMin(0);
so the final result comes out to be
How can I draw such a graph using Swing? I have used a JFreeChart library, but I don't know how can I draw such a line graph using that library?
import org.jfree.chart.*;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.*;
public class DrawGraph{
public void drawGraph(int[][] drawPoints) {
XYSeries series = new XYSeries("Average Weight");
for(int i=0;i<drawPoints.length;i++){
for(int j=0;j<=1;j+=2){
if(drawPoints[i][j]!=0){
series.add(bla...bla...bla...);
}
}
}
XYDataset xyDataset = new XYSeriesCollection(series);
JFreeChart chart = ChartFactory.createXYLineChart
("XYLine Chart using JFreeChart", "Age", "Weight",
xyDataset, PlotOrientation.VERTICAL, true, true, false);
ChartFrame frame1=new ChartFrame("XYLine Chart",chart);
frame1.setVisible(true);
frame1.setSize(300,300);
}
}
I have drawn graph using this but isn't working...
It looks like you're having trouble constructing a dataset. You can use a method like that shown below with either ChartFactory.createXYAreaChart() or ChartFactory.createXYLineChart().
private static XYDataset createDataset() {
XYSeriesCollection result = new XYSeriesCollection();
XYSeries series = new XYSeries("Test");
series.add(0, 2);
// more points here
series.add(10, 10);
result.addSeries(series);
return result;
}
See also these examples.
As an aside, it's not clear what's important in you picture, and I can't make sense of the unordered axis at the top. In my opinion, the better question is not How do I make this graph? but rather How can I best display this data?
http://sourceforge.net/apps/trac/jung/wiki/JUNGManual
Use JUNG instead. Its easy and written in java.
I have a JFreeChart instance that displays process memory status, initialized as follows:
m_data = new TimeSeriesCollection();
TimeSeries vmsize = new TimeSeries("VMSize");
TimeSeries resident = new TimeSeries("Resisdent");
TimeSeries shared = new TimeSeries("Shared memory");
TimeSeries code = new TimeSeries("Code");
TimeSeries data = new TimeSeries("Data");
m_data.addSeries(vmsize);
m_data.addSeries(resident);
m_data.addSeries(shared);
m_data.addSeries(code);
m_data.addSeries(data);
JFreeChart chart = ChartFactory.createTimeSeriesChart("Memory usage", "Time", "Size", m_data, true, true, false);
m_chart = new ChartPanel(chart);
Later I add values to each TimeSeries in the TimeSeriesCollection. I would like to somehow know - when the user clicks on the Chart - either what time associated with that columm, or even better - what is the index of the value.
I looked at the JFreeChart and ChartMouseListener classes, but I could not figure out how to do that (also the documentation of JFreeChart is annoyingly scarce, I guess they are trying to get people to buy their developer's guide).
if you click dead on the item, the event.getEntity() function returns XYItem and then from there onwards
XYItemEntity xyitem=(XYItemEntity) event.getEntity(); // get clicked entity
XYDataset dataset = (XYDataset)xyitem.getDataset(); // get data set
System.out.println(xyitem.getItem()+" item of "+xyitem.getSeriesIndex()+"series");
System.out.println(dataset.getXValue(xyitem.getSeriesIndex(), xyitem.getItem()));
System.out.println(dataset.getYValue(xyitem.getSeriesIndex(), xyitem.getItem()));
Comparable comparable=dataset.getSeriesKey(0);
XYPlot xyplot = (XYPlot) event.getChart().getPlot();
System.out.println(xyplot.getRangeCrosshairValue());
however incase you do not click on the item itself but your crosshair is set to auto lock on data, in such case the crosshair will move to nearest item but since the item has not been clicked, you will not be able to get the XYItem and hence you cannot know the series and item index, to solve this problem there is this code below, it should be put in the catch clause while the above mentioned code should be in try clause
first define a function which will take crosshair value at domain and range and also Xydataset, this functions returns an inner class object that groups item index and series index
public static SeriesAndItemIndex getItemIndex(double domainVal,double rangeVal,XYDataset xydataset){
Comparable comparable;
int indexOf;
for(int i=0;i<xydataset.getSeriesCount();i++){
comparable = xydataset.getSeriesKey(i);
indexOf=xydataset.indexOf(comparable);
for(int j=0 ; j<xydataset.getItemCount(indexOf);j++){
double x=xydataset.getXValue(indexOf, j);
double y=xydataset.getYValue(indexOf, j);
if(x == domainVal && y==rangeVal){
return new SeriesAndItemIndex(j,indexOf);//return item index and series index
}
}
}
return null;
}
private static class SeriesAndItemIndex{ ///inner CLASS to group series and item clicked index
public int itemIndex;
public int seriesIndex;
public SeriesAndItemIndex(int i,int s){
itemIndex=i;
seriesIndex=s;
}
#Override
public String toString(){
return "itemIndex="+itemIndex+",seriesIndex="+seriesIndex;
}
}
how to use it?
try{......code block from the top
}catch(Exception e){
Object source=event.getSource();
JFreeChart chartpanel=(JFreeChart)source;
XYPlot xyplot = (XYPlot) chartpanel.getPlot();
XYDataset xydataset= xyplot.getDataset();
double d=xyplot.getDomainCrosshairValue(); //get crosshair X value
double r =xyplot.getRangeCrosshairValue(); //get crosshair y value
SeriesAndItemIndex index=getItemIndex(d,r,xydataset);
if(index != null){
System.out.println(index.toString());
}
}
hmm should work, if you replace the last two lines by something like this:
ChartPanel panel=new ChartPanel(ChartFactory.createTimeSeriesChart("Memory usage", "Time", "Size", m_data, true, true, false)));
panel.addChartMouseListener(new ChartMouseListener(){
void chartMouseClicked(ChartMouseEvent e){
[...do something on click...]
}
void chartMouseMoved(ChartMouseEvent e){
[...do something on move...]
}
});
return panel;