package de.lmu.ifi.dbs.elki.visualization.visualizers.parallel;
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.projections.ProjectionParallel;
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;
import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisualization;
/**
* Abstract base class for parallel visualizations.
*
* @author Robert Rödler
* @author Erich Schubert
*
* @param Vector type in relation
*/
public abstract class AbstractParallelVisualization> extends AbstractVisualization {
/**
* The current projection
*/
final protected ProjectionParallel proj;
/**
* The representation we visualize
*/
final protected Relation relation;
/**
* margin
*/
final double[] margins;
/**
* Space between two axes
*/
protected double axsep;
/**
* viewbox size
*/
final double[] size;
/**
* Constructor.
*
* @param task Visualization task
*/
public AbstractParallelVisualization(VisualizationTask task) {
super(task);
this.proj = task.getProj();
this.relation = task.getRelation();
double ratio = task.width / task.height;
margins = new double[] { 0.05 * StyleLibrary.SCALE, 0.1 * StyleLibrary.SCALE, 0.05 * StyleLibrary.SCALE, 0.4 * StyleLibrary.SCALE };
size = new double[] { ratio * StyleLibrary.SCALE, StyleLibrary.SCALE };
recalcAxisPositions();
this.layer = setupCanvas(svgp, proj, task.getWidth(), task.getHeight());
}
/**
* Utility function to setup a canvas element for the visualization.
*
* @param svgp Plot element
* @param proj Projection to use
* @param width Width
* @param height Height
* @return wrapper element with appropriate view box.
*/
public Element setupCanvas(SVGPlot svgp, ProjectionParallel proj, double width, double height) {
Element layer = SVGUtil.svgElement(svgp.getDocument(), SVGConstants.SVG_G_TAG);
final String transform = SVGUtil.makeMarginTransform(width, height, size[0], size[1], margins[0], margins[1], margins[2], margins[3]);
SVGUtil.setAtt(layer, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, transform);
return layer;
}
/**
* Get width of main canvas.
*
* @return Width
*/
protected double getSizeX() {
return size[0];
}
protected double getSizeY() {
return size[1];
}
protected double getMarginLeft() {
return margins[0];
}
protected double getMarginTop() {
return margins[1];
}
/**
* Distance between axes.
*
* @return Axis separation
*/
protected double getAxisSep() {
return axsep;
}
/**
* Recalculate axis positions, in particular after projection changes.
*/
private void recalcAxisPositions() {
axsep = size[0] / (proj.getVisibleDimensions() - 1.);
}
/**
* Get the position of visible axis d
*
* @param d Visible axis number
* @return Position
*/
protected double getVisibleAxisX(double d) {
return d * axsep;
}
@Override
public void resultChanged(Result current) {
super.resultChanged(current);
if(current == proj) {
recalcAxisPositions();
synchronizedRedraw();
}
}
}