itemlabel for HighLowChart (and image labels)
itemlabel for HighLowChart (and image labels)
Hi. I'm trying to generate labels on highlow chart with OHLC dataset. I'm using HighLowItemLabelGenerator and there are no labels on chart.
Is there any way to put labels on HighLowChart?
Besides, i want to put labels only for spesific Items. How do i do that? Also, is there any way to put image as ItemLabel?
Thank you.
Is there any way to put labels on HighLowChart?
Besides, i want to put labels only for spesific Items. How do i do that? Also, is there any way to put image as ItemLabel?
Thank you.
Forum is dead, or what?
Maybe, administrators could answer, for i paid for documentation (which sucks in many ways, btw), and everything it says is "some of ItemLabelGenerators are not implemented", without specifying exactly list of generators which were not implemented yet.
It seems like renderer (HighLowRenderer) doesnt call generateLabel method. Is it my mistake, or its not working yet? Is there anybody who done that before? I could try to do it again, but what the point in spending my time, if its not implemented or something?
Maybe, administrators could answer, for i paid for documentation (which sucks in many ways, btw), and everything it says is "some of ItemLabelGenerators are not implemented", without specifying exactly list of generators which were not implemented yet.
It seems like renderer (HighLowRenderer) doesnt call generateLabel method. Is it my mistake, or its not working yet? Is there anybody who done that before? I could try to do it again, but what the point in spending my time, if its not implemented or something?
-
- JFreeChart Project Leader
- Posts: 11734
- Joined: Fri Mar 14, 2003 10:29 am
- antibot: No, of course not.
- Contact:
Please send me your transaction reference and I'll refund your purchase.dmitryx wrote:...i paid for documentation (which sucks in many ways, btw)...
HighLowRenderer is one of the renderers that doesn't yet support item labels.
David Gilbert
JFreeChart Project Leader
Read my blog
Support JFree via the Github sponsorship program
JFreeChart Project Leader


I'm not trying to get my money back and i'm satisfied with product, and without doc its almost useles, as your policy is to make people to buy docs (which is ok in general), but even after, to make something in any way "complex" work - we need to spend our time or pay for support (and i dont need year support to solve one problem), for something is missed in devguide.
Re: itemlabel for HighLowChart (and image labels)
Hey dmitryx, what you have done may work for something I am trying to accomplish. I need to place text and/or symbols at specific spots on a chart. Please post your code.
Is it possible to, instead of text, have it pick up an image file (gif, jpg, etc) and place it where the text would go?
Is it possible to, instead of text, have it pick up an image file (gif, jpg, etc) and place it where the text would go?
-
- JFreeChart Project Leader
- Posts: 11734
- Joined: Fri Mar 14, 2003 10:29 am
- antibot: No, of course not.
- Contact:
Re: itemlabel for HighLowChart (and image labels)
You can use XYTextAnnotation and/or XYImageAnnotation. Something that isn't supported yet, but would be a useful extension to JFreeChart, is an annotation that can be attached to a specific data item (rather than just an XY location) so that if/when the data item is updated, the annotation "follows" it. Just mentioning it, I don't know if you need that or not.
David Gilbert
JFreeChart Project Leader
Read my blog
Support JFree via the Github sponsorship program
JFreeChart Project Leader


Re:
How does one have to implement that? Is there another renderer where one could pinch an idea how to do it?david.gilbert wrote:HighLowRenderer is one of the renderers that doesn't yet support item labels.
-
- JFreeChart Project Leader
- Posts: 11734
- Joined: Fri Mar 14, 2003 10:29 am
- antibot: No, of course not.
- Contact:
Re: itemlabel for HighLowChart (and image labels)
You could look at the way it is implemented in XYLineAndShapeRenderer:
1195 // draw the item label if there is one...
1196 if (isItemLabelVisible(series, item)) {
1197 drawItemLabel(g2, orientation, dataset, series, item, xx, yy,
1198 (y1 < 0.0));
1199 }
I'm not sure what is the right way to handle the high and low values, particularly ensuring that the item labels don't overlap with the visual representation of these values.
1195 // draw the item label if there is one...
1196 if (isItemLabelVisible(series, item)) {
1197 drawItemLabel(g2, orientation, dataset, series, item, xx, yy,
1198 (y1 < 0.0));
1199 }
I'm not sure what is the right way to handle the high and low values, particularly ensuring that the item labels don't overlap with the visual representation of these values.
David Gilbert
JFreeChart Project Leader
Read my blog
Support JFree via the Github sponsorship program
JFreeChart Project Leader


Re: itemlabel for HighLowChart (and image labels)
Here comes how I implemented the input mentioned above. It is more a beginning than a fully fledged example of how to include labels in HighLowCharts.david.gilbert wrote:You could look at the way it is implemented in XYLineAndShapeRenderer:
1195 // draw the item label if there is one...
1196 if (isItemLabelVisible(series, item)) {
1197 drawItemLabel(g2, orientation, dataset, series, item, xx, yy,
1198 (y1 < 0.0));
1199 }
I'm not sure what is the right way to handle the high and low values, particularly ensuring that the item labels don't overlap with the visual representation of these values.
Code: Select all
/*
* Some parts of this example are copied from HighLowChartDemo1.java.
*/
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.Date;
import javax.swing.JPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTickMarkPosition;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.entity.EntityCollection;
import org.jfree.chart.event.RendererChangeEvent;
import org.jfree.chart.labels.StandardXYItemLabelGenerator;
import org.jfree.chart.labels.XYItemLabelGenerator;
import org.jfree.chart.plot.CrosshairState;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.HighLowRenderer;
import org.jfree.chart.renderer.xy.XYItemRendererState;
import org.jfree.data.xy.DefaultHighLowDataset;
import org.jfree.data.xy.OHLCDataset;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RefineryUtilities;
/**
* A demo showing a high-low-open-close chart.
*/
public class HLOCChartWithOwnRendering2 extends ApplicationFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* A demonstration application showing a high-low-open-close chart.
*
* @param title the frame title.
*/
public HLOCChartWithOwnRendering2(String title) {
super(title);
JPanel chartPanel = createDemoPanel();
chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
setContentPane(chartPanel);
}
private static JFreeChart createChart(OHLCDataset dataset) {
JFreeChart chart = ChartFactory.createHighLowChart(
"High-Low-Open-Close Demo", "Time", "Price", dataset, true);
XYPlot plot = (XYPlot) chart.getPlot();
// plug in my own renderer
plot.setRenderer(new MyHighLowRenderer2());
MyHighLowRenderer2 r = (MyHighLowRenderer2) plot.getRenderer();
r.setHLOCItemPaint(Color.black);
// To set Labels
XYItemLabelGenerator generator = new StandardXYItemLabelGenerator();
r.setBaseItemLabelGenerator(generator);
r.setBaseItemLabelsVisible(true);
DateAxis axis = (DateAxis) plot.getDomainAxis();
axis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);
NumberAxis yAxis = (NumberAxis) plot.getRangeAxis();
yAxis.setNumberFormatOverride(new DecimalFormat("$0.00"));
return chart;
}
private static final Calendar calendar = Calendar.getInstance();
/**
* Returns a date using the default locale and timezone.
*
* @param y the year (YYYY).
* @param m the month (1-12).
* @param d the day of the month.
* @param hour the hour of the day.
* @param min the minute of the hour.
*
* @return A date.
*/
private static Date createDate(int y, int m, int d, int hour, int min) {
calendar.clear();
calendar.set(y, m - 1, d, hour, min);
return calendar.getTime();
}
/**
* Creates a sample high low dataset.
*
* @return a sample high low dataset.
*/
public static OHLCDataset createDataset() {
Date[] date = new Date[14];
double[] high = new double[14];
double[] low = new double[14];
double[] open = new double[14];
double[] close = new double[14];
double[] volume = new double[14];
int jan = 1;
date[0] = createDate(2001, jan, 4, 12, 0);
high[0] = 54.00;
low[0] = 51.00;
open[0] = 52.00;
close[0] = 53.00;
volume[0] = 100.0;
date[1] = createDate(2001, jan, 5, 12, 0);
high[1] = 56.50;
low[1] = 51.80;
open[1] = 53.50;
close[1] = 56.00;
volume[1] = 150.0;
date[2] = createDate(2001, jan, 6, 12, 0);
high[2] = 57.00;
low[2] = 52.00;
open[2] = 56.00;
close[2] = 54.50;
volume[2] = 70.0;
date[3] = createDate(2001, jan, 7, 12, 0);
high[3] = 58.00;
low[3] = 54.00;
open[3] = 54.50;
close[3] = 57.50;
volume[3] = 200.0;
date[4] = createDate(2001, jan, 8, 12, 0);
high[4] = 58.50;
low[4] = 55.00;
open[4] = 57.50;
close[4] = 55.50;
volume[4] = 120.0;
date[5] = createDate(2001, jan, 9, 12, 0);
high[5] = 57.80;
low[5] = 53.00;
open[5] = 56.00;
close[5] = 53.00;
volume[5] = 110.0;
date[6] = createDate(2001, jan, 10, 12, 0);
high[6] = 55.0;
low[6] = 51.50;
open[6] = 53.50;
close[6] = 54.00;
volume[6] = 20.0;
date[7] = createDate(2001, jan, 11, 12, 0);
high[7] = 54.50;
low[7] = 51.80;
open[7] = 54.00;
close[7] = 52.00;
volume[7] = 30.0;
date[8] = createDate(2001, jan, 12, 12, 0);
high[8] = 52.50;
low[8] = 49.00;
open[8] = 52.00;
close[8] = 51.70;
volume[8] = 100.0;
date[9] = createDate(2001, jan, 13, 12, 0);
high[9] = 52.00;
low[9] = 48.90;
open[9] = 51.00;
close[9] = 49.00;
volume[9] = 50.0;
date[10] = createDate(2001, jan, 14, 12, 0);
high[10] = 49.30;
low[10] = 46.00;
open[10] = 49.00;
close[10] = 46.00;
volume[10] = 80.0;
date[11] = createDate(2001, jan, 15, 12, 0);
high[11] = 47.10;
low[11] = 45.90;
open[11] = 46.00;
close[11] = 47.00;
volume[11] = 90.0;
date[12] = createDate(2001, jan, 16, 12, 0);
high[12] = 47.10;
low[12] = 44.90;
open[12] = 46.80;
close[12] = 45.00;
volume[12] = 20.0;
date[13] = createDate(2001, jan, 17, 12, 0);
high[13] = 46.80;
low[13] = 43.10;
open[13] = 45.20;
close[13] = 44.50;
volume[13] = 70.0;
return new DefaultHighLowDataset("Series 1", date, high, low, open, close, volume);
}
/**
* Creates a panel for the demo (used by SuperDemo.java).
*
* @return A panel.
*/
public static JPanel createDemoPanel() {
JFreeChart chart = createChart(createDataset());
return new ChartPanel(chart);
}
/**
* Starting point for the demonstration application.
*
* @param args ignored.
*/
public static void main(String[] args) {
HLOCChartWithOwnRendering2 demo = new HLOCChartWithOwnRendering2(
"JFreeChart: HighLowChartDemo1.java");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
}
class MyHighLowRenderer2 extends HighLowRenderer {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* The paint used for the the HLOC-Items (modification).
*/
private transient Paint hlocItemPaint;
/**
* The paint used for the open ticks (if <code>null</code>, the series
* paint is used instead).
*/
private transient Paint openTickPaint;
/**
* The paint used for the close ticks (if <code>null</code>, the series
* paint is used instead).
*/
private transient Paint closeTickPaint;
/**
* Newly introduced method.
*
* Returns the paint used to draw the HLOC items.
*
* @return The paint used to draw the HLOC items.
*
* @see #setHLOCItemPaint(Paint)
*/
public Paint getHLOCItemPaint() {
return this.hlocItemPaint;
}
/**
* Newly introduced method.
*
* Sets the paint used to draw HLOC items and sends a
* {@link RendererChangeEvent} to all registered listeners.
*
* @param paint the paint (<code>null</code> permitted).
*
* @see #getHLOCPaint()
*/
public void setHLOCItemPaint(Paint paint) {
this.hlocItemPaint = paint;
fireChangeEvent();
}
/**
* Overwritten version of jfree.org.
*
* @param g2 the graphics device.
* @param state the renderer state.
* @param dataArea the area within which the plot is being drawn.
* @param info collects information about the drawing.
* @param plot the plot (can be used to obtain standard color
* information etc).
* @param domainAxis the domain axis.
* @param rangeAxis the range axis.
* @param dataset the dataset.
* @param series the series index (zero-based).
* @param item the item index (zero-based).
* @param crosshairState crosshair information for the plot
* (<code>null</code> permitted).
* @param pass the pass index.
*/
public void drawItem(Graphics2D g2,
XYItemRendererState state,
Rectangle2D dataArea,
PlotRenderingInfo info,
XYPlot plot,
ValueAxis domainAxis,
ValueAxis rangeAxis,
XYDataset dataset,
int series,
int item,
CrosshairState crosshairState,
int pass) {
double x = dataset.getXValue(series, item);
if (!domainAxis.getRange().contains(x)) {
return; // the x value is not within the axis range
}
double xx = domainAxis.valueToJava2D(x, dataArea,
plot.getDomainAxisEdge());
// setup for collecting optional entity info...
Shape entityArea = null;
EntityCollection entities = null;
if (info != null) {
entities = info.getOwner().getEntityCollection();
}
PlotOrientation orientation = plot.getOrientation();
RectangleEdge location = plot.getRangeAxisEdge();
Paint itemPaint = getItemPaint(series, item);
// if-block is a modification of jfree.org version.
if (this.hlocItemPaint != null) {
itemPaint = this.hlocItemPaint;
}
Stroke itemStroke = getItemStroke(series, item);
g2.setPaint(itemPaint);
g2.setStroke(itemStroke);
if (dataset instanceof OHLCDataset) {
OHLCDataset hld = (OHLCDataset) dataset;
double yHigh = hld.getHighValue(series, item);
double yLow = hld.getLowValue(series, item);
if (!Double.isNaN(yHigh) && !Double.isNaN(yLow)) {
double yyHigh = rangeAxis.valueToJava2D(yHigh, dataArea,
location);
double yyLow = rangeAxis.valueToJava2D(yLow, dataArea,
location);
if (orientation == PlotOrientation.HORIZONTAL) {
g2.draw(new Line2D.Double(yyLow, xx, yyHigh, xx));
entityArea = new Rectangle2D.Double(Math.min(yyLow, yyHigh),
xx - 1.0, Math.abs(yyHigh - yyLow), 2.0);
}
else if (orientation == PlotOrientation.VERTICAL) {
g2.draw(new Line2D.Double(xx, yyLow, xx, yyHigh));
entityArea = new Rectangle2D.Double(xx - 1.0,
Math.min(yyLow, yyHigh), 2.0,
Math.abs(yyHigh - yyLow));
}
}
double delta = getTickLength();
if (domainAxis.isInverted()) {
delta = -delta;
}
if (getDrawOpenTicks()) {
double yOpen = hld.getOpenValue(series, item);
if (!Double.isNaN(yOpen)) {
double yyOpen = rangeAxis.valueToJava2D(yOpen, dataArea,
location);
if (this.openTickPaint != null) {
g2.setPaint(this.openTickPaint);
}
else {
g2.setPaint(itemPaint);
}
if (orientation == PlotOrientation.HORIZONTAL) {
g2.draw(new Line2D.Double(yyOpen, xx + delta, yyOpen,
xx));
}
else if (orientation == PlotOrientation.VERTICAL) {
g2.draw(new Line2D.Double(xx - delta, yyOpen, xx,
yyOpen));
}
}
}
if (getDrawCloseTicks()) {
double yClose = hld.getCloseValue(series, item);
if (!Double.isNaN(yClose)) {
double yyClose = rangeAxis.valueToJava2D(
yClose, dataArea, location);
if (this.closeTickPaint != null) {
g2.setPaint(this.closeTickPaint);
}
else {
g2.setPaint(itemPaint);
}
if (orientation == PlotOrientation.HORIZONTAL) {
g2.draw(new Line2D.Double(yyClose, xx, yyClose,
xx - delta));
}
else if (orientation == PlotOrientation.VERTICAL) {
g2.draw(new Line2D.Double(xx, yyClose, xx + delta,
yyClose));
}
}
}
}
else {
// not a HighLowDataset, so just draw a line connecting this point
// with the previous point...
if (item > 0) {
double x0 = dataset.getXValue(series, item - 1);
double y0 = dataset.getYValue(series, item - 1);
double y = dataset.getYValue(series, item);
if (Double.isNaN(x0) || Double.isNaN(y0) || Double.isNaN(y)) {
return;
}
double xx0 = domainAxis.valueToJava2D(x0, dataArea,
plot.getDomainAxisEdge());
double yy0 = rangeAxis.valueToJava2D(y0, dataArea, location);
double yy = rangeAxis.valueToJava2D(y, dataArea, location);
if (orientation == PlotOrientation.HORIZONTAL) {
g2.draw(new Line2D.Double(yy0, xx0, yy, xx));
}
else if (orientation == PlotOrientation.VERTICAL) {
g2.draw(new Line2D.Double(xx0, yy0, xx, yy));
}
}
}
if (entities != null) {
addEntity(entities, entityArea, dataset, series, item, 0.0, 0.0);
}
/* The following if-Block is more or less a quick and dirty copy and past of
* some code out of function drawSecondaryPass out of class XYLineAndShapeRenderer (Version 1.0.13).
* The code in the if block does not exist in HighLowRenderer.
* */
if (isItemLabelVisible(series, item)) {
// get the data point...
double x1 = dataset.getXValue(series, item);
double y1 = dataset.getYValue(series, item);
if (Double.isNaN(y1) || Double.isNaN(x1)) {
return;
}
RectangleEdge xAxisLocation = plot.getDomainAxisEdge();
RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
double transX1 = domainAxis.valueToJava2D(x1, dataArea, xAxisLocation);
double transY1 = rangeAxis.valueToJava2D(y1, dataArea, yAxisLocation);
xx = transX1;
double yy = transY1;
yy = 100.0;
System.out.println(xx+" "+yy);
drawItemLabel(g2, orientation, dataset, series, item, xx, yy,
(y1 < 0.0));
}
}
}
-
- Posts: 1
- Joined: Mon May 07, 2012 11:04 am
- antibot: No, of course not.
- Contact:
Re: itemlabel for HighLowChart (and image labels)
People here seem to quite, the reason that I into this BBS, is want to learn some knowledge in this aspect.
Re: itemlabel for HighLowChart (and image labels)
As far as I know item labels are not supported by HighLowRenderer.princelee1019 wrote:It seems like renderer doesnt call generateLabel method. Is it my mistake, or its not working yet? Is there anybody who done that before? I could try to do it again, but what the point in spending my time, if its not implemented or something?
-
- Posts: 1
- Joined: Fri Nov 01, 2013 11:34 am
- antibot: No, of course not.
Re: itemlabel for HighLowChart (and image labels)
Thanks for sharing.