What's on your mind? Type two related topics that you are most interested in.
");
65 |
66 | // Create a label to display instructions.
67 | messageLabelA = new JLabel("Enter Topic A");
68 |
69 | // Create a text field 10 characters wide.
70 | topicA = new JTextField(10);
71 |
72 | messageLabelB = new JLabel("Topic B");
73 | topicB = new JTextField(10);
74 |
75 | // Create a button with the caption "Calculate".
76 | submitButton = new JButton("Submit");
77 |
78 | // Add an action listener to the button.
79 | submitButton.addActionListener(new ButtonListener());
80 |
81 | // Create a JPanel object and let the panel
82 | // field reference it.
83 | panel = new JPanel();
84 |
85 | // Add the label, text field, and button
86 | // components to the panel.
87 | panel.add(introduction);
88 | panel.add(messageLabelA);
89 | panel.add(topicA);
90 | panel.add(messageLabelB);
91 | panel.add(topicB);
92 | panel.add(submitButton);
93 |
94 | }
95 |
96 | class ButtonListener implements ActionListener {
97 |
98 | //String inputA;
99 | // String inputB; // To hold the user's input
100 |
101 | /**
102 | * The actionPerformed method executes when the user clicks on the
103 | * Submit button.
104 | *
105 | * @param e The event object.
106 | */
107 | @Override
108 | public void actionPerformed(ActionEvent e) {
109 |
110 | // Get the text entered by the user into the
111 | // text field.
112 | inputA = topicA.getText();
113 | inputB = topicB.getText();
114 | JOptionPane.showMessageDialog(null, "Thanks.");
115 |
116 |
117 | // For debugging, display a message indicating
118 | // the application is ready for more input.
119 |
120 | System.out.println("Ready for the next input");
121 |
122 | }
123 |
124 |
125 | public String getInputA() {
126 | return inputA;
127 | }
128 |
129 | public String getInputB() {
130 | return inputB;
131 | }
132 |
133 |
134 | } // End of SubmitButtonListener class
135 | /**
136 | * The main method creates an instance of the KiloConverterWindow class,
137 | * which displays its window on the screen.
138 | *
139 | * @param args
140 | */
141 | public static void main(String[] args) {
142 | Greetings greetings = new Greetings();
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/src/twittervis/TwitterDevApiKey.java:
--------------------------------------------------------------------------------
1 | package twittervis;
2 |
3 | /*
4 | * GPL 3.0 License
5 | */
6 |
7 | /**
8 | *
9 | * @author Xavier Wu
10 | */
11 | public interface TwitterDevApiKey {
12 |
13 | // The following credentials are NOT Valid. You need to get your own
14 | // API tokens from Twitter Developer Center
15 | // Go there and create an app on Twitter Dev. Copy and paste your
16 | // keys to the following four blocks.
17 | String KEY = "i0Rb2hdsj343Gv3k3k9UJGbSDPBjs";
18 | String SECRET = "QGcVkysdhfy7y7y2FZjndkukth7LYpHrWUmBkjpfsdfdsfKZwYqz";
19 | String TOKEN = "1859284573-U4XMRERD1Kfmt3icsLPHby7sfdy78yDSYGFcws3t";
20 | String TOKENSECRET = "9LiY0qwkFW5vHVDSHGF7Y7Y33AiKK9kfi0EXl9iuFL9";
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/twittervis/TwitterVis.java:
--------------------------------------------------------------------------------
1 | /*
2 | * GPL 3.0 License
3 | */
4 |
5 | package twittervis;
6 |
7 | import java.util.Iterator;
8 | import org.graphstream.graph.*;
9 | import org.graphstream.graph.implementations.*;
10 | import twitter4j.Query;
11 | import twitter4j.QueryResult;
12 | import twitter4j.Twitter;
13 | import twitter4j.TwitterException;
14 | import twitter4j.TwitterFactory;
15 | import twitter4j.conf.ConfigurationBuilder;
16 | import static twittervis.TwitterDevApiKey.KEY;
17 | import static twittervis.TwitterDevApiKey.SECRET;
18 | import static twittervis.TwitterDevApiKey.TOKEN;
19 | import static twittervis.TwitterDevApiKey.TOKENSECRET;
20 |
21 | public class TwitterVis {
22 |
23 | public static String keyword1;
24 | public static String keyword2;
25 | public ConfigurationBuilder cb;
26 | private final Graph graph;
27 | TwitterFactory tf;
28 | private String JoyNode;
29 | private String SadnessNode;
30 | private String AngerNode;
31 | private String DisgustNode;
32 | private String FearNode;
33 |
34 | public static void main(String args[]) {
35 |
36 | // The following two keywords will be taken as Search Keywords
37 | // They correspond to Topic A and Topic B
38 | keyword1 = "Trump";
39 | keyword2 = "Hilary";
40 | System.setProperty("org.graphstream.ui.renderer", "org.graphstream.ui.j2dviewer.J2DGraphRenderer");
41 | // Creating a new twitterVis instance
42 | TwitterVis twitterVis = new TwitterVis();
43 | }
44 |
45 | // Inititate an instance for twitter Search instance
46 | public void initiate() {
47 | cb = new ConfigurationBuilder();
48 | cb.setDebugEnabled(true)
49 | .setOAuthConsumerKey(KEY)
50 | .setOAuthConsumerSecret(SECRET)
51 | .setOAuthAccessToken(TOKEN)
52 | .setOAuthAccessTokenSecret(TOKENSECRET);
53 | tf = new TwitterFactory(cb.build());
54 |
55 | // Retrieve tweets for two topics using keyword1 and keyword2
56 | // the "true" and "false" values represent the binary status of two topics.
57 | // true = the 1st topic, and false = the 2nd topic
58 | retrieveTweets(keyword1, true);
59 | retrieveTweets(keyword2, false);
60 | }
61 |
62 |
63 | public void retrieveTweets(String keyword, boolean topic) {
64 |
65 |
66 | Twitter twitter = tf.getInstance();
67 | Query query = new Query(keyword);
68 | // The query parameter ("keyword") can be modified to make more
69 | // specific search queries based on language, users, time, etc.
70 | //Query query = new Query(keyword +" AND lang:en AND until:2016-12-01");
71 |
72 | //number of tweets needed for each topic.
73 | query.count(240);
74 |
75 | // Assign the tweets to the corresponding Emotion Node
76 | if (topic == true) {
77 | JoyNode = "Joy1";
78 | SadnessNode = "Sadness1";
79 | AngerNode = "Anger1";
80 | DisgustNode = "Disgust1";
81 | FearNode = "xFear1";
82 | } else {
83 | JoyNode = "Joy2";
84 | SadnessNode = "Sadness2";
85 | AngerNode = "Anger2";
86 | DisgustNode = "Disgust2";
87 | FearNode = "xFear2";
88 | }
89 |
90 | //Try making the query request.
91 | try {
92 | QueryResult result = twitter.search(query);
93 |
94 | // Process the analysis results and create new edges and nodes accordingly
95 | result.getTweets().forEach((status) -> {
96 | status.getText(); //get the textual info from a tweet
97 | // String userName = status.getUser().getScreenName();
98 | String TwtText = status.getText();
99 | System.out.println("@" + status.getUser().getScreenName() + ":" + status.getText());
100 | String twtEmotion = getTweetEmotion(TwtText);
101 |
102 | // A switch to assign the tweet to the correct node
103 | switch (twtEmotion) {
104 | case "Joy":
105 | System.out.println("Joy (*^__^*)");
106 | graph.addEdge(TwtText, JoyNode, TwtText);
107 | break;
108 | case "Sadness":
109 | System.out.println("Sad (*T_T*) ");
110 | graph.addEdge(TwtText, SadnessNode, TwtText);
111 | break;
112 | case "Anger":
113 | System.out.println("Anger ヽ(`Д´)ノ");
114 | graph.addEdge(TwtText, AngerNode, TwtText);
115 | break;
116 | case "Fear":
117 | System.out.println("Fear ⊙﹏⊙|||");
118 | graph.addEdge(TwtText, FearNode, TwtText);
119 | break;
120 | case "Disgust":
121 | System.out.println("Disgust (*⊙~⊙)");
122 | graph.addEdge(TwtText, DisgustNode, TwtText);
123 | break;
124 | }
125 | });
126 |
127 | } catch (TwitterException ex) { //fallback if exceptions occur
128 | System.out.println("Couldn't connect: " + ex);
129 | }
130 | }
131 |
132 | /**
133 | * Get the overall emotion of a single tweet
134 | * @param tweet
135 | * @return the final emotion of a single tweet
136 | */
137 | public String getTweetEmotion(String tweet) {
138 | GetEmotion newEmj = new GetEmotion(tweet);
139 | System.out.println("Final Emotion is: ");
140 | //System.out.println(GetEmotion.finalE);
141 | String twtEmotion = GetEmotion.finalE;
142 | return twtEmotion;
143 | }
144 |
145 | // Start the visualiztion part
146 | public TwitterVis() {
147 | graph = new SingleGraph("Twitter Visualization");
148 |
149 | System.setProperty("http.agent", "Chrome");
150 | graph.addAttribute("ui.stylesheet", "url('https://raw.githubusercontent.com/xavierwu2016/plexus/master/src/twittervis/stylesheet.css')");
151 | // the stylesheet can also be local, shown as below
152 | // graph.addAttribute("ui.stylesheet", "url('file:///Users/Xavier/NetBeansProjects/TwitterVis/src/twittervis/stylesheet.css')");
153 | graph.setAutoCreate(true);
154 | graph.setStrict(false);
155 | graph.display();
156 |
157 | // The topics here determine what to display in the graph
158 | // If you change the words below, you have to change them
159 | // in the stylesheet as well. tHE stylesheet is written in css
160 | // and thus the variables names cannot be altered here.
161 | // You need to change them manually.
162 | String topicA = "Trump";
163 | String topicB = "Hilary";
164 |
165 | // Create new edges
166 | // The following 10 "addEdge" commands will build the structure
167 | // of the visualization
168 | graph.addEdge("joy1", topicA, "Joy1");
169 | graph.addEdge("sadness1", topicA, "Sadness1");
170 | graph.addEdge("anger1", topicA, "Anger1");
171 | // There is an "x" before Fear1 because of a bug in Java AWT
172 | // The node name cannot start with or contain "fea" otherwise
173 | // it will be read as a color element, like #ffeeaa
174 | graph.addEdge("xfear1", topicA, "xFear1");
175 | graph.addEdge("disgust1", topicA, "Disgust1");
176 |
177 | graph.addEdge("joy2", topicB, "Joy2");
178 | graph.addEdge("sadness2", topicB, "Sadness2");
179 | graph.addEdge("anger2", topicB, "Anger2");
180 | graph.addEdge("xfear2", topicB, "xFear2");
181 | graph.addEdge("disgust2", topicB, "Disgust2");
182 |
183 | Node n = graph.getNode(topicA);
184 |
185 | // Label all the nodes
186 | for (Node node : graph) {
187 | node.addAttribute("ui.label", node.getId());
188 | }
189 |
190 | initiate();
191 |
192 | // Label the nodes for tweets again.
193 | for (Node node : graph) {
194 | node.addAttribute("ui.label", node.getId());
195 | }
196 |
197 | }
198 |
199 | // apply the styles based on the ui class
200 | public void explore(Node source) {
201 | Iterator extends Node> k = source.getBreadthFirstIterator();
202 |
203 | while (k.hasNext()) {
204 | Node next = k.next();
205 | next.setAttribute("ui.class", "marked");
206 |
207 | sleep();
208 | }
209 | }
210 |
211 | protected void sleep() {
212 | try {
213 | Thread.sleep(10);
214 | } catch (InterruptedException e) {
215 | }
216 | }
217 | }
218 |
--------------------------------------------------------------------------------
/src/twittervis/stylesheet.css:
--------------------------------------------------------------------------------
1 | /* This stylesheet defines the styles of all elements in the graph */
2 | /* Author: Xavier Wu*/
3 |
4 | graph {
5 | fill-color: #e6e6e6;
6 | padding: 10px;
7 |
8 | }
9 |
10 | node { fill-color: #E59D77;
11 | size: 12px,12px;
12 | text-visibility-mode: hidden;
13 | }
14 |
15 | node#Trump { size: 55px;
16 | text-size: 13;
17 | text-style: bold;
18 | text-alignment: center;
19 | shape: rounded-box;
20 | fill-color: #95C2DC;
21 | text-visibility-mode: normal;
22 | }
23 |
24 | node#Hilary { size: 55px;
25 | text-size: 13;
26 | text-style: bold;
27 | text-alignment: center;
28 | shape: rounded-box;
29 | fill-color: #79C7CC;
30 | text-visibility-mode: normal;
31 | }
32 |
33 | node#Joy1 { size: 33px;
34 | stroke-width: 6px;
35 | text-alignment: under;
36 | /* fill-color: #FF8B2B; */
37 | fill-mode: image-scaled;
38 | fill-image: url('https://raw.githubusercontent.com/xavierwu2016/plexus/master/style/joy.png');
39 | }
40 |
41 | node#Joy2 { size: 35px;
42 | stroke-width: 6px;
43 | text-alignment: under;
44 | fill-mode: image-scaled;
45 | fill-image: url('https://raw.githubusercontent.com/xavierwu2016/plexus/master/style/joy.png');
46 | }
47 |
48 | node#Sadness1 { size: 35px;
49 | stroke-width: 6px;
50 | text-alignment: under;
51 | fill-color: #8EA9C4;
52 | fill-mode: image-scaled;
53 | fill-image: url('https://raw.githubusercontent.com/xavierwu2016/plexus/master/style/sad.png');
54 | }
55 |
56 | node#Sadness2 { size: 35px;
57 | stroke-width: 6px;
58 | text-alignment: under;
59 | fill-color: #8EA9C4;
60 | fill-mode: image-scaled;
61 | fill-image: url('https://raw.githubusercontent.com/xavierwu2016/plexus/master/style/sad.png');
62 | }
63 |
64 | node#Anger1 { size: 35px;
65 | stroke-width: 6px;
66 | text-alignment: under;
67 | fill-color: #DC0530;
68 | fill-mode: image-scaled;
69 | fill-image: url('https://raw.githubusercontent.com/xavierwu2016/plexus/master/style/anger.png');
70 | }
71 |
72 | node#Anger2 { size: 35px;
73 | stroke-width: 6px;
74 | text-alignment: under;
75 | fill-color: #DC0530;
76 | fill-mode: image-scaled;
77 | fill-image: url('https://raw.githubusercontent.com/xavierwu2016/plexus/master/style/anger.png');
78 | }
79 |
80 | node#Disgust1 { size: 35px;
81 | stroke-width: 6px;
82 | text-alignment: under;
83 | fill-color: #D3C314;
84 | fill-mode: image-scaled;
85 | fill-image: url('https://raw.githubusercontent.com/xavierwu2016/plexus/master/style/disgust.png');
86 | }
87 |
88 | node#Disgust2 { size: 35px;
89 | stroke-width: 6px;
90 | text-alignment: under;
91 | fill-color: #D3C314;
92 | fill-mode: image-scaled;
93 | fill-image: url('https://raw.githubusercontent.com/xavierwu2016/plexus/master/style/disgust.png');
94 | }
95 |
96 | node#xFear1{ size: 35px;
97 | stroke-width: 6px;
98 | text-alignment: under;
99 | fill-color: #9B84F8;
100 | fill-mode: image-scaled;
101 | fill-image: url('https://raw.githubusercontent.com/xavierwu2016/plexus/master/style/fear.png');
102 |
103 | }
104 | node#xFear2 { size: 35px;
105 | stroke-width: 6px;
106 | text-alignment: under;
107 | fill-color: #9B84F8;
108 | fill-mode: image-scaled;
109 | fill-image: url('https://raw.githubusercontent.com/xavierwu2016/plexus/master/style/fear.png');
110 | }
111 |
112 | node:clicked {
113 | text-visibility-mode: normal;
114 | text-size: 15;
115 | fill-color: red;
116 | text-alignment: under;
117 | }
118 |
119 | edge { size: 0.5px; fill-color:#a6a6a6;}
120 | edge#joy1 { shape: blob; size: 1px; fill-color:#a6a6a6;}
121 | edge#joy2 { shape: blob; size: 1px; fill-color:#a6a6a6;}
122 | edge#sadness1 { shape: blob; size: 1px; fill-color:#a6a6a6;}
123 | edge#sadness2 { shape: blob; size: 1px; fill-color:#a6a6a6;}
124 | edge#anger1 { shape: blob; size: 1px; fill-color:#a6a6a6;}
125 | edge#anger2 { shape: blob; size: 1px; fill-color:#a6a6a6;}
126 | edge#disgust1 { shape: blob; size: 1px; fill-color:#a6a6a6;}
127 | edge#disgust2 { shape: blob; size: 1px; fill-color:#a6a6a6;}
128 | edge#xfear1 { shape: blob; size: 1px; fill-color:#a6a6a6;}
129 | edge#xfear2{ shape: blob; size: 1px; fill-color:#a6a6a6;}
--------------------------------------------------------------------------------
/style/ImagesFromPublication/emoji.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xavierwu2016/plexus/a1a237125de5750d4a7557926505d01af81231c8/style/ImagesFromPublication/emoji.png
--------------------------------------------------------------------------------
/style/ImagesFromPublication/hilaryVStrump-timeline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xavierwu2016/plexus/a1a237125de5750d4a7557926505d01af81231c8/style/ImagesFromPublication/hilaryVStrump-timeline.png
--------------------------------------------------------------------------------
/style/ImagesFromPublication/hilaryVStrump.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xavierwu2016/plexus/a1a237125de5750d4a7557926505d01af81231c8/style/ImagesFromPublication/hilaryVStrump.png
--------------------------------------------------------------------------------
/style/ImagesFromPublication/iphoneVSsamsung.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xavierwu2016/plexus/a1a237125de5750d4a7557926505d01af81231c8/style/ImagesFromPublication/iphoneVSsamsung.png
--------------------------------------------------------------------------------
/style/ImagesFromPublication/ui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xavierwu2016/plexus/a1a237125de5750d4a7557926505d01af81231c8/style/ImagesFromPublication/ui.png
--------------------------------------------------------------------------------
/style/ImagesFromPublication/vanVSla.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xavierwu2016/plexus/a1a237125de5750d4a7557926505d01af81231c8/style/ImagesFromPublication/vanVSla.png
--------------------------------------------------------------------------------
/style/anger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xavierwu2016/plexus/a1a237125de5750d4a7557926505d01af81231c8/style/anger.png
--------------------------------------------------------------------------------
/style/disgust.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xavierwu2016/plexus/a1a237125de5750d4a7557926505d01af81231c8/style/disgust.png
--------------------------------------------------------------------------------
/style/fear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xavierwu2016/plexus/a1a237125de5750d4a7557926505d01af81231c8/style/fear.png
--------------------------------------------------------------------------------
/style/joy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xavierwu2016/plexus/a1a237125de5750d4a7557926505d01af81231c8/style/joy.png
--------------------------------------------------------------------------------
/style/sad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xavierwu2016/plexus/a1a237125de5750d4a7557926505d01af81231c8/style/sad.png
--------------------------------------------------------------------------------