added arrows correctly

This commit is contained in:
Lorenz Padberg 2022-06-28 13:31:50 +02:00
parent 1af338c889
commit a8a239e395
1 changed files with 108 additions and 72 deletions

View File

@ -1,6 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import * as d3 from "d3"; import * as d3 from "d3";
import {useCircleStore} from '@/stores/circle';
import {onMounted} from "vue"; import {onMounted} from "vue";
import * as _ from 'underscore' import * as _ from 'underscore'
@ -41,7 +40,7 @@ const props = defineProps<{
width: { width: {
default: 500, default: 500,
type: number, type: number,
required: false required: false
}, },
height: { height: {
@ -52,112 +51,149 @@ const props = defineProps<{
}>() }>()
function calculatePieData(circle){ function calculatePieData(circle) {
let learningSequences = _.filter(circle.children, (child) => { return child.type === 'learnpath.LearningSequence'; }) let learningSequences = _.filter(circle.children, (child) => {
let pieWeights = new Array(Math.max(learningSequences.length, 1)).fill(1) return child.type === 'learnpath.LearningSequence';
let pieGenerator = d3.pie() })
let pieData = pieGenerator(pieWeights) let pieWeights = new Array(Math.max(learningSequences.length, 1)).fill(1)
let pieGenerator = d3.pie()
let pieData = pieGenerator(pieWeights)
console.log(pieData) console.log(pieData)
_.forEach(pieData, (pie) => { _.forEach(pieData, (pie) => {
pie.title = learningSequences[parseInt(pie.index)].title pie.title = learningSequences[parseInt(pie.index)].title
pie.icon = learningSequences[parseInt(pie.index)].icon pie.icon = learningSequences[parseInt(pie.index)].icon
pie.startAngle = pie.startAngle + Math.PI pie.startAngle = pie.startAngle + Math.PI
pie.endAngle = pie.endAngle + Math.PI pie.endAngle = pie.endAngle + Math.PI
}) pie.arrowStartAngle = pie.endAngle + (pie.startAngle- pie.endAngle) / 2
pieData = pieData.reverse() pie.arrowEndAngle = pie.startAngle + (pie.startAngle- pie.endAngle) / 2
return pieData })
pieData = pieData.reverse()
return pieData
} }
onMounted(async () => { onMounted(async () => {
let pieData = calculatePieData(props.circleData)
let pieData = calculatePieData(props.circleData) const width = 500,
height = 500,
radius = Math.min(width, height) / 3
const width = 500, const blue900 = '#00224D',
height = 500, blue700 = '#1A5197',
radius = Math.min(width, height) / 3 gray100 = '#EDF2F6',
gray300 = '#E0E5EC',
const blue900 = '#00224D', gray500 = '#B1C1CA',
blue700 = '#1A5197', sky400 = '#72CAFF',
gray100 = '#EDF2F6', sky500 = '#41B5FA'
gray300 = '#E0E5EC',
gray500 = '#B1C1CA',
sky400 = '#72CAFF',
sky500 = '#41B5FA'
const svg = d3.select('.circle-visualization') const svg = d3.select('.circle-visualization')
.attr('width', width) .attr('width', width)
.attr('height', height) .attr('height', height)
const g = svg.append('g').attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')') const g = svg.append('g').attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')')
// Generate the pie const arrowStrokeWidth = 2
const pie = d3.pie()
// Generate the pie diagram wede svg.append("svg:defs").append("svg:marker")
const wedge = d3 .attr("id", "triangle")
.arc() .attr("refX", 11)
.innerRadius(radius / 2.5) .attr("refY", 11)
.padAngle(12 / 360) .attr("markerWidth", 20)
.outerRadius(radius) .attr("markerHeight", 20)
.attr("markerUnits", "userSpaceOnUse")
.attr("orient", "auto")
.append("path")
.attr("d", "M -1 0 l 10 0 M 0 -1 l 0 10")
.attr('transform', 'rotate(-90, 10, 0)')
.attr('stroke-width', arrowStrokeWidth)
.attr('stroke', gray500)
// Generate the pie
const pie = d3.pie()
// Generate the pie diagram wede
const wedge = d3
.arc()
.innerRadius(radius / 2.5)
.padAngle(12 / 360)
.outerRadius(radius)
// Generate the arrows
const arrowRadius = radius * 1.1
const arrow = d3
.arc()
.innerRadius(arrowRadius)
.outerRadius(arrowRadius + arrowStrokeWidth)
.padAngle(30 / 360)
.startAngle(d => {return d.arrowStartAngle})
.endAngle(d => {return d.arrowEndAngle})
// Generate the arrows
const arrow = d3
.arc()
.innerRadius(radius * 1.15)
.padAngle(30 / 360)
.startAngle(d => {return d.startAngle + (d.startAngle - d.endAngle)/2})
.endAngle(d => {return d.endAngle + (d.startAngle - d.endAngle)/2})
.outerRadius(radius * 1.165)
//Generate groups //Generate groups
const wedgesGroup = g.selectAll('arc').data(pieData).enter().append('g').attr('class', 'arc') const wedgesGroup = g.selectAll('arc').data(pieData).enter().append('g').attr('class', 'arc')
wedgesGroup.append('path').attr('fill', sky400).attr('d', wedge)
wedgesGroup.append('path').attr('fill', sky400).attr('d', wedge)
const learningSequenceText = wedgesGroup const learningSequenceText = wedgesGroup
.append('text') .append('text')
.attr('fill', blue900) .attr('fill', blue900)
.style('font-size', 15) .style('font-size', 15)
.text((d) => {return d.title}) .text((d) => {
.attr("transform", function(d) { return d.title
})
.attr("transform", function (d) {
let translate = wedge.centroid(d) let translate = wedge.centroid(d)
translate = [translate[0], translate[1] + 20] translate = [translate[0], translate[1] + 20]
return "translate(" + translate + ")"; }) return "translate(" + translate + ")";
})
.attr('class', 'circlesText text-xl font-bold') .attr('class', 'circlesText text-xl font-bold')
.style('text-anchor', 'middle') .style('text-anchor', 'middle')
const learningSequenceIcon = wedgesGroup.append("svg:image") const iconWidth = 25
.attr("xlink:href", (d) => {return "/static/icons/"+d.icon.replace("it-", "")+".svg"})
.attr("width", 30) const learningSequenceIcon = wedgesGroup.append("svg:image")
.attr("height", 30) .attr("xlink:href", (d) => {
.attr("transform", function(d) { return "/static/icons/" + d.icon.replace("it-", "") + ".svg"
})
.attr("width", iconWidth)
.attr("height", iconWidth)
.attr("transform", function (d) {
let translate = wedge.centroid(d) let translate = wedge.centroid(d)
translate = [translate[0]-20, translate[1] - 35] translate = [translate[0] - iconWidth/2, translate[1] - iconWidth]
return "translate(" + translate + ")"; }) return "translate(" + translate + ")";
})
//Generate groups //Generate groups
const arrows = g const arrows = g
.selectAll('arrow') .selectAll('arrow')
.data(pieData) .data(pieData)
.enter() .enter()
.append('g') .append('g')
.attr('class', 'arrow') .attr('class', 'arrow')
.attr('marker-start', 'url(#triangle)') .attr('marker-end', 'url(#triangle)')
const markers = g.selectAll('arrow').attr('transform', 'translate(60, 60) rotate(30)') //arrows[3].remove()
//Draw wedge paths
//Draw arrow paths //Draw arrow paths
arrows.append('path').attr('fill', gray300).attr('d', arrow) arrows.append('path').attr('fill', gray500).attr('d', arrow)
} // .transition()
// .duration(500)
// .delay(function (d, i) {return i * 200;})
// .attrTween('d', function (d) {
// var i = d3.interpolate(d.arrowStartAngle, d.arrowEndAngle);
// return function (t) {
// d.arrowEndAngle = i(t);
// return d;
// }
// })
}
); );