@empoweredvote/ev-ui 0.8.1 → 0.8.3
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/dist/index.js +99 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +99 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -103,10 +103,13 @@ function RadarChartCore({
|
|
|
103
103
|
onReplaceTopic = () => {
|
|
104
104
|
},
|
|
105
105
|
size = 400,
|
|
106
|
+
labelFontSize = 13,
|
|
106
107
|
padding = 80,
|
|
108
|
+
labelOffset = 52,
|
|
107
109
|
tightFit = false,
|
|
108
110
|
activeSpoke = null,
|
|
109
|
-
writeIns = {}
|
|
111
|
+
writeIns = {},
|
|
112
|
+
darkMode = false
|
|
110
113
|
}) {
|
|
111
114
|
var _a;
|
|
112
115
|
const radius = size / 2 - 40;
|
|
@@ -177,9 +180,25 @@ function RadarChartCore({
|
|
|
177
180
|
acc[shortTitle] = userAdj > 10 || cmpAdj > 10;
|
|
178
181
|
return acc;
|
|
179
182
|
}, {});
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
+
const labelMeta = spokes.map(([shortTitle], i) => {
|
|
184
|
+
const angle = 2 * Math.PI * i / numSpokes;
|
|
185
|
+
const lines = wrapLabel(shortTitle, 12);
|
|
186
|
+
const longestLineLen = lines.reduce((m, ln) => ln.length > m ? ln.length : m, 0);
|
|
187
|
+
const estimatedWidth = longestLineLen * labelFontSize * 0.55;
|
|
188
|
+
const sinA = Math.sin(angle);
|
|
189
|
+
const side = sinA < -0.1 ? "left" : sinA > 0.1 ? "right" : "center";
|
|
190
|
+
return { estimatedWidth, side };
|
|
191
|
+
});
|
|
192
|
+
const leftLabelWidths = labelMeta.filter((m) => m.side === "left").map((m) => m.estimatedWidth);
|
|
193
|
+
const rightLabelWidths = labelMeta.filter((m) => m.side === "right").map((m) => m.estimatedWidth);
|
|
194
|
+
const minPadding = 40;
|
|
195
|
+
const maxPadding = padding * 2;
|
|
196
|
+
const rawLeft = Math.min(Math.max(leftLabelWidths.length ? Math.max(...leftLabelWidths) + labelOffset : 0, minPadding), maxPadding);
|
|
197
|
+
const rawRight = Math.min(Math.max(rightLabelWidths.length ? Math.max(...rightLabelWidths) + labelOffset : 0, minPadding), maxPadding);
|
|
198
|
+
const sidePadding = Math.max(rawLeft, rawRight);
|
|
199
|
+
const verticalPadding = padding;
|
|
200
|
+
let tightTop = -verticalPadding;
|
|
201
|
+
let tightHeight = size + verticalPadding * 2;
|
|
183
202
|
if (tightFit && numSpokes > 0) {
|
|
184
203
|
let yMin = Infinity, yMax = -Infinity;
|
|
185
204
|
for (let i = 0; i < numSpokes; i++) {
|
|
@@ -189,8 +208,9 @@ function RadarChartCore({
|
|
|
189
208
|
if (y < yMin) yMin = y;
|
|
190
209
|
if (y > yMax) yMax = y;
|
|
191
210
|
}
|
|
192
|
-
|
|
193
|
-
|
|
211
|
+
const labelMargin = labelOffset + labelFontSize * 2.5;
|
|
212
|
+
tightTop = yMin - labelMargin;
|
|
213
|
+
tightHeight = yMax + labelMargin - tightTop;
|
|
194
214
|
}
|
|
195
215
|
const guidePolygons = [];
|
|
196
216
|
for (let level = 1; level <= 5; level++) {
|
|
@@ -201,7 +221,7 @@ function RadarChartCore({
|
|
|
201
221
|
ring.push(`${centerX + radius * scale * Math.sin(angle)},${centerY - radius * scale * Math.cos(angle)}`);
|
|
202
222
|
}
|
|
203
223
|
guidePolygons.push(
|
|
204
|
-
/* @__PURE__ */ import_react.default.createElement("polygon", { key: level, points: ring.join(" "), fill: "none", stroke: "#ccc" })
|
|
224
|
+
/* @__PURE__ */ import_react.default.createElement("polygon", { key: level, points: ring.join(" "), fill: "none", stroke: darkMode ? "#555" : "#ccc" })
|
|
205
225
|
);
|
|
206
226
|
}
|
|
207
227
|
const getStanceText = (shortTitle, value) => {
|
|
@@ -238,7 +258,7 @@ function RadarChartCore({
|
|
|
238
258
|
y1: centerY,
|
|
239
259
|
x2: endX,
|
|
240
260
|
y2: endY,
|
|
241
|
-
stroke: isUnanswered ? "#9ca3af" : "#
|
|
261
|
+
stroke: isUnanswered ? "#9ca3af" : darkMode ? "#bbb" : "#888",
|
|
242
262
|
strokeDasharray: isUnanswered ? "4 3" : void 0,
|
|
243
263
|
opacity: isUnanswered ? 0.6 : 1
|
|
244
264
|
}
|
|
@@ -255,6 +275,39 @@ function RadarChartCore({
|
|
|
255
275
|
}
|
|
256
276
|
));
|
|
257
277
|
}),
|
|
278
|
+
spokes.map(([shortTitle], i) => {
|
|
279
|
+
const angle = 2 * Math.PI * i / numSpokes;
|
|
280
|
+
const cosA = Math.cos(angle);
|
|
281
|
+
const isBottom = cosA < -0.5;
|
|
282
|
+
const isTop = cosA > 0.5;
|
|
283
|
+
const lines = wrapLabel(shortTitle, 12);
|
|
284
|
+
const longestLine = lines.reduce((m, ln) => ln.length > m ? ln.length : m, 0);
|
|
285
|
+
const lineHeight = labelFontSize * 1.2;
|
|
286
|
+
const dynamicOffset = lines.length > 1 ? labelOffset + 6 : labelOffset;
|
|
287
|
+
const offset2 = radius + dynamicOffset;
|
|
288
|
+
const labelX = centerX + offset2 * Math.sin(angle);
|
|
289
|
+
let labelY = centerY - offset2 * Math.cos(angle);
|
|
290
|
+
if (isTop && lines.length > 1) labelY -= (lines.length - 1) * lineHeight;
|
|
291
|
+
const isActive = shortTitle === activeSpoke;
|
|
292
|
+
const isUnansweredLabel = !!unansweredSpokes[shortTitle];
|
|
293
|
+
const fSize = labelFontSize;
|
|
294
|
+
return /* @__PURE__ */ import_react.default.createElement(
|
|
295
|
+
"text",
|
|
296
|
+
{
|
|
297
|
+
key: `label-${shortTitle}`,
|
|
298
|
+
x: labelX,
|
|
299
|
+
y: labelY,
|
|
300
|
+
textAnchor: "middle",
|
|
301
|
+
dominantBaseline: isBottom ? "hanging" : "auto",
|
|
302
|
+
onClick: () => onReplaceTopic(shortTitle),
|
|
303
|
+
fill: isActive ? "#E85D26" : isUnansweredLabel ? "#9ca3af" : darkMode ? "#D3D7DE" : "#555",
|
|
304
|
+
fontWeight: isActive ? "bold" : "normal",
|
|
305
|
+
style: { cursor: "pointer", userSelect: "none", fontSize: fSize, fontFamily: "sans-serif" }
|
|
306
|
+
},
|
|
307
|
+
isUnansweredLabel && /* @__PURE__ */ import_react.default.createElement("title", null, "No stance on file for this topic."),
|
|
308
|
+
lines.map((ln, idx) => /* @__PURE__ */ import_react.default.createElement("tspan", { key: idx, x: labelX, dy: idx === 0 ? "0" : `${lineHeight}` }, ln))
|
|
309
|
+
);
|
|
310
|
+
}),
|
|
258
311
|
countChanged ? /* @__PURE__ */ import_react.default.createElement(
|
|
259
312
|
"polygon",
|
|
260
313
|
{
|
|
@@ -369,14 +422,14 @@ function RadarChartCore({
|
|
|
369
422
|
{
|
|
370
423
|
xmlns: "http://www.w3.org/1999/xhtml",
|
|
371
424
|
style: {
|
|
372
|
-
background: "
|
|
373
|
-
border: "1px solid #d1d5db",
|
|
374
|
-
borderRadius:
|
|
375
|
-
padding: "
|
|
376
|
-
fontSize:
|
|
425
|
+
background: darkMode ? "#2F3237" : "#ffffff",
|
|
426
|
+
border: darkMode ? "1px solid #59B0C4" : "1px solid #d1d5db",
|
|
427
|
+
borderRadius: 8,
|
|
428
|
+
padding: "7px 11px",
|
|
429
|
+
fontSize: 12,
|
|
377
430
|
lineHeight: 1.4,
|
|
378
|
-
color: "#111",
|
|
379
|
-
boxShadow: "0 2px 8px rgba(0,0,0,0.12)",
|
|
431
|
+
color: darkMode ? "#EBEDEF" : "#111",
|
|
432
|
+
boxShadow: darkMode ? "0 2px 12px rgba(0,0,0,0.4)" : "0 2px 8px rgba(0,0,0,0.12)",
|
|
380
433
|
width: tipW + "px",
|
|
381
434
|
wordWrap: "break-word"
|
|
382
435
|
}
|
|
@@ -387,6 +440,37 @@ function RadarChartCore({
|
|
|
387
440
|
})()
|
|
388
441
|
);
|
|
389
442
|
}
|
|
443
|
+
function wrapLabel(label, maxChars = 12) {
|
|
444
|
+
const str = String(label);
|
|
445
|
+
let rawWords;
|
|
446
|
+
if (str.includes("/")) {
|
|
447
|
+
rawWords = str.split("/").reduce((acc, segment, idx, arr) => {
|
|
448
|
+
const part = idx < arr.length - 1 ? segment + "/" : segment;
|
|
449
|
+
if (part.trim()) acc.push(part.trim());
|
|
450
|
+
return acc;
|
|
451
|
+
}, []);
|
|
452
|
+
} else {
|
|
453
|
+
rawWords = str.split(/\s+/);
|
|
454
|
+
}
|
|
455
|
+
const lines = [];
|
|
456
|
+
let line = "";
|
|
457
|
+
for (const word of rawWords) {
|
|
458
|
+
if (line === "") {
|
|
459
|
+
line = word;
|
|
460
|
+
} else if ((line + " " + word).length <= maxChars) {
|
|
461
|
+
line += " " + word;
|
|
462
|
+
} else {
|
|
463
|
+
lines.push(line);
|
|
464
|
+
line = word;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
if (line) lines.push(line);
|
|
468
|
+
if (lines.length > 2) {
|
|
469
|
+
const overflow = lines.splice(2).join(" ");
|
|
470
|
+
lines[1] = lines[1] + " " + overflow;
|
|
471
|
+
}
|
|
472
|
+
return lines;
|
|
473
|
+
}
|
|
390
474
|
|
|
391
475
|
// src/Header.jsx
|
|
392
476
|
var import_react3 = __toESM(require("react"));
|