Skip to content

Commit

Permalink
Fix high DPI issue in ChartPanel - bug #170
Browse files Browse the repository at this point in the history
  • Loading branch information
jfree committed Oct 23, 2020
1 parent 7dc25a0 commit fa5a113
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 15 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ The library is licensed under the terms of the GNU Lesser General Public
License (LGPL) version 2.1 or later.


Using JFreeChart
----------------
To use JFreeChart in your projects, add the following dependency to your build tool:

<dependency>
<groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.5.1</version>
</dependency>


Building JFreeChart
-------------------
You can build JFreeChart using Maven. The build requires JDK 8 or later.
Expand All @@ -49,6 +60,7 @@ History
-------

##### Version 1.5.1 (not yet released)
- modify buffer in ChartPanel to handle high DPI displays (bug #170);
- added Catalan translations (PR #117);
- fix for LayeredBarRenderer (bug #169);
- migrated to JUnit 5.
Expand Down
41 changes: 26 additions & 15 deletions src/main/java/org/jfree/chart/ChartPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* JFreeChart : a free chart library for the Java(tm) platform
* ===========================================================
*
* (C) Copyright 2000-2017, by Object Refinery Limited and Contributors.
* (C) Copyright 2000-2020, by Object Refinery Limited and Contributors.
*
* Project Info: http://www.jfree.org/jfreechart/index.html
*
Expand Down Expand Up @@ -218,8 +218,8 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.EventListener;
import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;

Expand Down Expand Up @@ -747,7 +747,7 @@ public ChartPanel(JFreeChart chart, int width, int height,
this.panMask = InputEvent.ALT_MASK;
}

this.overlays = new java.util.ArrayList<Overlay>();
this.overlays = new ArrayList<Overlay>();
}

/**
Expand Down Expand Up @@ -1566,12 +1566,21 @@ else if (drawHeight > this.maximumDrawHeight) {
// are we using the chart buffer?
if (this.useBuffer) {

// for better rendering on the HiDPI monitors upscaling the buffer to the "native" resoution
// instead of using logical one provided by Swing
final AffineTransform globalTransform = ((Graphics2D) g).getTransform();
final double globalScaleX = globalTransform.getScaleX();
final double globalScaleY = globalTransform.getScaleY();

final int scaledWidth = (int) (available.getWidth() * globalScaleX);
final int scaledHeight = (int) (available.getHeight() * globalScaleY);

// do we need to resize the buffer?
if ((this.chartBuffer == null)
|| (this.chartBufferWidth != available.getWidth())
|| (this.chartBufferHeight != available.getHeight())) {
this.chartBufferWidth = (int) available.getWidth();
this.chartBufferHeight = (int) available.getHeight();
|| (this.chartBufferWidth != scaledWidth)
|| (this.chartBufferHeight != scaledHeight)) {
this.chartBufferWidth = scaledWidth;
this.chartBufferHeight = scaledHeight;
GraphicsConfiguration gc = g2.getDeviceConfiguration();
this.chartBuffer = gc.createCompatibleImage(
this.chartBufferWidth, this.chartBufferHeight,
Expand All @@ -1584,17 +1593,19 @@ else if (drawHeight > this.maximumDrawHeight) {

this.refreshBuffer = false; // clear the flag

// scale graphics of the buffer to the same value as global
// Swing graphics - this allow to paint all elements as usual
// but applies all necessary smoothing
Graphics2D bufferG2 = (Graphics2D) this.chartBuffer.getGraphics();
bufferG2.scale(globalScaleX, globalScaleY);

Rectangle2D bufferArea = new Rectangle2D.Double(
0, 0, this.chartBufferWidth, this.chartBufferHeight);
0, 0, available.getWidth(), available.getHeight());

// make the background of the buffer clear and transparent
Graphics2D bufferG2 = (Graphics2D)
this.chartBuffer.getGraphics();
Composite savedComposite = bufferG2.getComposite();
bufferG2.setComposite(AlphaComposite.getInstance(
AlphaComposite.CLEAR, 0.0f));
Rectangle r = new Rectangle(0, 0, this.chartBufferWidth,
this.chartBufferHeight);
bufferG2.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
Rectangle r = new Rectangle(0, 0, (int) available.getWidth(), (int) available.getHeight());
bufferG2.fill(r);
bufferG2.setComposite(savedComposite);

Expand All @@ -1614,7 +1625,7 @@ else if (drawHeight > this.maximumDrawHeight) {
}

// zap the buffer onto the panel...
g2.drawImage(this.chartBuffer, insets.left, insets.top, this);
g2.drawImage(this.chartBuffer, insets.left, insets.top, (int) available.getWidth(), (int) available.getHeight(), this);

} else { // redrawing the chart every time...
AffineTransform saved = g2.getTransform();
Expand Down

0 comments on commit fa5a113

Please sign in to comment.