org.eclipse.birt.chart.device.svg_3.7.2.v20120213

    }
      else
      {
        gp = (SVGGradientPaint)paints.get(index);
      }
      this.paint = gp;
    }
    else if ((paint instanceof TexturePaint))
    {
      TexturePaint tp = (TexturePaint)paint;
      if (!textures.contains(tp))
      {
        textures.add(tp);
        Element elemImg = createEmbeddeImage(tp.getImage());
        if (elemImg != null)
        {
          definitions.appendChild(elemImg);
          String imgId = elemImg.getAttribute("id");
          definitions.appendChild(createTexturePaint(tp, 
            imgId, 
            false));
          definitions.appendChild(createTexturePaint(tp, 
            imgId, 
            true));
        }
      }
      this.paint = tp;
    }
    else
    {
      this.paint = paint;
    }
  }
  
  protected Element createGradientPaint(SVGGradientPaint paint, boolean highlight)
  {
    Element elem = dom.createElement("linearGradient");
    if (highlight) {
      elem.setAttribute("id", paint.getId() + "h");
    } else {
      elem.setAttribute("id", paint.getId());
    }
    elem.setAttribute("x1", toString(paint.getPoint1().getX()));
    elem.setAttribute("y1", toString(paint.getPoint1().getY()));
    elem.setAttribute("x2", toString(paint.getPoint2().getX()));
    elem.setAttribute("y2", toString(paint.getPoint2().getY()));
    elem.setAttribute("gradientUnits", "userSpaceOnUse");
    if (paint.isCyclic()) {
      elem.setAttribute("spreadMethod", "repeat");
    }
    Element startColor = dom.createElement("stop");
    startColor.setAttribute("offset", "0%");
    if (highlight) {
      startColor.setAttribute("stop-color", serializeHighlightToString(paint.getColor1()));
    } else {
      startColor.setAttribute("stop-color", serializeToString(paint.getColor1()));
    }
    String alpha = alphaToString(paint.getColor1());
    if (alpha != null) {
      startColor.setAttribute("stop-opacity", alpha);
    }
    elem.appendChild(startColor);
    Element endColor = dom.createElement("stop");
    endColor.setAttribute("offset", "100%");
    if (highlight) {
      endColor.setAttribute("stop-color", serializeHighlightToString(paint.getColor2()));
    } else {
      endColor.setAttribute("stop-color", serializeToString(paint.getColor2()));
    }
    alpha = alphaToString(paint.getColor2());
    if (alpha != null) {
      endColor.setAttribute("stop-opacity", alpha);
    }
    elem.appendChild(endColor);
    return elem;
  }
  
  private String getTextureId(TexturePaint paint)
  {
    return "tp" + paint.hashCode();
  }
  
  protected Element createTexturePaint(TexturePaint paint, String imgId, boolean highlight)
  {
    Element elem = dom.createElement("pattern");
    if (highlight) {
      elem.setAttribute("id", getTextureId(paint) + "h");
    } else {
      elem.setAttribute("id", getTextureId(paint));
    }
    BufferedImage img = paint.getImage();
    int width = img.getWidth();
    int height = img.getHeight();
    elem.setAttribute("patternUnits", "userSpaceOnUse");
    elem.setAttribute("width", Integer.toString(width));
    elem.setAttribute("height", Integer.toString(height));
    
    Element elemUse = dom.createElement("use");
    elemUse.setAttribute("x", "0");
    elemUse.setAttribute("y", "0");
    elemUse.setAttribute("xlink:href", "#" + imgId);
    
    elem.appendChild(elemUse);
    return elem;
  }
  
  private String serializeHighlightToString(Color cd)
  {
    if (cd != null)
    {
      int red = (cd.getRed() + 255) / 2;
      int green = (cd.getGreen() + 255) / 2;
      int blue = (cd.getBlue() + 255) / 2;
      
      String r = Integer.toHexString(red);
      if (red <= 15) {
        r = "0" + r;
      }
      String g = Integer.toHexString(green);
      if (green <= 15) {
        g = "0" + g;
      }
      String b = Integer.toHexString(blue);
      if (blue <= 15) {
        b = "0" + b;
      }
      return "#" + r + g + b;
    }
    return "";
  }
  
  protected Element createLine(double arg0, double arg1, double arg2, double arg3)
  {
    Element elem = createElement("line");
    elem.setAttribute("x1", toString(arg0));
    elem.setAttribute("y1", toString(arg1));
    elem.setAttribute("x2", toString(arg2));
    elem.setAttribute("y2", toString(arg3));
    return elem;
  }
  
  protected Element createShape(Shape shape)
  {
    PathIterator pathIter = shape.getPathIterator(null);
    StringBuffer pathStr = new StringBuffer();
    while (!pathIter.isDone())
    {
      double[] points = new double[6];
      int TYPE = pathIter.currentSegment(points);
      switch (TYPE)
      {
      case 4: 
        pathStr.append(" Z");
        break;
      case 1: 
        pathStr.append(" L").append(toString(points, 2, ' '));
        break;
      case 2: 
        pathStr.append(" Q").append(toString(points, 4, ' '));
        break;
      case 3: 
        pathStr.append(" C").append(toString(points, 6, ' '));
        break;
      case 0: 
        pathStr.append(" M").append(toString(points, 2, ' '));
      }
      pathIter.next();
    }
    Element elem = dom.createElement("path");
    elem.setAttribute("d", pathStr.toString());
    return elem;
  }
  
  protected Element createGeneralPath(Shape path)
  {
    Element elem = createShape(path);
    if (transforms.getType() != 0)
    {
      double[] matrix = new double[6];
      transforms.getMatrix(matrix);
      elem.setAttribute("transform", "matrix(" + toString(matrix, ',') + ")");
    }
    return elem;
  }
  
  protected Element createText(String text)
  {
    boolean bRtl = false;
    if (text.length() > 0)
    {
      int iEnd = text.length();
      if ('?' == text.charAt(text.length() - 1)) {
        iEnd--;
      }
      if ('?' == text.charAt(0))
      {
        bRtl = true;
        text = text.substring(1, iEnd);
      }
    }
    Element elem = dom.createElement("text");
    elem.appendChild(dom.createTextNode(text));
    switch (getFont().getStyle())
    {
    case 1: 
      elem.setAttribute("font-weight", "bold");
      break;
    case 2: 
      elem.setAttribute("font-style", "italic");
      break;
    case 3: 
      elem.setAttribute("font-style", "italic");
      elem.setAttribute("font-weight", "bold");
    }
    String textDecorator = null;
    Map<TextAttribute, ?> attributes = getFont().getAttributes();
    if (attributes.get(TextAttribute.UNDERLINE) == TextAttribute.UNDERLINE_ON) {
      textDecorator = "underline";
    }
    if (attributes.get(TextAttribute.STRIKETHROUGH) == TextAttribute.STRIKETHROUGH_ON) {
      if (textDecorator == null) {
        textDecorator = "line-through";
      } else {
        textDecorator = textDecorator + ",line-through";
      }
    }
    if (textDecorator != null) {
      elem.setAttribute("text-decoration", textDecorator);
    }
    elem.setAttribute("xml:space", "preserve");
    elem.setAttribute("stroke", "none");
    
    elem.setAttribute("font-family", getFont().getName());
    elem.setAttribute("font-size", Integer.toString(getFont().getSize()));
    String style = getRenderingStyle(RenderingHints.KEY_TEXT_ANTIALIASING);
    if (color != null)
    {
      String alpha = alphaToString(color);
      if (alpha != null) {
        style = style + "fill-opacity:" + alpha + ";";
      }
      style = style + "fill:" + serializeToString(color) + ";";
    }
    if (bRtl) {
      style = style + "direction:rtl; unicode-bidi:embed; ";
    }
    elem.setAttribute("style", style);
    if (transforms.getType() != 0)
    {
      double[] matrix = new double[6];
      transforms.getMatrix(matrix);
      elem.setAttribute("transform", "matrix(" + toString(matrix, ',') + ")");
    }
    return elem;
  }
  
  protected String getRenderingStyle(Object key)
  {
    Object value = renderingHints.get(key);
    if (key.equals(RenderingHints.KEY_TEXT_ANTIALIASING))
    {
      if (value.equals(RenderingHints.VALUE_TEXT_ANTIALIAS_OFF))
      {
        if (transforms.getType() != 0) {
          return "text-rendering:optimizeSpeed;";
        }
        return "text-rendering:optimizeLegibility;";
      }
      return "";
    }
    return "";
  }
  
  protected Element createRect(double arg0, double arg1, double arg2, double arg3)
  {
    Element elem = createElement("rect");
    elem.setAttribute("x", toString(arg0));
    elem.setAttribute("y", toString(arg1));
    elem.setAttribute("width", toString(arg2));
    elem.setAttribute("height", toString(arg3));
    return elem;
  }
  
  protected Element createRoundRect(double arg0, double arg1, double arg2, double arg3, double arg4, double arg5)
  {
    Element elem = createElement("rect");
    elem.setAttribute("x", toString(arg0));
    elem.setAttribute("y", toString(arg1));
    elem.setAttribute("width", toString(arg2));
    elem.setAttribute("height", toString(arg3));
    elem.setAttribute("rx", toString(arg2));
    elem.setAttribute("ry", toString(arg3));
    return elem;
  }
  
  protected Element createOval(double arg0, double arg1, double arg2, double arg3)
  {
    Element elem = createElement("ellipse");
    elem.setAttribute("cx", toString(arg0));
    elem.setAttribute("cy", toString(arg1));
    elem.setAttribute("rx", toString(arg2));
    elem.setAttribute("ry", toString(arg3));
    return elem;
  }
  
  protected Element createArc(double x, double y, double width, double height, double startAngle, double arcAngle)
  {
    Element elem = createElement("path");
    double startX = x * Math.cos(startAngle);
    double startY = y * Math.sin(startAngle);
    double endX = x * Math.cos(startAngle + arcAngle);
    double endY = y * Math.sin(startAngle + arcAngle);
    int sweepFlag = arcAngle < 0.0D ? 0 : 1;
    elem.setAttribute("d", "M" + toString(startX) + "," + toString(startY) + " a" + toString(width / 2.0D) + "," + toString(height / 2.0D) + " " + toString(Math.abs(arcAngle)) + " 0 " + sweepFlag + " " + toString(endX) + " " + toString(endY));
    return elem;
  }
  
  public Element createPolyline(int[] arg0, int[] arg1, int arg2)
  {
    Element elem = createElement("polyline");
    StringBuffer pointsStr = new StringBuffer();
    for (int x = 0; x < arg2; x++) {
      pointsStr.append(arg0[x]).append(",").append(arg1[x]).append(" ");
    }
    elem.setAttribute("points", pointsStr.toString());
    return elem;
  }
  
  public Element createPolygon(int[] arg0, int[] arg1, int arg2)
  {
    Element elem = createElement("polygon");
    StringBuffer pointsStr = new StringBuffer();
    for (int x = 0; x < arg2; x++) {
      pointsStr.append(arg0[x]).append(",").append(arg1[x]).append(" ");
    }
    elem.setAttribute("points", pointsStr.toString());
    return elem;
  }
  
  protected void initializeScriptStyles()
  {
    codeScript = dom.createElement("script");
    if (scriptable) {
      appendChild(codeScript);
    }
    styles = dom.createElement("style");
    styles.setAttribute("type", "text/css");
    appendChild(styles);
  }
  
  protected Element createElement(String id)
  {
    Element elem = dom.createElement(id);
    if (primitiveId != null) {
      elem.setAttribute("id", primitiveId);
    }
    if (transforms.getType() != 0)
    {
      double[] matrix = new double[6];
      transforms.getMatrix(matrix);
      elem.setAttribute("transform", "matrix(" + toString(matrix, ',') + ")");
    }
    return elem;
  }
  
  public void drawTooltip(String tooltip)
  {
    Element title = dom.createElement("title");
    title.appendChild(dom.createTextNode(tooltip));
    appendChild(title);
    currentParent.setAttribute("onmouseout", "TM.remove()");
    currentParent.setAttribute("onmouseover", "TM.show(evt)");
  }
  
  public Element getCurrentParent()
  {
    return currentParent;
  }
  
  public Element getCurrentElement()
  {
    return currentElement;
  }
  
  public String getStyleClass()
  {
    return styleClass;
  }
  
  public void setStyleClass(String styleClass)
  {
    this.styleClass = styleClass;
  }
  
  public void addCSSStyle(String className, String styleName, String styleValue)
  {
    styleBuffer.append(className).append("{").append(styleName).append(":").append(styleValue).append(";}");
  }
  
  public void addScript(String script)
  {
    scriptBuffer.append(script);
  }
  
  public void addScriptRef(String ref)
  {
    Element rootElem = dom.getDocumentElement();
    Element scriptElem = dom.createElement("script");
    if (scriptable) {
      rootElem.appendChild(scriptElem);
    }
    scriptElem.setAttribute("language", "JavaScript");
    scriptElem.setAttribute("xlink:href", ref);
  }
  
  public String getId()
  {
    return id;
  }
  
  public void setId(String id)
  {
    this.id = id;
  }
  
  public Element getDeferStrokColor()
  {
    return deferStrokColor;
  }
  
  public void setDeferStrokColor(Element deferStrokColor)
  {
    this.deferStrokColor = deferStrokColor;
  }
  
  public String getPrimitiveId()
  {
    return primitiveId;
  }
  
  public void setPrimitiveId(String primitiveId)
  {
    this.primitiveId = primitiveId;
  }
  
  public boolean isScriptable()
  {
    return scriptable;
  }
  
  public void setScriptable(boolean scriptable)
  {
    this.scriptable = scriptable;
  }
  
  static String toString(double v)
  {
    if (Double.isNaN(v)) {
      return "0";
    }
    return String.valueOf(v);
  }
  
  static String toString(float v)
  {
    if (Float.isNaN(v)) {
      return "0";
    }
    return String.valueOf(v);
  }
  
  static String toString(double[] v, char separator)
  {
    return toString(v, v.length, separator);
  }
  
  static String toString(double[] v, int length, char separator)
  {
    if (v.length == 0) {
      return "";
    }
    if (v.length == 1) {
      return toString(v[0]);
    }
    if (length > v.length) {
      length = v.length;
    }
    StringBuffer buffer = new StringBuffer(toString(v[0]));
    for (int i = 1; i < length; i++)
    {
      buffer.append(separator);
      buffer.append(toString(v[i]));
    }
    return buffer.toString();
  }
}

/* Location:
 * Qualified Name:     org.eclipse.birt.chart.device.svg.SVGGraphics2D
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package org.eclipse.birt.chart.device.svg;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import java.net.URL;
import org.apache.commons.codec.binary.Base64;

public class SVGImage
  extends Image
{
  protected Image image;
  protected URL url;
  protected byte[] data;
  public static final String BASE64 = "data:;base64,";
  
  public byte[] getData()
  {
    return data;
  }
  
  public SVGImage(Image image, URL url)
  {
    this(image, url, null);
  }
  
  /* Error */
  public SVGImage(Image image, URL url, byte[] data)
  {
    // Byte code:
    //   0: aload_0
    //   1: invokespecial 141	java/awt/Image:<init>	()V
    //   4: aload_0
    //   5: aload_1
    //   6: putfield 139	org/eclipse/birt/chart/device/svg/SVGImage:image	Ljava/awt/Image;
    //   9: aload_0
    //   10: aload_2
    //   11: putfield 140	org/eclipse/birt/chart/device/svg/SVGImage:url	Ljava/net/URL;
    //   14: aload_0
    //   15: aload_3
    //   16: putfield 138	org/eclipse/birt/chart/device/svg/SVGImage:data	[B
    //   19: aload_2
    //   20: ifnonnull +130 -> 150
    //   23: aload_3
    //   24: ifnonnull +126 -> 150
    //   27: aload_1
    //   28: instanceof 68
    //   31: ifeq +119 -> 150
    //   34: invokestatic 163	org/eclipse/birt/chart/device/ImageWriterFactory:instance	()Lorg/eclipse/birt/chart/device/IImageWriterFactory;
    //   37: ldc 4
    //   39: ldc 3
    //   41: invokeinterface 167 3 0
    //   46: astore 4
    //   48: new 69	java/io/ByteArrayOutputStream
    //   51: dup
    //   52: sipush 2048
    //   55: invokespecial 151	java/io/ByteArrayOutputStream:<init>	(I)V
    //   58: astore 5
    //   60: aload 5
    //   62: invokestatic 165	org/eclipse/birt/chart/util/SecurityUtil:newImageOutputStream	(Ljava/lang/Object;)Ljavax/imageio/stream/ImageOutputStream;
    //   65: astore 6
    //   67: aload 4
    //   69: invokevirtual 160	javax/imageio/ImageWriter:getDefaultWriteParam	()Ljavax/imageio/ImageWriteParam;
    //   72: astore 7
    //   74: aload 4
    //   76: aload 6
    //   78: invokevirtual 159	javax/imageio/ImageWriter:setOutput	(Ljava/lang/Object;)V
    //   81: aload 4
    //   83: aconst_null
    //   84: new 74	javax/imageio/IIOImage
    //   87: dup
    //   88: aload_1
    //   89: checkcast 68	java/awt/image/BufferedImage
    //   92: aconst_null
    //   93: aconst_null
    //   94: invokespecial 157	javax/imageio/IIOImage:<init>	(Ljava/awt/image/RenderedImage;Ljava/util/List;Ljavax/imageio/metadata/IIOMetadata;)V
    //   97: aload 7
    //   99: invokevirtual 161	javax/imageio/ImageWriter:write	(Ljavax/imageio/metadata/IIOMetadata;Ljavax/imageio/IIOImage;Ljavax/imageio/ImageWriteParam;)V
    //   102: aload 6
    //   104: invokeinterface 166 1 0
    //   109: aload_0
    //   110: aload 5
    //   112: invokevirtual 150	java/io/ByteArrayOutputStream:toByteArray	()[B
    //   115: putfield 138	org/eclipse/birt/chart/device/svg/SVGImage:data	[B
    //   118: aload 5
    //   120: invokevirtual 149	java/io/ByteArrayOutputStream:close	()V
    //   123: goto +22 -> 145
    //   126: pop
    //   127: aload 4
    //   129: invokevirtual 158	javax/imageio/ImageWriter:dispose	()V
    //   132: goto +18 -> 150
    //   135: astore 8
    //   137: aload 4
    //   139: invokevirtual 158	javax/imageio/ImageWriter:dispose	()V
    //   142: aload 8
    //   144: athrow
    //   145: aload 4
    //   147: invokevirtual 158	javax/imageio/ImageWriter:dispose	()V
    //   150: return
    // Line number table:
    //   Java source line #59	-> byte code offset #0
    //   Java source line #60	-> byte code offset #4
    //   Java source line #61	-> byte code offset #9
    //   Java source line #62	-> byte code offset #14
    //   Java source line #63	-> byte code offset #19
    //   Java source line #65	-> byte code offset #34
    //   Java source line #66	-> byte code offset #37
    //   Java source line #65	-> byte code offset #46
    //   Java source line #70	-> byte code offset #48
    //   Java source line #71	-> byte code offset #60
    //   Java source line #72	-> byte code offset #67
    //   Java source line #73	-> byte code offset #74
    //   Java source line #74	-> byte code offset #81
    //   Java source line #75	-> byte code offset #84
    //   Java source line #76	-> byte code offset #97
    //   Java source line #74	-> byte code offset #99
    //   Java source line #77	-> byte code offset #102
    //   Java source line #78	-> byte code offset #109
    //   Java source line #79	-> byte code offset #118
    //   Java source line #81	-> byte code offset #126
    //   Java source line #87	-> byte code offset #127
    //   Java source line #86	-> byte code offset #135
    //   Java source line #87	-> byte code offset #137
    //   Java source line #88	-> byte code offset #142
    //   Java source line #87	-> byte code offset #145
    //   Java source line #91	-> byte code offset #150
    // Local variable table:
    //   start	length	slot	name	signature
    //   0	151	0	this	SVGImage
    //   0	151	1	image	Image
    //   0	151	2	url	URL
    //   0	151	3	data	byte[]
    //   46	100	4	iw	javax.imageio.ImageWriter
    //   58	61	5	baos	java.io.ByteArrayOutputStream
    //   65	38	6	ios	javax.imageio.stream.ImageOutputStream
    //   72	26	7	iwp	javax.imageio.ImageWriteParam
    //   135	8	8	localObject	Object
    //   126	1	9	localIOException	java.io.IOException
    // Exception table:
    //   from	to	target	type
    //   48	123	126	java/io/IOException
    //   48	127	135	finally
  }
  
  public void flush()
  {
    image.flush();
  }
  
  public Graphics getGraphics()
  {
    return image.getGraphics();
  }
  
  public int getHeight(ImageObserver arg0)
  {
    return image.getHeight(arg0);
  }
  
  public Object getProperty(String arg0, ImageObserver arg1)
  {
    return image.getProperty(arg0, arg1);
  }
  
  public Image getScaledInstance(int arg0, int arg1, int arg2)
  {
    return image.getScaledInstance(arg0, arg1, arg2);
  }
  
  public ImageProducer getSource()
  {
    return image.getSource();
  }
  
  public int getWidth(ImageObserver arg0)
  {
    return image.getWidth(arg0);
  }
  
  public String getUrl()
  {
    if (url == null)
    {
      if (data != null) {
        return "data:;base64," + new String(Base64.encodeBase64(data));
      }
      return "";
    }
    return url.toExternalForm();
  }
  
  public void setUrl(URL url)
  {
    this.url = url;
  }
}

/* Location:
 * Qualified Name:     org.eclipse.birt.chart.device.svg.SVGImage
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package org.eclipse.birt.chart.device.svg;

import com.ibm.icu.util.ULocale;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;
import org.eclipse.birt.chart.computation.DataPointHints;
import org.eclipse.birt.chart.computation.LegendItemHints;
import org.eclipse.birt.chart.device.IDeviceRenderer;
import org.eclipse.birt.chart.device.IUpdateNotifier;
import org.eclipse.birt.chart.device.image.MultiActionValuesScriptGenerator;
import org.eclipse.birt.chart.device.util.CSSHelper;
import org.eclipse.birt.chart.device.util.ScriptUtil;
import org.eclipse.birt.chart.event.InteractionEvent;
import org.eclipse.birt.chart.event.PrimitiveRenderEvent;
import org.eclipse.birt.chart.event.StructureSource;
import org.eclipse.birt.chart.event.StructureType;
import org.eclipse.birt.chart.event.WrappedStructureSource;
import org.eclipse.birt.chart.exception.ChartException;
import org.eclipse.birt.chart.log.ILogger;
import org.eclipse.birt.chart.log.Logger;
import org.eclipse.birt.chart.model.Chart;
import org.eclipse.birt.chart.model.ChartWithAxes;
import org.eclipse.birt.chart.model.ChartWithoutAxes;
import org.eclipse.birt.chart.model.attribute.AccessibilityValue;
import org.eclipse.birt.chart.model.attribute.ActionType;
import org.eclipse.birt.chart.model.attribute.ActionValue;
import org.eclipse.birt.chart.model.attribute.Cursor;
import org.eclipse.birt.chart.model.attribute.CursorType;
import org.eclipse.birt.chart.model.attribute.LegendItemType;
import org.eclipse.birt.chart.model.attribute.MenuStylesKeyType;
import org.eclipse.birt.chart.model.attribute.MultiURLValues;
import org.eclipse.birt.chart.model.attribute.ScriptValue;
import org.eclipse.birt.chart.model.attribute.TooltipValue;
import org.eclipse.birt.chart.model.attribute.TriggerCondition;
import org.eclipse.birt.chart.model.attribute.URLValue;
import org.eclipse.birt.chart.model.component.Axis;
import org.eclipse.birt.chart.model.component.Series;
import org.eclipse.birt.chart.model.data.Action;
import org.eclipse.birt.chart.model.data.MultipleActions;
import org.eclipse.birt.chart.model.data.SeriesDefinition;
import org.eclipse.birt.chart.model.data.Trigger;
import org.eclipse.birt.chart.model.layout.Legend;
import org.eclipse.birt.chart.util.SecurityUtil;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.EMap;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

public class SVGInteractiveRenderer
{
  private Map<Series, List<String>> labelPrimitives = SecurityUtil.newHashtable();
  private List<String> scripts = new Vector();
  protected Element hotspotLayer;
  private Map<Object, List<String>> componentPrimitives = SecurityUtil.newHashtable();
  private IUpdateNotifier _iun;
  private static ILogger logger = Logger.getLogger("org.eclipse.birt.chart.device.svg/trace");
  SVGGraphics2D svg_g2d;
  private IDeviceRenderer device;
  private List<CacheEvent> cacheEvents = new ArrayList();
  private String defaultCursor = "cursor:pointer";
  private Map<Object, Boolean> mapOnloadAdded = new HashMap();
  private int iFirstDataPointIndex = -1;
  
  public SVGInteractiveRenderer(IDeviceRenderer device)
  {
    this.device = device;
  }
  
  public void setIUpdateNotifier(IUpdateNotifier iun)
  {
    _iun = iun;
  }
  
  public void setSVG2D(SVGGraphics2D svg2D)
  {
    svg_g2d = svg2D;
  }
  
  protected void groupPrimitive(PrimitiveRenderEvent pre, boolean drawText)
  {
    if (_iun == null)
    {
      logger.log(2, 
        org.eclipse.birt.chart.device.svg.i18n.Messages.getString("exception.missing.component.interaction", getULocale()));
      return;
    }
    if ((pre.getSource() instanceof StructureSource))
    {
      StructureSource sourceObject = (StructureSource)pre.getSource();
      Series seDT = (Series)getElementFromSource(sourceObject, 
        StructureType.SERIES);
      if (seDT != null)
      {
        String groupIdentifier = null;
        try
        {
          if ((isColoredByCategories()) && 
            (getElementFromSource(sourceObject, 
            StructureType.SERIES_DATA_POINT) != null))
          {
            seDT = findCategorySeries(seDT);
            groupIdentifier = String.valueOf(seDT.hashCode());
            
            DataPointHints dph = (DataPointHints)getElementFromSource(sourceObject, 
              StructureType.SERIES_DATA_POINT);
            groupIdentifier = groupIdentifier + "index";
            groupIdentifier = groupIdentifier + dph.getIndex();
            if (iFirstDataPointIndex < 0) {
              iFirstDataPointIndex = dph.getIndex();
            }
          }
          else
          {
            seDT = findDesignTimeSeries(seDT);
            groupIdentifier = String.valueOf(seDT.hashCode());
          }
        }
        catch (ChartException e)
        {
          logger.log(e);
          return;
        }
        if (drawText)
        {
          String id = Integer.toString(pre.hashCode());
          List<String> components = (List)labelPrimitives.get(seDT);
          if (components == null)
          {
            components = new ArrayList();
            labelPrimitives.put(seDT, components);
          }
          components.add(id);
          
          Element outerGroup = svg_g2d.createElement("g");
          svg_g2d.pushParent(outerGroup);
          
          Element primGroup = svg_g2d.createElement("g");
          outerGroup.appendChild(primGroup);
          svg_g2d.pushParent(primGroup);
          primGroup.setAttribute("id", groupIdentifier + "_" + id);
          primGroup.setAttribute("style", "visibility:visible;");
          outerGroup.setAttribute("id", groupIdentifier + "_" + id + "_g");
          outerGroup.setAttribute("style", "visibility:visible;");
        }
        else
        {
          String id = Integer.toString(pre.hashCode());
          List<String> components = (List)componentPrimitives.get(seDT);
          if (components == null)
          {
            components = new ArrayList();
            componentPrimitives.put(seDT, components);
          }
          String idTemp = id;
          if (components.size() > 0) {
            idTemp = id + "@" + components.size();
          }
          components.add(idTemp);
          
          Element primGroup = svg_g2d.createElement("g");
          svg_g2d.pushParent(primGroup);
          primGroup.setAttribute("id", groupIdentifier + "_" + idTemp);
          primGroup.setAttribute("style", "visibility:visible;");
          
          svg_g2d.setDeferStrokColor(primGroup);
        }
      }
      else
      {
        Object designObject = null;
        if (getElementFromSource(sourceObject, StructureType.TITLE) != null) {
          designObject = sourceObject.getSource();
        } else if (getElementFromSource(sourceObject, 
          StructureType.CHART_BLOCK) != null) {
          designObject = sourceObject.getSource();
        } else if (getElementFromSource(sourceObject, 
          StructureType.PLOT) != null) {
          designObject = sourceObject.getSource();
        } else if (getElementFromSource(sourceObject, 
          StructureType.AXIS) != null) {
          designObject = sourceObject.getSource();
        }
        if (designObject != null)
        {
          String groupIdentifier = String.valueOf(designObject.hashCode());
          String id = Integer.toString(pre.hashCode());
          List<String> components = (List)componentPrimitives.get(designObject);
          if (components == null)
          {
            components = new ArrayList();
            componentPrimitives.put(designObject, components);
          }
          String idTemp = id;
          if (components.size() > 0) {
            idTemp = id + "@" + components.size();
          }
          components.add(idTemp);
          
          Element primGroup = svg_g2d.createElement("g");
          svg_g2d.pushParent(primGroup);
          primGroup.setAttribute("id", groupIdentifier + "_" + idTemp);
          primGroup.setAttribute("style", "visibility:visible;");
          svg_g2d.setDeferStrokColor(primGroup);
        }
      }
    }
  }
  
  protected void ungroupPrimitive(PrimitiveRenderEvent pre, boolean drawText)
  {
    if (_iun == null)
    {
      logger.log(2, 
        org.eclipse.birt.chart.device.svg.i18n.Messages.getString("exception.missing.component.interaction", getULocale()));
      return;
    }
    if ((pre.getSource() instanceof StructureSource))
    {
      StructureSource sourceObject = (StructureSource)pre.getSource();
      Series series = (Series)getElementFromSource(sourceObject, 
        StructureType.SERIES);
      if (series != null)
      {
        if (drawText)
        {
          svg_g2d.popParent();
          svg_g2d.popParent();
        }
        else
        {
          svg_g2d.setDeferStrokColor(null);
          svg_g2d.popParent();
        }
      }
      else if ((getElementFromSource(sourceObject, StructureType.TITLE) != null) || 
        (getElementFromSource(sourceObject, 
        StructureType.AXIS) != null) || 
        (getElementFromSource(sourceObject, 
        StructureType.CHART_BLOCK) != null) || 
        (getElementFromSource(sourceObject, 
        StructureType.PLOT) != null))
      {
        svg_g2d.setDeferStrokColor(null);
        svg_g2d.popParent();
      }
    }
  }
  
  private Object getElementFromSource(StructureSource src, StructureType type)
  {
    if ((src instanceof WrappedStructureSource))
    {
      WrappedStructureSource wss = (WrappedStructureSource)src;
      while (wss != null)
      {
        if (wss.getType() == type) {
          return wss.getSource();
        }
        if (wss.getParent().getType() == type) {
          return wss.getParent().getSource();
        }
        if ((wss.getParent() instanceof WrappedStructureSource)) {
          wss = (WrappedStructureSource)wss.getParent();
        } else {
          wss = null;
        }
      }
    }
    else if (src.getType() == type)
    {
      return src.getSource();
    }
    return null;
  }
  
  private Series findCategorySeries(Series seDT)
  {
    Chart cmDT = _iun.getDesignTimeModel();
    if ((cmDT instanceof ChartWithAxes)) {
      return 
      
        (Series)((SeriesDefinition)((ChartWithAxes)cmDT).getBaseAxes()[0].getSeriesDefinitions().get(0)).getRunTimeSeries().get(0);
    }
    return 
    
      (Series)((SeriesDefinition)((ChartWithoutAxes)cmDT).getSeriesDefinitions().get(0)).getRunTimeSeries().get(0);
  }
  
  public void prepareInteractiveEvent(Element elm, InteractionEvent ie, Trigger[] triggers)
  {
    triggers = removeAddedOnloadEvent(ie, triggers);
    if ((triggers != null) && (triggers.length > 0)) {
      cacheEvents.add(new CacheEvent(elm, 
        ie.getStructureSource(), 
        triggers, 
        ie.getCursor()));
    }
  }
  
  private Trigger[] removeAddedOnloadEvent(InteractionEvent ie, Trigger[] triggers)
  {
    int indexOnload = -1;
    boolean bDelete = false;
    if (ie.getStructureSource().getType() == StructureType.SERIES_DATA_POINT)
    {
      for (int i = 0; i < triggers.length; i++) {
        if (triggers[i].getCondition().getValue() == 15)
        {
          if ((isColoredByCategories()) && (
            (triggers[i].getAction().getType() == ActionType.TOGGLE_VISIBILITY_LITERAL) || 
            (triggers[i].getAction().getType() == ActionType.TOGGLE_DATA_POINT_VISIBILITY_LITERAL)))
          {
            Object dph = ie.getStructureSource().getSource();
            if (!mapOnloadAdded.containsKey(dph))
            {
              mapOnloadAdded.put(dph, Boolean.TRUE);
              return triggers;
            }
            bDelete = true;
          }
          indexOnload = i;
          break;
        }
      }
      if (indexOnload >= 0)
      {
        Object series = ((WrappedStructureSource)ie.getStructureSource()).getParent()
          .getSource();
        if ((bDelete) || (mapOnloadAdded.containsKey(series)))
        {
          if (triggers.length == 1) {
            return null;
          }
          Trigger[] newTriggers = new Trigger[triggers.length - 1];
          System.arraycopy(triggers, 0, newTriggers, 0, indexOnload);
          System.arraycopy(triggers, 
            indexOnload + 1, 
            newTriggers, 
            indexOnload, 
            triggers.length - indexOnload - 1);
          return newTriggers;
        }
        mapOnloadAdded.put(series, Boolean.TRUE);
      }
    }
    return triggers;
  }
  
  public void addInteractivity()
  {
    for (Iterator<CacheEvent> iter = cacheEvents.iterator(); iter.hasNext();)
    {
      CacheEvent cEvent = (CacheEvent)iter.next();
      addEventHandling(cEvent.getElement(), 
        cEvent.getSource(), 
        cEvent.getTriggers(), 
        cEvent.getCursor());
    }
  }
  
  private void addEventHandling(Element elm, StructureSource src, Trigger[] triggers, Cursor cursor)
  {
    if ((elm != null) && (triggers != null))
    {
      if ((triggers != null) && (triggers.length > 0)) {
        setCursorAttribute(elm, cursor, defaultCursor);
      }
      Element aLink = svg_g2d.createElement("a");
      Element group = svg_g2d.createElement("g");
      group.appendChild(elm);
      
      aLink.setAttribute("xlink:href", "javascript:void(0);");
      aLink.appendChild(group);
      elm = group;
      hotspotLayer.appendChild(aLink);
      for (int x = 0; x < triggers.length; x++)
      {
        Trigger tg = triggers[x];
        
        String scriptEvent = getJsScriptEvent(tg.getCondition()
          .getValue());
        if (scriptEvent != null)
        {
          boolean bDblClick = false;
          if (scriptEvent.equals("ondblclick"))
          {
            scriptEvent = "onclick";
            bDblClick = true;
          }
          Action action = tg.getAction();
          if ((action instanceof MultipleActions)) {
            addMultiActionsJSCode(elm, 
              src, 
              tg, 
              scriptEvent, 
              bDblClick, 
              (MultipleActions)action);
          } else {
            addActionJSCode(elm, 
              src, 
              tg, 
              scriptEvent, 
              bDblClick, 
              action);
          }
        }
      }
    }
  }
  
  private void addActionJSCode(Element elm, StructureSource src, Trigger tg, String scriptEvent, boolean bDblClick, Action action)
  {
    switch (action.getType().getValue())
    {
    case 1: 
      addTooltipJSCode(elm, 
        src, 
        scriptEvent, 
        bDblClick, 
        action);
      break;
    case 0: 
      addURLRedirectJSCode(elm, 
        src, 
        scriptEvent, 
        bDblClick, 
        action);
      break;
    case 2: 
    case 4: 
    case 6: 
      addJSCodeOnElement(src, 
        tg, 
        elm, 
        scriptEvent, 
        action.getType().getValue(), 
        bDblClick);
      break;
    case 3: 
      addInvokeScriptJSCode(elm, 
        src, 
        tg, 
        scriptEvent, 
        bDblClick, 
        action);
    }
  }
  
  private void addMultiActionsJSCode(Element elm, StructureSource src, Trigger tg, String scriptEvent, boolean bDblClick, MultipleActions action)
  {
    List<Action> subActions = MultiActionValuesScriptGenerator.getValidActions(action);
    if (subActions.size() == 1)
    {
      Action subAction = (Action)subActions.get(0);
      addActionJSCode(elm, 
        src, 
        tg, 
        scriptEvent, 
        bDblClick, 
        subAction);
    }
    else if (subActions.size() > 1)
    {
      String callbackContent = getMultiActionsCallbackContent(action);
      StringBuffer callbackFunction = generateScriptCallbackFunctionName(callbackContent);
      String funcName = callbackFunction.toString();
      addCallBackScript(src, callbackFunction, false);
      
      boolean multipleTypes = false;
      for (Action subAction : subActions) {
        if (!(subAction instanceof MultipleActions))
        {
          int typeValue = subAction.getType().getValue();
          switch (typeValue)
          {
          case 2: 
          case 4: 
          case 6: 
            multipleTypes = true;
          }
          if (multipleTypes) {
            break;
          }
        }
      }
      if (multipleTypes) {
        callbackFunction.append(getJSCodeFunctionSuffix(src));
      } else {
        callbackFunction.append(")");
      }
      String jsFunction = callbackFunction.toString();
      elm.setAttribute(scriptEvent, wrapJS(bDblClick, 
        jsFunction));
      if (tg.getCondition().getValue() == 6) {
        elm.setAttribute("onmouseout", 
          jsFunction);
      }
      if (!scripts.contains(callbackContent))
      {
        svg_g2d.addScript(generateCallBackMethodName(funcName) + 
          "{" + callbackContent + "}");
        scripts.add(callbackContent);
      }
    }
  }
  
  private void addTooltipJSCode(Element elm, StructureSource src, String scriptEvent, boolean bDblClick, Action action)
  {
    String tooltipText = ((TooltipValue)action
      .getValue()).getText();
    if ((tooltipText != null) && 
      (tooltipText.trim().length() > 0))
    {
      Element title = svg_g2d.dom.createElement("title");
      title.appendChild(svg_g2d.dom.createTextNode(tooltipText));
      elm.appendChild(title);
      
      String componentId = null;
      if ((src instanceof WrappedStructureSource)) {
        componentId = findFirstComponentId((WrappedStructureSource)src);
      }
      if (scriptEvent.equals("onmouseover"))
      {
        elm.setAttribute("onmouseout", "TM.remove()");
        if (componentId != null) {
          elm.setAttribute("onmousemove", "TM.show(evt," + componentId + ")");
        } else {
          elm.setAttribute("onmousemove", "TM.show(evt)");
        }
      }
      else if (componentId != null)
      {
        elm.setAttribute(scriptEvent, 
          wrapJS(bDblClick, 
          "TM.toggleToolTip(evt," + componentId + ")"));
      }
      else
      {
        elm.setAttribute(scriptEvent, 
          wrapJS(bDblClick, 
          "TM.toggleToolTip(evt)"));
      }
    }
  }
  
  private void addInvokeScriptJSCode(Element elm, StructureSource src, Trigger tg, String scriptEvent, boolean bDblClick, Action action)
  {
    if (tg.getCondition().equals(TriggerCondition.ACCESSIBILITY_LITERAL))
    {
      AccessibilityValue accessValue = (AccessibilityValue)action
        .getValue();
      if (accessValue.getText() != null)
      {
        Element title = svg_g2d.createElement("title");
        title.appendChild(svg_g2d.dom.createTextNode(accessValue.getText()));
        elm.appendChild(title);
      }
      if (accessValue.getAccessibility() != null)
      {
        Element description = svg_g2d.createElement("desc");
        description.appendChild(svg_g2d.dom.createTextNode(accessValue.getAccessibility()));
        elm.appendChild(description);
      }
    }
    else
    {
      String script = ((ScriptValue)action
        .getValue()).getScript();
      
      StringBuffer callbackFunction = generateScriptCallbackFunctionName(script);
      
      String funcName = callbackFunction.toString();
      addCallBackScript(src, callbackFunction, true);
      
      elm.setAttr
1 2 3 4

Further reading...

For more information on Java 1.5 Tiger, you may find Java 1.5 Tiger, A developer's Notebook by D. Flanagan and B. McLaughlin from O'Reilly of interest.

New!JAR listings


Copyright 2006-2019. Infinite Loop Ltd