Fix typecheck errors on CircleDiagram

This commit is contained in:
Daniel Egger 2022-10-21 16:35:36 +02:00
parent bf70658710
commit 788f6cf663
6 changed files with 198 additions and 176 deletions

View File

@ -5,8 +5,10 @@ import * as _ from "lodash";
import * as log from "loglevel"; import * as log from "loglevel";
import { computed, onMounted } from "vue"; import { computed, onMounted } from "vue";
// @ts-ignore
import colors from "@/colors.json"; import colors from "@/colors.json";
import type { LearningSequence } from "@/types"; import type { LearningSequence } from "@/types";
import type { DefaultArcObject } from "d3";
const circleStore = useCircleStore(); const circleStore = useCircleStore();
@ -33,6 +35,17 @@ onMounted(async () => {
render(); render();
}); });
interface CirclePie extends d3.PieArcDatum<number> {
title: string;
icon: string;
slug: string;
translation_key: string;
arrowStartAngle: number;
arrowEndAngle: number;
someFinished: boolean;
allFinished: boolean;
}
const pieData = computed(() => { const pieData = computed(() => {
const circle = circleStore.circle; const circle = circleStore.circle;
console.log("initial of compute pie data ", circle); console.log("initial of compute pie data ", circle);
@ -42,37 +55,63 @@ const pieData = computed(() => {
const pieWeights = new Array(Math.max(circle.learningSequences.length, 1)).fill(1); const pieWeights = new Array(Math.max(circle.learningSequences.length, 1)).fill(1);
const pieGenerator = d3.pie(); const pieGenerator = d3.pie();
let angles = pieGenerator(pieWeights); const angles = pieGenerator(pieWeights);
_.forEach(angles, (pie) => { let result = angles.map((angle) => {
pie.startAngle = pie.startAngle + Math.PI; const thisLearningSequence = circle.learningSequences[angle.index];
pie.endAngle = pie.endAngle + Math.PI;
const thisLearningSequence = circle.learningSequences[pie.index]; return Object.assign(
pie.title = thisLearningSequence.title; {
pie.icon = thisLearningSequence.icon; startAngle: angle.startAngle + Math.PI,
pie.arrowStartAngle = pie.endAngle + (pie.startAngle - pie.endAngle) / 2; endAngle: angle.endAngle + Math.PI,
pie.arrowEndAngle = pie.startAngle + (pie.startAngle - pie.endAngle) / 2; ..._.pick(thisLearningSequence, ["title", "icon", "translation_key", "slug"]),
pie.translation_key = thisLearningSequence.translation_key; arrowStartAngle: angle.endAngle + (angle.startAngle - angle.endAngle) / 2,
pie.slug = thisLearningSequence.slug; arrowEndAngle: angle.startAngle + (angle.startAngle - angle.endAngle) / 2,
pie.someFinished = someFinished(thisLearningSequence); someFinished: someFinished(thisLearningSequence),
pie.allFinished = allFinished(thisLearningSequence); allFinished: allFinished(thisLearningSequence),
},
angle
);
}); });
angles = angles.reverse(); result = result.reverse();
return angles; return result as CirclePie[];
} }
return {};
return undefined;
}); });
const width = 450; const width = 450;
const height = 450; const height = 450;
const radius = Math.min(width, height) / 2.4; const radius = Math.min(width, height) / 2.4;
function render() { function getColor(d: CirclePie) {
const arrowStrokeWidth = 2; let color = colors.gray[300];
if (d.someFinished) {
color = colors.sky[500];
}
if (d.allFinished) {
color = colors.green[500];
}
return color;
}
function getHoverColor(d: CirclePie) {
let color = colors.gray[200];
if (d.someFinished) {
color = colors.sky[400];
}
if (d.allFinished) {
color = colors.green[400];
}
return color;
}
function render() {
const svg = d3.select(".circle-visualization"); const svg = d3.select(".circle-visualization");
// Clean svg before adding new stuff. // Clean svg before adding new stuff.
svg.selectAll("*").remove(); svg.selectAll("*").remove();
if (pieData.value) {
const arrowStrokeWidth = 2;
// Append marker as definition to the svg // Append marker as definition to the svg
svg svg
.attr("viewBox", `0 0 ${width} ${height}`) .attr("viewBox", `0 0 ${width} ${height}`)
@ -95,28 +134,6 @@ function render() {
.append("g") .append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
function getColor(d) {
let color = colors.gray[300];
if (d.someFinished) {
color = colors.sky[500];
}
if (d.allFinished) {
color = colors.green[500];
}
return color;
}
function getHoverColor(d) {
let color = colors.gray[200];
if (d.someFinished) {
color = colors.sky[400];
}
if (d.allFinished) {
color = colors.green[400];
}
return color;
}
// Generate the pie diagram wede // Generate the pie diagram wede
const wedgeGenerator = d3 const wedgeGenerator = d3
.arc() .arc()
@ -142,6 +159,7 @@ function render() {
.transition() .transition()
.duration(200) .duration(200)
.attr("fill", (d) => { .attr("fill", (d) => {
// @ts-ignore
return getHoverColor(d); return getHoverColor(d);
}); });
}) })
@ -150,6 +168,7 @@ function render() {
.transition() .transition()
.duration(200) .duration(200)
.attr("fill", (d) => { .attr("fill", (d) => {
// @ts-ignore
return getColor(d); return getColor(d);
}); });
}) })
@ -165,6 +184,7 @@ function render() {
return getColor(d); return getColor(d);
}); });
// @ts-ignore
learningSequences.append("path").attr("d", wedgeGenerator); learningSequences.append("path").attr("d", wedgeGenerator);
const learningSequenceText = learningSequences const learningSequenceText = learningSequences
@ -175,7 +195,7 @@ function render() {
return d.title; return d.title;
}) })
.attr("transform", function (d) { .attr("transform", function (d) {
let translate = wedgeGenerator.centroid(d); let translate = wedgeGenerator.centroid(d as unknown as DefaultArcObject);
translate = [translate[0], translate[1] + 20]; translate = [translate[0], translate[1] + 20];
return "translate(" + translate + ")"; return "translate(" + translate + ")";
}) })
@ -192,7 +212,7 @@ function render() {
.attr("width", iconWidth) .attr("width", iconWidth)
.attr("height", iconWidth) .attr("height", iconWidth)
.attr("transform", function (d) { .attr("transform", function (d) {
let translate = wedgeGenerator.centroid(d); let translate = wedgeGenerator.centroid(d as unknown as DefaultArcObject);
translate = [translate[0] - iconWidth / 2, translate[1] - iconWidth]; translate = [translate[0] - iconWidth / 2, translate[1] - iconWidth];
return "translate(" + translate + ")"; return "translate(" + translate + ")";
}) })
@ -205,10 +225,10 @@ function render() {
.outerRadius(arrowRadius + arrowStrokeWidth) .outerRadius(arrowRadius + arrowStrokeWidth)
.padAngle(20 / 360) .padAngle(20 / 360)
.startAngle((d) => { .startAngle((d) => {
return d.arrowStartAngle; return (d as unknown as CirclePie).arrowStartAngle;
}) })
.endAngle((d) => { .endAngle((d) => {
return d.arrowEndAngle; return (d as unknown as CirclePie).arrowEndAngle;
}); });
const arrows = g const arrows = g
@ -225,10 +245,13 @@ function render() {
}; };
const all_arows = g.selectAll(".arrow"); const all_arows = g.selectAll(".arrow");
// @ts-ignore
all_arows.last().remove(); all_arows.last().remove();
//Draw arrow paths //Draw arrow paths
// @ts-ignore
arrows.append("path").attr("fill", colors.gray[500]).attr("d", arrow); arrows.append("path").attr("fill", colors.gray[500]).attr("d", arrow);
}
return svg; return svg;
} }
</script> </script>

View File

@ -121,8 +121,8 @@ const learningSequenceBorderClass = computed(() => {
<span class="flex gap-4 items-center xl:h-10"> <span class="flex gap-4 items-center xl:h-10">
<button <button
class="cursor-pointer w-full sm:w-auto text-left" class="cursor-pointer w-full sm:w-auto text-left"
@click.stop="circleStore.openLearningContent(learningContent)"
:data-cy="`${learningContent.slug}`" :data-cy="`${learningContent.slug}`"
@click.stop="circleStore.openLearningContent(learningContent)"
> >
{{ learningContent.title }} {{ learningContent.title }}
</button> </button>

View File

@ -22,8 +22,8 @@ defineEmits(["update:modelValue"]);
'opacity-50': disabled, 'opacity-50': disabled,
'cursor-not-allowed': disabled, 'cursor-not-allowed': disabled,
}" }"
@click="$emit('update:modelValue', !modelValue)"
class="w-8 h-8 cursor-pointer" class="w-8 h-8 cursor-pointer"
@click="$emit('update:modelValue', !modelValue)"
> >
<button <button
v-if="modelValue" v-if="modelValue"

View File

@ -39,7 +39,6 @@ export const itPost = (url: RequestInfo, data: unknown, options: RequestInit = {
options options
); );
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore // @ts-ignore
options.headers["X-CSRFToken"] = getCookieValue("csrftoken"); options.headers["X-CSRFToken"] = getCookieValue("csrftoken");

View File

@ -13,8 +13,8 @@ const competenceStore = useCompetenceStore();
<div class="container-large"> <div class="container-large">
<nav class="py-4 lg:pb-8"> <nav class="py-4 lg:pb-8">
<router-link <router-link
class="btn-text inline-flex items-center pl-0"
v-if="competenceStore.competenceProfilePage" v-if="competenceStore.competenceProfilePage"
class="btn-text inline-flex items-center pl-0"
:to="competenceStore.competenceProfilePage?.frontend_url" :to="competenceStore.competenceProfilePage?.frontend_url"
> >
<it-icon-arrow-left /> <it-icon-arrow-left />

View File

@ -63,7 +63,7 @@ findCriteria();
@back="router.back()" @back="router.back()"
@next="router.back()" @next="router.back()"
> >
<div class="container-medium" v-if="currentQuestion"> <div v-if="currentQuestion" class="container-medium">
<div class="mt-4 lg:mt-8 p-6 lg:p-12 border"> <div class="mt-4 lg:mt-8 p-6 lg:p-12 border">
<h2 class="heading-2"> <h2 class="heading-2">
{{ currentQuestion.competence_id }} {{ currentQuestion.title }} {{ currentQuestion.competence_id }} {{ currentQuestion.title }}