|
1 | 1 | import Component from "@glimmer/component"; |
2 | | -import Chart from "admin/components/chart"; |
| 2 | +import { tracked } from "@glimmer/tracking"; |
| 3 | +import { fn, hash } from "@ember/helper"; |
| 4 | +import { on } from "@ember/modifier"; |
| 5 | +import { action, get } from "@ember/object"; |
| 6 | +import closeOnClickOutside from "discourse/modifiers/close-on-click-outside"; |
| 7 | +import dIcon from "discourse-common/helpers/d-icon"; |
| 8 | +import { i18n } from "discourse-i18n"; |
| 9 | +import DoughnutChart from "./doughnut-chart"; |
| 10 | +import PostList from "discourse/components/post-list"; |
3 | 11 |
|
4 | 12 | export default class AdminReportSentimentAnalysis extends Component { |
5 | | - get chartConfig() { |
6 | | - return { |
7 | | - type: "doughnut", |
8 | | - data: { |
9 | | - labels: ["Positive", "Neutral", "Negative"], |
10 | | - datasets: [ |
11 | | - { |
12 | | - data: [300, 50, 100], |
13 | | - backgroundColor: ["#2ecc71", "#95a5a6", "#e74c3c"], |
14 | | - }, |
| 13 | + @tracked selectedChart = null; |
| 14 | + |
| 15 | + get labels() { |
| 16 | + return ["Positive", "Neutral", "Negative"]; |
| 17 | + } |
| 18 | + |
| 19 | + get colors() { |
| 20 | + return ["#2ecc71", "#95a5a6", "#e74c3c"]; |
| 21 | + } |
| 22 | + |
| 23 | + get transformedData() { |
| 24 | + return this.args.model.data.map((data) => { |
| 25 | + return { |
| 26 | + category_name: data.category_name, |
| 27 | + scores: [ |
| 28 | + data.overall_scores.positive, |
| 29 | + data.overall_scores.neutral, |
| 30 | + data.overall_scores.negative, |
15 | 31 | ], |
16 | | - }, |
17 | | - options: { |
18 | | - responsive: true, |
19 | | - plugins: { |
20 | | - legend: { |
21 | | - position: "bottom", |
22 | | - }, |
23 | | - }, |
24 | | - }, |
25 | | - plugins: [ |
26 | | - { |
27 | | - id: "centerText", |
28 | | - afterDraw: function (chart) { |
29 | | - const cssVarColor = |
30 | | - getComputedStyle(document.documentElement).getPropertyValue( |
31 | | - "--primary" |
32 | | - ) || "#000"; |
33 | | - const cssFontSize = |
34 | | - getComputedStyle(document.documentElement).getPropertyValue( |
35 | | - "--font-down-2" |
36 | | - ) || "1.3em"; |
37 | | - const cssFontFamily = |
38 | | - getComputedStyle(document.documentElement).getPropertyValue( |
39 | | - "--font-family" |
40 | | - ) || "sans-serif"; |
| 32 | + // TODO slicing 3 posts for now |
| 33 | + posts: data.posts, |
| 34 | + }; |
| 35 | + }); |
| 36 | + } |
41 | 37 |
|
42 | | - const { ctx, chartArea } = chart; |
43 | | - const centerX = (chartArea.left + chartArea.right) / 2; |
44 | | - const centerY = (chartArea.top + chartArea.bottom) / 2; |
| 38 | + @action |
| 39 | + showDetails(data) { |
| 40 | + console.log(data); |
| 41 | + this.selectedChart = data; |
| 42 | + } |
45 | 43 |
|
46 | | - ctx.restore(); |
47 | | - ctx.textAlign = "center"; |
48 | | - ctx.textBaseline = "middle"; |
49 | | - ctx.fillStyle = cssVarColor.trim(); |
50 | | - ctx.font = `${cssFontSize.trim()} ${cssFontFamily.trim()}`; |
| 44 | + sentimentTopScore(post) { |
| 45 | + const { positive_score, neutral_score, negative_score } = post; |
| 46 | + const maxScore = Math.max(positive_score, neutral_score, negative_score); |
51 | 47 |
|
52 | | - // TODO: populate with actual tag / category title |
53 | | - ctx.fillText("member-experience", centerX, centerY); |
54 | | - ctx.save(); |
55 | | - }, |
56 | | - }, |
57 | | - ], |
58 | | - }; |
| 48 | + if (maxScore === positive_score) { |
| 49 | + return { |
| 50 | + id: "positive", |
| 51 | + text: i18n( |
| 52 | + "discourse_ai.sentiments.sentiment_analysis.score_types.positive" |
| 53 | + ), |
| 54 | + icon: "face-smile", |
| 55 | + }; |
| 56 | + } else if (maxScore === neutral_score) { |
| 57 | + return { |
| 58 | + id: "neutral", |
| 59 | + text: i18n( |
| 60 | + "discourse_ai.sentiments.sentiment_analysis.score_types.neutral" |
| 61 | + ), |
| 62 | + icon: "face-meh", |
| 63 | + }; |
| 64 | + } else { |
| 65 | + return { |
| 66 | + id: "negative", |
| 67 | + text: i18n( |
| 68 | + "discourse_ai.sentiments.sentiment_analysis.score_types.negative" |
| 69 | + ), |
| 70 | + icon: "face-angry", |
| 71 | + }; |
| 72 | + } |
59 | 73 | } |
60 | 74 |
|
61 | 75 | <template> |
62 | | - {{! TODO each-loop based on data, display doughnut component }} |
| 76 | + {{! TODO add more details about posts on click + tag data }} |
63 | 77 | <div class="admin-report-sentiment-analysis"> |
64 | | - <Chart @chartConfig={{this.chartConfig}} class="admin-report-doughnut" /> |
65 | | - <Chart @chartConfig={{this.chartConfig}} class="admin-report-doughnut" /> |
66 | | - <Chart @chartConfig={{this.chartConfig}} class="admin-report-doughnut" /> |
67 | | - <Chart @chartConfig={{this.chartConfig}} class="admin-report-doughnut" /> |
68 | | - <Chart @chartConfig={{this.chartConfig}} class="admin-report-doughnut" /> |
| 78 | + {{#each this.transformedData as |data|}} |
| 79 | + <div |
| 80 | + class="admin-report-sentiment-analysis__chart-wrapper" |
| 81 | + {{on "click" (fn this.showDetails data)}} |
| 82 | + {{closeOnClickOutside |
| 83 | + (fn (mut this.selectedChart) null) |
| 84 | + (hash |
| 85 | + targetSelector=".admin-report-sentiment-analysis-details" |
| 86 | + secondaryTargetSelector=".admin-report-sentiment-analysis" |
| 87 | + ) |
| 88 | + }} |
| 89 | + > |
| 90 | + <DoughnutChart |
| 91 | + @labels={{this.labels}} |
| 92 | + @colors={{this.colors}} |
| 93 | + @data={{data.scores}} |
| 94 | + @doughnutTitle={{data.category_name}} |
| 95 | + /> |
| 96 | + </div> |
| 97 | + {{/each}} |
69 | 98 | </div> |
| 99 | + |
| 100 | + {{#if this.selectedChart}} |
| 101 | + <div class="admin-report-sentiment-analysis-details"> |
| 102 | + <h3 class="admin-report-sentiment-analysis-details__title"> |
| 103 | + {{this.selectedChart.category_name}} |
| 104 | + </h3> |
| 105 | + |
| 106 | + <ul class="admin-report-sentiment-analysis-details__scores"> |
| 107 | + <li> |
| 108 | + {{dIcon "face-smile" style="color: #2ecc71"}} |
| 109 | + {{i18n |
| 110 | + "discourse_ai.sentiments.sentiment_analysis.score_types.positive" |
| 111 | + }}: |
| 112 | + {{get this.selectedChart.scores 0}}</li> |
| 113 | + <li> |
| 114 | + {{dIcon "face-meh"}} |
| 115 | + {{i18n |
| 116 | + "discourse_ai.sentiments.sentiment_analysis.score_types.neutral" |
| 117 | + }}: |
| 118 | + {{get this.selectedChart.scores 1}}</li> |
| 119 | + <li> |
| 120 | + {{dIcon "face-angry"}} |
| 121 | + {{i18n |
| 122 | + "discourse_ai.sentiments.sentiment_analysis.score_types.negative" |
| 123 | + }}: |
| 124 | + {{get this.selectedChart.scores 2}}</li> |
| 125 | + </ul> |
| 126 | + |
| 127 | + <PostList @posts={{this.selectedChart.posts}} @urlPath="postUrl"> |
| 128 | + <:abovePostItemExcerpt as |post|> |
| 129 | + {{#let (this.sentimentTopScore post) as |score|}} |
| 130 | + <span |
| 131 | + class="admin-report-sentiment-analysis-details__post-score" |
| 132 | + data-sentiment-score={{score.id}} |
| 133 | + > |
| 134 | + {{dIcon score.icon}} |
| 135 | + {{score.text}} |
| 136 | + </span> |
| 137 | + {{/let}} |
| 138 | + </:abovePostItemExcerpt> |
| 139 | + </PostList> |
| 140 | + </div> |
| 141 | + {{/if}} |
70 | 142 | </template> |
71 | 143 | } |
0 commit comments