Preface
At an alumni gathering, an alumnus from the top 500 executives of the world's top companies said: in this city, I can find a single person to get involved. In this society, mixed speech is amazing, but the truth is worth thinking deeply. This society is a huge relational network composed of people. Everyone is a node in this huge network. If we fully understand and utilize this network, our work and career will surely become even more powerful.
I believe everyone has this experience. In order to understand the software industry information or solve development difficulties, they will search for and seek help from csdn or javaeye experts. Similarly, in some cases, we will share our knowledge points through blogs or posts and become "experts" who help others ". These website users have a "Concern" relationship and "friend" relationship. In fact, this is also a huge Interpersonal Network and Knowledge Network. What does this network look like? Can it be as big as "three people can reach any point? With great curiosity, I came up with the idea that I could use a program to graphically present this huge network of people. I believe it will surely be have lots of fun!
After the idea came out, I first carefully observed the blog page STRUCTURE AND FRIENDS information LIST OF THE csdn website, and then wrote a simple program using Java swing. After nearly one week of modification, we finally got started! First of all, I would like to sincerely thank csdn for providing such good data. Secondly, I would like to thank my friends in the blog for making this image so nice. You have given me endless motivation!
If you don't talk nonsense, go first and finally:
Continue to elaborate on the program design ideas.
Technical preparation
I am most familiar with Java swing, so I can use swing to do it without a doubt. At the same time, it is natural to use twaver Java, which is familiar to me. Prepare JDK 6 and netbeans and start working.
First, set the font. No way. I have "" obsessive-compulsive disorder. Since I heard that every Chinese character at Microsoft has spent $100, I want to turn everything into a first, which is no exception here. I am sorry if I still use XP. I don't know how to display the font. It is easy to set up in swing. Here, I am lazy to pick it up. I only need to set the font of several components used, and then use swingutilities. invokelater to start the main form:
Public static void main (string [] ARGs) {<br/> swingutilities. invokelater (New runnable () {</P> <p> Public void run () {<br/> // setup swing fonts Before Start Program. <br/> Font font = new font ("", Font. plain, 12); <br/> uimanager. put ("label. font ", font); <br/> uimanager. put ("button. font ", font); <br/> uimanager. put ("radiobutton. font ", font); <br/> uimanager. put ("checkbox. font ", font); <br/> uimanager. put ("textfield. font ", font); </P> <p> // show main UI. <br/> mainui UI = new mainui (); <br/> UI. setvisible (true); <br/>}< br/>}); <br/>}
Capture webpage data
Next, we need to solve the problem of how to obtain csdn user information and friend information. After observing the csdn website, you can find that the user's blog homepage is http://blog.csdn.net/#user name. For example, my blog address is http://blog.csdn.net/solo. To view my friends, you need to view my details page. The URL is http://hi.csdn.net/solo. There is a user friend list on the right side of this page.
In this way, we can use URL and stream to read the page and parse the friends in it. Check the HTML source code in the browser, determine the HTML flag corresponding to the friend list, and then parse it using the following code:
Try {<br/> URL url = new URL (urlstring); <br/> bufferedreader reader = new bufferedreader (New inputstreamreader (URL. openstream (), "UTF-8"); <br/> string line = reader. readline (); <br/> while (line! = NULL) {<br/> line = line. trim (); <br/> If (line. startswith ("<Div id =/" space_avatar/">") {<br/> line = reader. readline (). trim (); <br/> int Index = line. indexof ("HTTP"); <br/> line = line. substring (INDEX); <br/> Index = line. indexof ("/" "); <br/> string imageurl = line. substring (0, index); <br/> Index = line. indexof ("alt ="); <br/> line = line. substring (index + 5); <br/> If (line. contains ("/" ") {<br/> line = line. substring (0, line. indexof ("/" "); <br/>}< br/> string tooltip = line; </P> <p> usernode centernode = addnode (null, tooltip, imageurl, null); <br/> return centernode; <br/>}</P> <p> line = reader. readline (); <br/>}< br/>} catch (exception ex) {<br/> // ex. printstacktrace (); <br/>}
In addition, in order to prevent the swing thread from blocking the process of reading the URL, encapsulate the interface and place it in a separate thread or runnable. After reading the result, dynamically Add the result to the interface:
Public class pageexplorer implements runnable {<br/> ....... <br/> Public void run () {<br/> try {<br/> If (parent = NULL) {<br/> usernode centernode = createcenternode (); <br/> addchildrennode (centernode); <br/> centernode. setreceived (); <br/>}else {<br/> addchildrennode (parent); <br/> parent. setinclued (); <br/>}< br/>} catch (exception ex) {<br/> joptionpane. showmessagedialog (network ," The user data cannot be obtained. "); <Br/>}< br/> ...... <br/>}
Data Display
How to display the obtained data is critical. The display effect must be intuitive, beautiful, and easy to understand. The topology of twaver is the best choice. A fully graphical topology is more intuitive and clever than a table.
Then define the graphic elements. In fact, there are only two elements, one is a vertex and the other is a line. A vertex represents a user node and a line represents its relationship. Here, only a simple friend relationship is displayed.
Next we will use the node and link of twaver to define two classes, encapsulate nodes and connections:
Public class usernode extends resizablenode {</P> <p> private Boolean male =! (Twaverutil. getrandomint (5) = 0); </P> <p> Public usernode () {<br/> Init (); <br/>}</P> <p> private void Init () {<br/> This. putbordervisible (false); </P> <p> This. putcustomdraw (true); <br/> This. putcustomdrawfill (true); <br/> This. putcustomdrawgradient (false); <br/> This. putcustomdrawgradient (true); </P> <p> This. putlabelcolor (color. white); <br/> This. putlabelfont (new font ("", Font. plain, 12); <br/> This. putlabelyoffset (-5); <br/> This. putlabelhighlightable (false); </P> <p> This. putlabelunderlinecolor (color. white); <br/> If (male) {<br/> This. setsize (10, 10); <br/> This. putcustomdrawgradient (false); <br/> This. putcustomdrawfill3d (true); <br/> This. putcustomdrawoutline (false); <br/> This. putcustomdrawshapefactory (twaverconst. shape_rectangle); <br/> This. putcustomdrawfillcolor (color. green. darker (); <br/>}else {<br/> This. setsize (15, 15); <br/> This. putcustomdrawshapefactory (twaverconst. shape_circle); <br/> This. putcustomdrawoutline (false); <br/> This. putcustomdrawgradientfactory (twaverconst. gradient_line_ne); <br/> This. putcustomdrawgradientcolor (color. yellow. brighter (); <br/> This. putcustomdrawfillcolor (color. orange); <br/>}< br/> .............. <br/>}
I tried my friend relationship, and the effect was good. Unfortunately, there were too few friends!
Shunteng
It is not enough to show your network of relationships. You must continue to expand and extend your network. The basic idea is simple: double-click the next node, capture the webpage URL of the person using the previous method, and fill in the next layer of friends again. This is a bit interesting:
Automatic Layout
After the data is complex, the results cannot be seen without a good organizational structure. Twaver provides a good Automatic Layout Algorithm, so I used two algorithms: one is the static and automatic layout of the ring, and the layout will remain static. The other is the Dynamic Layout Based on the spring algorithm, the node will be adjusted with the same animation, which is very interesting. Two buttons are provided for layout switching. The spring layout is vivid, and different gestures can be presented during the drag of nodes:
The spring layout parameters are as follows:
// Setup twaver auto-Layout Algorithm parameters. <br/> network. getspringlayouter (). setforcesize (3); <br/> network. getspringlayouter (). setstepsize (40); <br/> network. getspringlayouter (). setnoderepulsionfactor (1); <br/> network. getspringlayouter (). setlinkrepulsionfactor (30); <br/> network. getspringlayouter (). start (); <br/> network. getcanvasscrollpane (). setverticalscrollbarpolicy (scrollpaneconstants. vertical_scrollbar_never); <br/> network. getcanvasscrollpane (). sethorizontalscrollbarpolicy (scrollpaneconstants. horizontal_scrollbar_never); </P> <p> // when window resized, reset the spring layout limit bounds to canvas view port size. <br/> network. addcomponentlistener (New componentadapter () {</P> <p> @ override <br/> Public void componentresized (componentevent e) {<br/> network. getspringlayouter (). setlimitbounds (network. getcanvasscrollpane (). getbounds (); <br/>}< br/> });
Draw text description
I want to add some explanatory text, otherwise everyone will not know how to use it. Traditional text is too plain, and naturally does not conform to the aesthetic and style of the program. Just get fashion. Think of twaver's marker mechanism. This can paint anything on the topology graph. It meets my requirements! Therefore, fill a rectangle and then draw text:
Public class notemarker implements canvasmarker {</P> <p> private color backgroundcolor = new color (0,200,200, 50 ); <br/> private Font font = new font ("", Font. bold, 12); </P> <p> Public void mark (graphics2d g) {<br/> G. setcolor (backgroundcolor); <br/> G. fill3drect (50, 50,330,150, true); <br/> G. setfont (font); <br/> G. setcolor (color. white); <br/> G. setrenderinghint (renderinghints. key_antialiasing, renderinghints. value_antialias_on); <br/> int Space = 20; <br/> int x = 55; <br/> int y = 65; <br/> G. drawstring ("1. Double-click the color node green or yellow to expand the relationship", x, y); <br/> Y + = space; <br/> G. drawstring ("2. The gray node is an existing user", x, y); <br/> Y + = space; <br/> G. drawstring ("3. The green node is boy, the yellow node is girl", x, y); <br/> Y + = space; <br/> G. drawstring ("4. You can hover your mouse over this person's photo and blog URL", x, y); <br/> Y + = space; <br/> G. drawstring ("5. Select" annular layout "or" Spring layout "to switch the Layout Algorithm", x, y); <br/> Y + = space; <br/> G. drawstring ("6. Click" Expand randomly "to automatically expand nodes", x, y); <br/> Y + = space; <br/> G. drawstring ("7. Enter another csdn user name in the text box and click" Start again ", x, y); <br/>}< br/>}
Run the following code to install marker:
// Display notes on network canvas with a marker. <br/> network. addcanvasmarker (New notemarker ());
The effect is as follows:
In addition, a small function is added: After you hover your mouse over a node for a moment, you can use tooltip to display this person's photo and URL. At the same time, there is an amazing discovery: here we can support GIF animation!
Final Effect
For ease of expansion, a button is added to expand several nodes at will, saving a lot of mouse operations. After a burst of madness, we can see the complexity of the "relationship between people:
Download programs and source code
The source code and executable jar packages are provided here. If you are interested, you can continue to improve the functions on this basis. If you have the energy, you can make another javaeye version!
Because csdn is not very good at uploading attachments, you can download attachments from my javaeye blog:
Http://joshuaxiao.javaeye.com/
Thank you!
Preface
At an alumni gathering, an alumnus from the top 500 executives of the world's top companies said: in this city, I can find a single person to get involved. In this society, mixed speech is amazing, but the truth is worth thinking deeply. This society is a huge relational network composed of people. Everyone is a node in this huge network. If we fully understand and utilize this network, our work and career will surely become even more powerful.
I believe everyone has this experience. In order to understand the software industry information or solve development difficulties, they will search for and seek help from csdn or javaeye experts. Similarly, in some cases, we will share our knowledge points through blogs or posts and become "experts" who help others ". These website users have a "Concern" relationship and "friend" relationship. In fact, this is also a huge Interpersonal Network and Knowledge Network. What does this network look like? Can it be as big as "three people can reach any point? With great curiosity, I came up with the idea that I could use a program to graphically present this huge network of people. I believe it will surely be have lots of fun!
After the idea came out, I first carefully observed the blog page STRUCTURE AND FRIENDS information LIST OF THE csdn website, and then wrote a simple program using Java swing. After nearly one week of modification, we finally got started! First of all, I would like to sincerely thank csdn for providing such good data. Secondly, I would like to thank my friends in the blog for making this image so nice. You have given me endless motivation!
If you don't talk nonsense, go first and finally:
Continue to elaborate on the program design ideas.
Technical preparation
I am most familiar with Java swing, so I can use swing to do it without a doubt. At the same time, it is natural to use twaver Java, which is familiar to me. Prepare JDK 6 and netbeans and start working.
First, set the font. No way. I have "" obsessive-compulsive disorder. Since I heard that every Chinese character at Microsoft has spent $100, I want to turn everything into a first, which is no exception here. I am sorry if I still use XP. I don't know how to display the font. It is easy to set up in swing. Here, I am lazy to pick it up. I only need to set the font of several components used, and then use swingutilities. invokelater to start the main form:
Public static void main (string [] ARGs) {<br/> swingutilities. invokelater (New runnable () {</P> <p> Public void run () {<br/> // setup swing fonts Before Start Program. <br/> Font font = new font ("", Font. plain, 12); <br/> uimanager. put ("label. font ", font); <br/> uimanager. put ("button. font ", font); <br/> uimanager. put ("radiobutton. font ", font); <br/> uimanager. put ("checkbox. font ", font); <br/> uimanager. put ("textfield. font ", font); </P> <p> // show main UI. <br/> mainui UI = new mainui (); <br/> UI. setvisible (true); <br/>}< br/>}); <br/>}
Capture webpage data
Next, we need to solve the problem of how to obtain csdn user information and friend information. After observing the csdn website, you can find that the user's blog homepage is http://blog.csdn.net/#user name. For example, my blog address is http://blog.csdn.net/solo. To view my friends, you need to view my details page. The URL is http://hi.csdn.net/solo. There is a user friend list on the right side of this page.
In this way, we can use URL and stream to read the page and parse the friends in it. Check the HTML source code in the browser, determine the HTML flag corresponding to the friend list, and then parse it using the following code:
Try {<br/> URL url = new URL (urlstring); <br/> bufferedreader reader = new bufferedreader (New inputstreamreader (URL. openstream (), "UTF-8"); <br/> string line = reader. readline (); <br/> while (line! = NULL) {<br/> line = line. trim (); <br/> If (line. startswith ("<Div id =/" space_avatar/">") {<br/> line = reader. readline (). trim (); <br/> int Index = line. indexof ("HTTP"); <br/> line = line. substring (INDEX); <br/> Index = line. indexof ("/" "); <br/> string imageurl = line. substring (0, index); <br/> Index = line. indexof ("alt ="); <br/> line = line. substring (index + 5); <br/> If (line. contains ("/" ") {<br/> line = line. substring (0, line. indexof ("/" "); <br/>}< br/> string tooltip = line; </P> <p> usernode centernode = addnode (null, tooltip, imageurl, null); <br/> return centernode; <br/>}</P> <p> line = reader. readline (); <br/>}< br/>} catch (exception ex) {<br/> // ex. printstacktrace (); <br/>}
In addition, in order to prevent the swing thread from blocking the process of reading the URL, encapsulate the interface and place it in a separate thread or runnable. After reading the result, dynamically Add the result to the interface:
Public class pageexplorer implements runnable {<br/> ....... <br/> Public void run () {<br/> try {<br/> If (parent = NULL) {<br/> usernode centernode = createcenternode (); <br/> addchildrennode (centernode); <br/> centernode. setreceived (); <br/>}else {<br/> addchildrennode (parent); <br/> parent. setinclued (); <br/>}< br/>} catch (exception ex) {<br/> joptionpane. showmessagedialog (network ," The user data cannot be obtained. "); <Br/>}< br/> ...... <br/>}
Data Display
How to display the obtained data is critical. The display effect must be intuitive, beautiful, and easy to understand. The topology of twaver is the best choice. A fully graphical topology is more intuitive and clever than a table.
Then define the graphic elements. In fact, there are only two elements, one is a vertex and the other is a line. A vertex represents a user node and a line represents its relationship. Here, only a simple friend relationship is displayed.
Next we will use the node and link of twaver to define two classes, encapsulate nodes and connections:
Public class usernode extends resizablenode {</P> <p> private Boolean male =! (Twaverutil. getrandomint (5) = 0); </P> <p> Public usernode () {<br/> Init (); <br/>}</P> <p> private void Init () {<br/> This. putbordervisible (false); </P> <p> This. putcustomdraw (true); <br/> This. putcustomdrawfill (true); <br/> This. putcustomdrawgradient (false); <br/> This. putcustomdrawgradient (true); </P> <p> This. putlabelcolor (color. white); <br/> This. putlabelfont (new font ("", Font. plain, 12); <br/> This. putlabelyoffset (-5); <br/> This. putlabelhighlightable (false); </P> <p> This. putlabelunderlinecolor (color. white); <br/> If (male) {<br/> This. setsize (10, 10); <br/> This. putcustomdrawgradient (false); <br/> This. putcustomdrawfill3d (true); <br/> This. putcustomdrawoutline (false); <br/> This. putcustomdrawshapefactory (twaverconst. shape_rectangle); <br/> This. putcustomdrawfillcolor (color. green. darker (); <br/>}else {<br/> This. setsize (15, 15); <br/> This. putcustomdrawshapefactory (twaverconst. shape_circle); <br/> This. putcustomdrawoutline (false); <br/> This. putcustomdrawgradientfactory (twaverconst. gradient_line_ne); <br/> This. putcustomdrawgradientcolor (color. yellow. brighter (); <br/> This. putcustomdrawfillcolor (color. orange); <br/>}< br/> .............. <br/>}
I tried my friend relationship, and the effect was good. Unfortunately, there were too few friends!
Shunteng
It is not enough to show your network of relationships. You must continue to expand and extend your network. The basic idea is simple: double-click the next node, capture the webpage URL of the person using the previous method, and fill in the next layer of friends again. This is a bit interesting:
Automatic Layout
After the data is complex, the results cannot be seen without a good organizational structure. Twaver provides a good Automatic Layout Algorithm, so I used two algorithms: one is the static and automatic layout of the ring, and the layout will remain static. The other is the Dynamic Layout Based on the spring algorithm, the node will be adjusted with the same animation, which is very interesting. Two buttons are provided for layout switching. The spring layout is vivid, and different gestures can be presented during the drag of nodes:
The spring layout parameters are as follows:
// Setup twaver auto-Layout Algorithm parameters. <br/> network. getspringlayouter (). setforcesize (3); <br/> network. getspringlayouter (). setstepsize (40); <br/> network. getspringlayouter (). setnoderepulsionfactor (1); <br/> network. getspringlayouter (). setlinkrepulsionfactor (30); <br/> network. getspringlayouter (). start (); <br/> network. getcanvasscrollpane (). setverticalscrollbarpolicy (scrollpaneconstants. vertical_scrollbar_never); <br/> network. getcanvasscrollpane (). sethorizontalscrollbarpolicy (scrollpaneconstants. horizontal_scrollbar_never); </P> <p> // when window resized, reset the spring layout limit bounds to canvas view port size. <br/> network. addcomponentlistener (New componentadapter () {</P> <p> @ override <br/> Public void componentresized (componentevent e) {<br/> network. getspringlayouter (). setlimitbounds (network. getcanvasscrollpane (). getbounds (); <br/>}< br/> });
Draw text description
I want to add some explanatory text, otherwise everyone will not know how to use it. Traditional text is too plain, and naturally does not conform to the aesthetic and style of the program. Just get fashion. Think of twaver's marker mechanism. This can paint anything on the topology graph. It meets my requirements! Therefore, fill a rectangle and then draw text:
Public class notemarker implements canvasmarker {</P> <p> private color backgroundcolor = new color (0,200,200, 50 ); <br/> private Font font = new font ("", Font. bold, 12); </P> <p> Public void mark (graphics2d g) {<br/> G. setcolor (backgroundcolor); <br/> G. fill3drect (50, 50,330,150, true); <br/> G. setfont (font); <br/> G. setcolor (color. white); <br/> G. setrenderinghint (renderinghints. key_antialiasing, renderinghints. value_antialias_on); <br/> int Space = 20; <br/> int x = 55; <br/> int y = 65; <br/> G. drawstring ("1. Double-click the color node green or yellow to expand the relationship", x, y); <br/> Y + = space; <br/> G. drawstring ("2. The gray node is an existing user", x, y); <br/> Y + = space; <br/> G. drawstring ("3. The green node is boy, the yellow node is girl", x, y); <br/> Y + = space; <br/> G. drawstring ("4. You can hover your mouse over this person's photo and blog URL", x, y); <br/> Y + = space; <br/> G. drawstring ("5. Select" annular layout "or" Spring layout "to switch the Layout Algorithm", x, y); <br/> Y + = space; <br/> G. drawstring ("6. Click" Expand randomly "to automatically expand nodes", x, y); <br/> Y + = space; <br/> G. drawstring ("7. Enter another csdn user name in the text box and click" Start again ", x, y); <br/>}< br/>}
Run the following code to install marker:
// Display notes on network canvas with a marker. <br/> network. addcanvasmarker (New notemarker ());
The effect is as follows:
In addition, a small function is added: After you hover your mouse over a node for a moment, you can use tooltip to display this person's photo and URL. At the same time, there is an amazing discovery: here we can support GIF animation!
Final Effect
For ease of expansion, a button is added to expand several nodes at will, saving a lot of mouse operations. After a burst of madness, we can see the complexity of the "relationship between people:
Download programs and source code
The source code and executable jar packages are provided here. If you are interested, you can continue to improve the functions on this basis. If you have the energy, you can make another javaeye version!
Because csdn is not very good at uploading attachments, you can download attachments from my javaeye blog:
Http://joshuaxiao.javaeye.com/
Thank you!