int usable_width = bounds.width - PAD_LEFT - PAD_RIGHT;
int usable_height = bounds.height - PAD_TOP - PAD_BOTTOM;
Image image = new Image( canvas.getDisplay(), bounds );
GC gc = new GC( image );
try {
gc.setAntialias( SWT.ON );
} catch (Exception e) {
// Ignore ERROR_NO_GRAPHICS_LIBRARY error or any others
}
int font_height = gc.getFontMetrics().getHeight();
int char_width = gc.getFontMetrics().getAverageCharWidth();
Color[] colours = plot_views[0].plotGraph.getColours();
int max_x = 0;
int max_y = 0;
if ( zones.length > 0 ){
int max_metric = 0;
for (int i=0;i<zones.length;i++){
SpeedManagerPingZone zone = zones[i];
int metric = zone.getMetric();
if ( metric > 0 ){
max_metric = Math.max( max_metric, metric );
max_x = Math.max( max_x, zone.getUploadEndBytesPerSec());
max_y = Math.max( max_y, zone.getDownloadEndBytesPerSec());
}
}
if ( max_x > 0 && max_y > 0 ){
double x_ratio = (double)usable_width/max_x;
double y_ratio = (double)usable_height/max_y;
List texts = new ArrayList();
for (int i=0;i<zones.length;i++){
SpeedManagerPingZone zone = zones[i];
int metric = zone.getMetric();
int x1 = zone.getUploadStartBytesPerSec();
int y1 = zone.getDownloadStartBytesPerSec();
int x2 = zone.getUploadEndBytesPerSec();
int y2 = zone.getDownloadEndBytesPerSec();
if ( metric > 0 ){
int colour_index = (int)((float)metric*colours.length/max_metric);
if ( colour_index >= colours.length ){
colour_index = colours.length-1;
}
gc.setBackground( colours[colour_index] );
int x = PAD_LEFT + (int)(x1*x_ratio);
int y = PAD_TOP + (int)(y1*y_ratio);
int width = (int)Math.ceil((x2-x1+1)*x_ratio);
int height = (int)Math.ceil((y2-y1+1)*y_ratio );
int y_draw = usable_height + PAD_TOP + PAD_TOP - y - height;
gc.fillRectangle( x, y_draw, width, height );
int text_metric = zone.getMetric();
String text = String.valueOf( metric );
int text_width = text.length()*char_width + 4;
if ( width >= text_width && height >= font_height ){
Rectangle text_rect =
new Rectangle(
x + ((width-text_width)/2),
y_draw + ((height-font_height)/2),
text_width, font_height );
// check for overlap with existing and delete older
Iterator it = texts.iterator();
while( it.hasNext()){
Object[] old = (Object[])it.next();
Rectangle old_coords = (Rectangle)old[1];
if ( old_coords.intersects( text_rect )){
it.remove();
}
}
texts.add( new Object[]{ new Integer( text_metric ), text_rect });
}
}
}
// only do the last 100 texts as things get a little cluttered
int text_num = texts.size();
for (int i=(text_num>100?(text_num-100):0);i<text_num;i++){
Object[] entry = (Object[])texts.get(i);
String str = String.valueOf(entry[0]);
Rectangle rect = (Rectangle)entry[1];
gc.drawText(str, rect.x, rect.y, SWT.DRAW_TRANSPARENT );
}
}
}
// x axis
int x_axis_left_x = PAD_LEFT;
int x_axis_left_y = usable_height + PAD_TOP;
int x_axis_right_x = PAD_LEFT + usable_width;
int x_axis_right_y = x_axis_left_y;
gc.drawLine( x_axis_left_x, x_axis_left_y, x_axis_right_x, x_axis_right_y );
gc.drawLine( usable_width, x_axis_right_y - 4, x_axis_right_x, x_axis_right_y );
gc.drawLine( usable_width, x_axis_right_y + 4, x_axis_right_x, x_axis_right_y );
for (int i=1;i<10;i++){
int x = x_axis_left_x + ( x_axis_right_x - x_axis_left_x )*i/10;
gc.drawLine( x, x_axis_left_y, x, x_axis_left_y+4 );
}
SpeedManagerLimitEstimate le = mapper.getEstimatedUploadLimit( false );
if ( le != null ){
gc.setForeground(Colors.grey );
int[][] segs = le.getSegments();
if ( segs.length > 0 ){
int max_metric = 0;
int max_pos = 0;
for (int i=0;i<segs.length;i++){
int[] seg = segs[i];
max_metric = Math.max( max_metric, seg[0] );
max_pos = Math.max( max_pos, seg[2] );
}
double metric_ratio = max_metric==0?1:((float)50/max_metric);
double pos_ratio = max_pos==0?1:((float)usable_width/max_pos);
int prev_x = 1;
int prev_y = 1;
for (int i=0;i<segs.length;i++){
int[] seg = segs[i];
int next_x = (int)((seg[1] + (seg[2]-seg[1])/2)*pos_ratio) + 1;
int next_y = (int)((seg[0])*metric_ratio) + 1;
gc.drawLine(
x_axis_left_x + prev_x,
x_axis_left_y - prev_y,
x_axis_left_x + next_x,
x_axis_left_y - next_y );
prev_x = next_x;
prev_y = next_y;
}
}
gc.setForeground( Colors.black );
}
SpeedManagerLimitEstimate[] bad_up = mapper.getBadUploadHistory();
if ( bad_up.length > 0 ){
gc.setLineWidth( 3 );
gc.setForeground( Colors.red );
for (int i=0;i<bad_up.length;i++){
int speed = bad_up[i].getBytesPerSec();
int x = max_x == 0?0:(speed * usable_width / max_x);
gc.drawLine(
x_axis_left_x + x,
x_axis_left_y - 0,
x_axis_left_x + x,
x_axis_left_y - 10 );
}
gc.setForeground( Colors.black );
gc.setLineWidth( 1 );
}
String x_text = labels[0] + " - " + formatters[0].format( max_x+1 );
gc.drawText( x_text,
x_axis_right_x - 20 - x_text.length()*char_width,
x_axis_right_y - font_height - 2,
SWT.DRAW_TRANSPARENT );
// y axis
int y_axis_bottom_x = PAD_LEFT;
int y_axis_bottom_y = usable_height + PAD_TOP;
int y_axis_top_x = PAD_LEFT;
int y_axis_top_y = PAD_TOP;
gc.drawLine( y_axis_bottom_x, y_axis_bottom_y, y_axis_top_x, y_axis_top_y );
gc.drawLine( y_axis_top_x-4, y_axis_top_y+PAD_TOP, y_axis_top_x, y_axis_top_y );
gc.drawLine( y_axis_top_x+4, y_axis_top_y+PAD_TOP, y_axis_top_x, y_axis_top_y );
for (int i=1;i<10;i++){
int y = y_axis_bottom_y + ( y_axis_top_y - y_axis_bottom_y )*i/10;
gc.drawLine( y_axis_bottom_x, y, y_axis_bottom_x-4, y );
}
le = mapper.getEstimatedDownloadLimit( false );
if ( le != null ){
gc.setForeground(Colors.grey );
int[][] segs = le.getSegments();
if ( segs.length > 0 ){
int max_metric = 0;
int max_pos = 0;
for (int i=0;i<segs.length;i++){
int[] seg = segs[i];
max_metric = Math.max( max_metric, seg[0] );
max_pos = Math.max( max_pos, seg[2] );
}
double metric_ratio = max_metric==0?1:((float)50/max_metric);
double pos_ratio = max_pos==0?1:((float)usable_height/max_pos);
int prev_x = 1;
int prev_y = 1;
for (int i=0;i<segs.length;i++){
int[] seg = segs[i];
int next_x = (int)((seg[0])*metric_ratio) + 1;
int next_y = (int)((seg[1] + (seg[2]-seg[1])/2)*pos_ratio) + 1;
gc.drawLine(
y_axis_bottom_x + prev_x,
y_axis_bottom_y - prev_y,
y_axis_bottom_x + next_x,
y_axis_bottom_y - next_y );
prev_x = next_x;
prev_y = next_y;
}
}
gc.setForeground( Colors.black );
}
SpeedManagerLimitEstimate[] bad_down = mapper.getBadDownloadHistory();
if ( bad_down.length > 0 ){
gc.setForeground( Colors.red );
gc.setLineWidth( 3 );
for (int i=0;i<bad_down.length;i++){
int speed = bad_down[i].getBytesPerSec();
int y = max_y==0?0:( speed * usable_height / max_y );
gc.drawLine(
y_axis_bottom_x + 0,
y_axis_bottom_y - y,
y_axis_bottom_x + 10,
y_axis_bottom_y - y );
}
gc.setForeground( Colors.black );
gc.setLineWidth( 1 );
}
String y_text = labels[1] + " - " + formatters[1].format( max_y+1 );
gc.drawText( y_text, y_axis_top_x+4, y_axis_top_y + 2, SWT.DRAW_TRANSPARENT );
gc.drawText( title, ( bounds.width - title.length()*char_width )/2, 1, SWT.DRAW_TRANSPARENT );
gc.dispose();
return( image );
}