Skip to content

Commit

Permalink
started work on colormap labels for legend (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
hageldave committed May 7, 2020
1 parent 07ef89e commit 1eb5b44
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 4 deletions.
185 changes: 182 additions & 3 deletions jplotter/src/main/java/hageldave/jplotter/renderables/Legend.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.awt.Font;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
Expand All @@ -12,11 +13,13 @@
import org.w3c.dom.Element;

import hageldave.jplotter.canvas.FBOCanvas;
import hageldave.jplotter.color.ColorMap;
import hageldave.jplotter.font.CharacterAtlas;
import hageldave.jplotter.misc.Glyph;
import hageldave.jplotter.renderers.CompleteRenderer;
import hageldave.jplotter.renderers.Renderer;
import hageldave.jplotter.util.Annotations.GLContextRequired;
import hageldave.jplotter.util.Utils;

/**
* The Legend class is {@link Renderable} and its own {@link Renderer} at once.
Expand All @@ -37,14 +40,18 @@
*/
public class Legend implements Renderable, Renderer {

protected ArrayList<GlyphLabel> glyphLabels = new ArrayList<>();
protected ArrayList<GlyphLabel> glyphLabels = new ArrayList<>(0);

protected ArrayList<LineLabel> lineLabels = new ArrayList<>();
protected ArrayList<LineLabel> lineLabels = new ArrayList<>(0);

protected ArrayList<ColormapLabel> colormapLabels = new ArrayList<>(0);

protected Map<Glyph, Points> glyph2points = new LinkedHashMap<>();

protected Map<Integer, Lines> pattern2lines = new LinkedHashMap<>();

protected LinkedList<Triangles> triangles = new LinkedList<>();

protected LinkedList<Text> texts = new LinkedList<>();

protected CompleteRenderer delegate = new CompleteRenderer();
Expand Down Expand Up @@ -92,6 +99,34 @@ public LineLabel(String labelText, double thickness, int color, int pickColor){
}
}

protected static class ColormapLabel {
public String labelText;
public ColorMap cmap;
public boolean vertical;
public int pickColor;
public double[] ticks;
public String[] ticklabels;

public ColormapLabel(String labelText, ColorMap cmap, boolean vertical, int pickColor, double[] ticks, String[] ticklabels) {
this.labelText = labelText;
this.cmap = cmap;
this.vertical = vertical;
this.pickColor = pickColor;
this.ticks = ticks == null ? new double[0]:ticks;
this.ticklabels = ticklabels == null ? new String[0]:ticklabels;
}

public ColormapLabel(String labelText, ColorMap cmap, boolean vertical, int pickColor, double[] ticks) {
this(labelText, cmap, vertical, pickColor, ticks, null);
}

public ColormapLabel(String labelText, ColorMap cmap, boolean vertical, int pickColor) {
this(labelText, cmap, vertical, pickColor, null, null);
}


}

/**
* Sets the {@link #isDirty()} state of this legend to true.
* This indicates that a call to {@link #updateGL()} is necessary
Expand Down Expand Up @@ -164,6 +199,82 @@ public Legend addLineLabel(double thickness, int color, String labeltxt){
return addLineLabel(thickness, color, labeltxt, 0);
}

/**
* Adds a label for a color map to this legend.
* @param labelText text for the label
* @param cmap color map to label
* @param vertical orientation of the colormap
* @param pickColor picking color (see {@link FBOCanvas})
* @param ticks tick marks for the map
* @param ticklabels labels for the tick marks
* @return this for chaining
*/
public Legend addColormapLabel(String labelText, ColorMap cmap, boolean vertical, int pickColor, double[] ticks, String[] ticklabels){
colormapLabels.add(new ColormapLabel(labelText, cmap, vertical, pickColor, ticks, ticklabels));
return setDirty();
}

/**
* Adds a label for a color map to this legend.
* @param labelText text for the label
* @param cmap color map to label
* @param vertical orientation of the colormap
* @param pickColor picking color (see {@link FBOCanvas})
* @param ticks tick marks for the map
* @return this for chaining
*/
public Legend addColormapLabel(String labelText, ColorMap cmap, boolean vertical, int pickColor, double[] ticks){
return addColormapLabel(labelText, cmap, vertical, pickColor, ticks, null);
}

/**
* Adds a label for a color map to this legend.
* @param labelText text for the label
* @param cmap color map to label
* @param vertical orientation of the colormap
* @param pickColor picking color (see {@link FBOCanvas})
* @return this for chaining
*/
public Legend addColormapLabel(String labelText, ColorMap cmap, boolean vertical, int pickColor){
return addColormapLabel(labelText, cmap, vertical, pickColor, null, null);
}

/**
* Adds a label for a color map to this legend.
* @param labelText text for the label
* @param cmap color map to label
* @param vertical orientation of the colormap
* @param ticks tick marks for the map
* @param ticklabels labels for the tick marks
* @return this for chaining
*/
public Legend addColormapLabel(String labelText, ColorMap cmap, boolean vertical, double[] ticks, String[] ticklabels){
return addColormapLabel(labelText, cmap, vertical, 0, ticks, ticklabels);
}

/**
* Adds a label for a color map to this legend.
* @param labelText text for the label
* @param cmap color map to label
* @param vertical orientation of the colormap
* @param ticks tick marks for the map
* @return this for chaining
*/
public Legend addColormapLabel(String labelText, ColorMap cmap, boolean vertical, double[] ticks){
return addColormapLabel(labelText, cmap, vertical, 0, ticks, null);
}

/**
* Adds a label for a color map to this legend.
* @param labelText text for the label
* @param cmap color map to label
* @param vertical orientation of the colormap
* @return this for chaining
*/
public Legend addColormapLabel(String labelText, ColorMap cmap, boolean vertical){
return addColormapLabel(labelText, cmap, vertical, 0, null, null);
}

/**
* NOOP
*/
Expand All @@ -178,7 +289,7 @@ public boolean isDirty() {
}

/**
* Purges all {@link Points}, {@link Lines} and {@link Text}s of this Legend.
* Purges all {@link Points}, {@link Lines}, {@link Triangles} and {@link Text}s of this Legend.
* Then these Renderables are created again while laying them out according to
* the available viewport size.
*/
Expand Down Expand Up @@ -256,6 +367,65 @@ public void updateGL() {
currentY -= Math.max(10, fontHeight)+5;
}
}
// colormaps third
for(ColormapLabel cmlabel : colormapLabels) {
Text lbltxt = new Text(cmlabel.labelText, fontSize, fontStyle);
lbltxt.setPickColor(cmlabel.pickColor);
if(!lbltxt.getTextString().isEmpty())
texts.add(lbltxt);
int pattern = 0xffff;
if(!pattern2lines.containsKey(pattern)){
Lines lines = new Lines();
lines
.setStrokePattern(pattern)
.setVertexRoundingEnabled(true);
pattern2lines.put(pattern, lines);
}
Lines lines = pattern2lines.get(pattern);
Triangles tris = Utils.colormap2Tris(cmlabel.cmap, cmlabel.vertical);
triangles.add(tris);
int cmapSize = 12;
if(cmlabel.vertical){
// put label on top
int currX = currentX+4;
int currY;
if(!lbltxt.getTextString().isEmpty()){
lbltxt.setOrigin(currentX, currentY);
currY = currentY-fontSize+2;
} else {
currY = currentY;
}
int w = cmapSize;
int h = Math.max(cmapSize*3, (fontSize+2)*cmlabel.ticklabels.length);
// stretch triangles to correct size and translate to correct location
tris.getTriangleDetails().forEach(t->{
Arrays.asList(t.p0,t.p1,t.p2).forEach(p->{
p.setLocation(p.getX()*w+currX, currY-h+p.getY()*h);
});
});
// draw frame
lines.addLineStrip(currX,currY, currX+w,currY, currX+w,currY-h, currX,currY-h, currX,currY);
// add ticks (& tick labels)
for(int i=0; i<cmlabel.ticks.length; i++){
double tick = cmlabel.ticks[i];
String lbl = cmlabel.ticklabels.length==0 ? "":cmlabel.ticklabels[i];
double x = currX+w; double y=currY-h+tick*h;
lines.addSegment(x, y, x+3, y);
if(!lbl.isEmpty()){
Text ticklbl = new Text(lbl, fontSize-2, fontStyle).setOrigin((int)(x+5), (int)(y-(fontSize-2)/2));
texts.add(ticklbl);
}
}

} else {
/*
*
* TODO
*
*
*/
}
}

// initialize renderables
glyph2points.values().forEach(p->{
Expand All @@ -270,6 +440,10 @@ public void updateGL() {
t.initGL();
delegate.addItemToRender(t);
});
triangles.forEach(t->{
t.initGL();
delegate.addItemToRender(t);
});
isDirty = false;
}

Expand All @@ -293,6 +467,11 @@ protected void clearGL() {
l.close();
});
pattern2lines.clear();
triangles.forEach(t->{
t.close();
delegate.triangles.removeItemToRender(t);
});
triangles.clear();
texts.forEach(t->{
delegate.text.removeItemToRender(t);
t.close();
Expand Down
33 changes: 33 additions & 0 deletions jplotter/src/main/java/hageldave/jplotter/util/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

import hageldave.imagingkit.core.Img;
import hageldave.imagingkit.core.Pixel;
import hageldave.jplotter.color.ColorMap;
import hageldave.jplotter.renderables.Triangles;

/**
* Class containing utility methods
Expand Down Expand Up @@ -281,4 +283,35 @@ public static BufferedImage remoteRGBImage(Img img) {
BufferedImage bimg = new BufferedImage(cm, raster, false, null);
return bimg;
}

public static Triangles colormap2Tris(ColorMap cmap, boolean vertical){
Triangles tris = new Triangles();
for(int i=0; i<cmap.numColors()-1;i++){
int c1 = cmap.getColor(i);
int c2 = cmap.getColor(i+1);
double d1 = cmap.getLocation(i);
double d2 = cmap.getLocation(i+1);
if(vertical){
tris.addTriangle(0, d1, 1, d1, 0, d2)
.setColor0(c1).setColor1(c1).setColor2(c2);
tris.addTriangle(1, d2, 1, d1, 0, d2)
.setColor0(c2).setColor1(c1).setColor2(c2);
} else {
tris.addTriangle(d1, 0, d1, 1, d2, 0)
.setColor0(c1).setColor1(c1).setColor2(c2);
tris.addTriangle(d2, 1, d1, 1, d2, 0)
.setColor0(c2).setColor1(c1).setColor2(c2);
}
}
return tris;
}




}





6 changes: 5 additions & 1 deletion jplotter/src/test/java/hageldave/jplotter/Viz.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import org.w3c.dom.Document;

import hageldave.jplotter.canvas.BlankCanvas;
import hageldave.jplotter.color.ColorMap;
import hageldave.jplotter.color.DefaultColorMap;
import hageldave.jplotter.interaction.CoordSysScrollZoom;
import hageldave.jplotter.interaction.CoordSysViewSelector;
import hageldave.jplotter.misc.DefaultGlyph;
Expand All @@ -36,6 +38,7 @@
import hageldave.jplotter.renderers.SplitScreenRenderer;
import hageldave.jplotter.renderers.TextRenderer;
import hageldave.jplotter.svg.SVGUtils;
import hageldave.jplotter.util.Utils;

public class Viz {

Expand Down Expand Up @@ -84,7 +87,7 @@ public static void main(String[] args) {
lines.setGlobalThicknessMultiplier(2);
lines.setGlobalAlphaMultiplier(0.8);
content.lines.addItemToRender(lines);
content.triangles.addItemToRender(tris);
content.triangles.addItemToRender(tris).addItemToRender(Utils.colormap2Tris(DefaultColorMap.D_COOL_WARM, false));

Points trianglepoints = new Points(DefaultGlyph.TRIANGLE_F);
Points quiver = new Points(DefaultGlyph.ARROW);
Expand All @@ -106,6 +109,7 @@ public static void main(String[] args) {
legend.addGlyphLabel(DefaultGlyph.ARROW, 0xff377eb8, "-(x,y)");
legend.addLineLabel(2, 0xffff00ff, 0xf790, "sin(x)", 0);
legend.addLineLabel(2, 0xff00ff00, "x=y");
legend.addColormapLabel("asdasd", DefaultColorMap.D_COOL_WARM, true, new double[]{0,0.5,1}, new String[]{"lo","mid","hi"});
coordsys.setLegendRight(legend);
coordsys.setLegendRightWidth(80);

Expand Down

0 comments on commit 1eb5b44

Please sign in to comment.