Java generates the histogram of SVG chart instances 1.1

xiaoxiao2021-03-06  71

When you do a system, you have to display some charts, such as a histogram, and a graph. It used to use VML to make generic, numerical calculations and VML display on the page, all is made with JavaScript, However, the text positioning in VML is not particularly comfortable, and JavaScript calculates the number is not very accurate. I have learned SVG for a few days. I feel good, so I want to generate SVG files with Java, then display, there is no similar article on the Internet, so I will put my first work out, I hope everyone can put it to me. Opinions, improvement. I will put a good pie chart, a graph. I believe this is the first similar program in China, hoping to play the role of throwing jade.

This program can generate a single column chart and generate a multi-column chart. My comment is quite detailed, I believe everyone can understand. I don't use the Apache's Batik to generate an SVG file, but first constitute a string and generate an SVG file. The following is the source code, the original version 1.0, is designed according to 12 sets of data, when data is less, and the column will be wide. The current version 1.1 solves the problem that the column will not be too wide and the text cannot hit.

Package com.hh.paint;

Import java.io.file; import java.io.fileoutputstream; import java.math.bigdecimal

/ ** * This class is the use of SVG drawing dynamic column, simply calls the static method of this class Createsvg (String FileRealPath, String [] * pdata, String [] PDATANAME, I don't use the SVG class library provided by Apache To generate an SVG file, just return all SVG descriptions to the string * * @Author Gu Guo Yong * @version 1.0 * / public class painthistogram {

/ ** * 12 colors used in positive value * / public static string [] [] color = {{"# ff2222", "#ffaaaa", "# aa1111"}, {"# d0b83a", "# f2e692" , "# 9f8703"}, {"# ffdf00", "#fef195", "# CE9A31"}, {"# 22ff22", "#aaffaa", "green"}, {"# ff9e00", "# ffbe08" , "# bd7500"}, {"# 799ae1", "# 5778a1"}, {"# 992", "# aef292", "# 3e941b"}, {"# d0b83a", "# f2e692 "," # 9f8703 "}, {" # 319a00 "," # 297110 "}, {" # c27f34 "," # d6a97b "," # 82522b "}, {" # 2222ff "," # AAAAFF "," # 1111aa "}, {" # ff2222 "," #ffaaaa "," # aa1111 "}}; //, {" # 99c741 "," # aef292 "," # 3e941b "} / ** * The color used by negative value * / public static string [] [] colorneg = {{"black", "# 4f4f4f", "# 757575"}, {"# 1A0b0f", "# 4f4f4f", "# 757575"}} ;

/ ** * Store converted into Double type data for single case cylindrical * / public static double [] data;

/ ** * Store converted into Double type data for many cylindrical * / public static double [] [] DATA1;

/ ** * Total data, the default value is 0 * / public static int datanum = 0;

/ ** * Default pillar map X-axis initial x value * / public static double histogramxsx = 50.0;

/ ** * Default pillar map x-axis Y value * / public static double histogramxy = 440.0;

/ ** * Convert metadata into Double to Double, used for single-case cylindrical * @Param Data * string array forms of metadata * @return conversion good data * / static double [] convertDataodouble (String [] Data) {double [] ddata = new double [data.Length]; datanum = 0; for (int i = 0; i

/ ** * @Param FileRealPath * The full path for the specified SVG file, used for single case cylindrical * @Param PData * metadata array * @Param pDataName * metadata array name * / public static void createSvg (String FileRealPath, String [] pdata, string [] pdata, string {string sfile = Paint (PDATA, PDATANAME); try {byte [] bytefil = sfile.getbytes ("UTF-8"); file svgfile = new file (FileRealPath); if (svgfile.exists ()) {svgfile.delete ();} fileoutputstream fos = new fileoutputstream (svgfile); fos.write (bytefil); fos.close ();} catch (exception ex) {system.out.print EX.getMessage ());}}

/ ** * @Param FileREALPATH * The full path for the specified SVG file, used in multi-case cylindrical * @Param PData * metadata array * @Param PDATaname * metadata array name * / public static void createSvg (String FileRPATH, STRING [] PDATA, STRING [] pdataname) {Try {string sfile = Paint (PDATA, PDATANAME);

Byte [] bytefil = sfile.getbytes ("UTF-8"); file svgfile = new file (filerealpath); if (svgfile.exists ()) {svgfile.delete ();} fileoutputstream fos = new fileoutputstream (svgfile); Fos.write (bytefil); fos.close ();} catch (exception ex) {system.out.print ("CreatesVG:" ex.getMessage ());}

}

/ ** * According to the original data filtering, the various conditions (all positive numbers, all negative numbers are considering the data), and there is a negative value of the maximum or minimum value in the metadata. It is less than 1, and the absolute value of the corresponding value returned is 1; * If the maximum or minimum absolute value is less than 100, the absolute value of the last returned value is a multiple of 10; if the maximum or minimum absolute value is greater than 100. The absolute value of the last returned value is 50 times * * @Param Data * Original data * @return contains the maximum value of absolute value * / static double GetValuemax (double [] pdata) {// stores all data values ​​double max = pdata [0]; double min = pdata [0]; for (int i = 0; i max) max = pdata [i]; if (PDATA [i]

// All negative IF (Max <= 0 && min <0) {min = Math.Floor (min); Double Tmin = Math.Abs ​​(min); MAX = 0; if (Tmin <= 1) min = -1; Else {min = - (Tmin <100? Math.ceil (Tmin / 10) * 10: Math .ceil (TMIN / 50) * 50);}} // Positive IF (MIN <0 &&) Max> 0) {Max = Math.ceil (max); if (max <= 1) max = 1; Else {Max = Max <100? Math.ceil (max / 10) * 10: Math .ce (MAX / 50) * 50;

Min = math.abs (Math.floor (min)); if (min <= 1) min = -1; else {min = - (min <100? Math.ceil (min / 10) * 10: Math .ceil (min / 50) * 50);}} // All positive IF (min> = 0 &&m> = 0) {if (max == 0.0) {max = min = 0.0;} else {ix (Max < = 1) max = 1; else {max = max <100? Math.ceil (max / 10) * 10: Math .ceil (max / 50) * 50;}}}

Double absmax = math.abs (max)> math.abs (min)? Math.abs (max): Math .Abs (min); returnous absmax;}

/ ** * The class is initialized, mainly to declare the beginning and filter of the file, for the painting of the positive and negative Y-axis, universal * * @Return SVG file header * / static string initialize () {// file header StringBuffer sfile = new StringBuffer (); Sfile.append (""); Sfile.append ("/ n"); sfile .append (" "); sfile.append (" / N "); Sfile .append (" "); sfile .append ("/ n"); sfile.append (" Histogram ); sfile.append (" / n "); sfile .append (" "); sfile.append (" / n "); // Define the filter and Arrow sfile.Append (""); sfile.append ("/ n"); sfile .append (" "); sfile.append (" / n "); sfile.append (" "); sfile.append ("/ n"); sfile.append (""); sfile.append ("/ n"); sfile.append (""); sfile.append (" / N "); sfile.append (" "); sfile.append (" / n "); sfile.append (""); sfile.append ("/ n"); sfile.append ("); sfile.append ("/ n"); sfile .append (""); Sfile.Append ("/ n"); sfile .append (""); sfile.append ("/ n"); sfile .append (""); sfile.append ("/ n"); sfile.append ("/ n"); sfile .append ( ""); sFile.append ( "/ n "); sfile.append (" "); sfile.append (" / n "); sfile.append (" "); sfile.append (" / n "); sfile .append (" "); sfile.append (" / n "); sfile .append (" "); sfile.append (" / n " ); Sfile.append (""); sfile.append ("/ n"); sfile.append (""); sfile.append ("/ n"); sfile.append (" "); sfile.append (" / n "); sfile .append (""); sfile.append ("/ n"); sfile.append ("

}

/ ** * @Param args * / public static void main (string [] args) {try = {{"54", "44", "122"}, {"," 12 "," -468 "}, {" 78 "," 520 "," 10 "}}; string [] DATA1 = {" 54 "," 4424.225 "," 12200 "," -4658 "}; string [] DataName = {"Monarch 1", "222", "III"}; Painthistogram.createsvg ("D: //t1.svg", Data, Dataname); PainThistogram.createsvg ("D: // T2 . SVG ", DATA1, DATANAME);

} catch (exception ex) {system.out.print (ex.getMessage ());}}

/ ** * Picture of column and scale, apply only one column * * @Param PData * metadata * @Param PDATaname * Metadata * @Param pDAINT (String [] PDATA String [] pdataname) throws exception {stringbuffer sfile = new stringbuffer (); data = convertDataodouble (pdata);

Double Valuemm = getValuemax (data); // Get maximum sfile.Append (Initialize ()); // XY Step DoubleMM; Double Xstep = (New BigDecimal (600 / pDataName.length) .setscale 3, BigDecimal.Round_Half_up)). DoubleValue (); Double COLWIDTH = 0.0; // Column Width Double COLWIDTHPRE = 0.0; // Each cell start with the column DOUBLE COLWIDTHNEXT = 0.0; // Each End of cells with column type IF ((xstep / 2)> 40) {colwidth = 40; colwidthpre = (xStep - 40) / 2; COLWIDTHNEXT = (xstep - 40) / 2;} else {colwidth = xstep / 2; colwidthpre = xstep / 4; colwidthnext = xstep / 4;} / * x-axis tag line * / for (int i = 0; i

Double Tempx1 = i == 0? HistogramxsX i * xstep: histogramxsx i * xstep 10; // Each X-axis scale start position

// Double Tempx2 = TEMPX1 COLWIDTHPRE; / / Each column start position sfile.Append (" "); sfile.append (" / n ");} / * Painting Y-axis scale * / int maxvalue = (int) valuemm; int valuex; // Y-axis scale value started X coordinate string fontsize = ""; if (maxValue> 10000) {valuex = 5; fontsize = "11px "} Else {valuex = 15; fontsize =" 13px ";} for (int i = 0; i <10; i ) {sfile.append (" "); sfile.append ("/ n");}

/ * Paint rectangle * / sfile.append (""); sfile.append ("/ n"); for (int i = 0; i

Double Tempx1 = i == 0? HistogramxsX i * xstep: histogramxsx i * xstep 10; // Each X-axis scale start position

Double Tempx2 = Tempx1 COLWIDTHPRE; // Each column start position double colheight = math.ceil (Math.abs (data [i]) * YSTEP); Double Tempy = 440 - colHeight;

String [] colorhistogram; // three columns color IF (Data [i] <0) {colorhistogram = colorneg [0]; sfile.append (ColWidth, Colorhistogram, Tempx2, Tempy, Colorhistogram, Data [i] )));} Else if (data [i]> 0) {INT N = I% color.length; colorhistogram = color [n]; sfile.append (ColWidth, Colorhistogram, Tempx2, Tempy, Colorhistogram, Data [i ]));

/ * Add the X-axis field Description word cannot be displayed in one line, you need to wrap * / int n = (int) xstep / 13; // Show a few characters per line INT m = pDataName [i] .length ()% N == 0? PDATANAME [I] .length () / N: (int) (pD) (PDATANAME [i] .length () / n 1); / / total display a few line int L = 0; // record a total of total processing How many characters IF (m> 1) {sfile .append (""); for (int J = 0; J ");} if (l == pDataName [i] .Length ()) {breaf;}} sfile.append (""); sfile.append ("/ n");} else {double textoffset = (xstep - pdataname [i] .length () * 15) / 2; sfile .append (" pdataname [i ] ""); sfile.Append ("/ n");}} sfile.append (""); sfile.append ("/ n"); sfile.append ("< / svg> "); return sfile.toString ();

/ ** * Picture of column and scale, suitable for x-axis per grid to display multiple column * * @Param PData * specific metadata * @Param PDATaname * metadata name * / static string paint (String [String ] [] pData, string [] pdataaname) {stringbuffer sfile = new stringbuffer (); data1 = communicationDataodouble (pdata); // gain maximum double [] TempValue = new double [datanum]; for (int i = 0; i

Double ColWidthsum = xstep / 2; // Multiple column widths and double colwidthpre = xstep / 4; // Each cell start with cylindrical distance double colorThnext = xstep / 4; // Each cell End with cylindrical distance double colorth = COLWIDTHSUM / DATA1 [0] .length; // Single column width

/ * x-axis scale line * / for (int i = 0; i "); sfile.append ( "/ n");

/ * Painting Y-axis scale value * / int maxValue = (int) valuemmmmmmmm; int valuex; // Y-axis scale value started X coordinate string fontsize = ""; if (maxValue> 10000) {Valuex = 5; fontsize = "11px";} else {valueX = 15; fontsize = "13px";} for (int i = 0; i <10; i ) {sfile.append (""); sfile.append ("/ n");} / * Paint rectangle * / sfile.append (""); sfile.append ("/ n"); for (int i = 0; i 0) {INT N = J% Color.Length; ColorHistogram = Color [N]; Sfile.Append (ColWidth, Colorhistogram, Data1 [i] [J ]));

}

/ * Add the X-axis field Description word cannot be displayed in one line, you need to wrap * / int n = (int) xstep / 13; // Show a few characters per line INT m = pDataName [i] .length ()% N == 0? PDATANAME [I] .length () / N: (int) (pD) (PDATANAME [i] .length () / n 1); / / total display a few line int L = 0; // record a total of total processing How many characters IF (m> 1) {sfile .append (""); for (int J = 0; J ");} if (l == pDataName [i] .Length ()) {breaf;}} sfile.append (""); sfile.append ("/ n");} else {double textoffset = (xstep - pdataname [i] .length () * 15) / 2; sfile .append (" pdataname [i ] ""); sfile.Append ("/ n");}} sfile.append (""); sfile.append ("/ n"); sfile.append ("< / svg> "); return sfile.toString ();

}

/ ** * Draw a single column * * @Param COLWIDTH * Cylindrical width * @Param colheight * Cylindrical height * @Param x * Cylindrical x value * @PARAM Y * Cylindrical Y value * @Param Color * Cylindrical * @param three color plane value representative of the cylindrical dataValue * * @return SVG string * / static string paintHistogram (double colWidth, double colHeight, double x, double y, string [] color, double dataValue) {StringBuffer sFile = new stringbuffer (); double doffset = (COLWIDTH / 3)> 10.0? 10.0: (COLWIDTH / 3); // The offset sfile.Append (" "); Sfile.append (" / n "); sfile.append (" ") Sfile.append ("/ n"); sfile.append ("