We're using JFreeChart to build an engine to display graphs. This is a web service that runs on Tomcat + Java 1.5.0, and renders charts to PNGs and JPEGs (using ChartUtilities.writeChartAs{PNG,JPEG}() ).
We've run into a problem where JFreeChart seems to scale everything inside the Plot area, but only by a few pixels. The result is that the graph looks inconsistent, e.g.:
Minor ticks are sometimes stretched horizontally, so that they seem to be two pixels wide instead of one.
We use a small image in the top-right of the plot area as a watermark. This is stretched by one pixel horizontally and vertically somewhere near (but not exactly) its middle.
Background grid lines seem to appear on sub-pixel boundaries. I have not found a way to create an accurately dotted grid line.
We have tried both 1.0.9 and 1.0.13, with exactly the same results (except for the minor ticks, which were not available in the older version). Also, rendering the image to a Frame instead of JPEG/PNG produced an identical result.
Help is greatly appreciated, in advance :)
EDIT: An SSCCE:
#Test
public void testScaling1() throws InterruptedException {
// Load Image:
Component dummy = new Component() {};
MediaTracker tracker = new MediaTracker(dummy);
Image img = Toolkit.getDefaultToolkit().getImage("C:\\My\Image.gif");
tracker.addImage(img, 0);
tracker.waitForAll();
// Build Data set and base chart.
TimeSeriesCollection dataset = new TimeSeriesCollection();
TimeSeries ts = new TimeSeries("Sample");
ts.add(new Second(0, 0, 0, 1, 1, 1900), 1.0);
ts.add(new Second(1, 0, 0, 1, 1, 1900), 3.0);
ts.add(new Second(2, 0, 0, 1, 1, 1900), 4.0);
ts.add(new Second(3, 0, 0, 1, 1, 1900), 2.0);
dataset.addSeries(ts);
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"blabla",
null,
null,
dataset,
true,
true,
false
);
// Add BG image in top-right corner.
XYPlot xy = chart.getXYPlot();
xy.setBackgroundAlpha(0.0F);
xy.setBackgroundImage(img);
xy.setBackgroundImageAlignment(Align.NORTH_WEST);
xy.setBackgroundImageAlpha(1.0F);
paintChart(chart);
}
Use an image with small-font text, or a grid. This will show the scaling effect on the background image.
Edit 2:
We've resorted to subclassing or proxying Renderers and drawing the label in text in their drawItem() (or similar) methods. This works well.
However, minor ticks are now a problem - they also seem to be getting scaled. E.g.: See the 9th and 15th ticks.
look at the bottom http://img14.imageshack.us/img14/3625/76676732.jpg
I am unable to reproduce the effect you describe using either saveChartAsJPEG() or writeChartAsPNG() with version 1.0.13, Java 1.5, Mac OS X, in code like this:
try {
ChartUtilities.writeChartAsPNG(new FileOutputStream(
new File("test.png")), chart, 600, 400);
} catch (IOException ex) {
ex.printStackTrace();
}
Does the screen exhibit the same artifacts? What happens when you change the WIDTH and HEIGHT parameters or omit the watermark? Are you using special fonts with unusual metrics? Have you tried a different platform?
You can run TimeSeriesChartDemo1 as follows:
java -cp jfreechart-1.0.13.jar:jcommon-1.0.16.jar org.jfree.chart.demo.TimeSeriesChartDemo1
Mac OS 10.5.8, Java 1.5.0_24, JFreeChart 1.0.13, TimeSeriesDemo1, using saveChartAsPNG(), ImageIO.read() and setBackgroundImage(). setBackgroundImageAlignment(Align.NORTH_WEST) is a little funky, though.
Related
I have prototyped part of my application in Adobe XD
And now it is time to recreate that frosted glass effect in Java. However, the closest I could get is the following
As the more keen-eyed of you might see...it looks bad, and nothing like my design.
I achieved the look below by taking a screenshot of the relevant part of the screen and applying a gaussian blur to the Image. I have no idea how to achieve the above look so any help would be greatly appreciated.
Below you can see my code thus far
Robot robot = new Robot();
Toolkit myToolkit = Toolkit.getDefaultToolkit();
Dimension screenSize = myToolkit.getScreenSize();
Rectangle screen = new Rectangle(screenSize);
BufferedImage screenBlurImage = robot.createScreenCapture(screen);
//get relevant section
screenBlurImage = screenBlurImage.getSubimage(457,415,1006,107);
//set image
image.setImage(screenBlurImage);
//Apply blur
BoxBlur bb = new BoxBlur();
bb.setWidth(5);
bb.setHeight(5);
bb.setIterations(3);
image.setImage(SwingFXUtils.toFXImage(screenBlurImage, null ));
image.setEffect(bb);
I ended up exporting the Adobe XD Design as an HTML Webpage and rendering it using a JavaFX Webview with transparent background, turns out the way Adobe XD blurs backgrounds is by using the following CSS options:
box-shadow: inset 0 0 0 200px rgba(0, 0, 0, 0.5);
filter: blur(13px);
I am using aspose-slides-17.3-jdk16.jar for java. I have created the Area Chart using IChartDataWorkbook. I have used multiple series to plot area chart and following image is the chart output, where the data labels are overlapped.
Is there any way to organize or fit the data labels properly?
#Chandra Shekar,
I have observed your requirements and like to mention that you can try using different options label.getDataLabelFormat().setLabelPosition() and label.getDataLabelFormat().setShowLabelAsDataCallout(true) methods on your end to set the individual label positions for chart data points. You can please try using following sample code on your end and may alter this as per your requirements on your end.
public static void TestAreaChart()
{
Presentation pres = new Presentation();
IChart chart = pres.getSlides().get_Item(0).getShapes().addChart(ChartType.Area, 50, 50, 500, 400);
chart.getChartData().getSeries().get_Item(0).getLabels().getDefaultDataLabelFormat().setShowValue(true);
chart.getChartData().getSeries().get_Item(0).getLabels().getDefaultDataLabelFormat()
.setShowLabelAsDataCallout(true);
chart.getChartData().getSeries().get_Item(0).getLabels().get_Item(2).getDataLabelFormat()
.setShowLabelAsDataCallout(true);
chart.getChartData().getSeries().get_Item(0).getLabels().get_Item(2).getDataLabelFormat()
.setPosition(LegendDataLabelPosition.OutsideEnd);
pres.save("C:\\Aspose Data\\AreaChart.pptx", SaveFormat.Pptx);
}
I am working as Support developer/ Evangelist at Aspose.
I'm creating a chart in a servlet, and it works great.
chart = ChartFactory.createPieChart("Smart Chart", ds, true, true,
true);
PiePlot plot = (PiePlot) chart.getPlot();
ImageIcon icon = new ImageIcon(bgImageStr);
plot.setBackgroundPaint(Color.CYAN);
plot.setBackgroundAlpha(0.15f);
chart.setBackgroundPaint(Color.WHITE);
chart.getTitle().setBackgroundPaint(Color.PINK);
chart.setBackgroundImage(icon.getImage());
Problem is, the background image is not showing up. I've tried the plot and chart bg, and all kinds of other stuff. It must be simple, anyone see what is wrong? I'm just using the write to PNG to dump it to the browser. It shows up fine, with all the color changes, just no image.
OK, OP here, I fixed it.
I was calling the servlet from itself, and it did not like that. I used a resource (as suggested) and it worked fine without the infinite recursion (imagine that).
apply
try{
Thread.sleep(100);
}
catch(InterruptedException IntExp)
{
//your implementation
}
before chart.setBackgroundImage(icon.getImage());
I'm messing around with the examples of mt4j multitouch Java library and in the "advanced.drawing" example, i'm trying to change the background color of the drawingScene. Since it has set the setClear to false i'm not able to do it with the clearColor option. Any other ideas? Thanks
I've found with the help of TherioN from NUIGroup forums a way to do it. It is possible to add a MTRectangle with the fill color and then add the SceneTexture of the drawing example to that rectangle. I leav the piece of code as reference:
final MTSceneTexture sceneTexture = new MTSceneTexture(mtApplication,0, 0, mtApplication.width, mtApplication.height, drawingScene);
sceneTexture.getFbo().clear(true, 255, 255, 255, 0, true);
sceneTexture.setStrokeColor(new MTColor(155,155,155));
//Background
MTRectangle background = new MTRectangle(0,0,mtApplication.width, mtApplication.height , mtApplication);
background.setFillColor(new MTColor(255,244,150,255));
//Add the scene texture as a child of the background rectangle so the scene texture is drawn in front
background.addChild(sceneTexture);
frame.addChild(background);
I'm working on a simple 2D game engine in Java, and having no trouble with FSEM, buffer strategies, and so on; my issue is with the mouse cursor. In windowed mode, I can hide the mouse cursor, no problem, by using setCursor() from my JFrame to set a wholly-transparent cursor. However, after a call to device.setFullScreenWindow(this) to go into FSEM, the mouse cursor comes back, and subsequent calls to setCursor() to set it back to my blank cursor have no effect. Calling device.setFullScreenWindow(null) allows me to get rid of the cursor again - it's only while I'm in FSEM that I can't get rid of it.
I'm working under JDK 6, target platform is JDK 5+.
UPDATE: I've done some more testing, and it looks like this issue occurs under MacOS X 10.5 w/Java 6u7, but not under Windows XP SP3 with Java 6u7. So, it could possibly be a bug in the Mac version of the JVM.
Try Creating a custom invisible cursor:
Toolkit toolkit = Toolkit.getDefaultToolkit();
Point hotSpot = new Point(0,0);
BufferedImage cursorImage = new BufferedImage(1, 1, BufferedImage.TRANSLUCENT);
Cursor invisibleCursor = toolkit.createCustomCursor(cursorImage, hotSpot, "InvisibleCursor");
setCursor(invisibleCursor);
One developer found a way around it by creating a one pixel cursor out of a transparent GIF.
http://sevensoft.livejournal.com/23460.html
I know you tried that, but his is specifically addressing the issue of full-screen mode, exactly as you say, so perhaps there's something he's done that you haven't.
I think I've finally found the solution:
System.setProperty("apple.awt.fullscreenhidecursor","true");
This is an Apple-proprietary system property that hides the mouse cursor when an application is in full-screen mode. It's the only way I've found to fix it.
Here's what has been working for me:
Toolkit toolkit = Toolkit.getDefaultToolkit();
// get the smallest valid cursor size
Dimension dim = toolkit.getBestCursorSize(1, 1);
// create a new image of that size with an alpha channel
BufferedImage cursorImg = new BufferedImage(dim.width, dim.height, BufferedImage.TYPE_INT_ARGB);
// get a Graphics2D object to draw to the image
Graphics2D g2d = cursorImg.createGraphics();
// set the background 'color' with 0 alpha and clear the image
g2d.setBackground(new Color(0.0f, 0.0f, 0.0f, 0.0f));
g2d.clearRect(0, 0, dim.width, dim.height);
// dispose the Graphics2D object
g2d.dispose();
// now create your cursor using that transparent image
hiddenCursor = toolkit.createCustomCursor(cursorImg, new Point(0,0), "hiddenCursor");
Granted, I haven't tested it on Mac (yet), only Windows. But when I used the common methods I was getting the cursor as black box, so I use the code above the create a transparent box and set it as the cursor instead. Of course you have to use the setCursor method on an AWT object (such as your app's Frame) to set this hiddenCursor. Here is my hideMouse method ('fr' is my Frame):
public void hideMouse(boolean hide) {
if(hide) {
fr.setCursor(hiddenCursor);
} else {
fr.setCursor(Cursor.getDefaultCursor());
}
}
I don't know if this knowledge applies but in a old VB6 app I had the same problem and I got rid of it moving the cursor out of the screen giving it some very large values.
Hope it helps.
If you're running only on Windows, it looks like you'll need to call ShowCursor(FALSE) through JNI. At least, to make the cursor hide complete.
Here's some code which creates the 1x1 cursor. It works for me, though I still get a 1x1 cursor.
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension dim = toolkit.getBestCursorSize(1,1);
transCursor = toolkit.createCustomCursor(gc.createCompatibleImage(dim.width, dim.height),
new Point(0, 0), "transCursor");
((Component)mainFrame).setCursor(transCursor);
Specifically for your Mac problem, through JNI you could use the following:
Quartz Display Services Reference - CGDisplayHideCursor