/**
* Copyright (C) 2007-2009, Jens Lehmann
*
* This file is part of DL-Learner.
*
* DL-Learner is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* DL-Learner 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.dllearner.tools.protege;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.util.Random;
import java.util.Set;
import java.util.Vector;
import javax.swing.JPanel;
import org.dllearner.core.EvaluatedDescription;
import org.dllearner.learningproblems.EvaluatedDescriptionClass;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLIndividual;
/**
* This class draws the graphical coverage of a learned concept.
*
* @author Christian Koetteritzsch
*
*/
public class GraphicalCoveragePanel extends JPanel {
private static final long serialVersionUID = 855436961912515267L;
private static final int HEIGHT = 150;
private static final int WIDTH = 150;
private static final int ELLIPSE_X_AXIS = 5;
private static final int ELLIPSE_Y_AXIS = 5;
private static final int MAX_NUMBER_OF_INDIVIDUAL_POINTS = 20;
private static final int PLUS_SIZE = 5;
private static final int SUBSTRING_SIZE = 25;
private static final int SPACE_SIZE = 7;
private static final int MAX_RANDOM_NUMBER = 300;
private static final String EQUI_STRING = "equivalent class";
private final String id;
private int shiftXAxis;
private int distortionOld;
private Ellipse2D oldConcept;
private Ellipse2D newConcept;
private EvaluatedDescription eval;
private String conceptNew;
private final Vector<IndividualPoint> posCovIndVector;
private final Vector<IndividualPoint> posNotCovIndVector;
private final Vector<IndividualPoint> additionalIndividuals;
private final Vector<IndividualPoint> points;
private final Vector<String> conceptVector;
private final GraphicalCoveragePanelHandler handler;
private int adjustment;
private int shiftOldConcept;
private int shiftNewConcept;
private int shiftNewConceptX;
private int shiftCovered;
private int coveredIndividualSize;
private int additionalIndividualSize;
private int x1;
private int x2;
private int y1;
private int y2;
private int centerX;
private int centerY;
private final Random random;
private final Color darkGreen;
private final Color darkRed;
private int notCoveredInd;
private OWLDataFactory factory;
/**
*
* This is the constructor for the GraphicalCoveragePanel.
*
* @param desc
* EvaluatedDescription
* @param m
* DLLearnerModel
*/
public GraphicalCoveragePanel(EvaluatedDescription desc) {
this.setForeground(Color.GREEN);
eval = desc;
// id = model.getID();
id = EQUI_STRING;
darkGreen = new Color(0, 100, 0);
darkRed = new Color(205, 0, 0);
random = new Random();
// for(String uri : model.getOntologyURIString()) {
// if(eval.getDescription().toString().contains(uri)) {
// conceptNew = eval.getDescription().toManchesterSyntaxString(uri, null);
// }
// }
if(eval != null){
conceptNew = Manager.getInstance().getRendering(eval.getDescription());
} else{
conceptNew = "";
}
conceptVector = new Vector<String>();
posCovIndVector = new Vector<IndividualPoint>();
posNotCovIndVector = new Vector<IndividualPoint>();
additionalIndividuals = new Vector<IndividualPoint>();
points = new Vector<IndividualPoint>();
this.computeGraphics();
handler = new GraphicalCoveragePanelHandler(this, desc);
factory = Manager.getInstance().getActiveOntology().getOWLOntologyManager().getOWLDataFactory();
this.computeIndividualPoints();
this.addMouseMotionListener(handler);
this.addMouseListener(handler);
}
@Override
protected void paintComponent(Graphics g) {
if (eval != null) {
Graphics2D g2D;
g2D = (Graphics2D) g;
g2D.clearRect(0, 0, getWidth(), getHeight());
AlphaComposite ac = AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, 0.5f);
g2D.setColor(Color.YELLOW);
g2D.fill(oldConcept);
g2D.setColor(Color.ORANGE);
g2D.setComposite(ac);
g2D.fill(newConcept);
g2D.setColor(Color.BLACK);
// Plus 1
if (coveredIndividualSize != Manager.getInstance().getIndividuals().size()
&& notCoveredInd != 0) {
g2D.drawLine(x1 - 1 - shiftOldConcept, y1 - 1, x2 + 1
- shiftOldConcept, y1 - 1);
g2D.drawLine(x1 - shiftOldConcept, centerY - 1, x2
- shiftOldConcept, centerY - 1);
g2D.drawLine(x1 - shiftOldConcept, centerY, x2
- shiftOldConcept, centerY);
g2D.drawLine(x1 - shiftOldConcept, centerY + 1, x2
- shiftOldConcept, centerY + 1);
g2D.drawLine(x1 - 1 - shiftOldConcept, y2 + 1, x2 + 1
- shiftOldConcept, y2 + 1);
g2D.drawLine(x1 - 1 - shiftOldConcept, y1 - 1, x1 - 1
- shiftOldConcept, y2 + 1);
g2D.drawLine(centerX - 1 - shiftOldConcept, y1, centerX - 1
- shiftOldConcept, y2);
g2D.drawLine(centerX - shiftOldConcept, y1, centerX
- shiftOldConcept, y2);
g2D.drawLine(centerX + 1 - shiftOldConcept, y1, centerX + 1
- shiftOldConcept, y2);
g2D.drawLine(x2 + 1 - shiftOldConcept, y1 - 1, x2 + 1
- shiftOldConcept, y2 + 1);
}
// Plus 2
g2D.drawLine(x1 - 1 + shiftCovered, y1 - 1, x2 + 1 + shiftCovered,
y1 - 1);
g2D.drawLine(x1 + shiftCovered, centerY - 1, x2 + shiftCovered,
centerY - 1);
g2D
.drawLine(x1 + shiftCovered, centerY, x2 + shiftCovered,
centerY);
g2D.drawLine(x1 + shiftCovered, centerY + 1, x2 + shiftCovered,
centerY + 1);
g2D.drawLine(x1 - 1 + shiftCovered, y2 + 1, x2 + 1 + shiftCovered,
y2 + 1);
g2D.drawLine(x1 - 1 + shiftCovered, y1 - 1, x1 - 1 + shiftCovered,
y2 + 1);
g2D.drawLine(centerX - 1 + shiftCovered, y1, centerX - 1
+ shiftCovered, y2);
g2D
.drawLine(centerX + shiftCovered, y1, centerX
+ shiftCovered, y2);
g2D.drawLine(centerX + 1 + shiftCovered, y1, centerX + 1
+ shiftCovered, y2);
g2D.drawLine(x2 + 1 + shiftCovered, y1 - 1, x2 + 1 + shiftCovered,
y2 + 1);
// Plus 3
if (coveredIndividualSize != Manager.getInstance().getIndividuals().size() && ((EvaluatedDescriptionClass) eval).getAdditionalInstances().size() != 0) {
g2D.drawLine(x1 - 1 + shiftNewConcept, y1 - 1, x2 + 1
+ shiftNewConcept, y1 - 1);
g2D.drawLine(x1 + shiftNewConcept, centerY - 1, x2
+ shiftNewConcept, centerY - 1);
g2D.drawLine(x1 + shiftNewConcept, centerY, x2
+ shiftNewConcept, centerY);
g2D.drawLine(x1 + shiftNewConcept, centerY + 1, x2
+ shiftNewConcept, centerY + 1);
g2D.drawLine(x1 - 1 + shiftNewConcept, y2 + 1, x2 + 1
+ shiftNewConcept, y2 + 1);
g2D.drawLine(x1 - 1 + shiftNewConcept, y1 - 1, x1 - 1
+ shiftNewConcept, y2 + 1);
g2D.drawLine(centerX - 1 + shiftNewConcept, y1, centerX - 1
+ shiftNewConcept, y2);
g2D.drawLine(centerX + shiftNewConcept, y1, centerX
+ shiftNewConcept, y2);
g2D.drawLine(centerX + 1 + shiftNewConcept, y1, centerX + 1
+ shiftNewConcept, y2);
g2D.drawLine(x2 + 1 + shiftNewConcept, y1 - 1, x2 + 1
+ shiftNewConcept, y2 + 1);
}
//Plus 4
if (((EvaluatedDescriptionClass) eval).getAddition() != 1.0
&& ((EvaluatedDescriptionClass) eval).getCoverage() == 1.0) {
g2D.drawLine(x1 - 1 + shiftNewConceptX, y1 - 1
+ shiftNewConcept, x2 + 1 + shiftNewConceptX, y1 - 1
+ shiftNewConcept);
g2D.drawLine(x1 + shiftNewConceptX, centerY - 1
+ shiftNewConcept, x2 + shiftNewConceptX, centerY - 1
+ shiftNewConcept);
g2D.drawLine(x1 + shiftNewConceptX, centerY + shiftNewConcept,
x2 + shiftNewConceptX, centerY + shiftNewConcept);
g2D.drawLine(x1 + shiftNewConceptX, centerY + 1
+ shiftNewConcept, x2 + shiftNewConceptX, centerY + 1
+ shiftNewConcept);
g2D.drawLine(x1 - 1 + shiftNewConceptX, y2 + 1
+ shiftNewConcept, x2 + 1 + shiftNewConceptX, y2 + 1
+ shiftNewConcept);
g2D.drawLine(x1 - 1 + shiftNewConceptX, y1 - 1
+ shiftNewConcept, x1 - 1 + shiftNewConceptX, y2 + 1
+ shiftNewConcept);
g2D.drawLine(centerX - 1 + shiftNewConceptX, y1
+ shiftNewConcept, centerX - 1 + shiftNewConceptX, y2
+ shiftNewConcept);
g2D.drawLine(centerX + shiftNewConceptX, y1 + shiftNewConcept,
centerX + shiftNewConceptX, y2 + shiftNewConcept);
g2D.drawLine(centerX + 1 + shiftNewConceptX, y1
+ shiftNewConcept, centerX + 1 + shiftNewConceptX, y2
+ shiftNewConcept);
g2D.drawLine(x2 + 1 + shiftNewConceptX, y1 - 1
+ shiftNewConcept, x2 + 1 + shiftNewConceptX, y2 + 1
+ shiftNewConcept);
}
for (int i = 0; i < posCovIndVector.size(); i++) {
g2D.setColor(darkGreen);
g2D.fill(posCovIndVector.get(i).getIndividualPoint());
}
for (int i = 0; i < posNotCovIndVector.size(); i++) {
g2D.setColor(darkRed);
g2D.fill(posNotCovIndVector.get(i).getIndividualPoint());
}
for (int i = 0; i < additionalIndividuals.size(); i++) {
g2D.setColor(Color.BLACK);
g2D.fill(additionalIndividuals.get(i).getIndividualPoint());
}
}
}
public void setDescription(EvaluatedDescription desc){
this.eval = desc;
handler.setDescription(desc);
computeGraphics();
computeIndividualPoints();
repaint();
}
private void computeGraphics() {
if (eval != null) {
additionalIndividualSize = ((EvaluatedDescriptionClass) eval)
.getAdditionalInstances().size();
distortionOld = 0;
adjustment = 0;
Ellipse2D old = new Ellipse2D.Double(ELLIPSE_X_AXIS, ELLIPSE_Y_AXIS,
WIDTH, HEIGHT);
x1 = (int) old.getCenterX() - PLUS_SIZE;
x2 = (int) old.getCenterX() + PLUS_SIZE;
y1 = (int) old.getCenterY() - PLUS_SIZE;
y2 = (int) old.getCenterY() + PLUS_SIZE;
centerX = (int) old.getCenterX();
centerY = (int) old.getCenterY();
double coverage = ((EvaluatedDescriptionClass) eval).getCoverage();
shiftXAxis = (int) Math.round((WIDTH) * (1 - coverage));
if (additionalIndividualSize != 0 && ((EvaluatedDescriptionClass) eval).getCoverage() == 1.0 && ((EvaluatedDescriptionClass) eval).getAddition() < 1.0) {
distortionOld = (int) Math.round((WIDTH) * 0.3);
Ellipse2D newer = new Ellipse2D.Double(ELLIPSE_X_AXIS + shiftXAxis,
ELLIPSE_Y_AXIS, (WIDTH), HEIGHT);
adjustment = (int) Math.round(newer.getCenterY() / 4);
}
if (shiftXAxis == 0) {
oldConcept = new Ellipse2D.Double(ELLIPSE_X_AXIS
+ (2 * adjustment) + 3, ELLIPSE_Y_AXIS + 3, WIDTH,
HEIGHT);
} else {
oldConcept = new Ellipse2D.Double(ELLIPSE_X_AXIS
+ (2 * adjustment), ELLIPSE_Y_AXIS, WIDTH, HEIGHT);
}
if (shiftXAxis == 0) {
newConcept = new Ellipse2D.Double(ELLIPSE_X_AXIS + shiftXAxis
+ adjustment, ELLIPSE_Y_AXIS,
WIDTH + distortionOld + 6, HEIGHT + distortionOld + 6);
} else {
newConcept = new Ellipse2D.Double(ELLIPSE_X_AXIS + shiftXAxis
+ adjustment, ELLIPSE_Y_AXIS, WIDTH + distortionOld,
HEIGHT + distortionOld);
}
this.renderPlus();
}
}
private void renderPlus() {
if (eval != null) {
coveredIndividualSize = ((EvaluatedDescriptionClass) eval)
.getCoveredInstances().size();
double newConcepts = ((EvaluatedDescriptionClass) eval)
.getAddition();
double oldConcepts = ((EvaluatedDescriptionClass) eval)
.getCoverage();
shiftNewConcept = 0;
shiftOldConcept = 0;
shiftNewConceptX = 0;
shiftCovered = 0;
if (coveredIndividualSize == 0) {
shiftNewConcept = (int) Math.round(((WIDTH) / 2.0) * newConcepts);
} else if (additionalIndividualSize != coveredIndividualSize) {
shiftNewConcept = (int) Math.round(((WIDTH) / 2.0)
* (1.0 + (1.0 - oldConcepts)));
shiftOldConcept = (int) Math.round(((WIDTH) / 2.0) * oldConcepts);
shiftCovered = (int) Math.round(((WIDTH) / 2.0)
* (1 - oldConcepts));
}
if (((EvaluatedDescriptionClass) eval).getAddition() != 1.0 && ((EvaluatedDescriptionClass) eval)
.getCoverage() == 1.0) {
shiftCovered = (int) Math.round(((WIDTH) / 2.0) * 0.625);
shiftNewConceptX = shiftCovered;
shiftNewConcept = 2 * shiftNewConceptX;
}
}
int i = conceptNew.length();
while (i > 0) {
int sub = 0;
String subString = "";
if(conceptNew.contains(" ")) {
sub = conceptNew.indexOf(" ");
subString = conceptNew.substring(0, sub) + " ";
conceptNew = conceptNew.replace(conceptNew.substring(0, sub + 1),
"");
} else {
subString = conceptNew;
conceptNew = "";
}
while (sub < SUBSTRING_SIZE) {
if (conceptNew.length() > 0 && conceptNew.contains(" ")) {
sub = conceptNew.indexOf(" ");
if (subString.length() + sub < SUBSTRING_SIZE) {
subString = subString + conceptNew.substring(0, sub)
+ " ";
conceptNew = conceptNew.replace(conceptNew.substring(0,
sub + 1), "");
sub = subString.length();
} else {
break;
}
} else {
if (subString.length() + conceptNew.length() > SUBSTRING_SIZE
+ SPACE_SIZE) {
conceptVector.add(subString);
subString = conceptNew;
conceptNew = "";
break;
} else {
subString = subString + conceptNew;
conceptNew = "";
break;
}
}
}
conceptVector.add(subString);
i = conceptNew.length();
}
}
private void computeIndividualPoints() {
posCovIndVector.clear();
posNotCovIndVector.clear();
additionalIndividuals.clear();
points.clear();
if (eval != null) {
Set<OWLIndividual> posInd = ((EvaluatedDescriptionClass) eval)
.getCoveredInstances();
int i = 0;
double x = random.nextInt(MAX_RANDOM_NUMBER);
double y = random.nextInt(MAX_RANDOM_NUMBER);
boolean flag = true;
for (OWLIndividual ind : posInd) {
flag = true;
if (i < MAX_NUMBER_OF_INDIVIDUAL_POINTS) {
while (flag) {
if (newConcept.contains(x, y)
&& oldConcept.contains(x, y)
&& !(x >= this.getX1() + this.getShiftCovered()
&& x <= this.getX2()
+ this.getShiftCovered()
&& y >= this.getY1() && y <= this
.getY2())) {
posCovIndVector.add(new IndividualPoint("*",
(int) x, (int) y, Manager.getInstance().getRendering(ind), ind, ""));
i++;
flag = false;
x = random.nextInt(MAX_RANDOM_NUMBER);
y = random.nextInt(MAX_RANDOM_NUMBER);
break;
} else {
x = random.nextInt(MAX_RANDOM_NUMBER);
y = random.nextInt(MAX_RANDOM_NUMBER);
}
}
}
}
Set<OWLIndividual> posNotCovInd = ((EvaluatedDescriptionClass) eval)
.getAdditionalInstances();
int j = 0;
x = random.nextInt(MAX_RANDOM_NUMBER);
y = random.nextInt(MAX_RANDOM_NUMBER);
for (OWLIndividual ind : posNotCovInd) {
flag = true;
if (j < MAX_NUMBER_OF_INDIVIDUAL_POINTS) {
while (flag) {
if (!oldConcept.contains(x, y)
&& newConcept.contains(x, y)
&& !(x >= this.getX1()
+ this.getShiftNewConcept()
&& x <= this.getX2()
+ this.getShiftNewConcept()
&& y >= this.getY1() && y <= this
.getY2())
&& !(x >= this.getX1()
+ this.getShiftNewConceptX()
&& x <= this.getX2()
+ this.getShiftNewConceptX()
&& y >= this.getY1()
+ this.getShiftNewConcept() && y <= this
.getY2()
+ this.getShiftNewConcept())) {
if (id.equals(EQUI_STRING)) {
posNotCovIndVector.add(new IndividualPoint("*",
(int) x, (int) y, Manager.getInstance().getRendering(ind), ind, ""));
} else {
additionalIndividuals.add(new IndividualPoint("*",
(int) x, (int) y, Manager.getInstance().getRendering(ind), ind, ""));
}
j++;
flag = false;
x = random.nextInt(MAX_RANDOM_NUMBER);
y = random.nextInt(MAX_RANDOM_NUMBER);
break;
} else {
x = random.nextInt(MAX_RANDOM_NUMBER);
y = random.nextInt(MAX_RANDOM_NUMBER);
}
}
}
}
Set<OWLIndividual> notCovInd = Manager.getInstance().getIndividuals();
notCovInd.removeAll(posInd);
notCoveredInd = notCovInd.size();
int k = 0;
x = random.nextInt(MAX_RANDOM_NUMBER);
y = random.nextInt(MAX_RANDOM_NUMBER);
for (OWLIndividual ind : notCovInd) {
flag = true;
if (k < MAX_NUMBER_OF_INDIVIDUAL_POINTS) {
while (flag) {
if (oldConcept.contains(x, y)
&& !newConcept.contains(x, y)
&& !(x >= this.getX1()
- this.getShiftOldConcept()
&& x <= this.getX2()
- this.getShiftOldConcept()
&& y >= this.getY1() && y <= this
.getY2())) {
posNotCovIndVector.add(new IndividualPoint("*",
(int) x, (int) y, Manager.getInstance().getRendering(ind), ind, ""));
k++;
flag = false;
x = random.nextInt(MAX_RANDOM_NUMBER);
y = random.nextInt(MAX_RANDOM_NUMBER);
break;
} else {
x = random.nextInt(MAX_RANDOM_NUMBER);
y = random.nextInt(MAX_RANDOM_NUMBER);
}
}
}
}
points.addAll(posCovIndVector);
points.addAll(posNotCovIndVector);
points.addAll(additionalIndividuals);
}
}
/**
* This method returns a Vector of all individuals that are drawn in the
* panel.
*
* @return Vector of Individuals
*/
public Vector<IndividualPoint> getIndividualVector() {
return points;
}
/**
* This method returns the GraphicalCoveragePanel.
*
* @return GraphicalCoveragePanel
*/
public GraphicalCoveragePanel getGraphicalCoveragePanel() {
return this;
}
/**
* Returns the min. x value of the plus.
*
* @return int min X Value
*/
public int getX1() {
return x1;
}
/**
* Returns the max. x value of the plus.
*
* @return int max X Value
*/
public int getX2() {
return x2;
}
/**
* Returns the min. y value of the plus.
*
* @return int min Y Value
*/
public int getY1() {
return y1;
}
/**
* Returns the max. y value of the plus.
*
* @return int max Y Value
*/
public int getY2() {
return y2;
}
/**
* This method returns how much the old concept must be shifted.
* @return shift of the old concept
*/
public int getShiftOldConcept() {
return shiftOldConcept;
}
/**
* This method returns how much the plus in the middle must be shifted.
* @return shift of the middle plus
*/
public int getShiftCovered() {
return shiftCovered;
}
/**
* This method returns how much the new concept must be shifted.
* @return shift of the new concept
*/
public int getShiftNewConcept() {
return shiftNewConcept;
}
/**
* This method returns how much the new concept must be shifted.
* @return shift of the new concept
*/
public int getShiftNewConceptX() {
return shiftNewConceptX;
}
/**
* Unsets the panel after plugin is closed.
*/
public void unsetPanel() {
this.removeAll();
eval = null;
}
/**
* Returns the currently selected evaluated description.
*
* @return EvaluatedDescription
*/
public EvaluatedDescription getEvaluateddescription() {
return eval;
}
}