diff options
author | Erich Schubert <erich@debian.org> | 2019-03-09 22:48:46 +0000 |
---|---|---|
committer | Andrej Shadura <andrewsh@debian.org> | 2019-03-09 22:48:46 +0000 |
commit | a41e6e35d6837fd74d1cde7c44a004fabdafd0e2 (patch) | |
tree | 08cdf26c430312809668d7a2e97823d9c11bf118 | |
parent | 58fb6bbc8b085f8cef8d04e2210b4fd0204996a4 (diff) |
batik-performance
commit e02ba7683a45ffd3eb210d0d31a81c40f254e877
Author: Erich Schubert <schubert@informatik.uni-heidelberg.de>
Date: Wed Mar 29 15:26:04 2017 +0200
Improve Batik performance by avoiding `<symbol>` and `<use>`.
Batik will materialize the copies otherwise and add too many listeners.
So it is substantially faster to not use `<use>`
Gbp-Pq: Name batik-performance.patch
-rwxr-xr-x | addons/batikvis/src/main/java/de/lmu/ifi/dbs/elki/visualization/style/marker/PrettyMarkers.java | 114 |
1 files changed, 81 insertions, 33 deletions
diff --git a/addons/batikvis/src/main/java/de/lmu/ifi/dbs/elki/visualization/style/marker/PrettyMarkers.java b/addons/batikvis/src/main/java/de/lmu/ifi/dbs/elki/visualization/style/marker/PrettyMarkers.java index d8b8cc19..386355a3 100755 --- a/addons/batikvis/src/main/java/de/lmu/ifi/dbs/elki/visualization/style/marker/PrettyMarkers.java +++ b/addons/batikvis/src/main/java/de/lmu/ifi/dbs/elki/visualization/style/marker/PrettyMarkers.java @@ -23,11 +23,11 @@ package de.lmu.ifi.dbs.elki.visualization.style.marker; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import org.apache.batik.util.CSSConstants; import org.apache.batik.util.SVGConstants; import org.w3c.dom.Element; import de.lmu.ifi.dbs.elki.visualization.colors.ColorLibrary; +import de.lmu.ifi.dbs.elki.visualization.css.CSSClass; import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary; import de.lmu.ifi.dbs.elki.visualization.svg.SVGPlot; import de.lmu.ifi.dbs.elki.visualization.svg.SVGUtil; @@ -35,6 +35,8 @@ import de.lmu.ifi.dbs.elki.visualization.svg.SVGUtil; /** * Marker library achieving a larger number of styles by combining different * shapes with different colors. Uses object ID management by SVGPlot. + * + * TODO: Add more styles * * @author Erich Schubert * @since 0.4.0 @@ -104,79 +106,134 @@ public class PrettyMarkers implements MarkerLibrary { */ public void plotMarker(SVGPlot plot, Element parent, double x, double y, int style, double size) { assert (parent != null); - if (style == -1) { + if(style == -1) { plotUncolored(plot, parent, x, y, size); return; } - if (style == -2) { + if(style == -2) { plotGray(plot, parent, x, y, size); return; } - // TODO: add more styles. - String colorstr = colors.getColor(style); - String strokestyle = SVGConstants.CSS_STROKE_PROPERTY + ":" + colorstr + ";" + SVGConstants.CSS_STROKE_WIDTH_PROPERTY + ":" + SVGUtil.fmt(size / 6); + // No dot allowed! + String cssid = prefix + style + "_" + (int) (100 * size); - switch(style % 8){ + switch(style & 0x7){ case 0: { // + cross + if(!plot.getCSSClassManager().contains(cssid)) { + CSSClass c = new CSSClass(this, cssid); + String colorstr = colors.getColor(style); + c.setStatement(SVGConstants.CSS_STROKE_PROPERTY, colorstr); + c.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, size / 6); + plot.addCSSClassOrLogError(c); + } Element line1 = plot.svgLine(x, y - size / 2.2, x, y + size / 2.2); - SVGUtil.setStyle(line1, strokestyle); + SVGUtil.setCSSClass(line1, cssid); parent.appendChild(line1); Element line2 = plot.svgLine(x - size / 2.2, y, x + size / 2.2, y); - SVGUtil.setStyle(line2, strokestyle); + SVGUtil.setCSSClass(line2, cssid); parent.appendChild(line2); break; } case 1: { // X cross + if(!plot.getCSSClassManager().contains(cssid)) { + CSSClass c = new CSSClass(this, cssid); + String colorstr = colors.getColor(style); + c.setStatement(SVGConstants.CSS_STROKE_PROPERTY, colorstr); + c.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, size / 6); + plot.addCSSClassOrLogError(c); + } Element line1 = plot.svgLine(x - size / 2.828427, y - size / 2.828427, x + size / 2.828427, y + size / 2.828427); - SVGUtil.setStyle(line1, strokestyle); + SVGUtil.setCSSClass(line1, cssid); parent.appendChild(line1); Element line2 = plot.svgLine(x - size / 2.828427, y + size / 2.828427, x + size / 2.828427, y - size / 2.828427); - SVGUtil.setStyle(line2, strokestyle); + SVGUtil.setCSSClass(line2, cssid); parent.appendChild(line2); break; } case 2: { // O hollow circle + if(!plot.getCSSClassManager().contains(cssid)) { + CSSClass c = new CSSClass(this, cssid); + String colorstr = colors.getColor(style); + c.setStatement(SVGConstants.CSS_STROKE_PROPERTY, colorstr); + c.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, size / 6); + c.setStatement(SVGConstants.CSS_FILL_PROPERTY, SVGConstants.CSS_NONE_VALUE); + plot.addCSSClassOrLogError(c); + } Element circ = plot.svgCircle(x, y, size / 2.2); - SVGUtil.setStyle(circ, "fill: none;" + strokestyle); + SVGUtil.setCSSClass(circ, cssid); parent.appendChild(circ); break; } case 3: { // [] hollow rectangle + if(!plot.getCSSClassManager().contains(cssid)) { + CSSClass c = new CSSClass(this, cssid); + String colorstr = colors.getColor(style); + c.setStatement(SVGConstants.CSS_STROKE_PROPERTY, colorstr); + c.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, size / 6); + c.setStatement(SVGConstants.CSS_FILL_PROPERTY, SVGConstants.CSS_NONE_VALUE); + plot.addCSSClassOrLogError(c); + } Element rect = plot.svgRect(x - size / 2.4, y - size / 2.4, size / 1.2, size / 1.2); - SVGUtil.setStyle(rect, "fill: none;" + strokestyle); + SVGUtil.setCSSClass(rect, cssid); parent.appendChild(rect); break; } case 4: { // <> hollow diamond + if(!plot.getCSSClassManager().contains(cssid)) { + CSSClass c = new CSSClass(this, cssid); + String colorstr = colors.getColor(style); + c.setStatement(SVGConstants.CSS_STROKE_PROPERTY, colorstr); + c.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, size / 6); + c.setStatement(SVGConstants.CSS_FILL_PROPERTY, SVGConstants.CSS_NONE_VALUE); + plot.addCSSClassOrLogError(c); + } Element rect = plot.svgRect(x - size / 2.7, y - size / 2.7, size / 1.35, size / 1.35); - SVGUtil.setStyle(rect, "fill: none;" + strokestyle); + SVGUtil.setCSSClass(rect, cssid); SVGUtil.setAtt(rect, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, "rotate(45," + SVGUtil.fmt(x) + "," + SVGUtil.fmt(y) + ")"); parent.appendChild(rect); break; } case 5: { // O filled circle + if(!plot.getCSSClassManager().contains(cssid)) { + CSSClass c = new CSSClass(this, cssid); + String colorstr = colors.getColor(style); + c.setStatement(SVGConstants.CSS_FILL_PROPERTY, colorstr); + plot.addCSSClassOrLogError(c); + } Element circ = plot.svgCircle(x, y, size * .5); - SVGUtil.setStyle(circ, SVGConstants.CSS_FILL_PROPERTY + ":" + colorstr); + SVGUtil.setCSSClass(circ, cssid); parent.appendChild(circ); break; } case 6: { // [] filled rectangle + if(!plot.getCSSClassManager().contains(cssid)) { + CSSClass c = new CSSClass(this, cssid); + String colorstr = colors.getColor(style); + c.setStatement(SVGConstants.CSS_FILL_PROPERTY, colorstr); + plot.addCSSClassOrLogError(c); + } Element rect = plot.svgRect(x - size / 2.2, y - size / 2.2, size / 1.1, size / 1.1); - SVGUtil.setStyle(rect, "fill:" + colorstr); + SVGUtil.setCSSClass(rect, cssid); parent.appendChild(rect); break; } case 7: { // <> filled diamond + if(!plot.getCSSClassManager().contains(cssid)) { + CSSClass c = new CSSClass(this, cssid); + String colorstr = colors.getColor(style); + c.setStatement(SVGConstants.CSS_FILL_PROPERTY, colorstr); + plot.addCSSClassOrLogError(c); + } Element rect = plot.svgRect(x - size / 2.5, y - size / 2.5, size / 1.25, size / 1.25); - SVGUtil.setStyle(rect, "fill:" + colorstr); + SVGUtil.setCSSClass(rect, cssid); SVGUtil.setAtt(rect, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, "rotate(45," + SVGUtil.fmt(x) + "," + SVGUtil.fmt(y) + ")"); parent.appendChild(rect); break; @@ -185,7 +242,8 @@ public class PrettyMarkers implements MarkerLibrary { } /** - * Plot a replacement marker when an object is to be plotted as "disabled", usually gray. + * Plot a replacement marker when an object is to be plotted as "disabled", + * usually gray. * * @param plot Plot to draw to * @param parent Parent element @@ -216,23 +274,13 @@ public class PrettyMarkers implements MarkerLibrary { @Override public Element useMarker(SVGPlot plot, Element parent, double x, double y, int style, double size) { - String id = prefix + style + "_" + size; - Element existing = plot.getIdElement(id); - if(existing == null) { - Element symbol = plot.svgElement(SVGConstants.SVG_SYMBOL_TAG); - SVGUtil.setAtt(symbol, SVGConstants.SVG_ID_ATTRIBUTE, id); - SVGUtil.setAtt(symbol, CSSConstants.CSS_OVERFLOW_PROPERTY, CSSConstants.CSS_VISIBLE_VALUE); - plotMarker(plot, symbol, 0, 0, style, size); - plot.getDefs().appendChild(symbol); - plot.putIdElement(id, symbol); - } - Element use = plot.svgElement(SVGConstants.SVG_USE_TAG); - use.setAttributeNS(SVGConstants.XLINK_NAMESPACE_URI, SVGConstants.XLINK_HREF_QNAME, "#" + id); - SVGUtil.setAtt(use, SVGConstants.SVG_X_ATTRIBUTE, x); - SVGUtil.setAtt(use, SVGConstants.SVG_Y_ATTRIBUTE, y); + // Note: we used to use <symbol> and <use>, but Batik performance was much + // worse. + Element use = plot.svgElement(SVGConstants.SVG_G_TAG); + plotMarker(plot, use, x, y, style, size); if(parent != null) { parent.appendChild(use); } return use; } -}
\ No newline at end of file +} |