mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
support extend and extendfrac parameters in contourf function
This commit is contained in:
parent
11a1878633
commit
283b79a264
@ -69,7 +69,7 @@ public class ChartColorBar extends ChartLegend {
|
||||
this.tickColor = Color.black;
|
||||
this.drawMinLabel = false;
|
||||
this.drawMaxLabel = false;
|
||||
this.extendType = ExtendType.NEITHER;
|
||||
this.extendType = ls.getExtendType();
|
||||
this.drawMinorTick = false;
|
||||
this.minorTickNum = 5;
|
||||
this.setLegendScheme(ls);
|
||||
@ -525,6 +525,28 @@ public class ChartColorBar extends ChartLegend {
|
||||
}
|
||||
}
|
||||
|
||||
private PointD drawTickLine(Graphics2D g, double x, double y, float tickLen, boolean vertical, double shift) {
|
||||
if (vertical) {
|
||||
if (this.insideTick) {
|
||||
g.draw(new Line2D.Double(x + shift, y, x + shift, y - tickLen));
|
||||
} else {
|
||||
g.draw(new Line2D.Double(x + shift, y, x + shift, y + tickLen));
|
||||
y += tickLen;
|
||||
}
|
||||
y += 5;
|
||||
} else {
|
||||
if (this.insideTick) {
|
||||
g.draw(new Line2D.Double(x - tickLen, y + shift, x, y + shift));
|
||||
} else {
|
||||
g.draw(new Line2D.Double(x, y + shift, x + tickLen, y + shift));
|
||||
x += tickLen;
|
||||
}
|
||||
x += 5;
|
||||
}
|
||||
|
||||
return new PointD(x, y);
|
||||
}
|
||||
|
||||
private void drawHorizontal(Graphics2D g, LegendScheme ls) {
|
||||
PointF aP = new PointF(0, 0);
|
||||
PointF sP = new PointF(0, 0);
|
||||
@ -609,9 +631,6 @@ public class ChartColorBar extends ChartLegend {
|
||||
g.setStroke(new BasicStroke(this.neatLineSize));
|
||||
g.setColor(this.neatLineColor);
|
||||
switch (this.extendType) {
|
||||
case NEITHER:
|
||||
g.draw(new Rectangle.Double(0, y_shift, this.barWidth * bNum, this.barHeight));
|
||||
break;
|
||||
case BOTH:
|
||||
Path2D p = new Path2D.Float();
|
||||
p.moveTo(0, this.barHeight / 2 + y_shift);
|
||||
@ -645,6 +664,9 @@ public class ChartColorBar extends ChartLegend {
|
||||
p.closePath();
|
||||
g.draw(p);
|
||||
break;
|
||||
default:
|
||||
g.draw(new Rectangle.Double(0, y_shift, this.barWidth * bNum, this.barHeight));
|
||||
break;
|
||||
}
|
||||
|
||||
//Draw tick and label
|
||||
@ -738,15 +760,16 @@ public class ChartColorBar extends ChartLegend {
|
||||
|
||||
List<Integer> labelIdxs = new ArrayList<>();
|
||||
List<String> tLabels = new ArrayList<>();
|
||||
int tickGap = this.getTickGap(g);
|
||||
if (this.autoTick) {
|
||||
int tickGap = this.getTickGap(g);
|
||||
int sIdx = (bNum % tickGap) / 2;
|
||||
int labNum = bNum - 1;
|
||||
if (aLS.getLegendType() == LegendType.UNIQUE_VALUE) {
|
||||
labNum += 1;
|
||||
} else if (this.drawMinLabel) {
|
||||
sIdx = 0;
|
||||
labNum = bNum;
|
||||
int labNum = bNum;
|
||||
switch (extendType) {
|
||||
case NONE:
|
||||
case NEITHER:
|
||||
case MAX:
|
||||
sIdx = 0;
|
||||
break;
|
||||
}
|
||||
while (sIdx < labNum) {
|
||||
labelIdxs.add(sIdx);
|
||||
@ -770,7 +793,36 @@ public class ChartColorBar extends ChartLegend {
|
||||
}
|
||||
|
||||
this.barHeight = (float) this.legendWidth / this.aspect;
|
||||
barWidth = (float) this.legendWidth / bNum;
|
||||
int extendNum = 0;
|
||||
switch (extendType) {
|
||||
case BOTH:
|
||||
extendNum = 2;
|
||||
break;
|
||||
case MIN:
|
||||
case MAX:
|
||||
extendNum = 1;
|
||||
break;
|
||||
}
|
||||
float extendLength = 0;
|
||||
if (extendNum == 0) {
|
||||
barWidth = (float) this.legendWidth / bNum;
|
||||
} else {
|
||||
switch (extendFraction) {
|
||||
case NONE:
|
||||
extendLength = this.legendWidth * 0.05f;
|
||||
barWidth = (this.legendWidth - extendLength * extendNum) / (bNum - extendNum);
|
||||
break;
|
||||
case AUTO:
|
||||
barWidth = (float) this.legendWidth / bNum;
|
||||
extendLength = barWidth;
|
||||
break;
|
||||
case LENGTH:
|
||||
barWidth = this.legendWidth / (bNum + (extendFraction.fraction - 1) * extendNum);
|
||||
extendLength = barWidth * extendFraction.fraction;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float y_shift = 0;
|
||||
if (this.label != null){
|
||||
switch (this.labelLocation){
|
||||
@ -821,59 +873,72 @@ public class ChartColorBar extends ChartLegend {
|
||||
barHeight, DrawFill, DrawOutline, g);
|
||||
}
|
||||
} else {
|
||||
double extendw = barWidth;
|
||||
if (this.autoExtendFrac) {
|
||||
extendw = barHeight;
|
||||
}
|
||||
if (i == 0) {
|
||||
PointD[] Points = new PointD[4];
|
||||
Points[0] = new PointD();
|
||||
Points[0].X = barWidth - extendw;
|
||||
Points[0].Y = aP.Y + barHeight * 0.5;
|
||||
Points[1] = new PointD();
|
||||
Points[1].X = barWidth;
|
||||
Points[1].Y = aP.Y;
|
||||
Points[2] = new PointD();
|
||||
Points[2].X = barWidth;
|
||||
Points[2].Y = aP.Y + barHeight;
|
||||
Points[3] = new PointD();
|
||||
Points[3].X = barWidth - extendw;
|
||||
Points[3].Y = aP.Y + barHeight * 0.5;
|
||||
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
|
||||
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
|
||||
aPGB.setDrawOutline(false);
|
||||
Draw.drawPolygon(Points, aPGB, g);
|
||||
} else {
|
||||
Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
|
||||
switch (this.extendType) {
|
||||
case BOTH:
|
||||
case MIN:
|
||||
PointD[] Points = new PointD[4];
|
||||
Points[0] = new PointD(0, aP.Y + barHeight * 0.5);
|
||||
Points[1] = new PointD(extendLength, aP.Y);
|
||||
Points[2] = new PointD(extendLength, aP.Y + barHeight);
|
||||
Points[3] = new PointD(0, aP.Y + barHeight * 0.5);
|
||||
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
|
||||
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
|
||||
aPGB.setDrawOutline(false);
|
||||
Draw.drawPolygon(Points, aPGB, g);
|
||||
} else {
|
||||
Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
|
||||
}
|
||||
aP.X += extendLength - barWidth;
|
||||
break;
|
||||
default:
|
||||
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
|
||||
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
|
||||
aPGB.setDrawOutline(false);
|
||||
Draw.drawPolygonSymbol(aP.X, aP.Y, barWidth, barHeight, aPGB, g);
|
||||
} else {
|
||||
Draw.drawPolygonSymbol(aP.X, aP.Y, FillColor, OutlineColor, barWidth,
|
||||
barHeight, DrawFill, DrawOutline, g);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (i == bNum - 1) {
|
||||
PointD[] Points = new PointD[4];
|
||||
Points[0] = new PointD();
|
||||
Points[0].X = i * barWidth - 1.0f;
|
||||
Points[0].Y = aP.Y + barHeight;
|
||||
Points[1] = new PointD();
|
||||
Points[1].X = i * barWidth - 1.0f;
|
||||
Points[1].Y = aP.Y;
|
||||
Points[2] = new PointD();
|
||||
Points[2].X = i * barWidth + extendw;
|
||||
Points[2].Y = aP.Y + barHeight * 0.5;
|
||||
Points[3] = new PointD();
|
||||
Points[3].X = i * barWidth - 1.0f;
|
||||
Points[3].Y = aP.Y + barHeight;
|
||||
switch (this.extendType) {
|
||||
case BOTH:
|
||||
case MAX:
|
||||
PointD[] Points = new PointD[4];
|
||||
Points[0] = new PointD(legendWidth - extendLength, aP.Y + barHeight);
|
||||
Points[1] = new PointD(legendWidth - extendLength, aP.Y);
|
||||
Points[2] = new PointD(legendWidth, aP.Y + barHeight * 0.5);
|
||||
Points[3] = new PointD(legendWidth - extendLength, aP.Y + barHeight);
|
||||
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
|
||||
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
|
||||
aPGB.setDrawOutline(false);
|
||||
Draw.drawPolygon(Points, aPGB, g);
|
||||
} else {
|
||||
Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
|
||||
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
|
||||
aPGB.setDrawOutline(false);
|
||||
Draw.drawPolygonSymbol(aP.X, aP.Y, barWidth, barHeight, aPGB, g);
|
||||
} else {
|
||||
Draw.drawPolygonSymbol(aP.X, aP.Y, FillColor, OutlineColor, barWidth,
|
||||
barHeight, DrawFill, DrawOutline, g);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
|
||||
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
|
||||
aPGB.setDrawOutline(false);
|
||||
Draw.drawPolygon(Points, aPGB, g);
|
||||
Draw.drawPolygonSymbol(aP.X, aP.Y, barWidth, barHeight, aPGB, g);
|
||||
} else {
|
||||
Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
|
||||
Draw.drawPolygonSymbol(aP.X, aP.Y, FillColor, OutlineColor, barWidth,
|
||||
barHeight, DrawFill, DrawOutline, g);
|
||||
}
|
||||
} else if (aLS.getShapeType() == ShapeTypes.POLYGON) {
|
||||
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
|
||||
aPGB.setDrawOutline(false);
|
||||
Draw.drawPolygonSymbol(aP.X, aP.Y, barWidth, barHeight, aPGB, g);
|
||||
} else {
|
||||
Draw.drawPolygonSymbol(aP.X, aP.Y, FillColor, OutlineColor, barWidth,
|
||||
barHeight, DrawFill, DrawOutline, g);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -885,22 +950,50 @@ public class ChartColorBar extends ChartLegend {
|
||||
if (this.extendRect) {
|
||||
g.draw(new Rectangle.Double(0, y_shift, this.barWidth * bNum, this.barHeight));
|
||||
} else {
|
||||
double extendw = barWidth;
|
||||
if (this.autoExtendFrac) {
|
||||
extendw = barHeight;
|
||||
switch (this.extendType) {
|
||||
case BOTH:
|
||||
Path2D p = new Path2D.Double();
|
||||
p.moveTo(0, this.barHeight / 2 + y_shift);
|
||||
p.lineTo(extendLength, y_shift);
|
||||
p.lineTo(this.barWidth * (bNum - 2) + extendLength, y_shift);
|
||||
p.lineTo(this.barWidth * (bNum - 2) + extendLength * 2, this.barHeight / 2 + y_shift);
|
||||
p.lineTo(this.barWidth * (bNum - 2) + extendLength, this.barHeight + y_shift);
|
||||
p.lineTo(extendLength, this.barHeight + y_shift);
|
||||
p.closePath();
|
||||
g.draw(p);
|
||||
break;
|
||||
case MAX:
|
||||
p = new Path2D.Double();
|
||||
p.moveTo(0, y_shift);
|
||||
p.lineTo(this.barWidth * (bNum - 1), y_shift);
|
||||
p.lineTo(this.barWidth * (bNum - 1) + extendLength, this.barHeight / 2 + y_shift);
|
||||
p.lineTo(this.barWidth * (bNum - 1), this.barHeight + y_shift);
|
||||
p.lineTo(0, this.barHeight + y_shift);
|
||||
p.closePath();
|
||||
g.draw(p);
|
||||
break;
|
||||
case MIN:
|
||||
p = new Path2D.Double();
|
||||
p.moveTo(0, this.barHeight / 2 + y_shift);
|
||||
p.lineTo(extendLength, y_shift);
|
||||
p.lineTo(this.barWidth * (bNum - 1) + extendLength, y_shift);
|
||||
p.lineTo(this.barWidth * (bNum - 1) + extendLength, this.barHeight + y_shift);
|
||||
p.lineTo(extendLength, this.barHeight + y_shift);
|
||||
p.closePath();
|
||||
g.draw(p);
|
||||
break;
|
||||
default:
|
||||
g.draw(new Rectangle.Double(0, y_shift, this.barWidth * bNum, this.barHeight));
|
||||
break;
|
||||
}
|
||||
Path2D p = new Path2D.Double();
|
||||
p.moveTo(barWidth - extendw, this.barHeight / 2 + y_shift);
|
||||
p.lineTo(this.barWidth, y_shift);
|
||||
p.lineTo(this.barWidth * (bNum - 1), y_shift);
|
||||
p.lineTo(this.barWidth * (bNum - 1) + extendw, this.barHeight / 2 + y_shift);
|
||||
p.lineTo(this.barWidth * (bNum - 1), this.barHeight + y_shift);
|
||||
p.lineTo(this.barWidth, this.barHeight + y_shift);
|
||||
p.closePath();
|
||||
g.draw(p);
|
||||
}
|
||||
//Draw tick and label
|
||||
aP.X = -barWidth / 2;
|
||||
sP.X = 0;
|
||||
if (aLS.getLegendType() == LegendType.UNIQUE_VALUE) {
|
||||
sP.Y = barHeight + y_shift + 5;
|
||||
} else {
|
||||
sP.Y = barHeight + y_shift;
|
||||
}
|
||||
float tickLen = this.tickLength;
|
||||
if (this.insideTick) {
|
||||
if (this.barHeight < tickLen) {
|
||||
@ -912,8 +1005,7 @@ public class ChartColorBar extends ChartLegend {
|
||||
g.setColor(this.tickColor);
|
||||
idx = 0;
|
||||
for (int i = 0; i < bNum; i++) {
|
||||
aP.X += barWidth;
|
||||
aP.Y = barHeight / 2 + y_shift;
|
||||
sP.X += barWidth;
|
||||
if (labelIdxs.contains(i)) {
|
||||
ColorBreak cb = aLS.getLegendBreaks().get(i);
|
||||
if (this.autoTick) {
|
||||
@ -927,8 +1019,7 @@ public class ChartColorBar extends ChartLegend {
|
||||
}
|
||||
|
||||
if (aLS.getLegendType() == LegendType.UNIQUE_VALUE) {
|
||||
sP.X = aP.X;
|
||||
sP.Y = aP.Y + barHeight / 2 + 5;
|
||||
sP.X -= barWidth / 2;
|
||||
g.setColor(this.tickLabelColor);
|
||||
if (this.tickLabelAngle == 0) {
|
||||
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
|
||||
@ -938,70 +1029,87 @@ public class ChartColorBar extends ChartLegend {
|
||||
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
}
|
||||
} else {
|
||||
sP.X = aP.X + barWidth / 2;
|
||||
sP.Y = aP.Y + barHeight / 2;
|
||||
PointD ssP = (PointD)sP.clone();
|
||||
if (i == 0) {
|
||||
switch (extendType) {
|
||||
case BOTH:
|
||||
case MIN:
|
||||
sP.X = sP.X - barWidth + extendLength;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (this.autoTick) {
|
||||
if (i < bNum - 1) {
|
||||
g.setColor(this.tickColor);
|
||||
this.drawTickLine(g, sP, tickLen, true, 0);
|
||||
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, true, 0);
|
||||
g.setColor(this.tickLabelColor);
|
||||
if (this.tickLabelAngle == 0) {
|
||||
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
|
||||
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
|
||||
} else if (this.tickLabelAngle < 45) {
|
||||
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
|
||||
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
|
||||
} else {
|
||||
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
}
|
||||
if (this.drawMinLabel && i == 0) {
|
||||
g.setColor(this.tickColor);
|
||||
this.drawTickLine(g, ssP, tickLen, true, -this.barWidth);
|
||||
caption = DataConvert.removeTailingZeros(cb.getStartValue().toString());
|
||||
g.setColor(this.tickLabelColor);
|
||||
//Draw.drawString(g, ssP.X - this.barWidth, ssP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
|
||||
if (this.tickLabelAngle == 0) {
|
||||
Draw.drawString(g, ssP.X - this.barWidth, ssP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
|
||||
} else if (this.tickLabelAngle < 45) {
|
||||
Draw.drawString(g, ssP.X - this.barWidth, ssP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
|
||||
} else {
|
||||
Draw.drawString(g, ssP.X - this.barWidth, ssP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
if (i == 0) {
|
||||
switch (this.extendType) {
|
||||
case NEITHER:
|
||||
case MAX:
|
||||
if (tickGap == 1) {
|
||||
g.setColor(this.tickColor);
|
||||
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, true, -this.barWidth);
|
||||
caption = DataConvert.removeTailingZeros(cb.getStartValue().toString());
|
||||
g.setColor(this.tickLabelColor);
|
||||
//Draw.drawString(g, ssP.X - this.barWidth, ssP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
|
||||
if (this.tickLabelAngle == 0) {
|
||||
Draw.drawString(g, aP.X - this.barWidth, aP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
|
||||
} else if (this.tickLabelAngle < 45) {
|
||||
Draw.drawString(g, aP.X - this.barWidth, aP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
|
||||
} else {
|
||||
Draw.drawString(g, aP.X - this.barWidth, aP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (this.drawMaxLabel) {
|
||||
g.setColor(this.tickColor);
|
||||
this.drawTickLine(g, sP, tickLen, true, 0);
|
||||
g.setColor(this.tickLabelColor);
|
||||
if (this.tickLabelAngle == 0) {
|
||||
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
|
||||
} else if (this.tickLabelAngle < 45) {
|
||||
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
|
||||
} else {
|
||||
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
} else {
|
||||
switch (this.extendType) {
|
||||
case NEITHER:
|
||||
case MIN:
|
||||
g.setColor(this.tickColor);
|
||||
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, true, 0);
|
||||
g.setColor(this.tickLabelColor);
|
||||
if (this.tickLabelAngle == 0) {
|
||||
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
|
||||
} else if (this.tickLabelAngle < 45) {
|
||||
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
|
||||
} else {
|
||||
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (i == 0 && this.tickLocations.get(idx) == Double.parseDouble(cb.getStartValue().toString())) {
|
||||
g.setColor(this.tickColor);
|
||||
this.drawTickLine(g, sP, tickLen, true, -this.barWidth);
|
||||
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, true, -this.barWidth);
|
||||
g.setColor(this.tickLabelColor);
|
||||
//Draw.drawString(g, sP.X - this.barWidth, sP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
|
||||
if (this.tickLabelAngle == 0) {
|
||||
Draw.drawString(g, sP.X - this.barWidth, sP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
|
||||
Draw.drawString(g, aP.X - this.barWidth, aP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
|
||||
} else if (this.tickLabelAngle < 45) {
|
||||
Draw.drawString(g, sP.X - this.barWidth, sP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
|
||||
Draw.drawString(g, aP.X - this.barWidth, aP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
|
||||
} else {
|
||||
Draw.drawString(g, sP.X - this.barWidth, sP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
Draw.drawString(g, aP.X - this.barWidth, aP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
}
|
||||
} else {
|
||||
g.setColor(this.tickColor);
|
||||
this.drawTickLine(g, sP, tickLen, true, 0);
|
||||
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, true, 0);
|
||||
g.setColor(this.tickLabelColor);
|
||||
if (this.tickLabelAngle == 0) {
|
||||
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
|
||||
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
|
||||
} else if (this.tickLabelAngle < 45) {
|
||||
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
|
||||
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
|
||||
} else {
|
||||
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1126,9 +1234,6 @@ public class ChartColorBar extends ChartLegend {
|
||||
g.setStroke(new BasicStroke(this.neatLineSize));
|
||||
g.setColor(this.neatLineColor);
|
||||
switch (this.extendType) {
|
||||
case NEITHER:
|
||||
g.draw(new Rectangle.Double(x_shift, 0, this.barWidth, this.legendHeight));
|
||||
break;
|
||||
case BOTH:
|
||||
Path2D p = new Path2D.Double();
|
||||
p.moveTo(this.barWidth / 2 + x_shift, 0);
|
||||
@ -1162,6 +1267,9 @@ public class ChartColorBar extends ChartLegend {
|
||||
p.closePath();
|
||||
g.draw(p);
|
||||
break;
|
||||
default:
|
||||
g.draw(new Rectangle.Double(x_shift, 0, this.barWidth, this.legendHeight));
|
||||
break;
|
||||
}
|
||||
|
||||
//Draw tick and label
|
||||
@ -1250,15 +1358,16 @@ public class ChartColorBar extends ChartLegend {
|
||||
|
||||
List<Integer> labelIdxs = new ArrayList<>();
|
||||
List<String> tLabels = new ArrayList<>();
|
||||
int tickGap = this.getTickGap(g);
|
||||
if (this.autoTick) {
|
||||
int tickGap = this.getTickGap(g);
|
||||
int sIdx = (bNum % tickGap) / 2;
|
||||
int labNum = bNum - 1;
|
||||
if (aLS.getLegendType() == LegendType.UNIQUE_VALUE) {
|
||||
labNum += 1;
|
||||
} else if (this.drawMinLabel) {
|
||||
sIdx = 0;
|
||||
labNum = bNum;
|
||||
int labNum = bNum;
|
||||
switch (extendType) {
|
||||
case NONE:
|
||||
case NEITHER:
|
||||
case MAX:
|
||||
sIdx = 0;
|
||||
break;
|
||||
}
|
||||
while (sIdx < labNum) {
|
||||
labelIdxs.add(sIdx);
|
||||
@ -1290,7 +1399,36 @@ public class ChartColorBar extends ChartLegend {
|
||||
}
|
||||
|
||||
this.barWidth = (float) this.legendHeight / this.aspect;
|
||||
barHeight = (float) this.legendHeight / bNum;
|
||||
int extendNum = 0;
|
||||
switch (extendType) {
|
||||
case BOTH:
|
||||
extendNum = 2;
|
||||
break;
|
||||
case MIN:
|
||||
case MAX:
|
||||
extendNum = 1;
|
||||
break;
|
||||
}
|
||||
float extendLength = 0;
|
||||
if (extendNum == 0) {
|
||||
barHeight = (float) this.legendHeight / bNum;
|
||||
} else {
|
||||
switch (extendFraction) {
|
||||
case NONE:
|
||||
extendLength = this.legendHeight * 0.05f;
|
||||
barHeight = (this.legendHeight - extendLength * extendNum) / (bNum - extendNum);
|
||||
break;
|
||||
case AUTO:
|
||||
barHeight = (float) this.legendHeight / bNum;
|
||||
extendLength = barHeight;
|
||||
break;
|
||||
case LENGTH:
|
||||
barHeight = this.legendHeight / (bNum + (extendFraction.fraction - 1) * extendNum);
|
||||
extendLength = barHeight * extendFraction.fraction;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
aP.Y = this.legendHeight;
|
||||
float x_shift = 0;
|
||||
if (this.label != null){
|
||||
@ -1330,11 +1468,10 @@ public class ChartColorBar extends ChartLegend {
|
||||
FillColor = aCB.getColor();
|
||||
break;
|
||||
}
|
||||
|
||||
aP.Y = aP.Y - barHeight;
|
||||
|
||||
if (DrawShape) {
|
||||
if (this.extendRect) {
|
||||
aP.Y = aP.Y - barHeight;
|
||||
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
|
||||
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
|
||||
aPGB.setDrawOutline(false);
|
||||
@ -1343,55 +1480,77 @@ public class ChartColorBar extends ChartLegend {
|
||||
Draw.drawPolygonSymbol(aP.X, aP.Y, FillColor, OutlineColor, barWidth,
|
||||
barHeight, DrawFill, DrawOutline, g);
|
||||
}
|
||||
} else if (i == 0) {
|
||||
PointD[] Points = new PointD[4];
|
||||
Points[0] = new PointD();
|
||||
Points[0].X = aP.X + barWidth * 0.5;
|
||||
Points[0].Y = this.legendHeight;
|
||||
Points[1] = new PointD();
|
||||
Points[1].X = aP.X;
|
||||
Points[1].Y = aP.Y;
|
||||
Points[2] = new PointD();
|
||||
Points[2].X = aP.X + barWidth;
|
||||
Points[2].Y = aP.Y;
|
||||
Points[3] = new PointD();
|
||||
Points[3].X = aP.X + barWidth * 0.5;
|
||||
Points[3].Y = this.legendHeight;
|
||||
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
|
||||
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
|
||||
aPGB.setDrawOutline(false);
|
||||
Draw.drawPolygon(Points, aPGB, g);
|
||||
} else {
|
||||
Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
|
||||
}
|
||||
} else if (i == bNum - 1) {
|
||||
PointD[] Points = new PointD[4];
|
||||
Points[0] = new PointD();
|
||||
Points[0].X = aP.X;
|
||||
Points[0].Y = barHeight;
|
||||
Points[1] = new PointD();
|
||||
Points[1].X = aP.X + barWidth;
|
||||
Points[1].Y = barHeight;
|
||||
Points[2] = new PointD();
|
||||
Points[2].X = aP.X + barWidth * 0.5;
|
||||
Points[2].Y = 0;
|
||||
Points[3] = new PointD();
|
||||
Points[3].X = aP.X;
|
||||
Points[3].Y = barHeight;
|
||||
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
|
||||
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
|
||||
aPGB.setDrawOutline(false);
|
||||
Draw.drawPolygon(Points, aPGB, g);
|
||||
} else {
|
||||
Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
|
||||
}
|
||||
} else if (aLS.getShapeType() == ShapeTypes.POLYGON) {
|
||||
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
|
||||
aPGB.setDrawOutline(false);
|
||||
Draw.drawPolygonSymbol(aP.X, aP.Y, barWidth, barHeight, aPGB, g);
|
||||
} else {
|
||||
Draw.drawPolygonSymbol(aP.X, aP.Y, FillColor, OutlineColor, barWidth,
|
||||
barHeight, DrawFill, DrawOutline, g);
|
||||
if (i == 0) {
|
||||
switch (this.extendType) {
|
||||
case BOTH:
|
||||
case MIN:
|
||||
aP.Y = aP.Y - extendLength;
|
||||
PointD[] Points = new PointD[4];
|
||||
Points[0] = new PointD(aP.X + barWidth * 0.5, this.legendHeight);
|
||||
Points[1] = new PointD(aP.X, aP.Y);
|
||||
Points[2] = new PointD(aP.X + barWidth, aP.Y);
|
||||
Points[3] = new PointD(aP.X + barWidth * 0.5, this.legendHeight);
|
||||
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
|
||||
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
|
||||
aPGB.setDrawOutline(false);
|
||||
Draw.drawPolygon(Points, aPGB, g);
|
||||
} else {
|
||||
Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
aP.Y = aP.Y - barHeight;
|
||||
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
|
||||
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
|
||||
aPGB.setDrawOutline(false);
|
||||
Draw.drawPolygonSymbol(aP.X, aP.Y, barWidth, barHeight, aPGB, g);
|
||||
} else {
|
||||
Draw.drawPolygonSymbol(aP.X, aP.Y, FillColor, OutlineColor, barWidth,
|
||||
barHeight, DrawFill, DrawOutline, g);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (i == bNum - 1) {
|
||||
aP.Y = aP.Y - barHeight;
|
||||
switch (this.extendType) {
|
||||
case BOTH:
|
||||
case MAX:
|
||||
PointD[] Points = new PointD[4];
|
||||
Points[0] = new PointD(aP.X, extendLength);
|
||||
Points[1] = new PointD(aP.X + barWidth, extendLength);
|
||||
Points[2] = new PointD(aP.X + barWidth * 0.5, 0);
|
||||
Points[3] = new PointD(aP.X, extendLength);
|
||||
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
|
||||
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
|
||||
aPGB.setDrawOutline(false);
|
||||
Draw.drawPolygon(Points, aPGB, g);
|
||||
} else {
|
||||
Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
|
||||
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
|
||||
aPGB.setDrawOutline(false);
|
||||
Draw.drawPolygonSymbol(aP.X, aP.Y, barWidth, barHeight, aPGB, g);
|
||||
} else {
|
||||
Draw.drawPolygonSymbol(aP.X, aP.Y, FillColor, OutlineColor, barWidth,
|
||||
barHeight, DrawFill, DrawOutline, g);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
aP.Y = aP.Y - barHeight;
|
||||
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
|
||||
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
|
||||
aPGB.setDrawOutline(false);
|
||||
Draw.drawPolygonSymbol(aP.X, aP.Y, barWidth, barHeight, aPGB, g);
|
||||
} else {
|
||||
Draw.drawPolygonSymbol(aP.X, aP.Y, FillColor, OutlineColor, barWidth,
|
||||
barHeight, DrawFill, DrawOutline, g);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1401,19 +1560,54 @@ public class ChartColorBar extends ChartLegend {
|
||||
if (this.extendRect) {
|
||||
g.draw(new Rectangle.Double(x_shift, 0, this.barWidth, this.barHeight * bNum));
|
||||
} else {
|
||||
Path2D p = new Path2D.Double();
|
||||
p.moveTo(this.barWidth / 2 + x_shift, 0);
|
||||
p.lineTo(x_shift, this.barHeight);
|
||||
p.lineTo(x_shift, (this.barHeight * (bNum - 1)));
|
||||
p.lineTo(this.barWidth / 2 + x_shift, this.barHeight * bNum);
|
||||
p.lineTo(this.barWidth + x_shift, this.barHeight * (bNum - 1));
|
||||
p.lineTo(this.barWidth + x_shift, this.barHeight);
|
||||
p.closePath();
|
||||
g.draw(p);
|
||||
switch (this.extendType) {
|
||||
case BOTH:
|
||||
Path2D p = new Path2D.Double();
|
||||
p.moveTo(this.barWidth / 2 + x_shift, 0);
|
||||
p.lineTo(x_shift, extendLength);
|
||||
p.lineTo(x_shift, extendLength + this.barHeight * (bNum - 2));
|
||||
p.lineTo(this.barWidth / 2 + x_shift, this.legendHeight);
|
||||
p.lineTo(this.barWidth + x_shift, extendLength + this.barHeight * (bNum - 2));
|
||||
p.lineTo(this.barWidth + x_shift, extendLength);
|
||||
p.closePath();
|
||||
g.draw(p);
|
||||
break;
|
||||
case MAX:
|
||||
p = new Path2D.Double();
|
||||
p.moveTo(this.barWidth / 2 + x_shift, 0);
|
||||
p.lineTo(x_shift, extendLength);
|
||||
p.lineTo(x_shift, this.legendHeight);
|
||||
p.lineTo(this.barWidth + x_shift, this.legendHeight);
|
||||
p.lineTo(this.barWidth + x_shift, extendLength);
|
||||
p.closePath();
|
||||
g.draw(p);
|
||||
break;
|
||||
case MIN:
|
||||
p = new Path2D.Double();
|
||||
p.moveTo(x_shift, 0);
|
||||
p.lineTo(x_shift, this.barHeight * (bNum - 1));
|
||||
p.lineTo(this.barWidth / 2 + x_shift, this.barHeight * (bNum - 1) + extendLength);
|
||||
p.lineTo(this.barWidth + x_shift, this.barHeight * (bNum - 1));
|
||||
p.lineTo(this.barWidth + x_shift, 0);
|
||||
p.closePath();
|
||||
g.draw(p);
|
||||
break;
|
||||
default:
|
||||
g.draw(new Rectangle.Double(x_shift, 0, this.barWidth, this.barHeight * bNum));
|
||||
break;
|
||||
}
|
||||
}
|
||||
//Draw ticks
|
||||
g.setStroke(new BasicStroke(this.tickWidth));
|
||||
aP.Y = this.legendHeight + barHeight / 2;
|
||||
aP.X = barWidth / 2 + x_shift;
|
||||
if (aLS.getLegendType() == LegendType.UNIQUE_VALUE) {
|
||||
aP.Y = this.legendHeight - barHeight / 2;
|
||||
sP.X = aP.X + barWidth / 2 + 5;
|
||||
} else {
|
||||
aP.Y = this.legendHeight;
|
||||
sP.X = aP.X + barWidth / 2;
|
||||
}
|
||||
sP.Y = aP.Y;
|
||||
float tickLen = this.tickLength;
|
||||
if (this.insideTick) {
|
||||
if (this.barWidth < tickLen) {
|
||||
@ -1423,8 +1617,7 @@ public class ChartColorBar extends ChartLegend {
|
||||
g.setFont(tickLabelFont);
|
||||
idx = 0;
|
||||
for (int i = 0; i < bNum; i++) {
|
||||
aP.X = barWidth / 2 + x_shift;
|
||||
aP.Y = aP.Y - barHeight;
|
||||
sP.Y -= this.barHeight;
|
||||
if (labelIdxs.contains(i)) {
|
||||
ColorBreak cb = aLS.getLegendBreaks().get(i);
|
||||
if (this.autoTick) {
|
||||
@ -1438,44 +1631,59 @@ public class ChartColorBar extends ChartLegend {
|
||||
}
|
||||
|
||||
if (aLS.getLegendType() == LegendType.UNIQUE_VALUE) {
|
||||
sP.X = aP.X + barWidth / 2 + 5;
|
||||
sP.Y = aP.Y;
|
||||
g.setColor(this.tickLabelColor);
|
||||
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
} else {
|
||||
sP.X = aP.X + barWidth / 2;
|
||||
sP.Y = aP.Y - barHeight / 2;
|
||||
PointD ssP = (PointD)sP.clone();
|
||||
if (i == 0) {
|
||||
switch (extendType) {
|
||||
case BOTH:
|
||||
case MIN:
|
||||
sP.Y = aP.Y - extendLength;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (this.autoTick) {
|
||||
if (i < bNum - 1) {
|
||||
g.setColor(this.tickColor);
|
||||
this.drawTickLine(g, sP, tickLen, false, 0);
|
||||
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, false, 0);
|
||||
g.setColor(this.tickLabelColor);
|
||||
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
if (this.drawMinLabel && i == 0) {
|
||||
g.setColor(this.tickColor);
|
||||
this.drawTickLine(g, ssP, tickLen, false, this.barHeight);
|
||||
caption = DataConvert.removeTailingZeros(cb.getStartValue().toString());
|
||||
g.setColor(this.tickLabelColor);
|
||||
Draw.drawString(g, ssP.X, ssP.Y + this.barHeight, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
if (i == 0) {
|
||||
switch (this.extendType) {
|
||||
case NEITHER:
|
||||
case MAX:
|
||||
if (tickGap == 1) {
|
||||
g.setColor(this.tickColor);
|
||||
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, false, this.barHeight);
|
||||
caption = DataConvert.removeTailingZeros(cb.getStartValue().toString());
|
||||
g.setColor(this.tickLabelColor);
|
||||
Draw.drawString(g, aP.X, aP.Y + this.barHeight, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (this.extendType) {
|
||||
case NEITHER:
|
||||
case MIN:
|
||||
g.setColor(this.tickColor);
|
||||
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, false, 0);
|
||||
g.setColor(this.tickLabelColor);
|
||||
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
break;
|
||||
}
|
||||
} else if (this.drawMaxLabel) {
|
||||
g.setColor(this.tickColor);
|
||||
this.drawTickLine(g, sP, tickLen, false, 0);
|
||||
g.setColor(this.tickLabelColor);
|
||||
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
}
|
||||
} else {
|
||||
if (i == 0 && this.tickLocations.get(idx) == Double.parseDouble(cb.getStartValue().toString())) {
|
||||
g.setColor(this.tickColor);
|
||||
this.drawTickLine(g, sP, tickLen, false, this.barHeight);
|
||||
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, false, this.barHeight);
|
||||
g.setColor(this.tickLabelColor);
|
||||
Draw.drawString(g, sP.X, sP.Y + this.barHeight, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
Draw.drawString(g, aP.X, aP.Y + this.barHeight, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
} else {
|
||||
g.setColor(this.tickColor);
|
||||
this.drawTickLine(g, sP, tickLen, false, 0);
|
||||
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, false, 0);
|
||||
g.setColor(this.tickLabelColor);
|
||||
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,7 +71,7 @@ public class ChartLegend {
|
||||
private boolean autoRowColNum = true;
|
||||
private Dimension symbolDimension;
|
||||
protected boolean extendRect;
|
||||
protected boolean autoExtendFrac;
|
||||
protected ExtendFraction extendFraction;
|
||||
protected float xshift;
|
||||
protected float yshift;
|
||||
// </editor-fold>
|
||||
@ -107,8 +107,8 @@ public class ChartLegend {
|
||||
this.tickLabelColor = Color.black;
|
||||
this.tickLabelAngle = 0;
|
||||
this.symbolDimension = new Dimension(16, 10);
|
||||
this.extendRect = true;
|
||||
this.autoExtendFrac = false;
|
||||
this.extendRect = false;
|
||||
this.extendFraction = ls.getExtendFraction();
|
||||
this.xshift = 0;
|
||||
this.yshift = 0;
|
||||
}
|
||||
@ -699,23 +699,19 @@ public class ChartLegend {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if auto set extend fraction - extend has save width and height Only
|
||||
* valid for colorbar
|
||||
*
|
||||
* @return Boolean
|
||||
* Get extend fraction
|
||||
* @return Extend fraction
|
||||
*/
|
||||
public boolean isAutoExtendFrac() {
|
||||
return this.autoExtendFrac;
|
||||
public ExtendFraction getExtendFraction() {
|
||||
return this.extendFraction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if auto set extend fraction - extend has save width and height Only
|
||||
* valid for colorbar
|
||||
*
|
||||
* Set extend fraction
|
||||
* @param value
|
||||
*/
|
||||
public void setAutoExtendFrac(boolean value) {
|
||||
this.autoExtendFrac = value;
|
||||
public void setExtendFraction(ExtendFraction value) {
|
||||
this.extendFraction = value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -3341,6 +3341,112 @@ public class GraphicFactory {
|
||||
return new ImageGraphic(ishape, ls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create image
|
||||
*
|
||||
* @param data Grid data array
|
||||
* @param xa X coordinates array
|
||||
* @param ya Y coordinates array
|
||||
* @param ls Legend scheme
|
||||
* @param extent Extent
|
||||
* @return Image graphic
|
||||
*/
|
||||
public static Graphic createImage(Array data, Array xa, Array ya, LegendScheme ls, List<Number> extent) {
|
||||
int width, height, breakNum;
|
||||
width = (int) xa.getSize();
|
||||
height = (int) ya.getSize();
|
||||
BufferedImage aImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
if (ls.getColorMap() == null) {
|
||||
breakNum = ls.getValidBreakNum();
|
||||
double[] breakValue = new double[breakNum];
|
||||
Color[] breakColor = new Color[breakNum];
|
||||
Color undefColor = Color.white;
|
||||
int idx = 0;
|
||||
for (ColorBreak cb : ls.getLegendBreaks()) {
|
||||
if (cb.isNoData()) {
|
||||
undefColor = cb.getColor();
|
||||
} else {
|
||||
breakValue[idx] = Double.parseDouble(cb.getEndValue().toString());
|
||||
breakColor[idx] = cb.getColor();
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
Color defaultColor = breakColor[breakNum - 1]; //Last color
|
||||
double oneValue;
|
||||
Color oneColor;
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
oneValue = data.getDouble(i * width + j);
|
||||
if (Double.isNaN(oneValue)) {
|
||||
oneColor = undefColor;
|
||||
} else {
|
||||
oneColor = defaultColor;
|
||||
if (ls.getLegendType() == LegendType.GRADUATED_COLOR) {
|
||||
for (int k = 0; k < breakNum - 1; k++) {
|
||||
if (oneValue < breakValue[k]) {
|
||||
oneColor = breakColor[k];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int k = 0; k < breakNum - 1; k++) {
|
||||
if (oneValue == breakValue[k]) {
|
||||
oneColor = breakColor[k];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
aImage.setRGB(j, height - i - 1, oneColor.getRGB());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ColorMap colorMap = ls.getColorMap();
|
||||
int n = colorMap.getColorCount();
|
||||
Normalize normalize = ls.getNormalize();
|
||||
double v;
|
||||
Color fillColor = colorMap.getFillColor();
|
||||
Color color;
|
||||
int idx;
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
v = data.getDouble(i * width + j);
|
||||
if (Double.isNaN(v)) {
|
||||
color = fillColor;
|
||||
} else {
|
||||
idx = (int) (normalize.apply(v).floatValue() * n);
|
||||
if (idx < 0)
|
||||
idx = 0;
|
||||
else if (idx >= n)
|
||||
idx = n - 1;
|
||||
color = colorMap.getColor(idx);
|
||||
}
|
||||
aImage.setRGB(j, height - i - 1, color.getRGB());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImageShape ishape = new ImageShape();
|
||||
double xmin, xmax, ymin, ymax;
|
||||
if (extent == null) {
|
||||
double xdelta = BigDecimalUtil.mul(xa.getDouble(1) - xa.getDouble(0), 0.5);
|
||||
xmin = BigDecimalUtil.sub(xa.getDouble(0), xdelta);
|
||||
xmax = BigDecimalUtil.add(xa.getDouble(width - 1), xdelta);
|
||||
double ydelta = BigDecimalUtil.mul(ya.getDouble(1) - ya.getDouble(0), 0.5);
|
||||
ymin = BigDecimalUtil.sub(ya.getDouble(0), ydelta);
|
||||
ymax = BigDecimalUtil.add(ya.getDouble(height - 1), ydelta);
|
||||
} else {
|
||||
xmin = extent.get(0).doubleValue();
|
||||
xmax = extent.get(1).doubleValue();
|
||||
ymin = extent.get(2).doubleValue();
|
||||
ymax = extent.get(3).doubleValue();
|
||||
}
|
||||
ishape.setPoint(new PointD(xmin, ymin));
|
||||
ishape.setImage(aImage);
|
||||
ishape.setExtent(new Extent(xmin, xmax, ymin, ymax));
|
||||
return new ImageGraphic(ishape, ls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create image
|
||||
*
|
||||
|
||||
@ -893,16 +893,41 @@ public class MIMath {
|
||||
* @return Value array
|
||||
*/
|
||||
public static double[] getIntervalValues(double min, double max, double interval, int n) {
|
||||
double[] cValues;
|
||||
min = BigDecimalUtil.add(min, interval);
|
||||
double mod = BigDecimalUtil.mod(min, interval);
|
||||
min = BigDecimalUtil.sub(min, mod);
|
||||
return getIntervalValues(min, max, interval, n, false);
|
||||
}
|
||||
|
||||
cValues = new double[n];
|
||||
/**
|
||||
* Create values by interval
|
||||
*
|
||||
* @param min Minimum value
|
||||
* @param max Maximum value
|
||||
* @param interval Interval value
|
||||
* @param n Value number
|
||||
* @param isExtend Extend values or not
|
||||
* @return Value array
|
||||
*/
|
||||
public static double[] getIntervalValues(double min, double max, double interval, int n, boolean isExtend) {
|
||||
double minV = BigDecimalUtil.add(min, interval);
|
||||
double mod = BigDecimalUtil.mod(minV, interval);
|
||||
minV = BigDecimalUtil.sub(minV, mod);
|
||||
|
||||
List<Double> values = new ArrayList<>();
|
||||
for (int i = 0; i < n; i++) {
|
||||
cValues[i] = BigDecimalUtil.add(min, BigDecimalUtil.mul(i, interval));
|
||||
values.add(BigDecimalUtil.add(minV, BigDecimalUtil.mul(i, interval)));
|
||||
}
|
||||
|
||||
//Extend values
|
||||
if (isExtend) {
|
||||
if (values.get(0) > min) {
|
||||
values.add(0, BigDecimalUtil.sub(values.get(0), interval));
|
||||
}
|
||||
if (values.get(values.size() - 1) < max) {
|
||||
values.add(BigDecimalUtil.add(values.get(values.size() - 1), interval));
|
||||
}
|
||||
}
|
||||
|
||||
double[] cValues = values.stream().mapToDouble(Double::doubleValue).toArray();
|
||||
|
||||
return cValues;
|
||||
}
|
||||
|
||||
@ -915,6 +940,19 @@ public class MIMath {
|
||||
* @return Values
|
||||
*/
|
||||
public static double[] getIntervalValues(double min, double max, int n) {
|
||||
return getIntervalValues(min, max, n, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get interval values
|
||||
*
|
||||
* @param min Minimum value
|
||||
* @param max Maximum value
|
||||
* @param n Level number
|
||||
* @param isExtend Extend values or not
|
||||
* @return Values
|
||||
*/
|
||||
public static double[] getIntervalValues(double min, double max, int n, boolean isExtend) {
|
||||
int aD, aE;
|
||||
double range;
|
||||
String eStr;
|
||||
@ -939,7 +977,7 @@ public class MIMath {
|
||||
double bb = b.setScale(ln, RoundingMode.HALF_UP).doubleValue();
|
||||
double interval = BigDecimalUtil.mul(bb, Math.pow(10, aE));
|
||||
|
||||
return getIntervalValues(min, max, interval, n);
|
||||
return getIntervalValues(min, max, interval, n, isExtend);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1142,10 +1180,7 @@ public class MIMath {
|
||||
}
|
||||
}
|
||||
|
||||
double[] cValues = new double[values.size()];
|
||||
for (i = 0; i < values.size(); i++) {
|
||||
cValues[i] = values.get(i);
|
||||
}
|
||||
double[] cValues = values.stream().mapToDouble(Double::doubleValue).toArray();
|
||||
|
||||
r.add(cValues);
|
||||
r.add(cDelt);
|
||||
|
||||
@ -24,8 +24,10 @@ import org.meteoinfo.geo.drawing.ContourDraw;
|
||||
import org.meteoinfo.geo.drawing.Draw;
|
||||
import org.meteoinfo.geo.layer.*;
|
||||
import org.meteoinfo.geo.legend.LegendManage;
|
||||
import org.meteoinfo.geometry.colors.ExtendType;
|
||||
import org.meteoinfo.geometry.geoprocess.GeometryUtil;
|
||||
import org.meteoinfo.geometry.graphic.Graphic;
|
||||
import org.meteoinfo.geometry.graphic.GraphicCollection;
|
||||
import org.meteoinfo.geometry.legend.*;
|
||||
import org.meteoinfo.geometry.shape.*;
|
||||
import org.meteoinfo.geometry.geoprocess.GeoComputation;
|
||||
@ -33,6 +35,7 @@ import org.meteoinfo.math.meteo.MeteoMath;
|
||||
import org.meteoinfo.ndarray.Array;
|
||||
import org.meteoinfo.ndarray.DataType;
|
||||
import org.meteoinfo.ndarray.IndexIterator;
|
||||
import org.meteoinfo.ndarray.math.ArrayMath;
|
||||
import org.meteoinfo.ndarray.math.ArrayUtil;
|
||||
import org.meteoinfo.table.DataTable;
|
||||
import org.meteoinfo.table.Field;
|
||||
@ -871,6 +874,161 @@ public class DrawMeteoData {
|
||||
return createShadedLayer(gridData, ls, lName, fieldName, isSmooth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create shaded layer
|
||||
*
|
||||
* @param va Grid data array
|
||||
* @param xa X array
|
||||
* @param ya Y array
|
||||
* @param ls Legend scheme
|
||||
* @param lName Layer name
|
||||
* @param fieldName Field name
|
||||
* @param isSmooth If smooth the contour lines
|
||||
* @return Vector layer
|
||||
*/
|
||||
public static VectorLayer createShadedLayer(Array va, Array xa, Array ya, LegendScheme ls, String lName, String fieldName, boolean isSmooth) {
|
||||
double minData = ArrayMath.min(va).doubleValue();
|
||||
double maxData = ArrayMath.max(va).doubleValue();
|
||||
|
||||
ls = ls.convertTo(ShapeTypes.POLYGON);
|
||||
double[] cValues = ls.getValues(minData, maxData);
|
||||
int nv = cValues.length;
|
||||
|
||||
int[] shape = va.getShape();
|
||||
int[][] S1 = new int[shape[0]][shape[1]];
|
||||
double[] x = (double[])ArrayUtil.copyToNDJavaArray_Double(xa);
|
||||
double[] y = (double[])ArrayUtil.copyToNDJavaArray_Double(ya);
|
||||
if (x[1] - x[0] < 0) {
|
||||
ArrayUtils.reverse(x);
|
||||
va = va.flip(1);
|
||||
}
|
||||
if (y[1] - y[0] < 0) {
|
||||
ArrayUtils.reverse(y);
|
||||
va = va.flip(0);
|
||||
}
|
||||
double missingValue = -9999.0;
|
||||
double[][] data = (double[][]) ArrayUtil.copyToNDJavaArray_Double(va, missingValue);
|
||||
Object[] cbs = ContourDraw.tracingContourLines(data,
|
||||
cValues, x, y, missingValue, S1);
|
||||
List<PolyLine> contourLines = (List<PolyLine>) cbs[0];
|
||||
List<wcontour.global.Border> borders = (List<wcontour.global.Border>) cbs[1];
|
||||
|
||||
if (isSmooth) {
|
||||
contourLines = Contour.smoothLines(contourLines);
|
||||
}
|
||||
List<wcontour.global.Polygon> contourPolygons = ContourDraw.tracingPolygons(data, contourLines, borders, cValues);
|
||||
|
||||
//Create contour polygon layer
|
||||
VectorLayer layer = new VectorLayer(ShapeTypes.POLYGON);
|
||||
Field field = new Field(fieldName + "_Low", DataType.DOUBLE);
|
||||
layer.editAddField(field);
|
||||
field = new Field(fieldName + "_High", DataType.DOUBLE);
|
||||
layer.editAddField(field);
|
||||
|
||||
//Add polygon shape
|
||||
double v, min, max;
|
||||
ColorBreak cbb = ls.findLegendBreak(0);
|
||||
ExtendType extendType = ls.getExtendType();
|
||||
for (int i = 0; i < contourPolygons.size(); i++) {
|
||||
wcontour.global.Polygon poly = contourPolygons.get(i);
|
||||
v = poly.LowValue;
|
||||
int valueIdx = Arrays.binarySearch(cValues, v);
|
||||
if (valueIdx < 0) {
|
||||
valueIdx = -valueIdx;
|
||||
}
|
||||
if (valueIdx == nv - 1) {
|
||||
if (poly.IsHighCenter) {
|
||||
if (maxData > ls.getMaxValue()) {
|
||||
switch (extendType) {
|
||||
case NEITHER:
|
||||
case MIN:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
min = v;
|
||||
max = maxData;
|
||||
} else {
|
||||
max = v;
|
||||
min = cValues[valueIdx - 1];
|
||||
}
|
||||
} else if (valueIdx == 0){
|
||||
if (poly.IsHighCenter) {
|
||||
min = v;
|
||||
max = cValues[valueIdx + 1];
|
||||
} else {
|
||||
if (minData < ls.getMinValue()) {
|
||||
switch (extendType) {
|
||||
case NEITHER:
|
||||
case MAX:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
max = v;
|
||||
min = minData;
|
||||
}
|
||||
} else {
|
||||
if (poly.LowValue == poly.HighValue) {
|
||||
if (poly.IsHighCenter) {
|
||||
min = v;
|
||||
max = cValues[valueIdx + 1];
|
||||
} else {
|
||||
max = v;
|
||||
min = cValues[valueIdx - 1];
|
||||
}
|
||||
} else {
|
||||
min = v;
|
||||
max = poly.HighValue;
|
||||
}
|
||||
}
|
||||
|
||||
PointD aPoint;
|
||||
List<PointD> pList = new ArrayList<>();
|
||||
for (wcontour.global.PointD pointList : poly.OutLine.PointList) {
|
||||
aPoint = new PointD();
|
||||
aPoint.X = pointList.X;
|
||||
aPoint.Y = pointList.Y;
|
||||
pList.add(aPoint);
|
||||
}
|
||||
if (!GeoComputation.isClockwise(pList)) {
|
||||
Collections.reverse(pList);
|
||||
}
|
||||
PolygonShape aPolygonShape = new PolygonShape();
|
||||
aPolygonShape.setPoints(pList);
|
||||
aPolygonShape.setExtent(GeometryUtil.getPointsExtent(pList));
|
||||
aPolygonShape.lowValue = min;
|
||||
aPolygonShape.highValue = max;
|
||||
if (poly.HasHoles()) {
|
||||
for (PolyLine holeLine : poly.HoleLines) {
|
||||
pList = new ArrayList<>();
|
||||
for (wcontour.global.PointD pointList : holeLine.PointList) {
|
||||
aPoint = new PointD();
|
||||
aPoint.X = pointList.X;
|
||||
aPoint.Y = pointList.Y;
|
||||
pList.add(aPoint);
|
||||
}
|
||||
aPolygonShape.addHole(pList, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int shapeNum = layer.getShapeNum();
|
||||
try {
|
||||
if (layer.editInsertShape(aPolygonShape, shapeNum)) {
|
||||
layer.editCellValue(fieldName + "_Low", shapeNum, aPolygonShape.lowValue);
|
||||
layer.editCellValue(fieldName + "_High", shapeNum, aPolygonShape.highValue);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(DrawMeteoData.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
layer.setLayerName(lName);
|
||||
ls.setFieldName(fieldName + "_Low");
|
||||
layer.setLegendScheme(ls);
|
||||
layer.setLayerDrawType(LayerDrawType.SHADED);
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create shaded layer
|
||||
*
|
||||
@ -883,7 +1041,7 @@ public class DrawMeteoData {
|
||||
* @param isSmooth If smooth the contour lines
|
||||
* @return Vector layer
|
||||
*/
|
||||
public static VectorLayer createShadedLayer(Array data, Array x, Array y, LegendScheme aLS, String lName, String fieldName, boolean isSmooth) {
|
||||
public static VectorLayer createShadedLayer_bak(Array data, Array x, Array y, LegendScheme aLS, String lName, String fieldName, boolean isSmooth) {
|
||||
GridData gridData = new GridData(data, x, y);
|
||||
return createShadedLayer(gridData, aLS, lName, fieldName, isSmooth);
|
||||
}
|
||||
@ -934,8 +1092,6 @@ public class DrawMeteoData {
|
||||
}
|
||||
ContourPolygons = ContourDraw.tracingPolygons(gridData.getData(), ContourLines, borders, cValues);
|
||||
|
||||
//wContour.Global.Polygon aPolygon;
|
||||
//Color aColor;
|
||||
double aValue;
|
||||
int valueIdx;
|
||||
VectorLayer aLayer = new VectorLayer(ShapeTypes.POLYGON);
|
||||
@ -945,7 +1101,6 @@ public class DrawMeteoData {
|
||||
aLayer.editAddField(aDC);
|
||||
|
||||
for (Polygon aPolygon : ContourPolygons) {
|
||||
//aPolygon = ContourPolygon;
|
||||
aValue = aPolygon.LowValue;
|
||||
PointD aPoint;
|
||||
List<PointD> pList = new ArrayList<>();
|
||||
@ -981,22 +1136,11 @@ public class DrawMeteoData {
|
||||
if (valueIdx < 0) {
|
||||
valueIdx = -valueIdx - 1;
|
||||
}
|
||||
//valueIdx = Arrays.asList(cValues).indexOf(aValue);
|
||||
if (valueIdx >= cValues.length - 1) {
|
||||
aPolygonShape.highValue = maxData;
|
||||
} else {
|
||||
aPolygonShape.highValue = cValues[valueIdx + 1];
|
||||
}
|
||||
// if (!aPolygon.IsBorder) {
|
||||
// if (!aPolygon.IsHighCenter) {
|
||||
// aPolygonShape.highValue = aValue;
|
||||
// if (valueIdx == 0) {
|
||||
// aPolygonShape.lowValue = minData;
|
||||
// } else {
|
||||
// aPolygonShape.lowValue = cValues[valueIdx - 1];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if (!aPolygon.IsHighCenter && aPolygon.HighValue == aPolygon.LowValue) {
|
||||
aPolygonShape.highValue = aValue;
|
||||
if (valueIdx == 0) {
|
||||
@ -1020,9 +1164,6 @@ public class DrawMeteoData {
|
||||
ls.setFieldName(fieldName + "_Low");
|
||||
aLayer.setLegendScheme(ls);
|
||||
aLayer.setLayerDrawType(LayerDrawType.SHADED);
|
||||
// for (org.meteoinfo.legend.ColorBreak cb : aLayer.getLegendScheme().getLegendBreaks()){
|
||||
// System.out.println(cb.getColor().getAlpha());
|
||||
// }
|
||||
|
||||
return aLayer;
|
||||
}
|
||||
|
||||
@ -4,7 +4,8 @@ public enum ExtendType {
|
||||
NEITHER,
|
||||
BOTH,
|
||||
MIN,
|
||||
MAX;
|
||||
MAX,
|
||||
NONE;
|
||||
|
||||
/**
|
||||
* Get is extend max or not
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
package org.meteoinfo.geometry.legend;
|
||||
|
||||
public enum ExtendFraction {
|
||||
NONE,
|
||||
AUTO,
|
||||
LENGTH;
|
||||
|
||||
public float fraction = 1.0f;
|
||||
}
|
||||
@ -906,7 +906,7 @@ public class LegendManage {
|
||||
if (extendType.isExtendMin()) {
|
||||
ColorBreak cb = new ColorBreak();
|
||||
cb.setColor(colors[0]);
|
||||
cb.setStartValue(Double.MIN_VALUE);
|
||||
cb.setStartValue(-Double.MAX_VALUE);
|
||||
cb.setEndValue(values.getDouble(0));
|
||||
cb.setCaption("< " + DataConvert.removeTailingZeros(cb.getEndValue().toString()));
|
||||
legendScheme.addLegendBreak(0, cb);
|
||||
@ -1082,15 +1082,13 @@ public class LegendManage {
|
||||
* @param extend Extend min/max values or not
|
||||
* @return LegendScheme
|
||||
*/
|
||||
public static LegendScheme createLegendScheme(double min, double max, ColorMap ct, boolean extend) {
|
||||
double[] values = (double[]) MIMath.getIntervalValues(min, max, extend).get(0);
|
||||
if (extend) {
|
||||
Color[] colors = ct.getColors(values.length - 1);
|
||||
return createLegendScheme(values, colors);
|
||||
} else {
|
||||
Color[] colors = ct.getColors(values.length + 1);
|
||||
return createLegendScheme(min, max, values, colors, LegendType.GRADUATED_COLOR, ShapeTypes.IMAGE, false, -9999.0);
|
||||
}
|
||||
public static LegendScheme createLegendScheme(double min, double max, ColorMap ct, ExtendType extendType) {
|
||||
double[] values = (double[]) MIMath.getIntervalValues(min, max, true).get(0);
|
||||
Color[] colors = ct.getColors(values.length - 1);
|
||||
LegendScheme ls = createLegendScheme(values, colors);
|
||||
ls.setExtendType(extendType);
|
||||
|
||||
return ls;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1364,7 +1362,10 @@ public class LegendManage {
|
||||
* @return LegendScheme
|
||||
*/
|
||||
public static LegendScheme createLegendScheme(double min, double max, int n, ColorMap ct) {
|
||||
return createLegendScheme(min, max, n, ct, false);
|
||||
double[] values = MIMath.getIntervalValues(min, max, n);
|
||||
Color[] colors = ct.getColors(values.length + 1);
|
||||
|
||||
return createLegendScheme(min, max, values, colors, LegendType.GRADUATED_COLOR, ShapeTypes.IMAGE, false, -9999.0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1377,18 +1378,15 @@ public class LegendManage {
|
||||
* @param extend Extend min/max values or not
|
||||
* @return LegendScheme
|
||||
*/
|
||||
public static LegendScheme createLegendScheme(double min, double max, int n, ColorMap ct, boolean extend) {
|
||||
if (extend) {
|
||||
double[] values = MIMath.getIntervalValues(min, max, n);
|
||||
Color[] colors = ct.getColors(values.length - 1);
|
||||
public static LegendScheme createLegendScheme(double min, double max, int n, ColorMap ct,
|
||||
ExtendType extendType) {
|
||||
double[] values = MIMath.getIntervalValues(min, max, n, true);
|
||||
Color[] colors = ct.getColors(values.length - 1);
|
||||
|
||||
return createLegendScheme(values, colors);
|
||||
} else {
|
||||
double[] values = MIMath.getIntervalValues(min, max, n);
|
||||
Color[] colors = ct.getColors(values.length + 1);
|
||||
LegendScheme ls = createLegendScheme(values, colors);
|
||||
ls.setExtendType(extendType);
|
||||
|
||||
return createLegendScheme(min, max, values, colors, LegendType.GRADUATED_COLOR, ShapeTypes.IMAGE, false, -9999.0);
|
||||
}
|
||||
return ls;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -49,7 +49,8 @@ package org.meteoinfo.geometry.legend;
|
||||
private String fieldName = "";
|
||||
private LegendType legendType = LegendType.SINGLE_SYMBOL;
|
||||
private ShapeTypes shapeType;
|
||||
private ExtendType extendType = ExtendType.NEITHER;
|
||||
private ExtendType extendType = ExtendType.NONE;
|
||||
private ExtendFraction extendFraction = ExtendFraction.NONE;
|
||||
private List<ColorBreak> legendBreaks;
|
||||
private boolean hasNoData;
|
||||
private double minValue;
|
||||
@ -220,6 +221,22 @@ package org.meteoinfo.geometry.legend;
|
||||
extendType = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extend fraction
|
||||
* @return Extend fraction
|
||||
*/
|
||||
public ExtendFraction getExtendFraction() {
|
||||
return this.extendFraction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set extend fraction
|
||||
* @param value
|
||||
*/
|
||||
public void setExtendFraction(ExtendFraction value) {
|
||||
this.extendFraction = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set extend type
|
||||
* @param value Extend type
|
||||
|
||||
@ -1,34 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<MeteoInfo File="milconfig.xml" Type="configurefile">
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\common_math\interpolate">
|
||||
<RecentFolder Folder="D:\Working\MIScript\cuace_dust"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\cuace_dust\py"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\traj"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\json"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\contour"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\image"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\webmap"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo\wrf"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\io\awx">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\interpolate"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\imshow"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\surf"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\isosurface"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\funny"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\contour"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo\wrf"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\awx"/>
|
||||
</Path>
|
||||
<File>
|
||||
<OpenedFiles>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\traj\hy_conc_geojson.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\contour\contourf_bgcolor.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\contour\contourf_extend_1.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\contour\contourf_extend.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\common_math\interpolate\interp2d_1.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\awx\awx_fy4a_2.py"/>
|
||||
</OpenedFiles>
|
||||
<RecentFiles>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\traj\hy_conc_geojson.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\contour\contourf_bgcolor.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\contour\contourf_extend_1.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\contour\contourf_extend.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\common_math\interpolate\interp2d_1.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\io\awx\awx_fy4a_2.py"/>
|
||||
</RecentFiles>
|
||||
</File>
|
||||
<Font>
|
||||
@ -36,5 +34,5 @@
|
||||
</Font>
|
||||
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
|
||||
<Figure DoubleBuffering="true"/>
|
||||
<Startup MainFormLocation="-7,0" MainFormSize="1370,786"/>
|
||||
<Startup MainFormLocation="-7,0" MainFormSize="1361,807"/>
|
||||
</MeteoInfo>
|
||||
|
||||
Binary file not shown.
@ -14,7 +14,7 @@ from org.meteoinfo.common import XAlign, YAlign
|
||||
from org.meteoinfo.chart.axis import Axis, LonLatAxis, TimeAxis, LogAxis
|
||||
#from org.meteoinfo.geo.legend import LegendManage
|
||||
from org.meteoinfo.geometry.legend import BarBreak, PolygonBreak, PolylineBreak, \
|
||||
PointBreak, LineStyles, PointStyle, LegendScheme, LegendType, LegendManage
|
||||
PointBreak, LineStyles, PointStyle, LegendScheme, LegendType, LegendManage, ExtendFraction
|
||||
from org.meteoinfo.geometry.shape import ShapeTypes
|
||||
from org.meteoinfo.geometry.graphic import Graphic, GraphicCollection
|
||||
from org.meteoinfo.geometry.colors import ExtendType
|
||||
@ -2311,7 +2311,7 @@ class Axes(object):
|
||||
the order specified.
|
||||
:param smooth: (*boolean*) Smooth contour lines or not.
|
||||
|
||||
:returns: (*VectoryLayer*) Contour VectoryLayer created from array data.
|
||||
:returns: (*contour graphics*) Contour graphics created from array data.
|
||||
"""
|
||||
n = len(args)
|
||||
ls = kwargs.pop('symbolspec', None)
|
||||
@ -2447,9 +2447,15 @@ class Axes(object):
|
||||
contourf-coloring of values that are outside the levels range. If 'neither', values outside
|
||||
the levels range are not colored. If 'min', 'max' or 'both', color the values below, above
|
||||
or below and above the levels range.
|
||||
:param extendfrac: (*string or float*) {None, 'auto', length}, If set to None, both the minimum
|
||||
and maximum triangular colorbar extensions will have a length of 5% of the interior colorbar
|
||||
length (this is the default setting). If set to 'auto', makes the triangular colorbar
|
||||
extensions the same lengths as the interior boxes. If a scalar, indicates the length of both
|
||||
the minimum and maximum triangular colorbar extensions as a fraction of the interior colorbar
|
||||
length.
|
||||
:param smooth: (*boolean*) Smooth contour lines or not.
|
||||
|
||||
:returns: (*VectoryLayer*) Contour filled VectoryLayer created from array data.
|
||||
:returns: (*GraphicCollection*) Contour filled graphics created from array data.
|
||||
"""
|
||||
n = len(args)
|
||||
ls = kwargs.pop('symbolspec', None)
|
||||
@ -2479,17 +2485,25 @@ class Axes(object):
|
||||
level_arg = args[0]
|
||||
if isinstance(level_arg, int):
|
||||
cn = level_arg
|
||||
ls = LegendManage.createLegendScheme(vmin, vmax, cn, cmap, True)
|
||||
ls = LegendManage.createLegendScheme(vmin, vmax, cn, cmap, extend)
|
||||
else:
|
||||
if isinstance(level_arg, NDArray):
|
||||
level_arg = level_arg.aslist()
|
||||
ls = LegendManage.createLegendScheme(level_arg, cmap, extend)
|
||||
else:
|
||||
ls = LegendManage.createLegendScheme(vmin, vmax, cmap, True)
|
||||
ls = LegendManage.createLegendScheme(vmin, vmax, cmap, extend)
|
||||
ls = ls.convertTo(ShapeTypes.POLYGON)
|
||||
if 'edgecolor' not in kwargs.keys():
|
||||
kwargs['edgecolor'] = None
|
||||
plotutil.setlegendscheme(ls, **kwargs)
|
||||
extendfrac = kwargs.pop('extendfrac', None)
|
||||
if extendfrac is not None:
|
||||
if extendfrac == 'auto':
|
||||
efrac = ExtendFraction.AUTO
|
||||
else:
|
||||
efrac = ExtendFraction.LENGTH
|
||||
efrac.fraction = extendfrac
|
||||
ls.setExtendFraction(efrac)
|
||||
# norm = kwargs.pop('norm', colors.Normalize(vmin, vmax))
|
||||
# ls.setNormalize(norm._norm)
|
||||
# ls.setColorMap(cmap)
|
||||
@ -2518,7 +2532,7 @@ class Axes(object):
|
||||
Display an image on the axes.
|
||||
|
||||
:param X: (*array_like*) 2-D or 3-D (RGB or RGBA) image value array or BufferedImage.
|
||||
:param levs: (*array_like*) Optional. A list of floating point numbers indicating the level curves
|
||||
:param levels: (*array_like*) Optional. A list of floating point numbers indicating the level curves
|
||||
to draw, in increasing order.
|
||||
:param cmap: (*string*) Color map string.
|
||||
:param colors: (*list*) If None (default), the colormap specified by cmap will be used. If a
|
||||
@ -2527,6 +2541,108 @@ class Axes(object):
|
||||
the order specified.
|
||||
:param interpolation: (*string*) Interpolation option [None | bilinear | bicubic].
|
||||
|
||||
:returns: (*Image graphic*) Image graphic created from array data.
|
||||
"""
|
||||
n = len(args)
|
||||
cmap = plotutil.getcolormap(**kwargs)
|
||||
fill_value = kwargs.pop('fill_value', -9999.0)
|
||||
xaxistype = None
|
||||
isrgb = False
|
||||
isimage = False
|
||||
extent = None
|
||||
if n >= 3:
|
||||
xdata = args[0]
|
||||
ydata = args[1]
|
||||
extent = [xdata[0], xdata[-1], ydata[0], ydata[-1]]
|
||||
args = args[2:]
|
||||
X = args[0]
|
||||
if isinstance(X, (list, tuple)):
|
||||
isrgb = True
|
||||
elif isinstance(X, BufferedImage):
|
||||
isimage = True
|
||||
elif X.ndim > 2:
|
||||
isrgb = True
|
||||
else:
|
||||
if n < 3:
|
||||
if isinstance(X, DimArray):
|
||||
xdata = X.dimvalue(-1)
|
||||
ydata = X.dimvalue(-2)
|
||||
else:
|
||||
ny, nx = X.shape
|
||||
xdata = np.arange(nx)
|
||||
ydata = np.arange(ny)
|
||||
args = args[1:]
|
||||
|
||||
extent = kwargs.pop('extent', extent)
|
||||
if isrgb:
|
||||
if isinstance(X, (list, tuple)):
|
||||
rgbd = []
|
||||
for d in rgbdata:
|
||||
rgbd.append(d.asarray())
|
||||
rgbdata = rgbd
|
||||
else:
|
||||
rgbdata = X.asarray()
|
||||
igraphic = GraphicFactory.createImage(rgbdata, extent)
|
||||
ls = None
|
||||
elif isimage:
|
||||
igraphic = GraphicFactory.createImage(X)
|
||||
ls = None
|
||||
else:
|
||||
ls = kwargs.pop('symbolspec', None)
|
||||
if ls is None:
|
||||
vmin = kwargs.pop('vmin', X.min())
|
||||
vmax = kwargs.pop('vmax', X.max())
|
||||
if len(args) > 0:
|
||||
level_arg = args[0]
|
||||
if isinstance(level_arg, int):
|
||||
cn = level_arg
|
||||
ls = LegendManage.createImageLegend(X._array, cn, cmap)
|
||||
else:
|
||||
if isinstance(level_arg, NDArray):
|
||||
level_arg = level_arg.aslist()
|
||||
ls = LegendManage.createImageLegend(X._array, level_arg, cmap)
|
||||
else:
|
||||
ls = plotutil.getlegendscheme(args, vmin, vmax, **kwargs)
|
||||
norm = kwargs.pop('norm', colors.Normalize(vmin, vmax))
|
||||
ls.setNormalize(norm._norm)
|
||||
ls.setColorMap(cmap)
|
||||
ls = ls.convertTo(ShapeTypes.IMAGE)
|
||||
plotutil.setlegendscheme(ls, **kwargs)
|
||||
igraphic = GraphicFactory.createImage(X._array, xdata._array, ydata._array, ls, extent)
|
||||
|
||||
interpolation = kwargs.pop('interpolation', None)
|
||||
if not interpolation is None:
|
||||
igraphic.getShape().setInterpolation(interpolation)
|
||||
|
||||
if not xaxistype is None:
|
||||
self.set_xaxis_type(xaxistype)
|
||||
self._axes.updateDrawExtent()
|
||||
|
||||
zorder = kwargs.pop('zorder', None)
|
||||
self.add_graphic(igraphic, zorder=zorder)
|
||||
self._axes.setAutoExtent()
|
||||
gridline = self._axes.getGridLine()
|
||||
gridline.setTop(True)
|
||||
|
||||
if ls is None:
|
||||
return igraphic
|
||||
else:
|
||||
return ls
|
||||
|
||||
def imshow_bak(self, *args, **kwargs):
|
||||
"""
|
||||
Display an image on the axes.
|
||||
|
||||
:param X: (*array_like*) 2-D or 3-D (RGB or RGBA) image value array or BufferedImage.
|
||||
:param levels: (*array_like*) Optional. A list of floating point numbers indicating the level curves
|
||||
to draw, in increasing order.
|
||||
:param cmap: (*string*) Color map string.
|
||||
:param colors: (*list*) If None (default), the colormap specified by cmap will be used. If a
|
||||
string, like ‘r’ or ‘red’, all levels will be plotted in this color. If a tuple of matplotlib
|
||||
color args (string, float, rgb, etc.), different levels will be plotted in different colors in
|
||||
the order specified.
|
||||
:param interpolation: (*string*) Interpolation option [None | bilinear | bicubic].
|
||||
|
||||
:returns: (*Image graphic*) Image graphic created from array data.
|
||||
"""
|
||||
n = len(args)
|
||||
@ -3986,7 +4102,7 @@ class Axes(object):
|
||||
for out-of- range values. These are set for a given colormap using the colormap set_under and
|
||||
set_over methods.
|
||||
:param extendrect: (*boolean*) If ``True`` the minimum and maximum colorbar extensions will be
|
||||
rectangular (the default). If ``False`` the extensions will be triangular.
|
||||
rectangular. If ``False`` the extensions will be triangular (the default).
|
||||
:param extendfrac: [None | 'auto' | length] If set to *None*, both the minimum and maximum triangular
|
||||
colorbar extensions with have a length of 5% of the interior colorbar length (the default). If
|
||||
set to 'auto', makes the triangular colorbar extensions the same lengths as the interior boxes
|
||||
@ -3994,7 +4110,7 @@ class Axes(object):
|
||||
as a fraction of the interior colorbar length.
|
||||
:param ticks: [None | list of ticks] If None, ticks are determined automatically from the input.
|
||||
:param ticklabels: [None | list of ticklabels] Tick labels.
|
||||
:param tickin: (*boolean*) Draw tick line inside or outside of the colorbar.
|
||||
:param tickin: (*boolean*) Draw tick line inside or outside the colorbar.
|
||||
:param tickrotation: (*float*) Set tick label rotation angle.
|
||||
:param xshift: (*float*) X shift of the colorbar with pixel coordinate.
|
||||
:param yshift: (*float*) Y shift of the colorbar with pixel coordinate.
|
||||
@ -4074,13 +4190,19 @@ class Axes(object):
|
||||
legend.setPlotOrientation(PlotOrientation.VERTICAL)
|
||||
legend.setPosition(LegendPosition.RIGHT_OUTSIDE)
|
||||
legend.setDrawNeatLine(False)
|
||||
extend = kwargs.pop('extend', 'neither')
|
||||
legend.setExtendType(extend)
|
||||
extendrect = kwargs.pop('extendrect', True)
|
||||
extend = kwargs.pop('extend', None)
|
||||
if extend is not None:
|
||||
legend.setExtendType(extend)
|
||||
extendrect = kwargs.pop('extendrect', False)
|
||||
legend.setExtendRect(extendrect)
|
||||
extendfrac = kwargs.pop('extendfrac', None)
|
||||
if extendfrac == 'auto':
|
||||
legend.setAutoExtendFrac(True)
|
||||
if extendfrac is not None:
|
||||
if extendfrac == 'auto':
|
||||
efrac = ExtendFraction.AUTO
|
||||
else:
|
||||
efrac = ExtendFraction.LENGTH
|
||||
efrac.fraction = extendfrac
|
||||
legend.setExtendFraction(efrac)
|
||||
tickvisible = kwargs.pop('tickvisible', None)
|
||||
if not tickvisible is None:
|
||||
legend.setTickVisible(tickvisible)
|
||||
|
||||
Binary file not shown.
@ -1045,17 +1045,17 @@ class MapAxes(Axes):
|
||||
:param x: (*array_like*) Optional. X coordinate array.
|
||||
:param y: (*array_like*) Optional. Y coordinate array.
|
||||
:param z: (*array_like*) 2-D z value array.
|
||||
:param levs: (*array_like*) Optional. A list of floating point numbers indicating the level curves
|
||||
:param levels: (*array_like*) Optional. A list of floating point numbers indicating the level curves
|
||||
to draw, in increasing order.
|
||||
:param cmap: (*string*) Color map string.
|
||||
:param colors: (*list*) If None (default), the colormap specified by cmap will be used. If a
|
||||
string, like ``r`` or ``red``, all levels will be plotted in this color. If a tuple of matplotlib
|
||||
color args (string, float, rgb, etc), different levels will be plotted in different colors in
|
||||
color args (string, float, rgb, etc.), different levels will be plotted in different colors in
|
||||
the order specified.
|
||||
:param proj: (*ProjectionInfo*) Map projection of the data. Default is None.
|
||||
:param isadd: (*boolean*) Add layer or not. Default is ``True``.
|
||||
:param zorder: (*int*) Z-order of created layer for display.
|
||||
:param smooth: (*boolean*) Smooth countour lines or not.
|
||||
:param smooth: (*boolean*) Smooth contour lines or not.
|
||||
:param select: (*boolean*) Set the return layer as selected layer or not.
|
||||
|
||||
:returns: (*VectoryLayer*) Contour VectoryLayer created from array data.
|
||||
@ -1071,6 +1071,9 @@ class MapAxes(Axes):
|
||||
y = args[1]
|
||||
a = args[2]
|
||||
args = args[3:]
|
||||
|
||||
if not kwargs.has_key('extend'):
|
||||
kwargs['extend'] = 'neither'
|
||||
ls = plotutil.getlegendscheme(args, a.min(), a.max(), **kwargs)
|
||||
ls = ls.convertTo(ShapeTypes.POLYGON)
|
||||
if not kwargs.has_key('edgecolor'):
|
||||
|
||||
Binary file not shown.
@ -10,9 +10,8 @@ import datetime
|
||||
|
||||
from org.meteoinfo.geometry.legend import LineStyles, HatchStyle, ColorBreak, PointBreak, PolylineBreak, \
|
||||
PolygonBreak, ArrowBreak, ArrowLineBreak, ArrowPolygonBreak, StreamlineBreak, \
|
||||
PointStyle, MarkerType, LegendScheme
|
||||
#from org.meteoinfo.geo.legend import LegendManage
|
||||
from org.meteoinfo.geometry.legend import LegendManage
|
||||
PointStyle, MarkerType, LegendScheme, LegendManage, ExtendFraction
|
||||
from org.meteoinfo.geometry.colors import ExtendType
|
||||
from org.meteoinfo.common.colors import ColorUtil, ColorMap
|
||||
from org.meteoinfo.geometry.shape import ShapeTypes
|
||||
from org.meteoinfo.chart import ChartText
|
||||
@ -576,29 +575,43 @@ def getlegendbreak(geometry, **kwargs):
|
||||
def getlegendscheme(args, min, max, **kwargs):
|
||||
ls = kwargs.pop('symbolspec', None)
|
||||
if ls is None:
|
||||
extend = kwargs.pop('extend', None)
|
||||
if extend is not None:
|
||||
extend = ExtendType.valueOf(extend.upper())
|
||||
cmap = getcolormap(**kwargs)
|
||||
level_arg = kwargs.pop('levels', None)
|
||||
if level_arg is None and len(args) > 0:
|
||||
level_arg = args[0]
|
||||
|
||||
if level_arg is None:
|
||||
ls = LegendManage.createLegendScheme(min, max, cmap)
|
||||
if extend is None:
|
||||
ls = LegendManage.createLegendScheme(min, max, cmap)
|
||||
else:
|
||||
ls = LegendManage.createLegendScheme(min, max, cmap, extend)
|
||||
else:
|
||||
if isinstance(level_arg, int):
|
||||
cn = level_arg
|
||||
ls = LegendManage.createLegendScheme(min, max, cn, cmap)
|
||||
if extend is None:
|
||||
ls = LegendManage.createLegendScheme(min, max, cn, cmap)
|
||||
else:
|
||||
ls = LegendManage.createLegendScheme(min, max, cn, cmap, extend)
|
||||
else:
|
||||
if isinstance(level_arg, NDArray):
|
||||
level_arg = level_arg.aslist()
|
||||
ls = LegendManage.createLegendScheme(min, max, level_arg, cmap)
|
||||
if extend is None:
|
||||
ls = LegendManage.createLegendScheme(min, max, level_arg, cmap)
|
||||
else:
|
||||
ls = LegendManage.createLegendScheme(level_arg, cmap, extend)
|
||||
|
||||
extendfrac = kwargs.pop('extendfrac', None)
|
||||
if extendfrac is not None:
|
||||
if extendfrac == 'auto':
|
||||
efrac = ExtendFraction.AUTO
|
||||
else:
|
||||
efrac = ExtendFraction.LENGTH
|
||||
efrac.fraction = extendfrac
|
||||
ls.setExtendFraction(efrac)
|
||||
|
||||
# ecobj = kwargs.pop('edgecolor', None)
|
||||
# if not ecobj is None:
|
||||
# edgecolor = getcolor(ecobj)
|
||||
# ls = ls.convertTo(ShapeTypes.POLYGON)
|
||||
# for lb in ls.getLegendBreaks():
|
||||
# lb.setDrawOutline(True)
|
||||
# lb.setOutlineColor(edgecolor)
|
||||
return ls
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user