2

I would like to draw a Dirac (or Kronecker symbol if you prefer), by that I mean to draw discrete values on my chart with a vertical bar like that (without the labels) :

Good example I could make it with a BarChart but it's not very good looking... Is there a nice way to do it ?

EDIT : I used your method and I made that :

enter image description here

But as you can see some of the bars have a different color, maybe of the color gradient ? Do you know how to make the bars all red ?

Here is the code :

public class XYDiscreteBarChart {

    private final Color CHART_BACKGROUND_COLOR = new JPanel().getBackground();
    private final Color CHART_FOREGROUND_COLOR = new JLabel().getForeground();
    private final Color CROSSHAIR_COLOR = Color.BLUE;
    private final String title; // Titre du graphique
    private final String xTitle; // Titre de l'axe des abscisses
    private final String yTitle; // Titre de l'axe des ordonnées
    private final XYDataset dataset; // Les données affichées dans le graphique
    private final boolean isLegendVisible; // Affichage de la légende
    private final boolean isTooltipsVisible; // Affichge des tooltips
    private final boolean isUrlVisible; // Affichage des urls
    private final boolean isGridXVisible; // Affichage de la grille verticale
    private final boolean isGridYVisible; // Affichage de la grille horizontale
    private JFreeChart chart; // Le graphique
    private XYPlot plot; // La zone de dessin des courbes

    public XYDiscreteBarChart(String title, String xAxisLabel, String yAxisLabel, XYDataset dataset, boolean legend,
        boolean tooltip, boolean url) {
        this.title = title;
        this.xTitle = xAxisLabel;
        this.yTitle = yAxisLabel;
        this.isLegendVisible = legend;
        this.isTooltipsVisible = tooltip;
        this.isUrlVisible = url;
        this.dataset = dataset;
        this.isGridXVisible = true;
        this.isGridYVisible = true;

        createChart();
        setChartStyle();
    }

    private void createChart() {
        this.chart = ChartFactory.createXYBarChart(
            this.title,
            this.xTitle,
            false,
            this.yTitle,
            formatDataset(),
            PlotOrientation.VERTICAL,
            this.isLegendVisible,
            this.isTooltipsVisible,
            this.isUrlVisible);
        this.plot = (XYPlot) this.chart.getPlot();
    }

    private void setChartStyle() {
        this.plot.setBackgroundAlpha((float) 0.0);
        this.plot.setDomainCrosshairVisible(this.isGridXVisible);
        this.plot.setDomainCrosshairLockedOnData(true);
        this.plot.setRangeCrosshairVisible(this.isGridYVisible);
        this.plot.setRangeAxisLocation(AxisLocation.TOP_OR_LEFT);
        this.plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));

        this.chart.setBackgroundPaint(this.CHART_BACKGROUND_COLOR);
        this.plot.getDomainAxis(0).setAxisLinePaint(this.CHART_FOREGROUND_COLOR);
        this.plot.getDomainAxis(0).setLabelPaint(this.CHART_FOREGROUND_COLOR);
        this.plot.getDomainAxis(0).setTickLabelPaint(this.CHART_FOREGROUND_COLOR);
        this.plot.getDomainAxis(0).setTickMarkPaint(this.CHART_FOREGROUND_COLOR);
        this.plot.getRangeAxis(0).setAxisLinePaint(this.CHART_FOREGROUND_COLOR);
        this.plot.getRangeAxis(0).setLabelPaint(this.CHART_FOREGROUND_COLOR);
        this.plot.getRangeAxis(0).setTickLabelPaint(this.CHART_FOREGROUND_COLOR);
        this.plot.getRangeAxis(0).setTickMarkPaint(this.CHART_FOREGROUND_COLOR);
        this.plot.setBackgroundPaint(this.CHART_FOREGROUND_COLOR);
        this.plot.setDomainGridlinePaint(this.CHART_FOREGROUND_COLOR);
        this.plot.setRangeGridlinePaint(this.CHART_FOREGROUND_COLOR);
        this.plot.setDomainCrosshairPaint(this.CROSSHAIR_COLOR);
        this.plot.setRangeCrosshairPaint(this.CROSSHAIR_COLOR);

        XYBarRenderer renderer = (XYBarRenderer) this.plot.getRenderer();
        renderer.setBarPainter(createBarPainter());
        renderer.setSeriesPaint(0, Color.RED);
    }

    private IntervalXYDataset formatDataset() {
        final XYSeries series = new XYSeries("Filter Coefficients");

        for (int i = 0; i < this.dataset.getItemCount(0); i++) {
            series.add(this.dataset.getX(0, i), this.dataset.getY(0, i));
        }

        final XYSeriesCollection dataset = new XYSeriesCollection(series);
        return dataset;
    }

    private GradientXYBarPainter createBarPainter() {
        return new GradientXYBarPainter() {

            private static final long serialVersionUID = -1997018568242678921L;

            @Override
            public void paintBar(Graphics2D g2, XYBarRenderer renderer, int row, int column,
                RectangularShape bar, RectangleEdge base) {
                double wCoeff = 0.25;
                double hCoeff = 1.0;
                double newWidth, deltaW, deltaX;

                Rectangle2D rect = bar.getFrame();
                newWidth = rect.getWidth() * wCoeff;
                deltaW = rect.getWidth() - newWidth;
                deltaX = deltaW / 2;
                rect.setRect(rect.getX() + deltaX, rect.getY(), newWidth, rect.getHeight() * hCoeff);
                bar.setFrame(rect);
                super.paintBar(g2, renderer, row, column, bar, base);
            }
        };
    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
AwaX
  • 448
  • 3
  • 8
  • 19

1 Answers1

2

Assuming you mean the arrows, XYBarRenderer seems a likely starting point. You can replace its XYBarPainter with a custom implementation, for example.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Ok thank you, it works :) but do you think it's possible to draw a circle or maybe a triangle at the top of the arrow ? – AwaX Jan 11 '13 at 10:52
  • I'd look at extending `RectangularShape` or using [`XYShapeAnnotation`](http://stackoverflow.com/a/11751239/230513) – trashgod Jan 11 '13 at 11:04
  • 1
    I'm not sure which `XYBarPainter` you're using. There's an example using `StandardXYBarPainter` [here](http://stackoverflow.com/a/8002959/230513). Please edit your question to include an [sscce](http://sscce.org/) that exhibits the problem you describe. – trashgod Jan 11 '13 at 11:06
  • I edited the question, for the XYBarPainter see the method createBarPainter – AwaX Jan 11 '13 at 11:24
  • 1
    Absent a [_complete_](http://sscce.org/) [example](http://stackoverflow.com/a/14198851/230513), I can only guess that you want `StandardXYBarPainter`, not `GradientXYBarPainter`. – trashgod Jan 11 '13 at 11:50