How to create d3 svg in vue-cli? - d3.js

I'm new to d3 and trying to create d3 SVG in vue-cli.
the browser does not show anything with the code as below, but it work on HTML without vue.
Could anyone tell me what's the matter with my coding?
Thank you very much!
<template>
<div>
<div id='chart' ></div>
</div>
</template>
<script>
import * as d3 from 'd3'
export default {
name: 'priceChart',
data() {
return {
}
},
methods:{
createSvg(){
const svg =
d3.select('#chart').append('svg')
.attr('width',500)
.attr('height',400);
svg.append('rect')
.attr('x',0)
.attr('y',0)
.attr('width',500)
.attr('height',400)
.style('fill','red')
}
},
created(){
this.createSvg();
}
}
</script>

DOM element is not available in created methods, you should put it in mounted
In the created hook, you will be able to access reactive data and
events are active. Templates and Virtual DOM have not yet been mounted
or rendered.
<template>
<div>
<div id='chart' ></div>
</div>
</template>
<script>
import * as d3 from 'd3'
export default {
name: 'priceChart',
data() {
return {
}
},
methods:{
createSvg(){
const svg =
d3.select('#chart').append('svg')
.attr('width',500)
.attr('height',400);
svg.append('rect')
.attr('x',0)
.attr('y',0)
.attr('width',500)
.attr('height',400)
.style('fill','red')
}
},
mounted(){
this.createSvg();
}
}
</script>

Related

how to get each data from response api laravel in vue js 3

Need help , i can get all data from response api but having some problem when try to get data (looping data ) from key "get_item_cards" . Here's my response and code in vue js
Response api
<script setup>
<script>
import axios from 'axios'
export default {
name: 'ListNotes',
data() {
return {
cardNotes: [],
}
},
mounted() {
// console.log('Page mounted');
this.getListNotes();
},
methods: {
getListNotes() {
axios.get('http://localhost:8000/api/card').then(res => {
this.cardNotes = res.data.cardNotes
console.log(this.cardNotes);
})
}
}
}
</script>
how the best way to get all data & each data from relationship in vue js 3
Since the this.cardNote returns an array with three elements, you can use loop using v-for and access to the get_item_cards array like below,
<template>
<div>
<div v-for=(note, index) in cardNote>
<p>{{node.cardname}}</p>
<div v-for=(item, key) in note.get_item_cards>
<p>{{item.content}}</p>
</div>
</div>
</div>
</template>
<script setup>
<script>
import axios from 'axios'
export default {
name: 'ListNotes',
data() {
return {
cardNotes: [],
}
},
mounted() {
// console.log('Page mounted');
this.getListNotes();
},
methods: {
getListNotes() {
axios.get('http://localhost:8000/api/card').then(res => {
this.cardNotes = res.data.cardNotes
console.log(this.cardNotes);
})
}
}
}
</script>

Using Vue.js 3 component dynamically in the D3.js v7

im using the Vue.js 3 and D3.js v7 to making the flowchart.
My problem here is I can't dynamically append the component inside the D3.js.
My component is imported like shown below.
components: {
StoryPanel: defineAsyncComponent(() => import("#/Pages/Story/Partials/StoryPanel"))
},
let nodes = container.selectAll("g")
.data(root.descendants())
.join("g")
.append("foreignObject")
.attr("width", entityWidth - 10)
.attr("height", 150)
nodes.append("xhtml:div")
.attr("class", "border border-black")
.html(function (d) {
// return '<StoryPanel />' tried this but not working
})
.style("border", '1px solid black')
This is the generated html
<foreignObject width="190" height="150" transform="translate(-95,10)">
<div class="border border-black" style="border: 1px solid black;">
<storypanel></storypanel>
</div>
</foreignObject>
[Edit 1]
Tried this Rendering Vue 3 component into HTML string as #MichalLevĂ˝ suggested, but still not working
.html(function (d) {
const tempApp = createApp({
render() {
return h(StoryPanel,{step: d})
}
})
const el = document.createElement('div');
const mountedApp = tempApp.mount(el)
return mountedApp.$el.outerHTML
})
[Edit 2]
I found it works only when using const instead of a Component.vue
const CircleWithTextSvg = {
name: 'CircleWithTextSvg',
props: {
text: {
type: String,
default: "1"
},
fill: {
type: String,
default: "white"
}
},
template: `<div>template</div>`
}
Any help is appreciated. Thank you.
Use createApp
import {createApp} from 'vue';
and use this instead and return the outerHTML
const app = createApp(Component, {prop1: this.prop1})
.mount(document.createElement('div'))
return app.$el.outerHTML

Vuejs Displaying a component multiple times with Axios in it

I have been trying to figure out this for a hours but no luck. I have 2 components. The first component is dynamic and the second component just gets the user geolocation. The geolocation is then displayed in the first component.
My problem is that I display the first component a few times on the page and every time it is displayed it makes a GET request which is inefficient . If I display the component 3 times it will make 3 GET requests.
What would be the best way to rewrite this?
Thanks for the help
Component 1:
<template>
<section id="under-info">
THe user is from <ip_info></ip_info>
</section>
</template>
<script>
export default {
}
</script>
Component 2:
<template>
<span id="user-city">
{{value}}
</span>
</template>
<script>
export default {
mounted: function () {
this.$nextTick(function () {
this.getIpInfo(this.param)
})
},
props:['param'],
data: function () {
return {
value:null
}
},
methods:{
getIpInfo(){
var vm = this
delete axios.defaults.headers.common["X-Requested-With"];
delete axios.defaults.headers.common["X-CSRF-TOKEN"];
axios
.get('http://api.ipstack.com/check?access_key=?',{
timeout: 1000
})
.then(function(response) {
vm.value = response.data['city]
})
}
},
}
</script>
Wrap the code where you want to reuse this value 3x in a component.
<template>
<div>
The user is from {{location}}, and {{location}} is a great place. They have a baseball team in {{location}}
</div>
</template>
<script>
export default {
mounted: function () {
this.$nextTick(function () {
if(this.needLocation){
this.getIpInfo(this.param)
}
})
},
props:['param', 'needLocation'],
data: function () {
return {
location:null
}
},
methods:{
getIpInfo(){
this.location = //results from your API call
}
}
</script>

Laravel, Vue component template not show?

Sorry, my English is so bad!
File: app.js
window.auth_id = 0;
Vue.component('block-header-user-control', require('./HeaderComponent.vue'));
new Vue({
el: '#application'
});
File HeaderComponent.vue
<template lang="html">
<header-guest v-if="!auth"></header-guest>
<header-auth v-else></header-auth>
</template>
<script>
import HeaderGuest from './HeaderUserGuest.vue';
import HeaderAuth from './HeaderUserAuth.vue';
export default {
data: function () {
return {
auth: window.auth_id
}
},
components: {
'header-guest': HeaderGuest,
'header-auth': HeaderAuth,
},
methods: {},
}
</script>
File: HeaderUserGuest.vue
<script>
export default {
template: '#header-user-auth', // Not working,
// template: `<div>cascaaSA</div>`, // working
data() {
return {}
},
mounted() {
console.log('Created Guest');
},
}
</script>
File: HeaderUserAuth.vue
<script>
export default {
template: '#header-user-auth',
name: 'header-auth',
data() {
return {}
},
created() {
console.log('Created Auth');
},
}
</script>
File: index.blade.php
<div id="application">
<script type="text/x-template" id="header-user-guest">
Guest
</script>
<script type="text/x-template" id="header-user-auth">
Logged
</script>
<block-header-user-control></block-header-user-control>
</div>
"Created Guest" is displayed in browser console, but the "block-header-user-control" menu does not display "Guest".
Please help me. SPECIAL THANKS!!
====================
Thank all! It worked with html. Text not working
<div id="application">
<script type="text/x-template" id="header-user-guest">
<div>Guest</div>
</script>
<script type="text/x-template" id="header-user-auth">
<div>Logged</div>
</script>
<block-header-user-control></block-header-user-control>
</div>
You might need to move your templates outside of the scope of the application - move them below #application.

Vue Multiselect not displaying

I am trying to use Vue Multiselect V2 in my Laravel 5.3 project. I am using this example, http://monterail.github.io/vue-multiselect/#sub-single-select
I have the following setup, in my app.js file:
Vue.component('multiselect', require('./components/Multiselect.vue'));
var vm = new Vue({
el: '#app'
});
In the Multiselect.vue file
<script>
import Multiselect from 'vue-multiselect'
export default {
components: {
Multiselect
},
data () {
return {
value: '',
options: ['Select option', 'options', 'selected', 'mulitple', 'label', 'searchable', 'clearOnSelect', 'hideSelected', 'maxHeight', 'allowEmpty', 'showLabels', 'onChange', 'touched']
}
}
}
</script>
And I am calling it in the blade as below:
<div id="app">
<label class="typo__label">Single select</label>
<multiselect v-model="value" :options="options" :searchable="false" :close-on-select="false" :show-labels="false" placeholder="Pick a value"></multiselect>
<pre class="language-json"><code>#{{ value }}</code></pre>
</div>
This is how it displays in the DOM
<div id="app">
<label class="typo__label">Single select</label>
<!---->
<pre class="language-json"><code></code></pre>
</div>
Currently the dropdown does not display, and I don't see any errors in the console. I would have expected to add a template in somewhere but I couldn't find any mention of that in the Vue Multiselect docs.
For anyone having these issues, do not follow the examples on the official documentation. They do not work, rather use this from their Github page. https://github.com/monterail/vue-multiselect/tree/2.0#install--basic-usage
Basic example
<template>
<div>
<multiselect
v-model="selected"
:options="options">
</multiselect>
</div>
</template>
<script>
import Multiselect from 'vue-multiselect'
export default {
components: { Multiselect },
data () {
return {
selected: null,
options: ['list', 'of', 'options']
}
}
}
</script>
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
For updating the array from vue multiselect use #select and #remove events
Example: <multiselect #select="selectionChange" #remove="removeElement"> </multiselect>
Into methods add the next functions
methods: {
removeElement() {
this.$forceUpdate();
},
selectionChange() {
this.$forceUpdate();
},
}
this.$forceUpdate(); will update the state.

Resources