@baravak/risloo-profile-cli 3.1.0

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.
Files changed (200) hide show
  1. package/.github/workflows/push.yml +14 -0
  2. package/.prettierrc +16 -0
  3. package/.yarn/releases/yarn-1.22.19.cjs +147529 -0
  4. package/.yarnrc.yml +1 -0
  5. package/README.md +98 -0
  6. package/bin/risloo.js +9 -0
  7. package/package.json +44 -0
  8. package/src/Gift.js +29 -0
  9. package/src/Profile.js +405 -0
  10. package/src/cli-commands/Executor.js +118 -0
  11. package/src/cli-commands/ExtractExecutor.js +194 -0
  12. package/src/cli-commands/GiftExecutor.js +56 -0
  13. package/src/cli-commands/utilities/BaseOps.js +71 -0
  14. package/src/cli-commands/utilities/Benchmarker.js +88 -0
  15. package/src/cli-commands/utilities/CustomErrors.js +14 -0
  16. package/src/cli-commands/utilities/Response.js +59 -0
  17. package/src/cli-commands/utilities/STATUSES.js +16 -0
  18. package/src/cli-commands/utilities/Status.js +9 -0
  19. package/src/cli.js +125 -0
  20. package/src/handlebars/helpers/abs.js +8 -0
  21. package/src/handlebars/helpers/addCommas.js +8 -0
  22. package/src/handlebars/helpers/array.js +8 -0
  23. package/src/handlebars/helpers/assignGlobal.js +9 -0
  24. package/src/handlebars/helpers/boolean.js +19 -0
  25. package/src/handlebars/helpers/ceil.js +8 -0
  26. package/src/handlebars/helpers/concat.js +8 -0
  27. package/src/handlebars/helpers/cos.js +8 -0
  28. package/src/handlebars/helpers/displacePoint.js +11 -0
  29. package/src/handlebars/helpers/ellipsisChars.js +10 -0
  30. package/src/handlebars/helpers/ellipsisLines.js +11 -0
  31. package/src/handlebars/helpers/first.js +11 -0
  32. package/src/handlebars/helpers/floor.js +8 -0
  33. package/src/handlebars/helpers/forLoop.js +15 -0
  34. package/src/handlebars/helpers/getArrOfProp.js +8 -0
  35. package/src/handlebars/helpers/isArray.js +8 -0
  36. package/src/handlebars/helpers/join.js +10 -0
  37. package/src/handlebars/helpers/last.js +11 -0
  38. package/src/handlebars/helpers/lineWrap.js +28 -0
  39. package/src/handlebars/helpers/math.js +24 -0
  40. package/src/handlebars/helpers/modulo.js +8 -0
  41. package/src/handlebars/helpers/normalizeAngle.js +7 -0
  42. package/src/handlebars/helpers/object.js +8 -0
  43. package/src/handlebars/helpers/objectEntries.js +8 -0
  44. package/src/handlebars/helpers/polarToCartesian.js +14 -0
  45. package/src/handlebars/helpers/prepend.js +10 -0
  46. package/src/handlebars/helpers/profiles/bar.js +45 -0
  47. package/src/handlebars/helpers/profiles/calcGaugeSidePoints.js +34 -0
  48. package/src/handlebars/helpers/profiles/gauge.js +61 -0
  49. package/src/handlebars/helpers/profiles/polygon.js +40 -0
  50. package/src/handlebars/helpers/reverse.js +9 -0
  51. package/src/handlebars/helpers/roundToTwo.js +8 -0
  52. package/src/handlebars/helpers/setVar.js +8 -0
  53. package/src/handlebars/helpers/sin.js +8 -0
  54. package/src/handlebars/helpers/split.js +8 -0
  55. package/src/handlebars/helpers/tan.js +8 -0
  56. package/src/handlebars/helpers/ternary.js +9 -0
  57. package/src/handlebars/helpers/toDeg.js +8 -0
  58. package/src/handlebars/helpers/toRad.js +8 -0
  59. package/src/handlebars/helpers/withGroup.js +20 -0
  60. package/src/handlebars/helpers/wrapOnNewline.js +11 -0
  61. package/src/handlebars/helpers.js +86 -0
  62. package/src/handlebars/importPartials.js +40 -0
  63. package/src/handlebars/init.js +15 -0
  64. package/src/publish/bot.js +91 -0
  65. package/src/publish/json/gift/gift.json +16 -0
  66. package/src/publish/json/profiles/16PF93.json +201 -0
  67. package/src/publish/json/profiles/AEQ93.json +96 -0
  68. package/src/publish/json/profiles/AMS93.json +102 -0
  69. package/src/publish/json/profiles/AMS9A.json +102 -0
  70. package/src/publish/json/profiles/BAOMEIS93.json +99 -0
  71. package/src/publish/json/profiles/BEQI93.json +1589 -0
  72. package/src/publish/json/profiles/CAATS93.json +11355 -0
  73. package/src/publish/json/profiles/CADS93.json +351 -0
  74. package/src/publish/json/profiles/CARSP93.json +96 -0
  75. package/src/publish/json/profiles/CERQ93.json +106 -0
  76. package/src/publish/json/profiles/CRAAS93.json +98 -0
  77. package/src/publish/json/profiles/CSI93.json +143 -0
  78. package/src/publish/json/profiles/DSWLS93.json +93 -0
  79. package/src/publish/json/profiles/EMSS93.json +116 -0
  80. package/src/publish/json/profiles/FACES93.json +106 -0
  81. package/src/publish/json/profiles/FTEPT93.json +102 -0
  82. package/src/publish/json/profiles/GMIT93.json +98 -0
  83. package/src/publish/json/profiles/HPL93.json +102 -0
  84. package/src/publish/json/profiles/IBT93.json +106 -0
  85. package/src/publish/json/profiles/IUS93.json +93 -0
  86. package/src/publish/json/profiles/JCSI93.json +102 -0
  87. package/src/publish/json/profiles/JPFQ93.json +1 -0
  88. package/src/publish/json/profiles/KJGI93.json +100 -0
  89. package/src/publish/json/profiles/LMIQ93.json +109 -0
  90. package/src/publish/json/profiles/MMFAD93.json +103 -0
  91. package/src/publish/json/profiles/MMFAD9A.json +103 -0
  92. package/src/publish/json/profiles/MOCI93.json +100 -0
  93. package/src/publish/json/profiles/OBQ4493.json +96 -0
  94. package/src/publish/json/profiles/PIES93.json +104 -0
  95. package/src/publish/json/profiles/PIES9A.json +104 -0
  96. package/src/publish/json/profiles/PMCIEF93.json +1 -0
  97. package/src/publish/json/profiles/PSWQ93.json +97 -0
  98. package/src/publish/json/profiles/RIASEC93.json +2511 -0
  99. package/src/publish/json/profiles/SAFE93.json +110 -0
  100. package/src/publish/json/profiles/SASQ93.json +92 -0
  101. package/src/publish/json/profiles/SCASP93.json +611 -0
  102. package/src/publish/json/profiles/SDCAQ93.json +96 -0
  103. package/src/publish/json/profiles/STAIY93.json +98 -0
  104. package/src/publish/json/profiles/WAQ93.json +100 -0
  105. package/src/publish/json/profiles/YBOCS93.json +1322 -0
  106. package/src/publish/json/profiles/empty.json +139 -0
  107. package/src/publish/new-version.hbs +11 -0
  108. package/src/publish/test.js +109 -0
  109. package/src/qrcode/qrCodeGenerator.js +14 -0
  110. package/src/qrcode/qrRender.js +229 -0
  111. package/src/samples/16PF93.js +158 -0
  112. package/src/samples/AEQ93.js +121 -0
  113. package/src/samples/AMS93.js +139 -0
  114. package/src/samples/AMS9A.js +9 -0
  115. package/src/samples/BAOMEIS93.js +146 -0
  116. package/src/samples/BEQI93.js +255 -0
  117. package/src/samples/CAATS93.js +218 -0
  118. package/src/samples/CADS93.js +161 -0
  119. package/src/samples/CARSP93.js +134 -0
  120. package/src/samples/CERQ93.js +195 -0
  121. package/src/samples/CRAAS93.js +141 -0
  122. package/src/samples/CSI93.js +315 -0
  123. package/src/samples/DSWLS93.js +112 -0
  124. package/src/samples/EMSS93.js +178 -0
  125. package/src/samples/FACES93.js +225 -0
  126. package/src/samples/FTEPT93.js +167 -0
  127. package/src/samples/GMIT93.js +142 -0
  128. package/src/samples/HPL93.js +132 -0
  129. package/src/samples/IBT93.js +99 -0
  130. package/src/samples/IUS93.js +204 -0
  131. package/src/samples/JCSI93.js +174 -0
  132. package/src/samples/JPFQ93.js +74 -0
  133. package/src/samples/KJGI93.js +136 -0
  134. package/src/samples/LMIQ93.js +188 -0
  135. package/src/samples/MMFAD93.js +135 -0
  136. package/src/samples/MMFAD9A.js +31 -0
  137. package/src/samples/MOCI93.js +128 -0
  138. package/src/samples/OBQ4493.js +132 -0
  139. package/src/samples/PIES93.js +228 -0
  140. package/src/samples/PIES9A.js +32 -0
  141. package/src/samples/PMCIEF93.js +64 -0
  142. package/src/samples/PSWQ93.js +126 -0
  143. package/src/samples/RIASEC93.js +144 -0
  144. package/src/samples/SAFE93.js +64 -0
  145. package/src/samples/SASQ93.js +130 -0
  146. package/src/samples/SCASP93.js +207 -0
  147. package/src/samples/SDCAQ93.js +174 -0
  148. package/src/samples/STAIY93.js +159 -0
  149. package/src/samples/WAQ93.js +208 -0
  150. package/src/samples/YBOCS93.js +583 -0
  151. package/src/samples/empty.js +53 -0
  152. package/views/gift.hbs +160 -0
  153. package/views/profiles/fonts.css +18 -0
  154. package/views/profiles/layout.hbs +27 -0
  155. package/views/profiles/samples/16PF93.hbs +54 -0
  156. package/views/profiles/samples/AEQ93.hbs +31 -0
  157. package/views/profiles/samples/AMS93.hbs +97 -0
  158. package/views/profiles/samples/AMS9A.hbs +1 -0
  159. package/views/profiles/samples/BAOMEIS93.hbs +48 -0
  160. package/views/profiles/samples/BEQI93.hbs +118 -0
  161. package/views/profiles/samples/CAATS93.hbs +251 -0
  162. package/views/profiles/samples/CADS93.hbs +104 -0
  163. package/views/profiles/samples/CARSP93.hbs +26 -0
  164. package/views/profiles/samples/CERQ93.hbs +115 -0
  165. package/views/profiles/samples/CRAAS93.hbs +88 -0
  166. package/views/profiles/samples/CSI93_1.hbs +110 -0
  167. package/views/profiles/samples/CSI93_2.hbs +76 -0
  168. package/views/profiles/samples/DSWLS93.hbs +26 -0
  169. package/views/profiles/samples/EMSS93.hbs +101 -0
  170. package/views/profiles/samples/FACES93_1.hbs +107 -0
  171. package/views/profiles/samples/FACES93_2.hbs +51 -0
  172. package/views/profiles/samples/FTEPT93.hbs +67 -0
  173. package/views/profiles/samples/GMIT93.hbs +45 -0
  174. package/views/profiles/samples/HPL93.hbs +36 -0
  175. package/views/profiles/samples/IBT93.hbs +67 -0
  176. package/views/profiles/samples/IUS93.hbs +123 -0
  177. package/views/profiles/samples/JCSI93.hbs +65 -0
  178. package/views/profiles/samples/JPFQ93.hbs +44 -0
  179. package/views/profiles/samples/KJGI93.hbs +57 -0
  180. package/views/profiles/samples/LMIQ93.hbs +82 -0
  181. package/views/profiles/samples/MMFAD93.hbs +35 -0
  182. package/views/profiles/samples/MMFAD9A.hbs +1 -0
  183. package/views/profiles/samples/MOCI93.hbs +60 -0
  184. package/views/profiles/samples/OBQ4493.hbs +61 -0
  185. package/views/profiles/samples/PIES93.hbs +67 -0
  186. package/views/profiles/samples/PIES9A.hbs +1 -0
  187. package/views/profiles/samples/PMCIEF93.hbs +8 -0
  188. package/views/profiles/samples/PSWQ93.hbs +32 -0
  189. package/views/profiles/samples/RIASEC93.hbs +38 -0
  190. package/views/profiles/samples/SAFE93.hbs +118 -0
  191. package/views/profiles/samples/SASQ93.hbs +45 -0
  192. package/views/profiles/samples/SCASP93.hbs +94 -0
  193. package/views/profiles/samples/SDCAQ93.hbs +68 -0
  194. package/views/profiles/samples/STAIY93.hbs +67 -0
  195. package/views/profiles/samples/WAQ93.hbs +74 -0
  196. package/views/profiles/samples/YBOCS93_1.hbs +96 -0
  197. package/views/profiles/samples/YBOCS93_2.hbs +115 -0
  198. package/views/profiles/samples/YBOCS93_3.hbs +93 -0
  199. package/views/profiles/samples/empty.hbs +10 -0
  200. package/views/profiles/sidebar.hbs +193 -0
@@ -0,0 +1,121 @@
1
+ const { Profile, FS, Ticks } = require("../Profile");
2
+
3
+ class AEQ93 extends Profile {
4
+ // Number of pages
5
+ static pages = 1;
6
+
7
+ // Labels of the sample
8
+ labels = {
9
+ L1: { eng: "raw", fr: "نمره کل" },
10
+ };
11
+
12
+ profileSpec = {
13
+ /* "sample" determines some important info about the sample and profile */
14
+ /* Default prerequisites: 1. gender, 2. age, 3. education */
15
+ /* "prerequisites" is synonym to "fields" in our program */
16
+ sample: {
17
+ name: "پرسشنامه ارزیابی سطح کلی اضطراب" /* Name of the sample */,
18
+ multiProfile: false /* Whether the sample has multiple profiles or not */,
19
+ questions: false /* Determines whether to get questions from inital dataset or not */,
20
+ defaultFields: true /* Determines whether to have default prerequisites in the profile or not */,
21
+ fields: ["marital_status"] /* In case you want to get some additional fields and show in the profile */,
22
+ },
23
+ /* "profile" determines the dimensions of the drawn profile (to be used in svg tag viewbox) */
24
+ /* calculating its dimensions carefully is of great importance */
25
+ profile: {
26
+ get dimensions() {
27
+ return {
28
+ width: 728 + 2 * this.padding.x,
29
+ height: 415 + 2 * this.padding.y,
30
+ }
31
+ },
32
+ padding: {
33
+ x: 87,
34
+ y: 0,
35
+ },
36
+ },
37
+ /* "raw" is the general term used for total data element in the profile */
38
+ raw: {
39
+ minValue: 0 /* Minimum value of the raw mark */,
40
+ maxValue: 150 /* Maximum value of the item mark */,
41
+ circle: {
42
+ R: 340 /* Radius of the outer circle of the raw element */,
43
+ r: 325 /* Radius of the inner circle of the raw element */,
44
+ brs: {
45
+ tl: 0 /* Top left border radius */,
46
+ bl: 0 /* Bottom left border radius */,
47
+ tr: 0 /* Top right border radius */,
48
+ br: 0 /* Bottom right border radius */,
49
+ } /* Border radiuses at each end of the gauge of the item element */,
50
+ angles: {
51
+ start: FS.toRadians(-180),
52
+ end: FS.toRadians(0),
53
+ } /* Angles of each end of the raw element */,
54
+ direction: false /* Clockwise direction for the raw gauge element */,
55
+ },
56
+ ticks: {
57
+ num: 6,
58
+ },
59
+ },
60
+ /* "labels" part which has to be provided for each profile */
61
+ labels: Object.values(this.labels)
62
+ };
63
+
64
+ constructor(dataset, options, config = {}) {
65
+ super();
66
+ this._init(dataset, options, config);
67
+ }
68
+
69
+ _calcContext() {
70
+ const {
71
+ spec: { parameters: spec },
72
+ dataset,
73
+ } = this;
74
+
75
+ const { raw: rawSpec } = spec;
76
+
77
+ const rawData = dataset.score[0];
78
+
79
+ const rawTicks = new Ticks(rawSpec.minValue, rawSpec.maxValue, rawSpec.ticks.num);
80
+
81
+ const raw = {
82
+ label: rawData.label,
83
+ mark: rawData.mark,
84
+ angle: this._markToAngle(
85
+ rawData.mark,
86
+ rawSpec.minValue,
87
+ rawSpec.maxValue,
88
+ rawSpec.circle.angles,
89
+ rawSpec.circle.direction
90
+ ),
91
+ ticks: rawTicks.numbers.map((number) => ({
92
+ mark: number,
93
+ angle: this._markToAngle(
94
+ number,
95
+ rawSpec.minValue,
96
+ rawSpec.maxValue,
97
+ rawSpec.circle.angles,
98
+ rawSpec.circle.direction
99
+ ),
100
+ })),
101
+ };
102
+
103
+ return [{ raw }];
104
+ }
105
+
106
+ _markToAngle(mark, min, max, angles, direction) {
107
+ const totalAngle = this._calcDiffAngle(angles.end, angles.start, direction);
108
+ const deltaTheta = ((mark - min) / (max - min)) * totalAngle;
109
+ return this._calcDistAngle(deltaTheta, angles.start, direction);
110
+ }
111
+
112
+ _calcDiffAngle(theta, theta0, direction) {
113
+ return direction ? 2 * Math.PI - (theta - theta0) : theta - theta0;
114
+ }
115
+
116
+ _calcDistAngle(deltaTheta, theta0, direction) {
117
+ return direction ? 2 * Math.PI - deltaTheta + theta0 : deltaTheta + theta0;
118
+ }
119
+ }
120
+
121
+ module.exports = AEQ93;
@@ -0,0 +1,139 @@
1
+ const { Profile, FS, Mappings } = require("../Profile");
2
+
3
+ class AMS93 extends Profile {
4
+ // Number of pages
5
+ static pages = 1;
6
+
7
+ // Labels of the sample
8
+ labels = {
9
+ L1: { eng: "intrinsic_motivation_to_know", fr: "برای فهمیدن" },
10
+ L2: { eng: "intrinsic_motivation_toward_accomplishment", fr: "پیشرفت" },
11
+ L3: { eng: "intrinsic_motivation_to_experience_stimulation", fr: "برای تجربه تحریک" },
12
+ L4: { eng: "extrinsic_motivation_identified", fr: "تنظیم همانند شده" },
13
+ L5: { eng: "extrinsic_motivation_introjected", fr: "تنظیم تزریقی" },
14
+ L6: { eng: "extrinsic_motivation_external_regulation", fr: "تنظیم بیرونی" },
15
+ L7: { eng: "unmotivation", fr: "بی‌انگیزگی" },
16
+ };
17
+
18
+ profileSpec = {
19
+ /* "sample" determines some important info about the sample and profile */
20
+ /* Default prerequisites: 1. gender, 2. age, 3. education */
21
+ /* "prerequisites" is synonym to "fields" in our program */
22
+ sample: {
23
+ name: "پرسشنامه انگیزش تحصیلی والراند" /* Name of the sample */,
24
+ multiProfile: false /* Whether the sample has multiple profiles or not */,
25
+ questions: false /* Determines whether to get questions from inital dataset or not */,
26
+ defaultFields: true /* Determines whether to have default prerequisites in the profile or not */,
27
+ fields: ["marital_status"] /* In case you want to get some additional fields and show in the profile */,
28
+ },
29
+ /* "profile" determines the dimensions of the drawn profile (to be used in svg tag viewbox) */
30
+ /* calculating its dimensions carefully is of great importance */
31
+ profile: {
32
+ get dimensions() {
33
+ return {
34
+ width: 662 + 2 * this.padding.x,
35
+ height: 530 + 2 * this.padding.y,
36
+ }
37
+ },
38
+ padding: {
39
+ x: 0,
40
+ y: 93,
41
+ },
42
+ },
43
+ /* "items" is the general term used for independent data elements to be drawn in the profile */
44
+ items: {
45
+ minValue: 4 /* Minimum value of items mark provided by the dataset */,
46
+ maxValue: 28 /* Maximum value of items mark provided by the dataset */,
47
+ offsetX: 200 /* Horizontal offset between items and category label rectangle */,
48
+ offsetY1: 10 /* Vertical offset between two consecutive item in the profile */,
49
+ offsetY2: 60 /* Vertical offset between two categories of items */,
50
+ get distanceY() {
51
+ return this.offsetY1 + this.rect.height;
52
+ } /* Distance between two consecutive item in the profile */,
53
+ totalHeights: [] /* To be calculated in the class with the function provided */,
54
+ calcTotalHeight: function (n) {
55
+ return this.distanceY * (n - 1) + this.rect.height;
56
+ } /* Method for calculating the total height of items */,
57
+ ticks: {
58
+ num: 4 /* Number of ticks */,
59
+ heightOffset: 45 /* Half length that the ticks lines of items is greater than items total heigth */,
60
+ numberOffset: {
61
+ x: 10 /* Horizontal distance from the line */,
62
+ y: 10 /* Vertical distance from the line */,
63
+ },
64
+ },
65
+ rect: {
66
+ height: 40 /* Height of the items rectangle */,
67
+ get borderRadius() {
68
+ return this.height / 2;
69
+ } /* Border Radius of the items rectangle */,
70
+ colors: ["#8B5CF6", "#EC4899", "#71717A"] /* Colors used for theming items body parts */,
71
+ opacityMappings: new Mappings()
72
+ .addMapping("4", 0.6)
73
+ .addMapping("5-12", 0.7)
74
+ .addMapping("13-20", 0.8)
75
+ .addMapping("21-27", 0.9)
76
+ .addMapping("28", 1) /* Opacity mapping for marks */,
77
+ },
78
+ widthCoeff: 15 /* Used for converting mark to the width */,
79
+ label: {
80
+ offsetX: 10 /* Horizontal offset of label from item */,
81
+ rect: {
82
+ width: 42 /* Width of the category label rectangle of the items */,
83
+ borderRadius: 5 /* Border radius of the category label rectangle of the items */,
84
+ },
85
+ colors: ["#A27DF8", "#F06DAD", "#898E99"] /* Colors used for theming items label rectangle */,
86
+ },
87
+ },
88
+ /* "labels" part which has to be provided for each profile */
89
+ labels: Object.values(this.labels)
90
+ };
91
+
92
+ constructor(dataset, options, config = {}) {
93
+ super();
94
+ this._init(dataset, options, config);
95
+ }
96
+
97
+ _calcContext() {
98
+ const {
99
+ spec: { parameters: spec },
100
+ dataset,
101
+ } = this;
102
+
103
+ const { items: itemsSpec } = spec;
104
+
105
+ // Categorize Items Dataset
106
+ const itemsDatasets = [dataset.score.slice(0, 3), dataset.score.slice(3, 6), dataset.score.slice(6)];
107
+
108
+ // ّInit Spec
109
+ spec.items.totalHeights = itemsDatasets.map((dataset) => spec.items.calcTotalHeight(dataset.length));
110
+
111
+ // Gather Required Info for Items
112
+ const items = itemsDatasets.map((dataset, datasetIndex) =>
113
+ dataset.map((data) => ({
114
+ label: data.label,
115
+ mark: data.mark,
116
+ width: data.mark * itemsSpec.widthCoeff,
117
+ fill: itemsSpec.rect.colors[datasetIndex],
118
+ opacity: itemsSpec.rect.opacityMappings.map(data.mark),
119
+ }))
120
+ );
121
+
122
+ // Calculate Ticks Numbers Array for Items
123
+ const itemsTicksNumbers = FS.createArithmeticSequence(
124
+ itemsSpec.minValue,
125
+ (itemsSpec.maxValue - itemsSpec.minValue) / (itemsSpec.ticks.num - 1),
126
+ itemsSpec.ticks.num
127
+ );
128
+
129
+ // Gather Required Info for Items Ticks
130
+ const itemsTicks = itemsTicksNumbers.map((tick) => ({
131
+ number: tick,
132
+ leftPos: tick * itemsSpec.widthCoeff,
133
+ }));
134
+
135
+ return [{ items, itemsTicks }];
136
+ }
137
+ }
138
+
139
+ module.exports = AMS93;
@@ -0,0 +1,9 @@
1
+ const AMS93 = require("./AMS93");
2
+
3
+ // This profile is completely identical to AMS93
4
+
5
+ class AMS9A extends AMS93 {
6
+
7
+ }
8
+
9
+ module.exports = AMS9A;
@@ -0,0 +1,146 @@
1
+ const { Profile } = require("../Profile");
2
+
3
+ class BAOMEIS93 extends Profile {
4
+ // Number of pages
5
+ static pages = 1;
6
+
7
+ // Labels of the sample
8
+ labels = {
9
+ L1: { eng: "diffusion", fr: "آشفته" },
10
+ L2: { eng: "foreclosure", fr: "زود شکل گرفته" },
11
+ L3: { eng: "moratorium", fr: "تعویق افتاده" },
12
+ L4: { eng: "achievement", fr: "پیشرفته" },
13
+ };
14
+
15
+ profileSpec = {
16
+ /* "sample" determines some important info about the sample and profile */
17
+ /* Default prerequisites: 1. gender, 2. age, 3. education */
18
+ /* "prerequisites" is synonym to "fields" in our program */
19
+ sample: {
20
+ name: "پرسشنامه حالات هویت بنیون و آدامز" /* Name of the sample */,
21
+ multiProfile: false /* Whether the sample has multiple profiles or not */,
22
+ questions: false /* Determines whether to get questions from inital dataset or not */,
23
+ defaultFields: true /* Determines whether to have default prerequisites in the profile or not */,
24
+ fields: ["marital_status"] /* In case you want to get some additional fields and show in the profile */,
25
+ },
26
+ /* "profile" determines the dimensions of the drawn profile (to be used in svg tag viewbox) */
27
+ /* calculating its dimensions carefully is of great importance */
28
+ profile: {
29
+ get dimensions() {
30
+ return {
31
+ width: 696 + 2 * this.padding.x,
32
+ height: 565.44 + 2 * this.padding.y,
33
+ }
34
+ },
35
+ padding: {
36
+ x: 103,
37
+ y: 0,
38
+ },
39
+ },
40
+ /* "items" is the general term used for independent data elements to be drawn in the profile */
41
+ items: {
42
+ minValue: 16 /* Minimum value of items mark provided by the dataset */,
43
+ maxValue: 96 /* Maximum value of items mark provided by the dataset */,
44
+ offsetX1: 35.5 /* Horizontal offset between first item and left side of the profile */,
45
+ offsetX2: 80 /* Horizontal offset between two consecutive items in the profile */,
46
+ get distanceX() {
47
+ return this.offsetX2 + this.rect.width;
48
+ } /* Horizontal distance between two consecutive items in the profile */,
49
+ thresholdsNumber: {
50
+ offsetX: 8,
51
+ offsetY: 18,
52
+ },
53
+ thresholds: {
54
+ [this.labels.L1.eng]: 52,
55
+ [this.labels.L2.eng]: 52,
56
+ [this.labels.L3.eng]: 62,
57
+ [this.labels.L4.eng]: 72,
58
+ } /* Thresholds for the items marks */,
59
+ ticks: {
60
+ line: {
61
+ width: 600,
62
+ },
63
+ label: {
64
+ offsetX: 18,
65
+ },
66
+ },
67
+ rect: {
68
+ width: 60 /* Width of the items rectangle */,
69
+ base: {
70
+ height: 50 /* Start height of the items base rectangle (corresponding minimum value) */,
71
+ maxHeight: 150 /* Height of the base rectangle between minimum value and threshold */,
72
+ get totalHeight() {
73
+ return this.height + this.maxHeight;
74
+ } /* Total height of the base rectangle */,
75
+ borderRadius: 6 /* Border radius of the base rectangle */,
76
+ },
77
+ body: {
78
+ maxHeight: 260 /* Height of the body rectangle between threshold and maximum value */,
79
+ borderRadius: 8 /* Border radius of the body rectangle */,
80
+ colors: {
81
+ [this.labels.L1.eng]: "#F87171",
82
+ [this.labels.L2.eng]: "#FCD34D",
83
+ [this.labels.L3.eng]: "#93C5FD",
84
+ [this.labels.L4.eng]: "#6EE7B7",
85
+ } /* Colors used for theming items body parts */,
86
+ },
87
+ },
88
+ label: {
89
+ title: {
90
+ offsetY: 40,
91
+ },
92
+ shape: {
93
+ width: 50,
94
+ height: 40.88,
95
+ offsetY: 30,
96
+ },
97
+ colors: {
98
+ [this.labels.L1.eng]: "#EF4444",
99
+ [this.labels.L2.eng]: "#FBBF24",
100
+ [this.labels.L3.eng]: "#3B82F6",
101
+ [this.labels.L4.eng]: "#10B981",
102
+ } /* Colors used for theming labels */,
103
+ },
104
+ },
105
+ /* "labels" part which has to be provided for each profile */
106
+ labels: Object.values(this.labels)
107
+ };
108
+
109
+ constructor(dataset, options, config = {}) {
110
+ super();
111
+ this._init(dataset, options, config);
112
+ }
113
+
114
+ _calcContext() {
115
+ const {
116
+ spec: { parameters: spec },
117
+ dataset,
118
+ } = this;
119
+
120
+ const { items: itemsSpec } = spec;
121
+
122
+ const items = dataset.score.map((data) => ({
123
+ label: data.label,
124
+ mark: data.mark,
125
+ height:
126
+ data.mark > itemsSpec.thresholds[data.label.eng]
127
+ ? ((data.mark - itemsSpec.thresholds[data.label.eng]) /
128
+ (itemsSpec.maxValue - itemsSpec.thresholds[data.label.eng])) *
129
+ itemsSpec.rect.body.maxHeight +
130
+ itemsSpec.rect.base.maxHeight +
131
+ itemsSpec.rect.base.height
132
+ : ((data.mark - itemsSpec.minValue) / (itemsSpec.thresholds[data.label.eng] - itemsSpec.minValue)) *
133
+ itemsSpec.rect.base.maxHeight +
134
+ itemsSpec.rect.base.height,
135
+ exceedThreshold: data.mark > itemsSpec.thresholds[data.label.eng],
136
+ fill: {
137
+ body: itemsSpec.rect.body.colors[data.label.eng],
138
+ label: itemsSpec.label.colors[data.label.eng],
139
+ },
140
+ }));
141
+
142
+ return [{ items }];
143
+ }
144
+ }
145
+
146
+ module.exports = BAOMEIS93;
@@ -0,0 +1,255 @@
1
+ const { Profile, FS, Mappings } = require("../Profile");
2
+
3
+ class BEQI93 extends Profile {
4
+ // Number of pages
5
+ static pages = 1;
6
+
7
+ // Labels of the sample
8
+ labels = {
9
+ L1: { eng: "independence", fr: "استقلال" },
10
+ L2: { eng: "self_actualize", fr: "خودشکوفایی" },
11
+ L3: { eng: "assertiveness", fr: "خودابرازی" },
12
+ L4: { eng: "self_regard", fr: "احترام به خود" },
13
+ L5: { eng: "emotional_self_awareness", fr: "خودآگاهی هیجانی" },
14
+ L6: { eng: "responsibility", fr: "مسئولیت‌پذیری اجتماعی" },
15
+ L7: { eng: "interpersonal_relationship", fr: "روابط بین فردی" },
16
+ L8: { eng: "empathy", fr: "همدلی" },
17
+ L9: { eng: "problem_solving", fr: "حل مسئله" },
18
+ L10: { eng: "reality_testing", fr: "واقع‌گرایی" },
19
+ L11: { eng: "flexibility", fr: "انعطاف‌پذیری" },
20
+ L12: { eng: "happiness", fr: "شادمانی" },
21
+ L13: { eng: "optimism", fr: "خوش‌بینی" },
22
+ L14: { eng: "stress_tolerance", fr: "تحمل استرس" },
23
+ L15: { eng: "impulse_control", fr: "کنترل تکانه" },
24
+ L16: {
25
+ eng: "intrapersonal_skills",
26
+ fr: "مهارت درون‌فردی",
27
+ desc: "استقلال، خودشکوفایی، خودابرازی\nاحترام به خود، خودآگاهی هیجانی",
28
+ },
29
+ L17: { eng: "interpersonal_skills", fr: "مهارت بین‌فردی", desc: "مسئولیت‌پذیری اجتماعی،\nروابط بین‌فردی، همدلی" },
30
+ L18: { eng: "adjustment", fr: "سازگاری", desc: "حل مسئله، واقع‌گرایی،\nانعطاف‌پذیری" },
31
+ L19: { eng: "general_mood", fr: "خلق", desc: "شادمانی، خوش‌بینی" },
32
+ L20: { eng: "stress_management", fr: "مدیریت استرس", desc: "تحمل استرس، کنترل تکانه" },
33
+ L21: { eng: "raw", fr: "کل" },
34
+ };
35
+
36
+ profileSpec = {
37
+ /* "sample" determines some important info about the sample and profile */
38
+ /* Default prerequisites: 1. gender, 2. age, 3. education */
39
+ /* "prerequisites" is synonym to "fields" in our program */
40
+ sample: {
41
+ name: "پرسشنامه هوش هیجانی بار-آن" /* Name of the sample */,
42
+ multiProfile: false /* Whether the sample has multiple profiles or not */,
43
+ questions: false /* Determines whether to get questions from inital dataset or not */,
44
+ defaultFields: true /* Determines whether to have default prerequisites in the profile or not */,
45
+ fields: ["marital_status"] /* In case you want to get some additional fields and show in the profile */,
46
+ },
47
+ /* "profile" determines the dimensions of the drawn profile (to be used in svg tag viewbox) */
48
+ /* calculating its dimensions carefully is of great importance */
49
+ profile: {
50
+ get dimensions() {
51
+ return {
52
+ width: 843 + 2 * this.padding.x,
53
+ height: 690 + 2 * this.padding.y,
54
+ };
55
+ },
56
+ padding: {
57
+ x: 0,
58
+ y: 20,
59
+ },
60
+ },
61
+ /* "raw" is the general term used for total data element in the profile */
62
+ raw: {
63
+ maxValue: 450 /* Maximum value of raw mark provided by the dataset */,
64
+ ticks: {
65
+ arr: [450, 90],
66
+ line: {
67
+ width: 10 /* Width of the tick line */,
68
+ offsetX: 4 /* Horizontal offset from the rectangle */,
69
+ },
70
+ number: {
71
+ offsetX: 5 /* Horizontal Offset from the line */,
72
+ },
73
+ },
74
+ rect: {
75
+ width: 28 /* Width of the raw rectangle */,
76
+ height: 450 /* Height of the raw rectangle */,
77
+ borderRadius: 14,
78
+ },
79
+ heightCoeff: 1 /* Used for converting mark to the height */,
80
+ },
81
+ /* "items" is the general term used for independent data elements to be drawn in the profile */
82
+ items: {
83
+ maxValue: 30 /* Maximum value of items mark provided by the dataset */,
84
+ offsetY: 12 /* Offset between two consecutive item in the profile */,
85
+ get distanceY() {
86
+ return this.offsetY + this.rect.height;
87
+ } /* Distance between two consecutive item in the profile */,
88
+ totalHeight: "" /* To be calculated in the class with the function provided */,
89
+ calcTotalHeight: function (n) {
90
+ return this.distanceY * (n - 1) + this.base.rect.height;
91
+ } /* Method for calculating the total height of items */,
92
+ ticks: {
93
+ num: 5 /* Number of ticks */,
94
+ heightOffset: 25 /* Half length that the ticks lines of items is greater than items total heigth */,
95
+ numberOffset: {
96
+ x: 5 /* Horizontal distance from the line */,
97
+ y: 0 /* Vertical distance from the line */,
98
+ },
99
+ },
100
+ rect: {
101
+ borderRadius: 8,
102
+ height: 16 /* Height of the items rectangle (base part) */,
103
+ },
104
+ widthCoeff: 10,
105
+ label: {
106
+ offsetX: 8 /* Horizontal offset of the label from the circle */,
107
+ },
108
+ colors: [
109
+ "#C026D3",
110
+ "#C026D3",
111
+ "#C026D3",
112
+ "#C026D3",
113
+ "#C026D3",
114
+ "#E11D48",
115
+ "#E11D48",
116
+ "#E11D48",
117
+ "#F59E0B",
118
+ "#F59E0B",
119
+ "#F59E0B",
120
+ "#16A34A",
121
+ "#16A34A",
122
+ "#0EA5E9",
123
+ "#0EA5E9",
124
+ ] /* Colors used for theming items base parts */,
125
+ opacityMappings: new Mappings()
126
+ .addMapping("6-12", 0.7)
127
+ .addMapping("13-18", 0.8)
128
+ .addMapping("19-24", 0.9)
129
+ .addMapping("25-30", 1) /* Opacity mapping for marks */,
130
+ },
131
+ gaugeItems: {
132
+ offsetX: 40.5 /* Horizontal offset between two top items */,
133
+ get distanceX() {
134
+ return this.offsetX + this.circle.R * 2;
135
+ } /* Horizontal distance between two top items */,
136
+ maxValues: {
137
+ [this.labels.L16.eng]: 150,
138
+ [this.labels.L17.eng]: 90,
139
+ [this.labels.L18.eng]: 90,
140
+ [this.labels.L19.eng]: 60,
141
+ [this.labels.L20.eng]: 60,
142
+ } /* Maximum value of items */,
143
+ fills: {
144
+ [this.labels.L16.eng]: "#C026D3",
145
+ [this.labels.L17.eng]: "#E11D48",
146
+ [this.labels.L18.eng]: "#F59E0B",
147
+ [this.labels.L19.eng]: "#16A34A",
148
+ [this.labels.L20.eng]: "#0EA5E9",
149
+ } /* Color used in items */,
150
+ circle: {
151
+ R: 50 /* Radius of the outer circle of the items element */,
152
+ r: 34 /* Radius of the inner circle of the items element */,
153
+ brs: {
154
+ tl: 4 /* Top left border radius */,
155
+ bl: 4 /* Bottom left border radius */,
156
+ tr: 4 /* Top right border radius */,
157
+ br: 4 /* Bottom right border radius */,
158
+ } /* Border radiuses at each end of the gauge of the items element */,
159
+ angles: {
160
+ start: FS.toRadians(-90),
161
+ end: FS.toRadians(180),
162
+ } /* Angles of each end of the items element */,
163
+ direction: false /* Clockwise direction for the items gauge element */,
164
+ get totalAngle() {
165
+ return this.direction
166
+ ? 2 * Math.PI - (this.angles.end - this.angles.start)
167
+ : this.angles.end - this.angles.start;
168
+ },
169
+ },
170
+ },
171
+ tableItems: [
172
+ { label: this.labels.L1.fr, avg: 19.1, dev: 3.1 },
173
+ { label: this.labels.L2.fr, avg: 21.7, dev: 4.04 },
174
+ { label: this.labels.L3.fr, avg: 18.7, dev: 4.1 },
175
+ { label: this.labels.L4.fr, avg: 21.05, dev: 4.03 },
176
+ { label: this.labels.L5.fr, avg: 20.6, dev: 3.8 },
177
+ { label: this.labels.L6.fr, avg: 25.3, dev: 2.7 },
178
+ { label: this.labels.L7.fr, avg: 23.9, dev: 3.8 },
179
+ { label: this.labels.L8.fr, avg: 25.2, dev: 2.7 },
180
+ { label: this.labels.L9.fr, avg: 22.3, dev: 3.7 },
181
+ { label: this.labels.L10.fr, avg: 19.2, dev: 4.2 },
182
+ { label: this.labels.L11.fr, avg: 18.6, dev: 3.4 },
183
+ { label: this.labels.L12.fr, avg: 22.5, dev: 4.4 },
184
+ { label: this.labels.L13.fr, avg: 20.9, dev: 3.1 },
185
+ { label: this.labels.L14.fr, avg: 17.38, dev: 4.06 },
186
+ { label: this.labels.L15.fr, avg: 16.7, dev: 4.9 },
187
+ { label: this.labels.L21.fr, avg: 313.6, dev: 37.1 },
188
+ ],
189
+ /* "labels" part which has to be provided for each profile */
190
+ labels: Object.values(this.labels),
191
+ };
192
+
193
+ constructor(dataset, options, config = {}) {
194
+ super();
195
+ this._init(dataset, options, config);
196
+ }
197
+
198
+ _calcContext() {
199
+ const {
200
+ spec: { parameters: spec },
201
+ dataset,
202
+ } = this;
203
+
204
+ // Deconstructing the Spec of the Profile
205
+ const { raw: rawSpec, items: itemsSpec, gaugeItems: gaugeItemsSpec } = spec;
206
+
207
+ const rawData = dataset.score.pop();
208
+
209
+ const items = dataset.score.slice(0, 15).map((data, index) => ({
210
+ label: data.label,
211
+ mark: data.mark,
212
+ width: data.mark * itemsSpec.widthCoeff,
213
+ fill: itemsSpec.colors[index],
214
+ opacity: itemsSpec.opacityMappings.map(data.mark),
215
+ }));
216
+
217
+ const raw = {
218
+ label: rawData.label,
219
+ mark: rawData.mark,
220
+ height: rawData.mark * rawSpec.heightCoeff,
221
+ };
222
+
223
+ // Gather Required Info for Raw Ticks
224
+ const rawTicks = rawSpec.ticks.arr.map((tick) => ({
225
+ number: tick,
226
+ bottomPos: (tick / rawSpec.maxValue) * rawSpec.rect.height,
227
+ }));
228
+
229
+ // Calculate Ticks Numbers Array for Items
230
+ const itemsTicksNumbers = FS.createArithmeticSequence(
231
+ itemsSpec.maxValue,
232
+ -itemsSpec.maxValue / itemsSpec.ticks.num,
233
+ itemsSpec.ticks.num
234
+ ).reverse();
235
+
236
+ // Gather Required Info for Items Ticks
237
+ const itemsTicks = itemsTicksNumbers.map((tick) => ({
238
+ number: tick,
239
+ leftPos: tick * itemsSpec.widthCoeff,
240
+ }));
241
+
242
+ let gaugeItems = dataset.score.slice(15).map((data) => ({
243
+ label: data.label,
244
+ mark: data.mark,
245
+ zeta:
246
+ (data.mark / gaugeItemsSpec.maxValues[data.label.eng]) * gaugeItemsSpec.circle.totalAngle +
247
+ gaugeItemsSpec.circle.angles.start,
248
+ fill: gaugeItemsSpec.fills[data.label.eng],
249
+ }));
250
+
251
+ return [{ items, raw, itemsTicks, rawTicks, gaugeItems }];
252
+ }
253
+ }
254
+
255
+ module.exports = BEQI93;