Dynamic chart legend wrapping [message #548958] |
Fri, 23 July 2010 14:34 |
Missing name Missing name Messages: 94 Registered: November 2009 |
Member |
|
|
Hi,
I'm trying to use the following blog to make the wrapping of the chart legend a little smarter: http://java.sys-con.com/node/1469694
Does anyone know how to create the new wrapped text to set back on the legendItemHints object or why he is talking about a binary search?
so far i've got
function beforeRendering(gcs, icsc) {
importPackage(org.eclipse.birt.chart.computation);
var legendLayoutHints = gcs.getRunTimeContext().getLegendLayoutHints();
var legendItemHints = legendLayoutHints.getLegendItemHints();
for(i = 0; i < legendItemHints.length; i++) {
var chartComputation = new BIRTChartComputation();
var label = GObjectFactory.instance().createLabel();
label.getCaption().setValue(legendItemHints[i].getItemText());
label.getCaption().getFont().setWordWrap(true);
var fontHeight = chartComputation.computeFontHeight(
gcs.getDisplayServer(), label);
var labelSize = chartComputation.computeLabelSize(
gcs.getDisplayServer(), label, 20, fontHeight);
chartComputation.applyWrapping(gcs.getDisplayServer(), label, 3);
legendItemHints[i].setItemText(label.getCaption().getValue());
}
}
However, no wrapping occurs....i'm not sure that the dWrapping paramter is supposed to be so i've tried random values of 20 and 3 respectively
thanks
[Updated on: Fri, 23 July 2010 16:15] Report message to a moderator
|
|
|
|
|
|
Re: Dynamic chart legend wrapping [message #549356 is a reply to message #549057] |
Mon, 26 July 2010 14:02 |
Steve Schafer Messages: 23 Registered: December 2009 |
Junior Member |
|
|
I encapsulated the wrapping logic in the following classes. Usage: Instantiate Wrapper and then call the wrap method. There are a couple of externally defined static variables but I think it should be obvious what they are. Let me know if you have questions.
private static class WrapResult
{
private final boolean truncated;
private final double height;
private final String text;
public WrapResult( final boolean truncated, final double height, final String text )
{
this.truncated = truncated;
this.height = height;
this.text = text;
}
}
private static class Wrapper
{
private final char[] chars;
private final Label label;
private final double maxHeight;
private final double maxWidth;
private final int minWordWrapLength;
private final IDisplayServer displayServer;
private final Double fontHeight;
private int lineStart = 0;
private int lineEnd = 0;
BoundingBox boundingBox = null;
public Wrapper( final String text, final double height, final double width, final GeneratedChartState gcs,
final int minWordWrapLength ) throws ChartException
{
this.chars = text.toCharArray();
// create a label to use for computations
this.label = goFactory.createLabel();
this.label.setCaption( goFactory.copyOf( gcs.getChartModel().getLegend().getText() ) );
this.label.getCaption().setValue( text );
this.maxHeight = height;
this.maxWidth = width;
this.minWordWrapLength = minWordWrapLength;
this.displayServer = gcs.getDisplayServer();
this.fontHeight = chartComputation.computeFontHeight( this.displayServer, this.label );
}
private void updateLabel()
{
final int count = this.lineEnd - this.lineStart;
final String text = new String( this.chars, this.lineStart, count ).trim();
this.label.getCaption().setValue( text );
}
private void updateBoundingBox() throws ChartException
{
this.updateLabel();
this.boundingBox = chartComputation.computeLabelSize( this.displayServer, this.label, 0, this.fontHeight );
}
private void setLineEnd( final int lineEnd ) throws ChartException
{
this.lineEnd = lineEnd;
this.updateBoundingBox();
}
private void skipSpaces()
{
while ( this.lineStart < this.chars.length && Character.isWhitespace( this.chars[ this.lineStart ] ) )
this.lineStart++;
}
private void findWordWrapPoint() throws ChartException
{
int tmpLineEnd = this.lineEnd;
while ( tmpLineEnd - this.lineStart > this.minWordWrapLength )
{
if ( Character.isWhitespace( this.chars[ tmpLineEnd - 1 ] ) )
{
this.setLineEnd( tmpLineEnd );
return;
}
tmpLineEnd--;
}
}
private boolean getNextLine() throws ChartException
{
this.lineStart = this.lineEnd;
this.skipSpaces();
// binary search for lineEnd
int lo = this.lineStart;
int hi = this.chars.length;
if ( hi - lo <= 0 )
return false;
if ( hi - lo == 1 )
{
// only 1 char
this.setLineEnd( this.chars.length );
return true;
}
while ( hi - lo > 1 )
{
this.setLineEnd( lo + ( hi - lo ) / 2 );
if ( this.boundingBox.getWidth() > this.maxWidth )
hi = this.lineEnd;
else
lo = this.lineEnd;
}
// binary search can leave us one character short
if ( this.lineEnd < this.chars.length && this.boundingBox.getWidth() <= this.maxWidth )
{
this.setLineEnd( this.lineEnd + 1 );
if ( this.lineEnd > this.lineStart && this.boundingBox.getWidth() > this.maxWidth )
this.setLineEnd( this.lineEnd - 1 );
}
this.findWordWrapPoint();
return true;
}
public WrapResult wrap() throws ChartException
{
final List<String> lines = new ArrayList<String>();
double heightOfLines = 0;
boolean truncated = false;
while ( this.getNextLine() && !truncated )
{
heightOfLines += this.boundingBox.getHeight();
truncated = heightOfLines > this.maxHeight;
if ( !truncated )
lines.add( this.label.getCaption().getValue() );
}
final StringBuilder sb = new StringBuilder();
String sep = "";
for ( final String line : lines )
{
sb.append( sep );
sep = "\r\n";
sb.append( line );
}
return new WrapResult( truncated, heightOfLines, sb.toString() );
}
}
|
|
|
|
Powered by
FUDForum. Page generated in 0.02908 seconds