I need to move labels outside from bars, towards right. Image link is given above.
Bar chart label code:
BarRenderer br = (BarRenderer) plot.getRenderer();
br.setItemMargin(0);
br.setSeriesPaint(0, new java.awt.Color(227, 110, 37));
br.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
br.setBaseItemLabelsVisible(true);
br.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.INSIDE3, TextAnchor.CENTER_RIGHT, TextAnchor.CENTER, 0.0));
Related
Is it possible to place crosshair label in the custom position? I have x and y crosshair. I want that y crosshair label was positioned near the data point (change label offset X coordinate).
The problem is that RectangleAnchor has no such option
Crosshair yCrosshair = new Crosshair(Double.NaN, Color.DARK_GRAY, new BasicStroke(0f));
yCrosshair.setLabelAnchor(RectangleAnchor.CENTER);
And it seems that JFreeChart completely ignores label offset settings:
Crosshair yCrosshair = new Crosshair(Double.NaN, Color.DARK_GRAY, new BasicStroke(0f));
yCrosshair.setLabelXOffset(5);
I have the desired plot coordinates for the label in the mouse listener but I can't find how to apply it to the label position.
Ok I've solved my problem by using XYPointerAnnotation.
XYPointerAnnotation pointer = new XYPointerAnnotation( "", 0, 0, 7.0 * Math.PI / 4.0 );
pointer.setTipRadius(3.0);
pointer.setBaseRadius(15.0);
pointer.setPaint(Color.blue);
pointer.setTextAnchor(TextAnchor.HALF_ASCENT_LEFT);
pointer.setBackgroundPaint(new Color(180, 180, 180, 180));
And on mouse move event I've position the annotation to the desired point
mainPlot.removeAnnotation(pointer);
if ( !sY.isNaN() ) {
pointer.setX(x);
pointer.setY(sY);
pointer.setText("POWER: "+ sY);
mainPlot.addAnnotation(pointer);
}
I'd like to get stacked area chart with beginning chart in first point and completing in last point like here:
But picture is out of point's range like here:
How can I make stacked area starting exactly from the first point and completing exactly in the last point?
(Different manipulations with dateAxis.setLowerMargin(-0.075D) dateAxis.setUpperMargin(-0.075D) are not helping)
JFreeChart stackedAreaChart = ChartFactory.createStackedAreaChart(name, X_AXIS_TITLE, Y_AXIS_TITLE, dataset,
PlotOrientation.VERTICAL, true, true, false);
CategoryPlot plot = stackedAreaChart.getCategoryPlot();
CategoryAxis dateAxis = plot.getDomainAxis();
dateAxis.setLowerMargin(-0.075D);
dateAxis.setUpperMargin(-0.075D);
dateAxis.setCategoryMargin(0.0D);
StackArea renderer = new StackArea();
dateAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
...
plot.setRenderer(renderer);
renderer.setBaseItemLabelGenerator(new LabelGenerator());
renderer.setBaseItemLabelsVisible(true);
...
plot.setRenderer(renderer);
plot.setAxisOffset(new RectangleInsets(5.0, 1.0, 5.0, 1.0));
ValueAxis rangeAxis = plot.getRangeAxis();
NumberAxis axis2 = new NumberAxis(Y_AXIS_TITLE);
axis2.setAutoRangeIncludesZero(false);
axis2.setLabelFont(rangeAxis.getLabelFont());
axis2.setTickLabelFont(rangeAxis.getTickLabelFont());
...
plot.setRangeAxis(1, axis2);
plot.setRangeAxisLocation(1, AxisLocation.TOP_OR_RIGHT);
plot.mapDatasetToRangeAxes(0, Arrays.asList(0, 1));
setAxisColor(rangeAxis, axisColor);
rangeAxis.setTickLabelPaint(ColorUtils.VaadinAWTColor(params.getColorParams().getFontSlideColor()));
rangeAxis.setLabelPaint(ColorUtils.VaadinAWTColor(params.getColorParams().getFontSlideColor()));
You can get the effect you want by using the default margins on the chart's CategoryAxis, i.e. don't change them as the demo does.
CategoryAxis categoryaxis = categoryplot.getDomainAxis();
//categoryaxis.setLowerMargin(0.0D);
//categoryaxis.setUpperMargin(0.0D);
//categoryaxis.setCategoryMargin(0.0D);
I need stacked area to start for the first point—exactly from C1 in your picture, not earlier, and stop on C8, not later.
You may need to adjust the values to get closer to the desired result.
categoryaxis.setLowerMargin(-0.075D);
categoryaxis.setUpperMargin(-0.075D);
categoryaxis.setCategoryMargin(0.0D);
Edited to add working image at end.
I need to add some sort of annotation to a line graph that I've generated. The red line is the data I'm graphing successfully using a XYLineChart and a XYLineAndShapeRenderer. The squares and text are samples of what I would like to add but have been unable to get working. The data for the graph may be updated as fast as once per second.
Here is how I'm creating the chart:
private JFreeChart createChart(XYDataset dataset) {
final JFreeChart result = ChartFactory.createXYLineChart(
TITLE, // chart title
XAXIS, // domain axis label (x-axis)
YAXIS, // range axis label (y-axis)
dataset, // data
PlotOrientation.VERTICAL, // orientation
false, // include legend
true, // tooltips?
false // URLs?
);
customizeChart(result);
return result;
}
private void customizeChart(final JFreeChart result) {
// NOW DO SOME OPTIONAL CUSTOMIZATION OF THE CHART...
// set the background color for the chart...
result.setBackgroundPaint(null); //makes background transparent.
// get a reference to the plot for further customisation...
XYPlot plot = (XYPlot) result.getPlot();
plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
plot.setRangePannable(false);
XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(true, true);
// I've also tried to use a spline renderer
// XYSplineRenderer renderer = new XYSplineRenderer();
renderer.setSeriesShapesVisible(0, false);
renderer.setBaseShapesVisible(true);
plot.setRenderer(renderer);
// set the range axis to display integers only...
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
rangeAxis.setTickUnit(new NumberTickUnit(10.0)); //otherwise tick units will randomly change to be 5's sometimes.
//set the max/min values
rangeAxis.setUpperBound(MAX);
rangeAxis.setLowerBound(MIN);
// rangeAxis.setInverted(true);
rangeAxis.setInverted(false);
//get the other axis for work in the next step.
NumberAxis domainAxis = (NumberAxis) plot.getDomainAxis();
domainAxis.setAutoRange(true);
domainAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
//do some font stuff
Font axisFont = new Font("Tahoma", Font.BOLD, 12);
Font tickFont = new Font("Tahoma", Font.PLAIN, 11);
Font titleFont = new Font("Tahoma", Font.BOLD, 18);
result.getTitle().setFont(titleFont);
rangeAxis.setLabelFont(axisFont);
rangeAxis.setTickLabelFont(tickFont);
domainAxis.setLabelFont(axisFont);
domainAxis.setTickLabelFont(tickFont);
}
Here's how I'm trying to get something to draw right now:
XYPlot plot = chart.getXYPlot();
XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) plot.getRenderer();
BasicStroke stroke = new BasicStroke(2.0f);
Rectangle2D.Double rect = new Rectangle2D.Double(10, 10, 10, 20);
// renderer.addAnnotation(new XYShapeAnnotation(
// rect, stroke, Color.GREEN), Layer.BACKGROUND);
plot.addAnnotation(new XYShapeAnnotation(
rect, stroke, Color.GREEN));
Ellipse2D.Double circle = new Ellipse2D.Double(8, 8, 20, 20);
renderer.addAnnotation(new XYShapeAnnotation(
circle, stroke, blue), Layer.BACKGROUND);
plot.drawAnnotations((Graphics2D) chartPanel.getGraphics(), chartPanel.getBounds(), chartPanel.getChartRenderingInfo().getPlotInfo());
// This line does draw, but immediately disappears
Graphics2D g2 = (Graphics2D) chartPanel.getGraphics();
Line2D line = new Line2D.Double(0, 100, 500, 350);
g2.draw(line);
Thanks.
Edit with working image:
I think maybe the circle and rectangle I was trying to add are off of the visible chart coordinate space.
It may help to note that org.jfree.chart.annotations typically require that coordinates are specified in model (dataset) coordinates, not view (plot) coordinates.
I placed the legend in the top left corner and there is an unnecessary gap between the chart and the legend.
How to reduce this?
There is considerable amount of space between pie chart and its border.
public void setPie() {
RingPlot plot = (RingPlot) this.chart.getPlot();
plot.setSectionPaint("", WHITE_COLOR);
plot.setCircular(true);
plot.setShadowPaint(null);
}
public void setLegend() {
LegendTitle legend = this.chart.getLegend();
legend.setVerticalAlignment(VerticalAlignment.TOP);
legend.setVisible(true);
legend.setPosition(RectangleEdge.LEFT);
Rectangle rect = new Rectangle(LEGEND_LENGTH, LEGEND_WIDTH);
RingPlot plot = (RingPlot) this.chart.getPlot();
plot.setLegendItemShape((Shape) rect);
}
You could try tweaking the margins around the LegendTitle. Something like:
chart.getLegend().setMargin(top, left, bottom, right);
EDIT: As suggested in the post in the comments, you could try to draw the legend manually at a given position:
//Print legend at X & Y location
Rectangle2D r2DD = new Rectangle2D.Double(119, 47, 120, 180);
LegendTitle legend = new LegendTitle(chart.getPlot());
legendTitle.draw(g2,r2DD);
But I'm not sure how to implement it, as you need access to the ChartPanel's Graphics2D. Perhaps by extending ChartPanel and overriding paintComponent(Graphics g) ?
I have updatable OHLCChart.
I need to draw a line over chart.
How to implement it?
If you want to draw a vertical or horizontal line at a given position on an axis, you can use a ValueMarker :
ValueMarker marker = new ValueMarker(position); // position is the value on the axis
marker.setPaint(Color.black);
//marker.setLabel("here"); // see JavaDoc for labels, colors, strokes
XYPlot plot = (XYPlot) chart.getPlot();
plot.addDomainMarker(marker);
Use plot.addRangeMarker() if you want to draw an horizontal line.
Something like this should work if you want to plot a line indicator (like a moving average for example):
XYDataset dataSet = // your line dataset
CombinedDomainXYPlot plot = (CombinedDomainXYPlot) chart.getPlot();
XYPlot plot = (XYPlot) plot.getSubplots().get(0);
int dataSetIndx = plot.getDatasetCount();
plot.setDataset(dataSetIndx, dataSet);
XYLineAndShapeRenderer lineRenderer = new XYLineAndShapeRenderer(true, false);
plot.setRenderer(dataSetIndx, lineRenderer);