Closed viswasakthi3 closed 2 weeks ago
feels quite fishy what's this how will this solve my issue ??
Ignore the comment, the user is obviously trying to phish people with some weird download links that probably contain malicious content.
As for your report, it's not a bug.
The example code shows imports to files that you have to create. You want a custom node? Create a custom node. There are a ton of examples on the docs that you can reference and copy+paste.
thanks for the response the issue solved but a new problem when we use some 400+ topics in a mindmap it renders slowly is there any way we can make it fast ??
Yeah just get a faster computer. But seriously, what sort of question is this? You have not provided any code, any reproduction, literally nothing and you're asking me "app slow, how make faster?" as if I can magically conjure up some solution for you.
Please take the time to properly formulate questions, provide context, reproductions etc. if you want me to help you otherwise I can't do anything for you.
okay , btw i was not sure it was designed to handle a lot of topics internally by itself i was thinking you may suggest some libraries or something also how can i show the code for something that slowly renders which works normally when we use less number of topics and not moving smoothly when we feed some larger amount of topis in a mind map
also for the horizontal view i tried so many ways but the topic node it not using the left and the right side for the targetPosition and the sourcePosition.
this is the code im using (nuxt 3) :
please help me if you are free
<template>
<div style="height: 98vh; width: 100%;">
<button @click="toggleLayout" class="layout-toggle">
{{ layoutDirection === 'TB' ? 'Switch to Horizontal' : 'Switch to Vertical' }}
</button>
<VueFlow v-if="elements.length > 0"
v-model="elements"
:fit-view-on-init="true"
:node-types="nodeTypes"
:default-viewport="{ zoom: 0.75 }"
:default-edge-options="{ type: 'smoothstep' }">
<Background pattern-color="#aaa" gap="8" />
<MiniMap />
<Controls />
</VueFlow>
<div v-else>Loading...</div>
</div>
</template>
<script setup>
import { VueFlow, useVueFlow, Position } from '@vue-flow/core'
import { Background } from '@vue-flow/background'
import { MiniMap } from '@vue-flow/minimap'
import { Controls } from '@vue-flow/controls'
import { ref, onMounted, computed, defineComponent, h, watch } from 'vue'
import axios from 'axios'
import dagre from '@dagrejs/dagre'
const config = useRuntimeConfig()
const { fitView } = useVueFlow()
const route = useRoute();
const topic = route.params.topic;
const main_topic = ref(topic);
const main_topic_id = ref(null)
const chartData = ref([])
const parentChildMap = ref({})
const layoutDirection = ref('TB') // 'TB' for vertical, 'LR' for horizontal
const colors = [
'#64B5F6', '#81C784', '#FFB74D', '#E57373', '#BA68C8', '#4DB6AC', '#9CCC65', '#7986CB',
'#FF8A65', '#A1887F', '#90A4AE', '#AED581', '#F06292', '#FFD54F', '#4FC3F7', '#FFB74D',
'#B39DDB', '#80CBC4', '#FFCC80', '#EF9A9A', '#C5E1A5', '#9FA8DA', '#FFE082', '#BCAAA4',
'#B0BEC5', '#FFF59D', '#A5D6A7', '#90CAF9', '#F48FB1', '#80DEEA', '#FFAB91', '#CE93D8'
];
const TopicNode = defineComponent({
props: ['data'],
render() {
return h('div', {
style: {
background: this.data.color,
padding: '15px',
borderRadius: '10px',
textAlign: 'center',
fontWeight: 'bold',
fontSize: '16px',
width: '180px',
boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
border: '2px solid #fff',
color: 'white'
}
}, this.data.label)
}
})
const nodeTypes = {
topicNode: TopicNode
}
function useLayout() {
const graph = ref(new dagre.graphlib.Graph())
function layout(nodes, edges, direction) {
const dagreGraph = new dagre.graphlib.Graph()
graph.value = dagreGraph
dagreGraph.setDefaultEdgeLabel(() => ({}))
const isHorizontal = direction === 'LR'
dagreGraph.setGraph({ rankdir: direction, nodesep: 80, ranksep: 120 })
for (const node of nodes) {
dagreGraph.setNode(node.id, { width: 180, height: 50 })
}
for (const edge of edges) {
dagreGraph.setEdge(edge.source, edge.target)
}
dagre.layout(dagreGraph)
return nodes.map((node) => {
const nodeWithPosition = dagreGraph.node(node.id)
return {
...node,
targetPosition: isHorizontal ? Position.Left : Position.Top,
sourcePosition: isHorizontal ? Position.Right : Position.Bottom,
position: { x: nodeWithPosition.x, y: nodeWithPosition.y },
}
})
}
return { layout }
}
const { layout } = useLayout()
const elements = computed(() => {
if (chartData.value.length === 0 || Object.keys(parentChildMap.value).length === 0) {
return []
}
const isHorizontal = layoutDirection.value === 'LR'
const nodes = chartData.value.map((topic, index) => ({
id: topic.id.toString(),
type: 'topicNode',
data: { label: topic.name, color: colors[index % colors.length] },
position: { x: 0, y: 0 }, // Initial position, will be updated by layout
targetPosition: isHorizontal ? Position.Left : Position.Top,
sourcePosition: isHorizontal ? Position.Right : Position.Bottom,
}))
const edges = Object.entries(parentChildMap.value).flatMap(([parentId, children]) =>
children.map(childId => ({
id: `e${parentId}-${childId}`,
source: parentId.toString(),
target: childId.toString(),
type: 'smoothstep',
style: { stroke: nodes.find(n => n.id === parentId.toString())?.data.color }
}))
)
const layoutedNodes = layout(nodes, edges, layoutDirection.value)
return [...layoutedNodes, ...edges]
})
const organizeTopics = (topics) => {
const parentChildMap = {}
const chartData = topics.map(topic => ({
id: topic.id,
name: topic.name,
parent: topic.parent_id
}))
topics.forEach(topic => {
if (!parentChildMap[topic.parent_id]) {
parentChildMap[topic.parent_id] = []
}
parentChildMap[topic.parent_id].push(topic.id)
})
return { chartData, parentChildMap }
}
const fetchTopicStructure = async () => {
try {
const response = await axios.post(
`${config.public.API_BASE_URL}/get_topic_structure`,
{ topic: main_topic.value }
)
const mainTopicData = response.data.topics.find(topic => topic.parent_id === null)
if (mainTopicData) {
main_topic.value = mainTopicData.name
main_topic_id.value = mainTopicData.id
} else {
console.error("Main topic not found in the response")
}
const organizedData = organizeTopics(response.data.topics)
chartData.value = organizedData.chartData
parentChildMap.value = organizedData.parentChildMap
} catch (error) {
console.error("Error fetching topic structure:", error)
}
}
const toggleLayout = () => {
layoutDirection.value = layoutDirection.value === 'TB' ? 'LR' : 'TB'
setTimeout(() => fitView({ padding: 0.2 }), 100)
}
onMounted(async () => {
await fetchTopicStructure()
setTimeout(() => fitView({ padding: 0.2 }), 100)
})
watch(layoutDirection, () => {
setTimeout(() => fitView({ padding: 0.2 }), 100)
})
</script>
<style>
@import '@vue-flow/core/dist/style.css';
@import '@vue-flow/core/dist/theme-default.css';
@import '@vue-flow/controls/dist/style.css';
@import '@vue-flow/minimap/dist/style.css';
.vue-flow__edge {
stroke-width: 2;
}
.vue-flow__edge-path {
stroke: inherit;
}
.layout-toggle {
position: absolute;
top: 10px;
left: 10px;
z-index: 5;
padding: 8px 12px;
background-color: #4a4a4a;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.layout-toggle:hover {
background-color: #5a5a5a;
}
</style>
data format :
{ "topics": [ { "branch_number": 0, "branch_order": 0, "id": 48, "level": 0, "name": "Psychology ", "parent_id": null }, { "branch_number": 1, "branch_order": 1, "id": 49, "level": 1, "name": "Biological Psychology", "parent_id": 48 }, { "branch_number": 1, "branch_order": 2, "id": 50, "level": 1, "name": "Cognitive Psychology", "parent_id": 48 },
also for the horizontal view i tried so many ways but the topic node it not using the left and the right side for the targetPosition and the sourcePosition.
Why would it? you've never assigned it any source or target positions. Your custom node doesn't even have a <Handle>
at all, which will break your app either way because nodes need a <Handle>
for the edges to properly work!
Please read through the docs and the examples properly first.
As for performance - can't say what's wrong because your code snippet doesn't quite reveal if you're doing some excessive recomputing on the arrays or not and since you keep using built-in Array functions, which are a lot slower than for for of
loops, it might be you're just slowing yourself down with it but it's impossible for me to tell.
If you want me to help you debug this properly, take the time and create a proper reproduction.
thanks i fixed the issues the library is soo good awesome work man , i want to use the fit view as function i have added a different button for a button when i click the button it will change the layout but the view port is at the different place to make it see the whole view i need that fit view button functionality , i even saw the controls.vue file but i still can understand it is there a a function we can use ??
Is there an existing issue for this?
Current Behavior
Failed to resolve component: SpecialNode in nuxt 3
Expected Behavior
the minimum example should work
Steps To Reproduce
install Vue flow and make a component or page paste the basic code in given in this
Url : https://vueflow.dev/guide/getting-started.html
Relevant log output
Anything else?