/******************************************************************************* * Copyright 2015 xWic group (http://www.xwic.de) * * Licensed under the Apache License, Version 2.0 (the "License"). * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *******************************************************************************/ /** * */ package de.jwic.ecolib.minichart; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import javax.imageio.IIOImage; import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; import javax.imageio.stream.MemoryCacheImageOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.sun.imageio.plugins.png.PNGImageWriter; import de.jwic.base.Control; import de.jwic.base.IControlContainer; import de.jwic.base.IResourceControl; import de.jwic.controls.AbstractImageMap; /** * @author Florian Lippisch * */ public class MiniChart extends Control implements IResourceControl { private static final long serialVersionUID = 1L; private IChartDataProvider dataProvider = null; private int width = 48; private int height = 16; private int maxValues = 12; private MiniChartStyle chartStyle = new MiniChartStyle(); /** * @param container * @param name */ public MiniChart(IControlContainer container, String name) { super(container, name); } /* (non-Javadoc) * @see de.jwic.base.IResourceControl#attachResource(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ public void attachResource(HttpServletRequest req, HttpServletResponse res) throws IOException { String options = req.getParameter("options"); res.setHeader ("Content-Disposition","filename=" + getFilename()); res.setHeader ("Expires", "0"); res.setHeader ("Cache-Control", "no-cache"); res.setHeader ("Pragma", "no-cache"); res.setContentType(AbstractImageMap.MIME_TYPE_PNG); // render image ByteArrayOutputStream imageOutputStream = new ByteArrayOutputStream(); renderChart(options, imageOutputStream); imageOutputStream.writeTo(res.getOutputStream()); res.getOutputStream().close(); } /** * @param options * @param imageOutputStream */ private void renderChart(String options, ByteArrayOutputStream imageOutputStream) { BufferedImage bi = new BufferedImage(width, height, chartStyle.isTransparentBackground() ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB); Graphics2D g2d = bi.createGraphics(); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setBackground(chartStyle.getBackgroundColor()); if (!chartStyle.isTransparentBackground()) { g2d.clearRect(0, 0, width, height); } Color fgColor = chartStyle.getDefaultFgColor(); g2d.setColor(fgColor); g2d.setBackground(fgColor); g2d.setStroke(new BasicStroke(1)); if (dataProvider != null) { Number[] values = dataProvider.getChartValues(options, maxValues); if (values != null && values.length > 0) { // evaluate max and min values double min = values[0].doubleValue(); double max = values[0].doubleValue(); for (int i = 0; i < values.length; i++) { min = Math.min(min, values[i].doubleValue()); max = Math.max(max, values[i].doubleValue()); } if (chartStyle.isUseFixedBaseValue()) { if (min > 0) { min = 0; } } double diff = max - min; // draw values double factor = diff / ((double)height); int baseLine = height - ((int)((-min) / factor)); int barWidth = (width - values.length + 1) / values.length; if (chartStyle.isDrawBaseLine()) { g2d.setColor(chartStyle.getBaseLineColor()); g2d.drawLine(0, baseLine - 1, width, baseLine - 1); } int x = 0; for (int i = 0; i < values.length; i++) { int barHeight = (int)(values[i].doubleValue() / factor); if (barHeight >= 0) { int y = baseLine - barHeight; g2d.setColor(chartStyle.getDefaultFgColor()); g2d.fillRect(x, y, barWidth, barHeight); } else { int y = baseLine; g2d.setColor(chartStyle.getNegativeFgColor()); g2d.fillRect(x, y, barWidth, -barHeight); } x += barWidth + 1; } } else { g2d.drawLine(0, height, width, height); // just draw baseline } } ImageWriter imageWriter = new PNGImageWriter(null); ImageWriteParam param = imageWriter.getDefaultWriteParam(); imageWriter.setOutput(new MemoryCacheImageOutputStream(imageOutputStream)); try { imageWriter.write(null, new IIOImage(bi, null, null), param); } catch (IOException e) { log.error("Error rendering image!"); } imageWriter.dispose(); } /** * Returns the image URL. * @return */ public String getImageURL() { return getSessionContext().getCallBackURL() + "&_resreq=1&controlId=" + getControlID(); } /** * Returns the image URL. * @return */ public String getImageURL(String options) { if (options != null) { try { return getImageURL() + "&options=" + URLEncoder.encode(options, "UTF-8"); } catch (UnsupportedEncodingException e) { log.error("Error encoding options: " + e, e); return getImageURL(); } } else { return getImageURL(); } } /** * @return */ private String getFilename() { return "minichart.png"; } /** * @return the dataProvider */ public IChartDataProvider getDataProvider() { return dataProvider; } /** * @param dataProvider the dataProvider to set */ public void setDataProvider(IChartDataProvider dataProvider) { this.dataProvider = dataProvider; } /** * @return the height */ public int getHeight() { return height; } /** * @param height the height to set */ public void setHeight(int height) { this.height = height; } /** * @return the width */ public int getWidth() { return width; } /** * @param width the width to set */ public void setWidth(int width) { this.width = width; } /** * @return the maxValues */ public int getMaxValues() { return maxValues; } /** * @param maxValues the maxValues to set */ public void setMaxValues(int maxValues) { this.maxValues = maxValues; } /** * @return the chartStyle */ public MiniChartStyle getChartStyle() { return chartStyle; } /** * @param chartStyle the chartStyle to set */ public void setChartStyle(MiniChartStyle chartStyle) { this.chartStyle = chartStyle; } }