JRobin的默认字体,不直接中文,要显示中文可以对字体做这样的设置(JRobin1.4)
graphDef.setDefaultFont(new Font("monospaced", Font.PLAIN, 11)); graphDef.setTitleFont(new Font("SansSerif", Font.BOLD, 14));
但是使用RrdGraphDef的line方法,legend的值中含中文时,会发生错位的现象。
public void line( String sourceName, Color color, String legend )
产生的原因为,JRboin把在同一行的legend拼成一个字符串,进行绘图,而把legend前面的颜色方框分别绘制,颜色方框的x位置,是根据legend的length和计算的;英文字符的宽度大概相关于字体高的0.5倍,而汉字宽度则大于这个倍数,作者没有考虑中文的问题;所以计算出来的位置不正确。
简单解法:
//中文字符个数+1,中文比英文字符多出来的宽度 int cnChars = 0; char[] charArray = tmpStr.toString().toCharArray(); for(int k=0; k<charArray.length;k++){ if ((charArray[k] >= 0x4e00)&&(charArray[k] <= 0x9fbb)){ cnChars++; } } cnChars = (int)(cnChars*0.88); markerList.addLast( new LegendMarker( (tmpStr.length()+ cnChars) * nfont_width, ((Legend) clist[i]).getColor() ) ); //上面是对源码的修改 tmpStr.append( " " ); // Add 3 spaces where the mark will be
均分各列
LinkedList markerList = new LinkedList(); //add LinkedList legendList = new LinkedList(); ... if ( clist[i].commentType == Comment.CMT_LEGEND ) { markerList.addLast( new LegendMarker( tmpStr.length() * nfont_width, ((Legend) clist[i]).getColor() ) ); tmpStr.append( " " ); // Add 3 spaces where the mark will be } else { if ( clist[i].commentType == Comment.CMT_GPRINT ) { ((Gprint) clist[i]).setValue( sources, sourceIndex, valueFormat ); } markerList.addLast( null ); } ... ArrayList tknpairs = clist[i].getTokens(); //add if (tknpairs.size() >0){ String legend = (String) tknpairs.get(0); if ( clist[i].trimString() ) legendList.addLast(legend.trim()); else legendList.addLast(legend); } ... //替换graphString( g, tmpStr.toString(), posx, posy );到while循环的代码 tmpStr = new StringBuffer(""); drawText = false; if (!markerList.isEmpty()){ //一行有几个legend int legendCols = markerList.size(); //两边分别离posx宽的间距,再均分每个legend的间距 int legendWidth = (imgWidth - posx*2)/legendCols; int currentCol = 0; // Plot the markers while ( !markerList.isEmpty() ) { //绘制颜色方框 LegendMarker lm = (LegendMarker) markerList.removeFirst(); //方框的起始位置 int startPosx = posx + currentCol*legendWidth; g.setColor( lm.getColor() ); g.fillRect( startPosx, posy - 9, 10, 10 ); g.setColor( normalFontColor ); g.drawRect( startPosx, posy - 9, 10, 10 ); //绘制legend,颜色方框的宽度约为12 String legend = (String) legendList.removeFirst(); graphString( g, legend , startPosx + 12, posy ); currentCol++; } }
紧凑排列
//其他代码与均无各列的相同 if (!markerList.isEmpty()){ // Plot the markers int startPosx = posx; while ( !markerList.isEmpty() ) { //绘制颜色方框 LegendMarker lm = (LegendMarker) markerList.removeFirst(); //方框的起始位置 g.setColor( lm.getColor() ); g.fillRect( startPosx, posy - 9, 10, 10 ); g.setColor( normalFontColor ); g.drawRect( startPosx, posy - 9, 10, 10 ); //绘制legend,颜色方框的宽度约为12 String legend = (String) legendList.removeFirst(); int legendStartPosx = startPosx + 12; graphString( g, legend , legendStartPosx, posy ); char[] charArray = legend.toCharArray(); //中文字符个数+1,中文是英文字符宽度的两倍 int cnChars = 1; for(int k=0; k<charArray.length;k++){ if ((charArray[k] >= 0x4e00)&&(charArray[k] <= 0x9fbb)){ cnChars++; } } //下一个方框开始的位置为,本legend的起始位置加上legned文字的宽度 startPosx = legendStartPosx + (legend.length()+ cnChars)*nfont_width; } }
原代码如下:
private void plotComments( Graphics2D g ) throws RrdException { if ( !graphDef.showLegend() ) return; LinkedList markerList = new LinkedList(); // Position the cursor just below the chart area int posy = y_offset + chartHeight + CHART_UPADDING + CHART_BPADDING + ( graphDef.showMajorGridX() ? nfont_height : 0 ); int posx = LBORDER_SPACE; g.setColor( normalFontColor ); g.setFont( normal_font ); Comment[] clist = graphDef.getComments(); StringBuffer tmpStr = new StringBuffer(""); boolean newLine = false; boolean drawText = false; for (int i = 0; i < clist.length; i++) { if ( clist[i].commentType == Comment.CMT_LEGEND ) { markerList.addLast( new LegendMarker( tmpStr.length() * nfont_width, ((Legend) clist[i]).getColor() ) ); tmpStr.append( " " ); // Add 3 spaces where the mark will be } else if ( clist[i].commentType == Comment.CMT_GPRINT ) ((Gprint) clist[i]).setValue( sources, sourceIndex, valueFormat ); ArrayList tknpairs = clist[i].getTokens(); for (int j = 0; j < tknpairs.size(); j++) { String str = (String) tknpairs.get(j++); Byte tkn = (Byte) tknpairs.get(j); if ( clist[i].trimString() ) tmpStr.append( str.trim() ); else tmpStr.append( str ); if ( tkn != Comment.TKN_NULL ) { drawText = true; if ( tkn == Comment.TKN_ALF ) { newLine = true; posx = LBORDER_SPACE; } else if ( tkn == Comment.TKN_ARF ) { newLine = true; posx = imgWidth - RBORDER_SPACE - (tmpStr.length() * nfont_width); } else if ( tkn == Comment.TKN_ACF ) { newLine = true; posx = imgWidth / 2 - (tmpStr.length() * nfont_width) / 2; } else if ( tkn == Comment.TKN_AL ) posx = LBORDER_SPACE; else if ( tkn == Comment.TKN_AR ) posx = imgWidth - RBORDER_SPACE - (tmpStr.length() * nfont_width); else if ( tkn == Comment.TKN_AC ) posx = imgWidth / 2 - (tmpStr.length() * nfont_width) / 2; } if ( !newLine && clist[i].addSpacer() ) tmpStr.append( SPACER ); // Plot the string if ( drawText ) { graphString( g, tmpStr.toString(), posx, posy ); tmpStr = new StringBuffer(""); drawText = false; // Plot the markers while ( !markerList.isEmpty() ) { LegendMarker lm = (LegendMarker) markerList.removeFirst(); g.setColor( lm.getColor() ); g.fillRect( posx + lm.getXPosition(), posy - 9, 10, 10 ); g.setColor( normalFontColor ); g.drawRect( posx + lm.getXPosition(), posy - 9, 10, 10 ); } } if ( newLine ) { posy += nfont_height + LINE_PADDING; newLine = false; } } } if ( tmpStr.length() > 0) { posx = LBORDER_SPACE; graphString( g, tmpStr.toString(), posx, posy ); tmpStr = new StringBuffer(""); drawText = false; // Plot the markers while ( !markerList.isEmpty() ) { LegendMarker lm = (LegendMarker) markerList.removeFirst(); g.setColor( lm.getColor() ); g.fillRect( posx + lm.getXPosition(), posy - 9, 10, 10 ); g.setColor( normalFontColor ); g.drawRect( posx + lm.getXPosition(), posy - 9, 10, 10 ); } } }