Add LearningPathDiagram mini version
This commit is contained in:
parent
55d4ea6080
commit
1f7321f935
|
|
@ -1,20 +1,20 @@
|
||||||
<script>
|
<script>
|
||||||
import colors from "@/colors.json";
|
import colors from "@/colors.json";
|
||||||
import { useLearningPathStore } from "@/stores/learningPath";
|
|
||||||
import * as d3 from "d3";
|
import * as d3 from "d3";
|
||||||
import * as _ from "lodash";
|
import * as _ from "lodash";
|
||||||
import * as log from "loglevel";
|
import * as log from "loglevel";
|
||||||
import { mapState } from "pinia";
|
|
||||||
|
// type DiagramType = "horizontal" | "vertical" | "horizontalSmall";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
vertical: {
|
diagramType: {
|
||||||
default: false,
|
|
||||||
type: Boolean,
|
|
||||||
},
|
|
||||||
identifier: {
|
|
||||||
required: true,
|
|
||||||
type: String,
|
type: String,
|
||||||
|
default: "horizontal",
|
||||||
|
},
|
||||||
|
learningPath: {
|
||||||
|
required: true,
|
||||||
|
type: Object,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -24,7 +24,9 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(useLearningPathStore, ["learningPath"]),
|
svgId() {
|
||||||
|
return `learningpath-diagram-${this.learningPath.slug}-${this.diagramType}`;
|
||||||
|
},
|
||||||
viewBox() {
|
viewBox() {
|
||||||
return `0 0 ${this.width} ${this.height}`;
|
return `0 0 ${this.width} ${this.height}`;
|
||||||
},
|
},
|
||||||
|
|
@ -76,7 +78,7 @@ export default {
|
||||||
return [];
|
return [];
|
||||||
},
|
},
|
||||||
svg() {
|
svg() {
|
||||||
const result = d3.select("#" + this.identifier);
|
const result = d3.select("#" + this.svgId);
|
||||||
result.selectAll("*").remove();
|
result.selectAll("*").remove();
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
@ -86,14 +88,17 @@ export default {
|
||||||
log.debug("LearningPathDiagram mounted");
|
log.debug("LearningPathDiagram mounted");
|
||||||
|
|
||||||
// clean old svg
|
// clean old svg
|
||||||
d3.select("#" + this.identifier)
|
d3.select("#" + this.svgId)
|
||||||
.selectAll("*")
|
.selectAll("*")
|
||||||
.remove();
|
.remove();
|
||||||
|
|
||||||
const circleWidth = this.vertical ? 60 : 200;
|
let circleWidth = 200;
|
||||||
|
if (this.diagramType === "vertical") {
|
||||||
|
circleWidth = 60;
|
||||||
|
}
|
||||||
const radius = (circleWidth * 0.8) / 2;
|
const radius = (circleWidth * 0.8) / 2;
|
||||||
|
|
||||||
if (this.vertical) {
|
if (this.diagramType === "vertical") {
|
||||||
this.width = Math.min(960, window.innerWidth - 32);
|
this.width = Math.min(960, window.innerWidth - 32);
|
||||||
this.height = 860;
|
this.height = 860;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -132,7 +137,7 @@ export default {
|
||||||
.append("g")
|
.append("g")
|
||||||
.attr("class", "circle")
|
.attr("class", "circle")
|
||||||
.attr("data-cy", (d) => {
|
.attr("data-cy", (d) => {
|
||||||
if (this.vertical) {
|
if (this.diagramType === "vertical") {
|
||||||
return `circle-${d.slug}-vertical`;
|
return `circle-${d.slug}-vertical`;
|
||||||
} else {
|
} else {
|
||||||
return `circle-${d.slug}`;
|
return `circle-${d.slug}`;
|
||||||
|
|
@ -196,7 +201,7 @@ export default {
|
||||||
.style("font-size", "18px")
|
.style("font-size", "18px")
|
||||||
.style("overflow-wrap", "break-word")
|
.style("overflow-wrap", "break-word")
|
||||||
.text((d) => {
|
.text((d) => {
|
||||||
if (!this.vertical) {
|
if (this.diagramType === "horizontal") {
|
||||||
return d.title.replace("Prüfungsvorbereitung", "Prüfungs- vorbereitung");
|
return d.title.replace("Prüfungsvorbereitung", "Prüfungs- vorbereitung");
|
||||||
}
|
}
|
||||||
return d.title;
|
return d.title;
|
||||||
|
|
@ -267,7 +272,7 @@ export default {
|
||||||
|
|
||||||
// Calculate positions of objects
|
// Calculate positions of objects
|
||||||
|
|
||||||
if (this.vertical) {
|
if (this.diagramType === "vertical") {
|
||||||
const Circles_X = radius;
|
const Circles_X = radius;
|
||||||
const Topics_X = Circles_X - 20;
|
const Topics_X = Circles_X - 20;
|
||||||
|
|
||||||
|
|
@ -313,7 +318,16 @@ export default {
|
||||||
.attr("y", radius + 30)
|
.attr("y", radius + 30)
|
||||||
.style("text-anchor", "middle")
|
.style("text-anchor", "middle")
|
||||||
.call(wrap, circleWidth - 20)
|
.call(wrap, circleWidth - 20)
|
||||||
.attr("class", "circlesText text-xl font-bold hidden lg:block");
|
.attr("class", () => {
|
||||||
|
let classes = "circlesText text-xl font-bold block";
|
||||||
|
if (
|
||||||
|
this.diagramType === "vertical" ||
|
||||||
|
this.diagramType === "horizontalSmall"
|
||||||
|
) {
|
||||||
|
classes += " hidden";
|
||||||
|
}
|
||||||
|
return classes;
|
||||||
|
});
|
||||||
|
|
||||||
topicGroups
|
topicGroups
|
||||||
.attr("transform", (d, i) => {
|
.attr("transform", (d, i) => {
|
||||||
|
|
@ -324,7 +338,15 @@ export default {
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.attr("class", (d) => {
|
.attr("class", (d) => {
|
||||||
return "topic ".concat(d.is_visible ? "hidden lg:block" : "hidden");
|
let classes = "topic";
|
||||||
|
if (
|
||||||
|
this.diagramType === "vertical" ||
|
||||||
|
this.diagramType === "horizontalSmall" ||
|
||||||
|
!d.is_visible
|
||||||
|
) {
|
||||||
|
classes += " hidden";
|
||||||
|
}
|
||||||
|
return classes;
|
||||||
});
|
});
|
||||||
|
|
||||||
topicLines
|
topicLines
|
||||||
|
|
@ -336,11 +358,15 @@ export default {
|
||||||
.duration("1000")
|
.duration("1000")
|
||||||
.attr("y2", 350);
|
.attr("y2", 350);
|
||||||
|
|
||||||
|
let topicTitlesClassValue = "topic-title font-bold";
|
||||||
|
if (this.diagramType === "horizontalSmall") {
|
||||||
|
topicTitlesClassValue += " hidden";
|
||||||
|
}
|
||||||
topicTitles
|
topicTitles
|
||||||
.attr("y", 20)
|
.attr("y", 20)
|
||||||
.style("font-size", "18px")
|
.style("font-size", "18px")
|
||||||
.call(wrap, circleWidth * 0.8)
|
.call(wrap, circleWidth * 0.8)
|
||||||
.attr("class", "topicTitles font-bold");
|
.attr("class", topicTitlesClassValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
function wrap(text, width) {
|
function wrap(text, width) {
|
||||||
|
|
@ -384,10 +410,10 @@ export default {
|
||||||
<template>
|
<template>
|
||||||
<div class="svg-container h-full content-start">
|
<div class="svg-container h-full content-start">
|
||||||
<svg
|
<svg
|
||||||
:id="identifier"
|
:id="svgId"
|
||||||
class="learning-path-visualization h-full mx-auto -mt-6 lg:mt-0"
|
class="learning-path-visualization h-full mx-auto -mt-6 lg:mt-0"
|
||||||
:class="{
|
:class="{
|
||||||
'max-h-[384px]': !vertical,
|
'max-h-[384px]': ['horizontal', 'horizontalSmall'].includes(diagramType),
|
||||||
}"
|
}"
|
||||||
:viewBox="viewBox"
|
:viewBox="viewBox"
|
||||||
></svg>
|
></svg>
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ const emits = defineEmits(["closemodal"]);
|
||||||
<LearningPathDiagram
|
<LearningPathDiagram
|
||||||
v-if="learningPathStore.learningPath"
|
v-if="learningPathStore.learningPath"
|
||||||
class="w-full"
|
class="w-full"
|
||||||
:identifier="`verticalVisualization-${learningPathStore.learningPath.slug}`"
|
:learning-path="learningPathStore.learningPath"
|
||||||
:vertical="true"
|
diagram-type="vertical"
|
||||||
></LearningPathDiagram>
|
></LearningPathDiagram>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ import { computed } from "vue";
|
||||||
import { RouterLink } from "vue-router";
|
import { RouterLink } from "vue-router";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
// Vue-TypeScript make special things with `defineProps` so it's hard
|
||||||
|
// to make this without @ts-ignore...
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
...RouterLink.props,
|
...RouterLink.props,
|
||||||
|
|
|
||||||
|
|
@ -69,8 +69,8 @@ const createContinueUrl = (learningPath: LearningPath): [string, boolean] => {
|
||||||
</div>
|
</div>
|
||||||
<LearningPathDiagram
|
<LearningPathDiagram
|
||||||
class="mx-auto max-w-[1920px] max-h-[380px] w-full px-4"
|
class="mx-auto max-w-[1920px] max-h-[380px] w-full px-4"
|
||||||
:identifier="`mainVisualization-${learningPathStore.learningPath.slug}`"
|
diagram-type="horizontal"
|
||||||
:vertical="false"
|
:learning-path="learningPathStore.learningPath"
|
||||||
></LearningPathDiagram>
|
></LearningPathDiagram>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue