@baravak/risloo-profile-cli 4.18.1 → 4.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@baravak/risloo-profile-cli",
3
- "version": "4.18.1",
3
+ "version": "4.19.1",
4
4
  "description": "**Risloo Profile CLI** is a library for creating profiles, reports and sheets for *psychological* samples.",
5
5
  "main": "bin/risloo.js",
6
6
  "publishConfig": {
@@ -0,0 +1,9 @@
1
+ // ceil Helper
2
+ // Get the `Math.round()` of the given value.
3
+
4
+ function round(value, decimals = 0) {
5
+ const factor = Math.pow(10, decimals);
6
+ return Math.round(value * factor) / factor;
7
+ };
8
+
9
+ module.exports = round;
@@ -37,6 +37,7 @@ const first = require("./helpers/first");
37
37
  const last = require("./helpers/last");
38
38
  const ceil = require("./helpers/ceil");
39
39
  const floor = require("./helpers/floor");
40
+ const round = require("./helpers/round");
40
41
 
41
42
  const polygon = require("./helpers/profiles/polygon");
42
43
  const gauge = require("./helpers/profiles/gauge");
@@ -82,6 +83,7 @@ const helpers = {
82
83
  last,
83
84
  ceil,
84
85
  floor,
86
+ round,
85
87
  polygon,
86
88
  gauge,
87
89
  bar,
@@ -91,13 +91,26 @@
91
91
  }
92
92
  ],
93
93
  "score": {
94
- "raw": 159,
95
- "problem_solving": 6,
96
- "roles": 36,
97
- "affective_responsiveness": 27,
98
- "communication": 14,
99
- "affective_involvement": 8,
100
- "behaviour_control": 18,
101
- "overall_performance": 50
94
+ "overall_performance_raw": 24,
95
+ "overall_performance_avg": 2,
96
+ "overall_performance_report": "unhealthy",
97
+ "problem_solving_raw": 12,
98
+ "problem_solving_avg": 2,
99
+ "problem_solving_report": "healthy",
100
+ "communication_raw": 19,
101
+ "communication_avg": 2.1,
102
+ "communication_report": "healthy",
103
+ "roles_raw": 22,
104
+ "roles_avg": 2,
105
+ "roles_report": "healthy",
106
+ "affective_involvement_raw": 14,
107
+ "affective_involvement_avg": 2,
108
+ "affective_involvement_report": "healthy",
109
+ "behaviour_control_raw": 16,
110
+ "behaviour_control_avg": 1.7,
111
+ "behaviour_control_report": "healthy",
112
+ "affective_responsiveness_raw": 9,
113
+ "affective_responsiveness_avg": 1.5,
114
+ "affective_responsiveness_report": "healthy"
102
115
  }
103
116
  }
@@ -1,31 +1,129 @@
1
- const MMAFD93 = require("./MMFAD93");
2
-
3
- const customConfig = {
4
- test: {
5
- name: "پرسشنامه عملکرد خانواده ۶۰ سؤالی" /* Name of the test */,
6
- },
7
- raw: {
8
- maxValue: 240,
9
- },
10
- items: {
11
- maxValues: {
12
- problem_solving: 24,
13
- roles: 36,
14
- affective_responsiveness: 28,
15
- communication: 28,
16
- affective_involvement: 36,
17
- behaviour_control: 36,
18
- overall_performance: 52,
19
- } /* Maximum value of marks provided by the dataset */,
20
- },
21
- };
22
-
23
- // This profile is completely identical to MMFAD93
24
-
25
- class MMFAD9A extends MMAFD93 {
26
- constructor(dataset, options, config = customConfig) {
27
- super(dataset, options, config);
1
+ const round = require("../handlebars/helpers/round");
2
+ const { Profile, FS } = require("../Profile");
3
+
4
+ class MMAFD9A extends Profile {
5
+ // Number of pages
6
+ static pages = 1;
7
+
8
+ // Labels of the sample
9
+ labels = {
10
+ L1: { eng: "problem_solving_raw", fr: "حل مسأله", CoP: 2.2},
11
+ L1_2 : {eng: "problem_solving_avg"},
12
+ L1_3 : {eng: "problem_solving_report"},
13
+
14
+ L2: { eng: "roles_raw", fr: "نقش‌ها", CoP: 2.3},
15
+ L2_2 : {eng: "roles_avg"},
16
+ L2_3 : {eng: "roles_report"},
17
+
18
+ L3: { eng: "affective_responsiveness_raw", fr: "پاسخ‌دهی عاطفی", CoP: 2.2},
19
+ L3_2 : {eng: "affective_responsiveness_avg"},
20
+ L3_3 : {eng: "affective_responsiveness_report"},
21
+
22
+ L4: { eng: "communication_raw", fr: "ارتباط", CoP: 2.2},
23
+ L4_2 : {eng: "communication_avg"},
24
+ L4_3 : {eng: "communication_report"},
25
+
26
+ L5: { eng: "affective_involvement_raw", fr: "مشارکت عاطفی", CoP: 2.1},
27
+ L5_2 : {eng: "affective_involvement_avg"},
28
+ L5_3 : {eng: "affective_involvement_report"},
29
+
30
+ L6: { eng: "behaviour_control_raw", fr: "کنترل رفتار", CoP: 1.9},
31
+ L6_2 : {eng: "behaviour_control_avg"},
32
+ L6_3 : {eng: "behaviour_control_report"},
33
+
34
+ L7: { eng: "overall_performance_raw", fr: "کارکرد عمومی", CoP: 2},
35
+ L7_2 : {eng: "overall_performance_avg"},
36
+ L7_3 : {eng: "overall_performance_report"},
37
+ };
38
+
39
+ profileSpec = {
40
+ /* "prerequisites" is synonym to "fields" in our program */
41
+ sample: {
42
+ name: "پرسشنامه عملکرد خانواده ۶۰ سؤالی" /* Name of the sample */,
43
+ multiProfile: false /* Whether the sample has multiple profiles or not */,
44
+ questions: false /* Determines whether to get questions from inital dataset or not */,
45
+ defaultFields: true /* Determines whether to have default prerequisites in the profile or not */,
46
+ fields: [] /* In case you want to get some additional fields and show in the profile */,
47
+ },
48
+ /* "profile" determines the dimensions of the drawn profile (to be used in svg tag viewbox) */
49
+ /* calculating its dimensions carefully is of great importance */
50
+ profile: {
51
+ get dimensions() {
52
+ return {
53
+ width: 634 + 2 * this.padding.x,
54
+ height: 668 + 2 * this.padding.y,
55
+ };
56
+ },
57
+ padding: {
58
+ x: 135,
59
+ y: 23,
60
+ },
61
+ },
62
+ /* "labels" part which has to be provided for each profile */
63
+ labels: Object.values(this.labels),
64
+ };
65
+
66
+ constructor(dataset, options, config = {}) {
67
+ super();
68
+ this._init(dataset, options, config);
69
+ }
70
+
71
+ _calcContext() {
72
+ const {
73
+ spec: { parameters: spec },
74
+ dataset,
75
+ } = this;
76
+ const scores = []
77
+ for (let i = 0; i < 21; i+= 3) {
78
+ const item = {mark: dataset.score[i].mark, label: {...dataset.score[i].label}}
79
+ const avg = dataset.score[i + 1].mark
80
+ item.label.avg = avg
81
+
82
+ const elements = [];
83
+ let greenLiene = 12;
84
+ for (let i = 0; i < 31; i++) {
85
+ let color = "";
86
+ let type = "";
87
+ const point = 1 + round(i * 0.1, 1);
88
+ if (point < item.label.CoP) {
89
+ greenLiene += 14;
90
+ }
91
+ if (point === avg) {
92
+ color = avg >= item.label.CoP ? "#DC2626" : "#16A34A";
93
+ type = "selected";
94
+ } else {
95
+ type = Math.round(point) === point ? "z" : "nz";
96
+ if (point === item.label.CoP) {
97
+ color = "#A8A29E";
98
+ } else if (point > item.label.CoP) {
99
+ color = type === "z" ? '#F43F5E33' : "#F43F5E1A";
100
+ } else {
101
+ color = type === 'z' ? '#16A34A33' : "#16A34A1A";
102
+ }
103
+ }
104
+ elements.push({
105
+ point,
106
+ color,
107
+ type,
108
+ isCoP: point === item.label.CoP,
109
+ });
110
+ }
111
+ item.label.CoPText = item.label.CoP.toString().replace(".", "٬");
112
+ scores.push({
113
+ ...item,
114
+ elements,
115
+ greenLiene,
116
+ redLine: 446 - greenLiene,
117
+ avgText: item.label.avg.toString().replace(".", "٬"),
118
+ avgSelected: elements.findIndex((e) => e.type === "selected")
119
+ })
120
+ }
121
+ return [
122
+ {
123
+ scores
124
+ },
125
+ ];
28
126
  }
29
127
  }
30
128
 
31
- module.exports = MMFAD9A;
129
+ module.exports = MMAFD9A;
@@ -1 +1,59 @@
1
- {{> MMFAD93}}
1
+ {{#> layout}}
2
+ <defs>
3
+ <linearGradient id="red-gradient">
4
+ <stop offset="0%" stop-color="#FFE4E6" stop-opacity=".08"/>
5
+ <stop offset="100%" stop-color="#F43F5E" stop-opacity=".08"/>
6
+ </linearGradient>
7
+ <linearGradient id="green-gradient">
8
+ <stop offset="0%" stop-color="#22C55E" stop-opacity=".08"/>
9
+ <stop offset="100%" stop-color="#DCFCE7" stop-opacity=".08"/>
10
+ </linearGradient>
11
+ <linearGradient id="help-gradient">
12
+ <stop stop-color="#22C55E"/>
13
+ <stop offset="0.45" stop-color="white"/>
14
+ <stop offset="1" stop-color="#EF4444"/>
15
+ </linearGradient>
16
+ </defs>
17
+ <g transform="translate({{spec.profile.padding.x}}, {{spec.profile.padding.y}})">
18
+ <g transform="translate(113, 0)">
19
+ <text x="0" y="7" text-anchor="end" dy=".3em" fill="#16A34A" font-size="11" font-weight="500" opacity="0.5">کارکرد سالم</text>
20
+ <text x="446" y="7" text-anchor="start" dy=".3em" fill="#DC2626" font-size="11" font-weight="500" opacity="0.5">کارکرد ناسالم</text>
21
+ <rect y="12" width="446" height="2" fill="url(#help-gradient)" fill-opacity="0.1"/>
22
+ </g>
23
+ <g transform="translate(0, 38)">
24
+ {{#each scores}}
25
+ <g transform="translate(0, {{math 94 '*' @index}})">
26
+ <text x="100" y="35.5" text-anchor="start" dy=".3em" fill="#4B5563" font-size="14" font-weight="500">{{label.fr}}</text>
27
+ <text text-anchor="middle" x="129" dy=".3em" y="60" fill="#9CA3AF" font-size="12" font-weight="400">1</text>
28
+ <text text-anchor="middle" x="549" dy=".3em" y="60" fill="#9CA3AF" font-size="12" font-weight="400">4</text>
29
+ {{bar greenLiene 24 (object tr=0 tl=4 br=0 bl=4) (toRad 0) fill="url(#green-gradient)" transform="translate(116, 24)"}}
30
+ <g transform="translate({{greenLiene}}, 0)">
31
+ {{bar redLine 24 (object tr=4 tl=0 br=4 bl=0) (toRad 0) fill="url(#red-gradient)" transform="translate(116, 24)"}}
32
+ </g>
33
+ <g transform="translate(128, 20)">
34
+ <text text-anchor="middle" dy=".3em" y="-13" x="{{math (math avgSelected '*' 14) '+' 2}}" fill="{{ternary (boolean label.avg '>=' label.CoP) '#DC2626' '#16A34A'}}" font-size="16" font-weight="700">{{avgText}}</text>
35
+ {{#each elements}}
36
+ <g transform="translate({{math @index '*' 14}}, 0)">
37
+ {{#if (boolean type '==' 'selected')}}
38
+ {{bar 4 28 (object tr=2 tl=2 br=0 bl=0) (toRad 0) fill=color transform="translate(-1, 0)"}}
39
+ {{else if (boolean (boolean type '==' 'z') '||' (boolean isCoP '==' true))}}
40
+ <rect width="2" height="16" rx="1" y="8" fill="{{color}}" />
41
+ {{else}}
42
+ <rect width="2" height="12" rx="1" y="10" fill="{{color}}" />
43
+ {{/if}}
44
+ {{#if (boolean isCoP '==' true)}}
45
+ <text text-anchor="middle" dy=".3em" y="40" x="1" fill="#78716C" font-size="12" font-weight="400">{{../label.CoPText}}</text>
46
+ {{/if}}
47
+ </g>
48
+ {{/each}}
49
+ </g>
50
+ <text text-anchor="start" direction="ltr">
51
+ <tspan x="577" y="36.5" dy=".3em" fill="#6B7280" font-size="16" font-weight="600">{{mark}}</tspan>
52
+ <tspan y="36.5" dy=".3em" fill="#6B7280" font-size="12" font-weight="300">/</tspan>
53
+ <tspan y="36.5" dy=".3em" fill="#6B7280" font-size="13" font-weight="400">{{label.max}}</tspan>
54
+ </text>
55
+ </g>
56
+ {{/each}}
57
+ </g>
58
+ </g>
59
+ {{/layout}}