package jp.yucchi.personalitydiagnosis;
import com.ibm.watson.developer_cloud.personality_insights.v3.model.Profile;
import com.ibm.watson.developer_cloud.personality_insights.v3.model.Trait;
import java.io.StringReader;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.concurrent.Task;
import static javafx.concurrent.Worker.State.RUNNING;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontSmoothingType;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import javafx.util.Duration;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
import twitter4j.Status;
/**
*
* @author Yucchi
*/
public class FXMLPersonalityDiagnosisController implements Initializable {
@FXML
private ResourceBundle resources;
@FXML
private URL location;
@FXML
private AnchorPane anchorPane;
@FXML
private Canvas personalityChart;
@FXML
private Canvas personalityCanvas;
@FXML
private Canvas needsChart;
@FXML
private Canvas needsCanvas;
@FXML
private Canvas valuesChart;
@FXML
private Canvas valuesCanvas;
@FXML
private Label big5Label;
@FXML
private Label needsLabel;
@FXML
private Label valueLabel;
@FXML
private Label idLabel;
@FXML
private TextField idTextField;
@FXML
private Button diagnosisButton;
@FXML
private Button cancelButton;
@FXML
private ProgressIndicator progressIndicator;
@FXML
private Button clearButton;
@FXML
private Label messageLabel;
// PersonalityChart 頂点の座標
// 知的好奇心
private double opennessX;
private double opennessY;
// 誠実性
private double conscientiousnessX;
private double conscientiousnessY;
// 外向性
private double extraversionX;
private double extraversionY;
// 感情起伏
private double emotionalRangeX;
private double emotionalRangeY;
// 協調性
private double agreeablenessX;
private double agreeablenessY;
// NeedsChart 頂点の座標
// 実用主義
private double practicalityX;
private double practicalityY;
// 好奇心
private double curiosityX;
private double curiosityY;
// 自己表現
private double selfExpressionX;
private double selfExpressionY;
// 理想
private double idealX;
private double idealY;
// 自由主義
private double libertyX;
private double libertyY;
// 安定性
private double stabilityX;
private double stabilityY;
// 仕組
private double structureX;
private double structureY;
// 興奮
private double excitementX;
private double excitementY;
// 挑戦
private double challengeX;
private double challengeY;
// 社会性
private double loveX;
private double loveY;
// 調和
private double harmonyX;
private double harmonyY;
// 親密
private double closenessX;
private double closenessY;
// ValueChart 頂点の座標
// 快楽主義
private double hedonismX;
private double hedonismY;
// 自己増進
private double selfEnhancementX;
private double selfEnhancementY;
// 変化許容性
private double opennessToChangeX;
private double opennessToChangeY;
// 現状維持
private double conservationX;
private double conservationY;
// 自己超越
private double selfTranscendenceX;
private double selfTranscendenceY;
private final ExecutorService service = Executors.newSingleThreadExecutor();
private Task<Profile> task;
private TweetCollection tweetCollection;
private PersonalityAnalysis personalityAnalysis;
private GraphicsContext personalityGc;
private GraphicsContext needsGc;
private GraphicsContext valuesGc;
private double width;
private double jpCenterHeight;
private double offset;
@FXML
void cancel(ActionEvent event) {
task.cancel();
}
@FXML
void diagnosis(ActionEvent event) {
clearChart();
getprofile();
}
@FXML
void clear(ActionEvent event) {
clearChart();
idTextField.clear();
messageLabel.textProperty().unbind();
messageLabel.setText("Please enter the Twitter ID and press the diagnosis button.");
}
private void getprofile() {
progressIndicator.setOpacity(1.0);
task = new Task<>() {
@Override
protected Profile call() throws Exception {
List<Status> tweets;
Profile profile;
updateMessage("Getting a tweets.");
tweets = tweetCollection.getTweets(idTextField, task);
if (isCancelled()) {
return null;
}
updateMessage("Completed getting tweets. Personality analysis started. Please wait for a while.");
profile = personalityAnalysis.toAnalyze(tweets);
if (profile == null) {
failed();
}
return profile;
}
@Override
protected void succeeded() {
super.succeeded();
Profile profile = getValue();
List<Trait> personality = profile.getPersonality();
List<Trait> needs = profile.getNeeds();
List<Trait> values = profile.getValues();
JsonObject jsonObject;
try (JsonReader jsonReader = Json.createReader(new StringReader(profile.toString()))) {
jsonObject = jsonReader.readObject();
}
updateMessage("Personality analysis is completed with " + jsonObject.getInt("word_count") + " words of Tweet.");
Map<String, Double> personalityMap = new HashMap<>(personality.size());
Map<String, Double> valuesMap = new HashMap<>(values.size());
Map<String, Double> needsMap = new HashMap<>(needs.size());
for (int i = 0; personality.size() > i; i++) {
String key = jsonObject.getJsonArray("personality").getJsonObject(i).getJsonString("name").getString();
double value = jsonObject.getJsonArray("personality").getJsonObject(i).getJsonNumber("percentile").doubleValue();
personalityMap.put(key, value);
}
for (int i = 0; values.size() > i; i++) {
String key = jsonObject.getJsonArray("values").getJsonObject(i).getJsonString("name").getString();
double value = jsonObject.getJsonArray("values").getJsonObject(i).getJsonNumber("percentile").doubleValue();
valuesMap.put(key, value);
}
for (int i = 0; needs.size() > i; i++) {
String key = jsonObject.getJsonArray("needs").getJsonObject(i).getJsonString("name").getString();
double value = jsonObject.getJsonArray("needs").getJsonObject(i).getJsonNumber("percentile").doubleValue();
needsMap.put(key, value);
}
drawPersonalityResult(personalityMap);
drawNeedsResult(needsMap);
drawValuesResult(valuesMap);
}
@Override
protected void cancelled() {
super.cancelled();
updateMessage("Cancelled!");
clearChart();
}
@Override
protected void failed() {
super.failed();
updateMessage("Failed! An unexpected error occurred for some reason.");
}
private void drawPersonalityResult(Map<String, Double> personalityMap) {
// PersonalityResult
double openness = personalityMap.getOrDefault("知的好奇心", 0.0);
double conscientiousness = personalityMap.getOrDefault("誠実性", 0.0);
double extraversion = personalityMap.getOrDefault("外向性", 0.0);
double emotionalRange = personalityMap.getOrDefault("感情起伏", 0.0);
double agreeableness = personalityMap.getOrDefault("協調性", 0.0);
// チャート表示用
String opennessResult = String.format("%.2f", openness * 100).concat("%");
String conscientiousnessResult = String.format("%.2f", conscientiousness * 100).concat("%");
String extraversionResult = String.format("%.2f", extraversion * 100).concat("%");
String emotionalRangeResult = String.format("%.2f", emotionalRange * 100).concat("%");
String agreeablenessResult = String.format("%.2f", agreeableness * 100).concat("%");
// 原点
final double originX = personalityCanvas.getWidth() / 2;
final double originY = personalityCanvas.getHeight() / 2;
// ライン長さ
final double lineLength = 150.0;
// 項目数
final int items = personalityMap.size();
// 知的好奇心 スコアポジション
final double opennessScoreX = getPositionX(originX, lineLength, openness, items, 0);
final double opennessScoreY = getPositionY(originY, lineLength, openness, items, 0);
// 誠実性 スコアポジション
final double conscientiousnessScoreX = getPositionX(originX, lineLength, conscientiousness, items, 1);
final double conscientiousnessScoreY = getPositionY(originY, lineLength, conscientiousness, items, 1);
// 外向性 スコアポジション
final double extraversionScoreX = getPositionX(originX, lineLength, extraversion, items, 2);
final double extraversionScoreY = getPositionY(originY, lineLength, extraversion, items, 2);
// 感情起伏 スコアポジション
final double emotionalRangeScoreX = getPositionX(originX, lineLength, emotionalRange, items, 3);
final double emotionalRangeScoreY = getPositionY(originY, lineLength, emotionalRange, items, 3);
// 協調性 スコアポジション
final double agreeablenessScoreX = getPositionX(originX, lineLength, agreeableness, items, 4);
final double agreeablenessScoreY = getPositionY(originY, lineLength, agreeableness, items, 4);
// スコア表示
personalityGc.setStroke(Color.rgb(255, 0, 255));
personalityGc.setLineWidth(2);
personalityGc.beginPath();
personalityGc.moveTo(opennessScoreX, opennessScoreY);
personalityGc.lineTo(conscientiousnessScoreX, conscientiousnessScoreY);
personalityGc.lineTo(extraversionScoreX, extraversionScoreY);
personalityGc.lineTo(emotionalRangeScoreX, emotionalRangeScoreY);
personalityGc.lineTo(agreeablenessScoreX, agreeablenessScoreY);
personalityGc.closePath();
personalityGc.stroke();
personalityGc.setFill(Color.rgb(255, 0, 255, 0.3));
personalityGc.fill();
// 項目 結果表示
personalityGc.setFontSmoothingType(FontSmoothingType.LCD);
personalityGc.setFont(Font.font(18));
personalityGc.setFill(Color.RED);
personalityGc.fillText(opennessResult, opennessX - width * 5 / 2, opennessY + jpCenterHeight - offset - offset * 1.1);
personalityGc.fillText(conscientiousnessResult, conscientiousnessX + width / 2, conscientiousnessY + jpCenterHeight - offset * 1.1);
personalityGc.fillText(extraversionResult, extraversionX - width, extraversionY + jpCenterHeight + offset + offset * 1.1);
personalityGc.fillText(emotionalRangeResult, emotionalRangeX - width * 9 / 4, emotionalRangeY + jpCenterHeight + offset + offset * 1.1);
personalityGc.fillText(agreeablenessResult, agreeablenessX - width * 7 / 2, agreeablenessY + jpCenterHeight - offset * 1.1);
}
private void drawNeedsResult(Map<String, Double> needsMap) {
// NeedsResult
double practicality = needsMap.getOrDefault("実用主義", 0.0);
double curiosity = needsMap.getOrDefault("好奇心", 0.0);
double selfExpression = needsMap.getOrDefault("自己表現", 0.0);
double ideal = needsMap.getOrDefault("理想", 0.0);
double liberty = needsMap.getOrDefault("自由主義", 0.0);
double stability = needsMap.getOrDefault("安定性", 0.0);
double structure = needsMap.getOrDefault("仕組", 0.0);
double excitement = needsMap.getOrDefault("興奮", 0.0);
double challenge = needsMap.getOrDefault("挑戦", 0.0);
double love = needsMap.getOrDefault("社会性", 0.0);
double harmony = needsMap.getOrDefault("調和", 0.0);
double closeness = needsMap.getOrDefault("親密", 0.0);
// チャート表示用
String practicalityResult = String.format("%.2f", practicality * 100).concat("%");
String curiosityResult = String.format("%.2f", curiosity * 100).concat("%");
String selfExpressionResult = String.format("%.2f", selfExpression * 100).concat("%");
String idealResult = String.format("%.2f", ideal * 100).concat("%");
String libertyResult = String.format("%.2f", liberty * 100).concat("%");
String stabilityResult = String.format("%.2f", stability * 100).concat("%");
String structureResult = String.format("%.2f", structure * 100).concat("%");
String excitementResult = String.format("%.2f", excitement * 100).concat("%");
String challengeResult = String.format("%.2f", challenge * 100).concat("%");
String loveResult = String.format("%.2f", love * 100).concat("%");
String harmonyResult = String.format("%.2f", harmony * 100).concat("%");
String closenessResult = String.format("%.2f", closeness * 100).concat("%");
// 原点
final double originX = needsCanvas.getWidth() / 2;
final double originY = needsCanvas.getHeight() / 2;
// ライン長さ
final double lineLength = 150.0;
// 項目数
final int items = needsMap.size();
// 実用主義 スコアポジション
final double practicalityScoreX = getPositionX(originX, lineLength, practicality, items, 0);
final double practicalityScoreY = getPositionY(originY, lineLength, practicality, items, 0);
// 好奇心 スコアポジション
final double curiosityScoreX = getPositionX(originX, lineLength, curiosity, items, 1);
final double curiosityScoreY = getPositionY(originY, lineLength, curiosity, items, 1);
// 自己表現 スコアポジション
final double selfExpressionScoreX = getPositionX(originX, lineLength, selfExpression, items, 2);
final double selfExpressionScoreY = getPositionY(originY, lineLength, selfExpression, items, 2);
// 理想 スコアポジション
final double idealScoreX = getPositionX(originX, lineLength, ideal, items, 3);
final double idealScoreY = getPositionY(originY, lineLength, ideal, items, 3);
// 自由主義 スコアポジション
final double libertyScoreX = getPositionX(originX, lineLength, liberty, items, 4);
final double libertyScoreY = getPositionY(originY, lineLength, liberty, items, 4);
// 安定性 スコアポジション
final double stabilityScoreX = getPositionX(originX, lineLength, stability, items, 5);
final double stabilityScoreY = getPositionY(originY, lineLength, stability, items, 5);
// 仕組 スコアポジション
final double structureScoreX = getPositionX(originX, lineLength, structure, items, 6);
final double structureScoreY = getPositionY(originY, lineLength, structure, items, 6);
// 興奮 スコアポジション
final double excitementScoreX = getPositionX(originX, lineLength, excitement, items, 7);
final double excitementScoreY = getPositionY(originY, lineLength, excitement, items, 7);
// 挑戦 スコアポジション
final double challengeScoreX = getPositionX(originX, lineLength, challenge, items, 8);
final double challengeScoreY = getPositionY(originY, lineLength, challenge, items, 8);
// 社会性 スコアポジション
final double loveScoreX = getPositionX(originX, lineLength, love, items, 9);
final double loveScoreY = getPositionY(originY, lineLength, love, items, 9);
// 調和 スコアポジション
final double harmonyScoreX = getPositionX(originX, lineLength, harmony, items, 10);
final double harmonyScoreY = getPositionY(originY, lineLength, harmony, items, 10);
// 親密 スコアポジション
final double closenessScoreX = getPositionX(originX, lineLength, closeness, items, 11);
final double closenessScoreY = getPositionY(originY, lineLength, closeness, items, 11);
// スコア表示
needsGc.setStroke(Color.rgb(255, 0, 255));
needsGc.setLineWidth(2);
needsGc.beginPath();
needsGc.moveTo(practicalityScoreX, practicalityScoreY);
needsGc.lineTo(curiosityScoreX, curiosityScoreY);
needsGc.lineTo(selfExpressionScoreX, selfExpressionScoreY);
needsGc.lineTo(idealScoreX, idealScoreY);
needsGc.lineTo(libertyScoreX, libertyScoreY);
needsGc.lineTo(stabilityScoreX, stabilityScoreY);
needsGc.lineTo(structureScoreX, structureScoreY);
needsGc.lineTo(excitementScoreX, excitementScoreY);
needsGc.lineTo(challengeScoreX, challengeScoreY);
needsGc.lineTo(loveScoreX, loveScoreY);
needsGc.lineTo(harmonyScoreX, harmonyScoreY);
needsGc.lineTo(closenessScoreX, closenessScoreY);
needsGc.closePath();
needsGc.stroke();
needsGc.setFill(Color.rgb(255, 0, 255, 0.3));
needsGc.fill();
// 項目 結果表示
needsGc.setFontSmoothingType(FontSmoothingType.LCD);
needsGc.setFont(Font.font(18));
needsGc.setFill(Color.RED);
needsGc.fillText(practicalityResult, practicalityX - width * 4 / 2, practicalityY + jpCenterHeight - offset - offset * 1.1);
needsGc.fillText(curiosityResult, curiosityX + width / 2, curiosityY + jpCenterHeight - offset / 2 - offset * 1.1);
needsGc.fillText(selfExpressionResult, selfExpressionX + width / 2, selfExpressionY - jpCenterHeight + offset / 2 - offset * 1.1);
needsGc.fillText(idealResult, idealX + width / 2, idealY + jpCenterHeight - offset * 1.1);
needsGc.fillText(libertyResult, libertyX + width / 2, libertyY + jpCenterHeight + offset / 2 + offset * 1.1);;
needsGc.fillText(stabilityResult, stabilityX + width / 2, stabilityY - jpCenterHeight + offset * 1.5 + offset * 1.1);
needsGc.fillText(structureResult, structureX - width * 2 / 2, structureY + jpCenterHeight + offset + offset * 1.1);
needsGc.fillText(excitementResult, excitementX - width * 5 / 2, excitementY - jpCenterHeight + offset * 1.5 + offset * 1.1);
needsGc.fillText(challengeResult, challengeX - width * 5 / 2, challengeY + jpCenterHeight + offset / 2 + offset * 1.1);
needsGc.fillText(loveResult, loveX - width * 7 / 2, loveY + jpCenterHeight - offset * 1.1);
needsGc.fillText(harmonyResult, harmonyX - width * 5 / 2, harmonyY - jpCenterHeight + offset / 2 - offset * 1.1);
needsGc.fillText(closenessResult, closenessX - width * 5 / 2, closenessY + jpCenterHeight - offset / 2 - offset * 1.1);
}
private void drawValuesResult(Map<String, Double> valuesMap) {
double hedonism = valuesMap.getOrDefault("快楽主義", 0.0);
double selfEnhancement = valuesMap.getOrDefault("自己増進", 0.0);
double opennessToChange = valuesMap.getOrDefault("変化許容性", 0.0);
double conservation = valuesMap.getOrDefault("現状維持", 0.0);
double selfTranscendence = valuesMap.getOrDefault("自己超越", 0.0);
String hedonismResult = String.format("%.2f", hedonism * 100).concat("%");
String selfEnhancementResult = String.format("%.2f", selfEnhancement * 100).concat("%");
String opennessToChangeResult = String.format("%.2f", opennessToChange * 100).concat("%");
String conservationResult = String.format("%.2f", conservation * 100).concat("%");
String selfTranscendenceResult = String.format("%.2f", selfTranscendence * 100).concat("%");
// 原点
final double originX = valuesCanvas.getWidth() / 2;
final double originY = valuesCanvas.getHeight() / 2;
// ライン長さ
final double lineLength = 150.0;
// 項目数
final int items = valuesMap.size();
// 快楽主義 スコアポジション
final double hedonismScoreX = getPositionX(originX, lineLength, hedonism, items, 0);
final double hedonismScoreY = getPositionY(originY, lineLength, hedonism, items, 0);
// 自己増進 スコアポジション
final double selfEnhancementScoreX = getPositionX(originX, lineLength, selfEnhancement, items, 1);
final double selfEnhancementScoreY = getPositionY(originY, lineLength, selfEnhancement, items, 1);
// 変化許容性 スコアポジション
final double opennessToChangeScoreX = getPositionX(originX, lineLength, opennessToChange, items, 2);
final double opennessToChangeScoreY = getPositionY(originY, lineLength, opennessToChange, items, 2);
// 現状維持 スコアポジション
final double conservationScoreX = getPositionX(originX, lineLength, conservation, items, 3);
final double conservationScoreY = getPositionY(originY, lineLength, conservation, items, 3);
// 自己超越 スコアポジション
final double selfTranscendenceScoreX = getPositionX(originX, lineLength, selfTranscendence, items, 4);
final double selfTranscendenceScoreY = getPositionY(originY, lineLength, selfTranscendence, items, 4);
// スコア表示
valuesGc.setStroke(Color.rgb(255, 0, 255));
valuesGc.setLineWidth(2);
valuesGc.beginPath();
valuesGc.moveTo(hedonismScoreX, hedonismScoreY);
valuesGc.lineTo(selfEnhancementScoreX, selfEnhancementScoreY);
valuesGc.lineTo(opennessToChangeScoreX, opennessToChangeScoreY);
valuesGc.lineTo(conservationScoreX, conservationScoreY);
valuesGc.lineTo(selfTranscendenceScoreX, selfTranscendenceScoreY);
valuesGc.closePath();
valuesGc.stroke();
valuesGc.setFill(Color.rgb(255, 0, 255, 0.3));
valuesGc.fill();
// 項目 結果表示
valuesGc.setFontSmoothingType(FontSmoothingType.LCD);
valuesGc.setFont(Font.font(18));
valuesGc.setFill(Color.RED);
valuesGc.fillText(hedonismResult, hedonismX - width * 4 / 2, hedonismY + jpCenterHeight - offset - offset * 1.1);
valuesGc.fillText(selfEnhancementResult, selfEnhancementX + width / 2, selfEnhancementY + jpCenterHeight - offset * 1.1);
valuesGc.fillText(opennessToChangeResult, opennessToChangeX - width * 2, opennessToChangeY + jpCenterHeight + offset + offset * 1.1);
valuesGc.fillText(conservationResult, conservationX - width * 9 / 4, conservationY + jpCenterHeight + offset + offset * 1.1);
valuesGc.fillText(selfTranscendenceResult, selfTranscendenceX - width * 9 / 2, selfTranscendenceY + jpCenterHeight - offset * 1.1);
}
};
service.submit(task);
idTextField.editableProperty().bind(task.stateProperty().isNotEqualTo(RUNNING));
diagnosisButton.disableProperty().bind(Bindings.or(
task.stateProperty().isEqualTo(RUNNING),
idTextField.textProperty().isEmpty()));
cancelButton.disableProperty().bind(task.stateProperty().isNotEqualTo(RUNNING));
clearButton.disableProperty().bind(task.stateProperty().isEqualTo(RUNNING));
progressIndicator.visibleProperty().bind(task.stateProperty().isEqualTo(RUNNING));
messageLabel.textProperty().bind(task.messageProperty());
}
@Override
public void initialize(URL url, ResourceBundle rb) {
tweetCollection = new TweetCollection();
personalityAnalysis = new PersonalityAnalysis();
personalityGc = personalityCanvas.getGraphicsContext2D();
needsGc = needsCanvas.getGraphicsContext2D();
valuesGc = valuesCanvas.getGraphicsContext2D();
progressIndicator.setProgress(-1.0);
diagnosisButton.disableProperty().bind(idTextField.textProperty().isEmpty());
// Canvas のテキスト座標設定に使う。生肉、焼肉、苦肉の策としてこうなった。(>_<。) 今後の課題とする。
Text text = new Text("夢");
text.setFont(Font.font(18));
width = text.getBoundsInLocal().getWidth();
jpCenterHeight = (2 * text.getBaselineOffset() - text.getBoundsInLocal().getHeight()) / 2;
offset = text.getFont().getSize();
drawPersonalityChart();
drawNeedsChart();
drawValueChart();
}
void setStage(Stage stage) {
stage.setOnCloseRequest((WindowEvent we) -> {
// クロージングアニメーション
DoubleProperty closeOpacityProperty = new SimpleDoubleProperty(1.0);
stage.opacityProperty().bind(closeOpacityProperty);
Timeline closeTimeline = new Timeline(
new KeyFrame(
new Duration(100),
new KeyValue(closeOpacityProperty, 1.0)
), new KeyFrame(
new Duration(2_500),
new KeyValue(closeOpacityProperty, 0.0)
));
EventHandler<ActionEvent> eh = ae -> {
service.shutdownNow();
Platform.exit();
System.exit(0);
};
closeTimeline.setOnFinished(eh);
closeTimeline.setCycleCount(1);
closeTimeline.play();
we.consume();
});
}
private void drawPersonalityChart() {
// 原点
final double originX = personalityChart.getWidth() / 2;
final double originY = personalityChart.getHeight() / 2;
// ライン長さ
final double lineLength = 150.0;
// 項目数
final int items = 5;
// 知的好奇心
opennessX = getPositionX(originX, lineLength, 1.0, items, 0);
opennessY = getPositionY(originY, lineLength, 1.0, items, 0);
// 誠実性
conscientiousnessX = getPositionX(originX, lineLength, 1.0, items, 1);
conscientiousnessY = getPositionY(originY, lineLength, 1.0, items, 1);
// 外向性
extraversionX = getPositionX(originX, lineLength, 1.0, items, 2);
extraversionY = getPositionY(originY, lineLength, 1.0, items, 2);
// 感情起伏
emotionalRangeX = getPositionX(originX, lineLength, 1.0, items, 3);
emotionalRangeY = getPositionY(originY, lineLength, 1.0, items, 3);
// 協調性
agreeablenessX = getPositionX(originX, lineLength, 1.0, items, 4);
agreeablenessY = getPositionY(originY, lineLength, 1.0, items, 4);
GraphicsContext gc = personalityChart.getGraphicsContext2D();
gc.setStroke(Color.BLUE);
gc.setLineWidth(1);
gc.strokeLine(originX, originY, opennessX, opennessY);
gc.strokeLine(originX, originY, conscientiousnessX, conscientiousnessY);
gc.strokeLine(originX, originY, extraversionX, extraversionY);
gc.strokeLine(originX, originY, emotionalRangeX, emotionalRangeY);
gc.strokeLine(originX, originY, agreeablenessX, agreeablenessY);
for (int i = 0; 6 > i; i++) {
gc.beginPath();
gc.moveTo(getPositionX(originX, lineLength, i * 0.2, items, 0), getPositionY(originY, lineLength, i * 0.2, items, 0));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 1), getPositionY(originY, lineLength, i * 0.2, items, 1));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 2), getPositionY(originY, lineLength, i * 0.2, items, 2));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 3), getPositionY(originY, lineLength, i * 0.2, items, 3));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 4), getPositionY(originY, lineLength, i * 0.2, items, 4));
gc.closePath();
gc.stroke();
}
gc.setFontSmoothingType(FontSmoothingType.LCD);
gc.setFont(Font.font(18));
gc.setFill(Color.RED);
gc.fillText("知的好奇心", opennessX - width * 5 / 2, opennessY + jpCenterHeight - offset);
gc.fillText("誠実性", conscientiousnessX + width / 2, conscientiousnessY + jpCenterHeight);
gc.fillText("外向性", extraversionX - width, extraversionY + jpCenterHeight + offset);
gc.fillText("感情起伏", emotionalRangeX - width * 9 / 4, emotionalRangeY + jpCenterHeight + offset);
gc.fillText("協調性", agreeablenessX - width * 7 / 2, agreeablenessY + jpCenterHeight);
}
private void drawNeedsChart() {
// 原点
final double originX = needsChart.getWidth() / 2;
final double originY = needsChart.getHeight() / 2;
// ライン長さ
final double lineLength = 150.0;
// 項目数
final int items = 12;
// 実用主義
practicalityX = getPositionX(originX, lineLength, 1.0, items, 0);
practicalityY = getPositionY(originY, lineLength, 1.0, items, 0);
// 好奇心
curiosityX = getPositionX(originX, lineLength, 1.0, items, 1);
curiosityY = getPositionY(originY, lineLength, 1.0, items, 1);
// 自己表現
selfExpressionX = getPositionX(originX, lineLength, 1.0, items, 2);
selfExpressionY = getPositionY(originY, lineLength, 1.0, items, 2);
// 理想
idealX = getPositionX(originX, lineLength, 1.0, items, 3);
idealY = getPositionY(originY, lineLength, 1.0, items, 3);
// 自由主義
libertyX = getPositionX(originX, lineLength, 1.0, items, 4);
libertyY = getPositionY(originY, lineLength, 1.0, items, 4);
// 安定性
stabilityX = getPositionX(originX, lineLength, 1.0, items, 5);
stabilityY = getPositionY(originY, lineLength, 1.0, items, 5);
// 仕組
structureX = getPositionX(originX, lineLength, 1.0, items, 6);
structureY = getPositionY(originY, lineLength, 1.0, items, 6);
// 興奮
excitementX = getPositionX(originX, lineLength, 1.0, items, 7);
excitementY = getPositionY(originY, lineLength, 1.0, items, 7);
// 挑戦
challengeX = getPositionX(originX, lineLength, 1.0, items, 8);
challengeY = getPositionY(originY, lineLength, 1.0, items, 8);
// 社会性
loveX = getPositionX(originX, lineLength, 1.0, items, 9);
loveY = getPositionY(originY, lineLength, 1.0, items, 9);
// 調和
harmonyX = getPositionX(originX, lineLength, 1.0, items, 10);
harmonyY = getPositionY(originY, lineLength, 1.0, items, 10);
// 親密
closenessX = getPositionX(originX, lineLength, 1.0, items, 11);
closenessY = getPositionY(originY, lineLength, 1.0, items, 11);
GraphicsContext gc = needsChart.getGraphicsContext2D();
gc.setStroke(Color.BLUE);
gc.setLineWidth(1);
gc.strokeLine(originX, originY, practicalityX, practicalityY);
gc.strokeLine(originX, originY, curiosityX, curiosityY);
gc.strokeLine(originX, originY, selfExpressionX, selfExpressionY);
gc.strokeLine(originX, originY, idealX, idealY);
gc.strokeLine(originX, originY, libertyX, libertyY);
gc.strokeLine(originX, originY, stabilityX, stabilityY);
gc.strokeLine(originX, originY, structureX, structureY);
gc.strokeLine(originX, originY, excitementX, excitementY);
gc.strokeLine(originX, originY, challengeX, challengeY);
gc.strokeLine(originX, originY, loveX, loveY);
gc.strokeLine(originX, originY, harmonyX, harmonyY);
gc.strokeLine(originX, originY, closenessX, closenessY);
for (int i = 0; 6 > i; i++) {
gc.beginPath();
gc.moveTo(getPositionX(originX, lineLength, i * 0.2, items, 0), getPositionY(originY, lineLength, i * 0.2, items, 0));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 1), getPositionY(originY, lineLength, i * 0.2, items, 1));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 2), getPositionY(originY, lineLength, i * 0.2, items, 2));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 3), getPositionY(originY, lineLength, i * 0.2, items, 3));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 4), getPositionY(originY, lineLength, i * 0.2, items, 4));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 5), getPositionY(originY, lineLength, i * 0.2, items, 5));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 6), getPositionY(originY, lineLength, i * 0.2, items, 6));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 7), getPositionY(originY, lineLength, i * 0.2, items, 7));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 8), getPositionY(originY, lineLength, i * 0.2, items, 8));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 9), getPositionY(originY, lineLength, i * 0.2, items, 9));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 10), getPositionY(originY, lineLength, i * 0.2, items, 10));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 11), getPositionY(originY, lineLength, i * 0.2, items, 11));
gc.closePath();
gc.stroke();
}
gc.setFontSmoothingType(FontSmoothingType.LCD);
gc.setFont(Font.font(18));
gc.setFill(Color.RED);
gc.fillText("実用主義", practicalityX - width * 4 / 2, practicalityY + jpCenterHeight - offset);
gc.fillText("好奇心", curiosityX + width / 2, curiosityY + jpCenterHeight - offset / 2);
gc.fillText("自己表現", selfExpressionX + width / 2, selfExpressionY - jpCenterHeight + offset / 2);
gc.fillText("理想", idealX + width / 2, idealY + jpCenterHeight);
gc.fillText("自由主義", libertyX + width / 2, libertyY + jpCenterHeight + offset / 2);
gc.fillText("安定性", stabilityX + width / 2, stabilityY - jpCenterHeight + offset * 1.5);
gc.fillText("仕組", structureX - width * 2 / 2, structureY + jpCenterHeight + offset);
gc.fillText("興奮", excitementX - width * 5 / 2, excitementY - jpCenterHeight + offset * 1.5);
gc.fillText("挑戦", challengeX - width * 5 / 2, challengeY + jpCenterHeight + offset / 2);
gc.fillText("社会性", loveX - width * 7 / 2, loveY + jpCenterHeight);
gc.fillText("調和", harmonyX - width * 5 / 2, harmonyY - jpCenterHeight + offset / 2);
gc.fillText("親密", closenessX - width * 5 / 2, closenessY + jpCenterHeight - offset / 2);
}
private void drawValueChart() {
// 原点
final double originX = valuesChart.getWidth() / 2;
final double originY = valuesChart.getHeight() / 2;
// ライン長さ
final double lineLength = 150.0;
// 項目数
final int items = 5;
// 快楽主義
hedonismX = getPositionX(originX, lineLength, 1.0, items, 0);
hedonismY = getPositionY(originY, lineLength, 1.0, items, 0);
// 自己増進
selfEnhancementX = getPositionX(originX, lineLength, 1.0, items, 1);
selfEnhancementY = getPositionY(originY, lineLength, 1.0, items, 1);
// 変化許容性
opennessToChangeX = getPositionX(originX, lineLength, 1.0, items, 2);
opennessToChangeY = getPositionY(originY, lineLength, 1.0, items, 2);
// 現状維持
conservationX = getPositionX(originX, lineLength, 1.0, items, 3);
conservationY = getPositionY(originY, lineLength, 1.0, items, 3);
// 自己超越
selfTranscendenceX = getPositionX(originX, lineLength, 1.0, items, 4);
selfTranscendenceY = getPositionY(originY, lineLength, 1.0, items, 4);
GraphicsContext gc = valuesChart.getGraphicsContext2D();
gc.setStroke(Color.BLUE);
gc.setLineWidth(1);
gc.strokeLine(originX, originY, hedonismX, hedonismY);
gc.strokeLine(originX, originY, selfEnhancementX, selfEnhancementY);
gc.strokeLine(originX, originY, opennessToChangeX, opennessToChangeY);
gc.strokeLine(originX, originY, conservationX, conservationY);
gc.strokeLine(originX, originY, selfTranscendenceX, selfTranscendenceY);
for (int i = 0; 6 > i; i++) {
gc.beginPath();
gc.moveTo(getPositionX(originX, lineLength, i * 0.2, items, 0), getPositionY(originY, lineLength, i * 0.2, items, 0));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 1), getPositionY(originY, lineLength, i * 0.2, items, 1));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 2), getPositionY(originY, lineLength, i * 0.2, items, 2));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 3), getPositionY(originY, lineLength, i * 0.2, items, 3));
gc.lineTo(getPositionX(originX, lineLength, i * 0.2, items, 4), getPositionY(originY, lineLength, i * 0.2, items, 4));
gc.closePath();
gc.stroke();
}
gc.setFontSmoothingType(FontSmoothingType.LCD);
gc.setFont(Font.font(18));
gc.setFill(Color.RED);
gc.fillText("快楽主義", hedonismX - width * 4 / 2, hedonismY + jpCenterHeight - offset);
gc.fillText("自己増進", selfEnhancementX + width / 2, selfEnhancementY + jpCenterHeight);
gc.fillText("変化許容性", opennessToChangeX - width * 2, opennessToChangeY + jpCenterHeight + offset);
gc.fillText("現状維持", conservationX - width * 9 / 4, conservationY + jpCenterHeight + offset);
gc.fillText("自己超越", selfTranscendenceX - width * 9 / 2, selfTranscendenceY + jpCenterHeight);
}
private double getPositionX(double originX, double lineLength, double ratio, int items, int vertex) {
return originX + lineLength * ratio * Math.cos(Math.toRadians(90 - (360 / items) * vertex));
}
private double getPositionY(double originY, double lineLength, double ratio, int items, int vertex) {
return originY - lineLength * ratio * Math.sin(Math.toRadians(90 - (360 / items) * vertex));
}
private void clearChart() {
personalityGc.clearRect(0, 0, personalityCanvas.getWidth(), personalityCanvas.getHeight());
needsGc.clearRect(0, 0, needsCanvas.getWidth(), needsCanvas.getHeight());
valuesGc.clearRect(0, 0, valuesCanvas.getWidth(), valuesCanvas.getHeight());
}
}