/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 ro.nextreports.server.web.dashboard.indicator; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.GradientPaint; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.geom.Arc2D; import java.awt.geom.Area; import org.apache.wicket.markup.html.image.resource.RenderedDynamicImageResource; import ro.nextreports.engine.exporter.util.IndicatorData; import ro.nextreports.engine.util.StringUtil; public class IndicatorDynamicImageResource extends RenderedDynamicImageResource { private static final long serialVersionUID = 1L; private int width; private int height; private IndicatorData data; public IndicatorDynamicImageResource(int width, int height, IndicatorData data) { super(width, height); this.width = width; this.height = height; this.data = data; } @Override protected boolean render(Graphics2D graphics, Attributes attributes) { graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); int canWidth = getWidth(); int canHeight = getHeight(); int size = canHeight; if (10*canWidth/11 <= canHeight) { size = 10*canWidth/11; } int radix = 7*size/11; int arcWidth = size/2; int x = canWidth/2; int y = 8*size/11; graphics.setPaint(data.getBackground()); Rectangle rectangle = new Rectangle(0, 0, getWidth(), getHeight()); graphics.fill(rectangle); // draw initial background color Arc2D externalArc = new Arc2D.Double(x-size/2, y-size/2, size, size, 0, 180, Arc2D.OPEN); Arc2D innerArc = new Arc2D.Double(x-size/2 + arcWidth/2, y-size/2 + arcWidth/2, size - arcWidth, size - arcWidth, 0, 180, Arc2D.OPEN); Area i1 = new Area(externalArc); Area i2 = new Area(innerArc); i1.subtract(i2); graphics.setPaint(new Color(240, 240, 240)); graphics.fill(i1); // draw background color depending on gauge's value double val = data.getValue(); if (data.getValue() < data.getMin()) { val = data.getMin(); } if (data.getValue() > data.getMax()) { val = data.getMax(); } double range = Math.abs(data.getMax()-data.getMin()); double delta = Math.abs(data.getMin() - val); double f = (range - delta) /range; double angle = 180 * f ; Arc2D externalArcColor = new Arc2D.Double(x-size/2, y-size/2, size, size, angle, 180 - angle, Arc2D.PIE); Arc2D innerArcColor = new Arc2D.Double(x-size/2 + arcWidth/2, y-size/2 + arcWidth/2, size - arcWidth, size - arcWidth, 0, 180, Arc2D.PIE); Area a1 = new Area(externalArcColor); Area a2 = new Area(innerArcColor); a1.subtract(a2); graphics.setPaint(new GradientPaint(x-size/2, y-size/2, Color.WHITE, x+size/2, y-size/2, data.getColor())); graphics.fill(a1); // clear any glitches under inner arc Arc2D ia = new Arc2D.Double(x-size/2 + arcWidth/2, y-size/2 + arcWidth/2, size - arcWidth, size - arcWidth, 0, 360, Arc2D.PIE); Area ia2 = new Area(ia); graphics.setPaint(data.getBackground()); graphics.fill(ia2); // draw arcs & base lines graphics.setPaint(Color.GRAY); graphics.setStroke(new BasicStroke(1f)); graphics.draw(externalArc); graphics.draw(innerArc); graphics.drawLine(x-size/2, y, x-size/2 + arcWidth/2, y); graphics.drawLine(x+size/2 - arcWidth/2, y, x+size/2, y); if (data.isShowMinMax()) { Font font = new Font(graphics.getFont().getFontName(), graphics.getFont().getStyle(), size / 11); graphics.setFont(font); String smin; if (hasNoDecimals(data.getMin())) { smin = String.valueOf((int) data.getMin()); } else { smin = String.valueOf(data.getMin()); } if ((data.getUnit() != null) && !data.getUnit().isEmpty()) { smin = smin + data.getUnit(); } int swidth = graphics.getFontMetrics().stringWidth(smin); graphics.drawString(smin, x-size/2 + arcWidth / 4 - swidth / 2, y + size/11); String smax; if (hasNoDecimals(data.getMax())) { smax = String.valueOf((int) data.getMax()); } else { smax = String.valueOf(data.getMax()); } if ((data.getUnit() != null) && !data.getUnit().isEmpty()) { smax = smax + data.getUnit(); } swidth = graphics.getFontMetrics().stringWidth(smax); graphics.drawString(smax, x + size/2 - arcWidth/4 - swidth / 2 , y + size/11); } if ((data.getDescription() != null) && !data.getDescription().isEmpty()) { Font font = new Font(graphics.getFont().getFontName(), graphics.getFont().getStyle(), size/12); graphics.setFont(font); int swidth = graphics.getFontMetrics().stringWidth(data.getDescription()); graphics.setPaint(Color.GRAY); graphics.drawString(data.getDescription(), x - swidth/2 , y + size/12); } Font font = new Font(graphics.getFont().getFontName(), Font.BOLD, size/8); graphics.setFont(font); graphics.setPaint(Color.BLACK); String svalue; if (hasNoDecimals(data.getValue())) { svalue = String.valueOf((int)data.getValue()); } else { svalue = String.valueOf(data.getValue()); if (data.getPattern() != null) { svalue = StringUtil.getValueAsString(data.getValue(), data.getPattern()); } } if ((data.getUnit() != null) && !data.getUnit().isEmpty()) { svalue = svalue + data.getUnit(); } int swidth = graphics.getFontMetrics().stringWidth(svalue); graphics.drawString(svalue, x - swidth/2 , y ); if ((data.getTitle() != null) && !data.getTitle().isEmpty()) { font = new Font(graphics.getFont().getFontName(), Font.BOLD, size/11); graphics.setFont(font); swidth = graphics.getFontMetrics().stringWidth(data.getTitle()); graphics.drawString(data.getTitle(), x - swidth/2 , y - radix + arcWidth/2 + size/11 ); } return true; } private boolean hasNoDecimals(double d) { return ((int)d == d); } }