link1233 link1234 link1235 link1236 link1237 link1238 link1239 link1240 link1241 link1242 link1243 link1244 link1245 link1246 link1247 link1248 link1249 link1250 link1251 link1252 link1253 link1254 link1255 link1256 link1257 link1258 link1259 link1260 link1261 link1262 link1263 link1264 link1265 link1266 link1267 link1268 link1269 link1270 link1271 link1272 link1273 link1274 link1275 link1276 link1277 link1278 link1279 link1280 link1281 link1282 link1283 link1284 link1285 link1286 link1287 link1288 link1289 link1290 link1291 link1292 link1293 link1294 link1295 link1296 link1297 link1298 link1299 link1300 link1301 link1302 link1303 link1304 link1305 link1306 link1307 link1308 link1309 link1310 link1311 link1312 link1313 link1314 link1315 link1316 link1317 link1318 link1319 link1320 link1321 link1322 link1323 link1324 link1325 link1326 link1327 link1328 link1329 link1330 link1331 link1332 link1333 link1334 link1335 link1336 link1337 link1338 link1339 link1340 link1341 link1342 link1343 link1344 link1345 link1346 link1347 link1348 link1349 link1350 link1351 link1352 link1353 link1354 link1355 link1356 link1357 link1358 link1359 link1360 link1361 link1362 link1363 link1364 link1365 link1366 link1367 link1368 link1369

[Vue.js] Vuejs setting an arrayCreate a filter.Or use a computed property.

If I set to Vue.data array like this [0: Object, 2: Object];
I will get in vue.js console log panel array like this [0: Object, 1: undefined 2: Object];
and after iteration in ‘v-for=”cell in row.cells”‘ I got the problem of getting any property of undefined.

I resolved my problem like this:

v-for=”cell in row.cells” v-bind:colspan=”cell.colspan” v-if=”typeof cell !== ‘undefined’”

v-for=”cell in row.cells” v-bind:colspan=”cell.colspan” v-if=”typeof cell !== ‘undefined’”

to get in vue.js array as I’ve tried to set without index shift or any array changings.

Solution :

vue.js can iterate Objects the same as they do Arrays, if you insist on named values why not do this:

cells: {
0: {},
1: {},
2: {}
}

If you got unwanted “data” in the array, you could say the following.

const filteredCells = row.cells.filter(cell => cell !== undefined)

and then iterate the filteredCells instead, id make filteredCells a computed value.

v-for=”cell in filteredCells”

Keep index:

export default {
data() {
return {
row: {
cells: [
{name: ‘peter’},
{name: ‘louise’},
{name: ‘hans’},
undefined,
{name: ‘mia’},
{name: ‘john’}
]
}
}
},

computed: {
filteredCellsWithIndex() {
if (!this.row || !this.row.cells) {
return
}

const { cells } = this.row

return cells.map((cell, index) => {
if (cell === undefined) {
return
}

cell.yourIndex = index
return cell
}).filter(cell => cell !== undefined)
}
}
}

Solution 2:

There are a couple of ways to cleanly remove the undefined values without making the template overly complicated.

Create a filter.

v-for=”cell in row.cells | isDefined”

{
filters: {
isDefined(items) {
return items.filter(it => it !== undefined)
}
}
}

Or use a computed property.

v-for=”cell in cells”

{
computed: {
cells() {
return this.row.cells.filter(it => it !== undefined)
}
}
}

[Vue.js] Color dots bases on their values - vue - javascriptPart of my vue code to display the value columnPart of my javascript codePart of my javascript code

there is created a table from a database. One of the columns called value.
Instead of displaying the value. when trying to display color dots based on a range.
For example, value is zero or 0.5 then the color of the dot is red. If the value is between 1 and 3 then the color is orange.
If the value is greater then 3 the dot is colored green.

At the moment I got the following error:
[vue.js warn]: Error in render: “TypeError: _vm.range is not a function”

It’s probably something about how if define my function. And the type of data, I gave to my function.
I don’t understand what the problem is. Could someone help me? Thanks a lot;

Part of my vue.js code to display the value column

<template slot=”value” slot-scope=”row”>
<span class=”green dot” v-if=”range(row.item.value) == 2”></span>
<span class=”orange dot” v-if=”range(row.item.value) == 1”></span>
<span class=”red dot” v-if=”range(row.item.value) == 1”></span>
</template>

Part of my javascript code

export default {
props: [‘dbdata’],
data() {
return {
dbs: this.dbdata,
dbSearch: ‘’,
totalRows: 1,
currentPage: 1,
perPage: 10,
pageOptions: [10, 20, 50,100],
sortBy: “id”,
sortDesc: false,
sortDirection: ‘asc’,
filter: null,
selectMode: ‘multi’,
selected: [],
fields: {
id: {
label: “Id”,
sortable: true
},
name: {
label: “Name”,
sortable: true
},
value: {
label: “value”,
sortable: true
}
}
}
},
computed:{
hits: function(){
var hits = this.dbs.length
return hits
},
range: function(x){
if (x < 1){
x = 0;
}if(x >= 1 && x <= 3 ){
x = 1;
}if(x >= 3 ){
x = 2;
}
return x
}

},

Solution :

the methods should be in the methods property:

computed: {
hits: function(){
var hits = this.dbs.length
return hits
},
}
methods: {
range: function(x){
if (x < 1){
x = 0;
}if(x >= 1 && x <= 3 ){
x = 1;
}if(x >= 3 ){
x = 2;
}
return x
}
}

https://vuejs.org/v2/guide/events.html#Method-Event-Handlers

Instead of using the v-if in this case, maybe you could use the css property to add the correct color. Try create a function that return the color as string and pass it to the :class property:

<template slot=”value” slot-scope=”row”>
<span class=”dot” :class=”color” />
</template>

https://vuejs.org/v2/guide/class-and-style.html#Object-Syntax

I hope that maked sense.

Solution 2:

You’re using a computed property, which doesn’t accept an argument.
What you have to use is a basic method like this :

methods: {
range(x) {
if (x < 1) {
x = 0;
} if(x >= 1 && x <= 3 ) {
x = 1;
} if(x >= 3 ) {
x = 2;
}
return x
}
}

Now you can use the method in the template.

Solution 3:

After the help I found the following.

The vue.js code

<template slot=”value” slot-scope=”row”>
<span class=’dot largerSize’ :class=”statusColor[range(row.item.value)]“></span>
</template>

Part of my javascript code

range: function(x){
if (x < this.min){
return 0;
}else if(x >= this.min && x <= this.max ){
return 1;
}else if(x >= this.max ){
return 2;
}
}

[Vue.js] Google Maps Geocode unexpected property location

I’m trying to set up geocoding for my vue.js app. I’m not using any third party library, only google maps installed via npm.

When calling the geocode method, it throws an error saying, that the property location is unexpected. I’ve tried “location”, “latlng”, the coordinates itself and so on. Longitude and latitude come from the navigator.geolocation object.

Here is a part of my setup-script:

Vue.component(‘catalog’, require(‘./components/Catalog’));
Vue.component(‘address-autocomplete’, require(‘./components/AddressAutoComplete’));
window.googleMapsClient = require(‘@google/maps’).createClient({
key: “MY_API_KEY”
});

And my Vue-component:

getLocationFromGeoData() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
this.setLocation,
this.showError
);
} else {
showLocationError(“Geolocation wird nicht untersttzt!”);
}
},
setLocation(position) {
var self = this;

this.location.latitude = position.coords.latitude;
this.location.longitude = position.coords.longitude;

var latLng = {
lat: parseFloat(this.location.latitude),
lng: parseFloat(this.location.longitude)
};

googleMapsClient.geocode({‘location’: latLng}).asPromise()
.then((response) => {
self.location.address = results[1].formatted_address;
}).catch((err) => {
showLocationError(err);
});
},

Solution :

geocode is method of class google.maps.Geocoder - https://developers.google.com/maps/documentation/javascript/geocoding.

const geocoder = new google.maps.Geocoder;
geocoder.geocode({‘location’: latlng}, function(results, status) { // code

Solution 2:

Please note that you try to resolve a coordinate to the address. This process typically is called reverse geocoding. That means you must use a .reverseGeocode(query, callback) method instead of .geocode(query, callback) method.

the code should be changed to something similar to

var latLng = {
lat: parseFloat(this.location.latitude),
lng: parseFloat(this.location.longitude)
};

googleMapsClient.reverseGeocode({‘latlng’: latLng}).asPromise()
.then((response) => {
self.location.address = results[1].formatted_address;
}).catch((err) => {
showLocationError(err);
});

For more details have a look at the documentation of Maps Web Services client library for Node.js at

https://googlemaps.github.io/google-maps-services-js/docs/GoogleMapsClient.html

I hope this helps!

[Vue.js] Navigation inside vue component with vue-native-router

The vue-native-router docs provide a good example about how to implement a navigation to switch between screens, which works so far in my little demo app that I’m trying to build to get a grasp about how things work.

The basics that are required to navigate from one screen to another, inside a screen vue.js template, are so far:

<template>
<view class=”o-container”>
<button title=”ChangeView” :on-press=”goToMyNewFancyView” />
</view>
</template>

<script>
export default {
props: {
navigation: {
type: Object
}
},
methods: {
goToMyNewFancyView() {
this.navigation.navigate(‘MyNewFancyView’);
}
}
};
</script>

(I’ve skipped the main setup of the StackNavigator as this is completely the same as in the docs and not really helpful for this question, see TJ Weems answer).

My aim is now to have a list of components that display a title and a description. By clicking on the component, the screen should be changed to the component’s detail view. Thus, I tried to implement the same for my component:

<template>
<view>
<text>This is a component.</text>

<button title=”show more” :on-press=”show” />
</view>
</template>

<script>
export default {
props: {
navigation: {
type: Object
}
},
methods: {
show() {
this.navigation.navigate(‘MyShowView’);
}
}
};

However, this.navigation is undefined inside the vue.js component. Somehow I don’t understand the connections here and could not find anything relatable that would explain this. I’m also not sure if this is the correct way, or if navigation should happen outside of the component at all.

How would one implement a link from a component that is a teaser for a thing to the actual detail screen?

Dependencies:

“dependencies”: {
“expo”: “^32.0.0”,
“react”: “16.5.0”,
“react-native”: “https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz"
},
“devDependencies”: {
“@babel/core”: “^7.0.0-0”,
“babel-preset-expo”: “^5.0.0”,
“vue-native-core”: “0.0.8”,
“vue-native-helper”: “0.0.10”,
“vue-native-router”: “0.0.1-alpha.3”,
“vue-native-scripts”: “0.0.14”
},

Solution :

Did you do this part? or something similar..

<script>
import { StackNavigator } from “vue-native-router”;
import HomeScreen from “../src/screens/homeScreen.vue”;
import DetailsScreen from “../src/screens/detailsScreen.vue”;
const AppNavigation = StackNavigator(
{
Home: HomeScreen,
Details: DetailsScreen,
},
{
initialRouteName: ‘Home’,
}
);
export default {
components: { AppNavigation }
}
</script>

Instance of component

<template>
<app-navigation></app-navigation>
</template>

Solution 2:

My aim is now to have a list of components that display a title and a
description. By clicking on the component, the screen should be
changed to the component’s detail view. Thus, I tried to implement the
same for my component:

Why couldnt you do something like this?

StackNavigator({
Home: HomeScreen,
Detail: {
screen: DetailScreen,
navigationOptions: {
title: ‘Detail Screen’,
headerStyle: {
backgroundColor: ‘transparent’,
},
},
},
})

using the navigationOptions to add a title and description to the list of routing components, you would have this data available to you to display.

each router component would still render the view or screen you have associated with that link.

[Vue.js] How do increment value while it being declared inside function

there is a small issue where i’m trying to increment/decrement the buttons in x steps this is all dynamic dependant on what ever the quantity step is, my code works fine when its increments of one because when just using ++ there is no scope issue

I’ve tried a few things but no much luck i can’t really declare it outside of the function as there is multiple input boxes and i’d need to do some sort of mapping to know which one relates to which input.

I know what the issue is its because of scoping im defining a variable inside a function but its not a simple thing to do it outside of it any other solutions to get past this without defining it outside ?

When i had it like this this.$refs[codeForRef][0].value++ it worked fine and would increment by one

increment: function(e) {
e.preventDefault();
var codeForRef = e.srcElement.id;

var test = parseInt(this.$refs[codeForRef][0].value, 10); //the value of the qty
test += this.dyQty //whatever it needs to go up in
},

Solution :

what i understood from the question, this should work for you.

increment: function(e) {
e.preventDefault();
var codeForRef = e.srcElement.id;

var test = parseInt(this.$refs[codeForRef][0].value, 10); //the value of the qty
test += this.dyQty //whatever it needs to go up in
this.$refs[codeForRef][0].value = test;
}

[Vue.js] Modal not showing in vue.js

So there is an issue, there is made a map application with various features in vanilla js. when now trying to translate all this code to vue.js and it’s a slow process. there is a modal to popup when clicking the button “Add step”, but it doesn’t. there is read documentation and viewed examples but I can’t figure it out.

As I mentioned I’ve tried various examples I’ve found here on stackoverflow and elsewhere.

I understand the solution might be very simple indeed, but I’m stuck and this modal wont show. Any tips or tricks? Things to think about when using vue?
Here is a fiddle of my entire project in it’s wholesome, https://jsfiddle.net/8Lmjrhgs/ .
Many thanks for the time people!

This is how my vanilla.js modal looked like

let btn = document.getElementById(“myBtn”);
let span = document.getElementsByClassName(“close”)[0];

btn.onclick = function() {
modal.style.display = “block”;
};
span.onclick = function() {
modal.style.display = “none”;
};
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = “none”;
}
};```

Solution :

Note: data() { return { …

data() {
return {
showModal: false,
isEditing: false,
user: {
mapTitle: ‘Add a title to the map’,
mapDescription: ‘Add a description to the map’,
},
steps: [{title: “”, description: “”}],
step: {title: “”, description: “”}
}

},

Don’t put the v-show on the transition-group, put it on the immediate child, the same actually goes for click, I would also not toggle the value for “Close modal”, since you dont for “Open modal” at least id make those handle that the same way.

<transition name=”modal” :modalData=’customData’ @close=’showModal = !showModal’>
<div class=”modal-mask” v-show=”showModal”>

I believe the main issue here was the way you’ve created the component, which in this specific case is redundant since all the code is there anyway (but the real code might be actually importing it, so I cant say for sure)
Removing the script tags got the modal out.

https://jsfiddle.net/1kv24wyr/1/

[Vue.js] Adding functionality to Vuetify component, mass pass in props

to be able to send props to a Vuetify component without needing to assign each one within my component, is there a way I can just mass pass in all of the props?

Below is what i’m currently doing, however there’s a lot of prop’.

there is attempted to simply extend the VSelect component, however this returns multiple errors which don’t seem simple to fix!

<template>
<v-flex xs12 sm6>
<v-select v-model=”selected” :items=”data”
:label=”label”
:multiple=”multiple”
:chips=”chips”
:hint=”hint”
:persistent-hint=”persistentHint”
:counter=”counter”
:dark=”dark”
\></v-select>
</v-flex>
</template>
<script>
export default {
props: {
label: {
default: false,
type: String|Boolean
},
multiple: {
default: true,
type: Boolean
},
chips: {
default: true,
type: Boolean
},
hint: {
default: ‘’,
type: String|Boolean
},
persistentHint: {
default: this.hint !== ‘’ || this.hint !== false,
type: String|Boolean
},
counter: {
default: false,
type: Number|Boolean
},
dark: {
default: false,
type: Boolean
},
},
data: function() {
return {
selected: [ ],
data: [
‘test’, ‘test2’, ‘test3’
]
}
}
}
</script>

Solution :

You can pass props as an object:

<v-select
v-model=”selected”
:items=”data”
v-bind=”$props”
\></v-select>

[ https://vuejs.org/v2/guide/components-props.html#Passing-the-Properties-of-an-Object ]

[Vue.js] Why is my data object variable being altered when I'm not reassigning manipulated values to it?

I’m cloning a variable for manipulation in one of my functions, and I’m NOT reassigning it back. Why is the second console.log() printing the below?

Here is the code:

console.log(‘BEFORE -> ‘, JSON.parse(JSON.stringify(vm.referenceMatrix)));

var referenceId = null;

var referenceMatrix = vm.referenceMatrix;

for (var i = 0; i < length; i++) {
referenceId = references[i].article_reference_id;

referenceMatrix[referenceId] = i + 1;
}

console.log(‘AFTER -> ‘, JSON.parse(JSON.stringify(vm.referenceMatrix)));

//vm.referenceMatrix = referenceMatrix;

As you can see, vm.referenceMatrix = referenceMatrix; is commented out, so how it this possible?

Edit:

This code generates the same output as in the image above:

console.log(‘BEFORE -> ‘, JSON.parse(JSON.stringify(vm.referenceMatrix)));

var referenceId = null;

var referenceMatrixs = vm.referenceMatrix;

for (var i = 0; i < length; i++) {
referenceId = references[i].article_reference_id;

referenceMatrixs[referenceId] = i + 1;
}

console.log(‘AFTER -> ‘, JSON.parse(JSON.stringify(vm.referenceMatrix)));

//vm.referenceMatrix = referenceMatrix;

Solution :

I’m cloning a variable for manipulation in one of my functions

I think you mean this line of code:

var referenceMatrixs = vm.referenceMatrix;

This does not clone anything. Instead it assigns a reference to the object. All changes to referenceMatrixs will also be seen in vm.referenceMatrix.

Note that the output statements do clone the object:

console.log(‘BEFORE -> ‘, JSON.parse(JSON.stringify(vm.referenceMatrix)));

However, the clone is only used for output and immediately thrown away. This is a lot of code for basically no purpose. You will get the exact same result with

console.log(‘BEFORE -> ‘, vm.referenceMatrix);

Since this statement does not modify the object, there is no reason to clone here.

Solution 2:

Perhaps you come from a different language, but in JavaScript - each assignment is by reference. That means that:

const x = { value: 1};
const y = x;
y.value = 2;
console.log(x); // { value: 2 }

Because the object is not cloned, and the reference is shared between the too variables.
If you want to deep copy the variables (“copy by value”, like in C++), there are a lot of ways to do that (What is the most efficient way to deep clone an object in JavaScript?)

[Vue.js] add class to a specific parent div when click a component created with v-for

when new to vuejs, this is what to do:
there is a list of components, each in a div. Now if I do something with the component (i.e. click it). to add a class to the parent div. This is what I did so far, the code is simplified, just to show what to do with a simple case.

my app.vue:

<div class=”toggle-box” v-for=”(name, index) in names” :class=”classActive” :key=”index”>
<app-comp :myName=”name” :myIndex=”index” @someEvent=”doSomething”></app-counter>
</div>
data() {
classActive: ‘’,
names: [‘alpha’, ‘beta’, ‘gamma’]
},
methods: {
doSomething() {
this.classActive === ‘’ ? this.classActive = ‘is-active’: this.classActive=’’;
}
}

the component:

<div>
<button @click=”toggle”>{ myName } - { myIndex }</button>
</div>

props: [‘myName’, ‘myIndex’],
methods: {
toggle() {
this.$emit(‘someEvent’, index);
}
}

what this do: it creates 3 divs with “toggle-box”-class with a button in it which has the label “name - index”. When I click a button, it emits the “someEvent”-event with index attached. The parent listens to this event and toggle the class ‘is-active’ on the div with the ‘toggle-box’ class. The thing is, right now, when I click a button, it adds the class to all 3 divs. Probably because there is no different between the 3 divs for vuejs. I know I can append the index to the event and call this with $event in the parent, but how do I use this? Or is there perhaps a better way to achieve what I want?

thanks for helping.

Solution :

There are several different ways to approach this but I think the starting point is to think about how you want to represent this as data rather than how that appears in the UI. So model before view.

Presumably you’re going to want to do something with these active items after they’ve been selected. I’d focus on that rather than the problem of highlighting them. The highlighting would then fall out relatively painlessly.

For the sake of argument, let’s assume that an array of active items is a suitable model for what you’re trying to achieve. It might not be but it makes for a simple example.

So:

data() {
return {
activeNames: [],
names: [‘alpha’, ‘beta’, ‘gamma’]
}
},

No mention of classes here as we’re not worrying about the UI concern, we’re trying to model the underlying data.

For the toggle method I’d be more inclined to emit the name than the index, but you’re better placed to judge which represents the data better. For my example it’ll be name:

methods: {
toggle() {
this.$emit(‘someEvent’, this.myName);
}
}

Then in the parent component we’ll add/remove the name from the array when the event is emitted. Other data structures might be better for this, I’ll come back to that at the end.

methods: {
doSomething(name) {
if (this.activeNames.includes(name)) {
this.activeNames = this.activeNames.filter(item => item !== name);
} else {
this.activeNames.push(name);
}
}
}

Now we have an array containing the active names we can use that to derive the class for those wrapper divs.

<div
class=”toggle-box”
v-for=”(name, index) in names”
:class=”{‘is-active’: activeNames.includes(name)}”
:key=”index”
\>

Done.

As promised, I’ll now return to other data structures you could use.

Instead of an array we might use an object with boolean values:

data() {
return {
names: [‘alpha’, ‘beta’, ‘gamma’],
activeNames: {
alpha: false,
beta: false,
gamma: false
}
}
}

In many ways this is an easier structure to work with for this particular example but we do end up duplicating the names as property keys. If we don’t prepopulate it like this we can end up with reactivity problems (though those can be solved using $set).

A further alternative is to use objects to represent the names in the first place:

data() {
return {
names: [
{name: ‘alpha’, active: false},
{name: ‘beta’, active: false},
{name: ‘gamma’, active: false}
]
}
}

Whether this kind of data structure makes sense for the use case I can’t really judge.

Update:

Based on what you’ve said in the comments I’d be inclined to create another component to represent the toggle-box. Each of these can store its own active state rather than trying to hold them all on the parent component. the v-for would then create instances of this new component directly. Depending on the circumstances it may be that this new component could merged into the original component.

There are all sorts of other considerations here that make it really difficult to give a definitive answer. If the active state needs to be known outside the toggle-box component then it’s a very different scenario to if it’s just internal state. If only one toggle-box can be open at once (like an accordion) then that’s similarly tricky as internal state is not sufficient.

[Vue.js] How to attach D3 component to div in another vue file

I’m incorporating D3JS charts in my VueJS application and am having trouble understanding how to connect the D3 component to a div in a .vue.js file. The D3 chart renders beautifully when I attach it to the HTML body, but I don’t want it to appear on every view, just the view that I’ve imported it to and just to the div I want.

I’ve looked at other answers that do mounting and computing of D3 components in the vue.js — all of which seems excessively complicated.

Likely I’m not understanding how D3 charts should work as vue.js components. I’m trying to keep it simple as possible. Here’s my Home.vue.js in views/

<template>
<div id=”chart”>
</div>
</template>

<script>
import MainChart from “@/components/MainChart.vue”;

export default {
name: ‘chart’,
components: {
MainChart
}
}
</script>

And then my MainChart component in components/

<template>
<div id=”chart”>
</div>

</div>
</template>

<script>
import * as d3 from “d3”;
export default {
name: “MainChart”,
};
// 2. Use the margin convention practice
var margin = {top: 50, right: 50, bottom: 50, left: 50}
, width = window.innerWidth - margin.left - margin.right // Use the window’s width
, height = window.innerHeight - margin.top - margin.bottom; // Use the window’s height

// The number of datapoints
var n = 30;

// 5. X scale will use the index of our data
var xScale = d3.scalePow()
.domain([0, n-1]) // input
.range([0, width]); // output

// 6. Y scale will use the randomly generate number
var yScale = d3.scalePow()
.domain([0, 1000]) // input
.range([height, 0]); // output

// 1. Add the SVG to the page and employ #2
var svg = d3.select(“#chart”).append(“svg”)
.attr(“width”, width + margin.left + margin.right)
.attr(“height”, height + margin.top + margin.bottom)
.append(“g”)
.attr(“transform”, “translate(“ + margin.left + “,” + margin.top + “)”);

// 3. Call the x axis in a group tag
svg.append(“g”)
.attr(“class”, “x axis”)
.attr(“transform”, “translate(0,” + height + “)”)
.call(d3.axisBottom(xScale)); // Create an axis component with d3.axisBottom

svg.append(“text”)
.attr(“class”, “x label”)
.attr(“text-anchor”, “end”)
.attr(“x”, width)
.attr(“y”, height - 6)
.text(“Time”);

// 4. Call the y axis in a group tag
svg.append(“g”)
.attr(“class”, “y axis”)
.call(d3.axisLeft(yScale)); // Create an axis component with d3.axisLeft

svg.append(“text”)
.attr(“class”, “y label”)
.attr(“text-anchor”, “end”)
.attr(“y”, 6)
.attr(“dy”, “.75em”)
.attr(“transform”, “rotate(-90)”)
.text(“Views”);

// 7. d3’s line generator
var line = d3.line()
.x(function(d, i) { return xScale(i); }) // set the x values for the line generator
.y(function(d) { return yScale(d.y); }) // set the y values for the line generator
.curve(d3.curveMonotoneX) // apply smoothing to the line

// 8. An array of objects of length N. Each object has key -> value pair, the key being “y” and the value is a random number
// var dataset = d3.range(n).map(function(d) { return {“y”: d3.randomUniform(1)() } })
var dataset = [],
n = 30,
a = 20,
b = 1.15;

for (var k = 0; k < n; k++) {
dataset.push({x: 1 * k, y: a * Math.pow(b, k)});
}

// 9. Append the path, bind the data, and call the line generator
svg.append(“path”)
.datum(dataset) // 10. Binds data to the line
.attr(“class”, “line”) // Assign a class for styling
.attr(“d”, line) // 11. Calls the line generator
.attr(“stroke-dasharray”, 100 + “ “ + 100)
.attr(“stroke-dashoffset”, 1000)
.attr(“fill”, “none”)
.transition()
.duration(10000)
.ease(d3.easeLinear)
.attr(“stroke-dashoffset”, 0);

// 12. Appends a circle for each datapoint
svg.selectAll(“.dot”)
.data(dataset)
.enter().append(“circle”) // Uses the enter().append() method
.attr(“class”, “dot”) // Assign a class for styling
.attr(“cx”, function(d, i) { return xScale(i) })
.attr(“cy”, function(d) { return yScale(d.y) })
.attr(“r”, 5);

</script>

<style>
/* 13. Basic Styling with CSS */

/* Style the lines by removing the fill and applying a stroke */
.line {
fill: none;
stroke: #678C1A;
stroke-width: 3;
}

.axis text { display: none; }

/* Style the dots by assigning a fill and stroke */
.dot {
fill: #C7D941;
stroke: #fff;
}
</style>

Because it works fine when I attach the svg to “body” it must be the case that the D3 chart isn’t finding the div when it loads into the Home.vue, right?

Solution :

From the examples posted I see some syntax errors.

Home.vue

<template>
<div id=”home”>
<MainChart></MainChart>
</div>
</template>

<script>
import MainChart from “@/components/MainChart.vue”;

export default {
name: ‘chart’,
components: {
MainChart
}
}
</script>

MainChart.vue

<template>
<div id=”chart”></div>
</template>

<script>
import * as d3 from “d3”;
export default {
name: “MainChart”,
};
// 2. Use the margin convention practice
var margin = {top: 50, right: 50, bottom: 50, left: 50}
, width = window.innerWidth - margin.left - margin.right // Use the window’s width
, height = window.innerHeight - margin.top - margin.bottom; // Use the window’s height

// The number of datapoints
var n = 30;

// 5. X scale will use the index of our data
var xScale = d3.scalePow()
.domain([0, n-1]) // input
.range([0, width]); // output

// 6. Y scale will use the randomly generate number
var yScale = d3.scalePow()
.domain([0, 1000]) // input
.range([height, 0]); // output

// 1. Add the SVG to the page and employ #2
var svg = d3.select(“#chart”).append(“svg”)
.attr(“width”, width + margin.left + margin.right)
.attr(“height”, height + margin.top + margin.bottom)
.append(“g”)
.attr(“transform”, “translate(“ + margin.left + “,” + margin.top + “)”);

// 3. Call the x axis in a group tag
svg.append(“g”)
.attr(“class”, “x axis”)
.attr(“transform”, “translate(0,” + height + “)”)
.call(d3.axisBottom(xScale)); // Create an axis component with d3.axisBottom

svg.append(“text”)
.attr(“class”, “x label”)
.attr(“text-anchor”, “end”)
.attr(“x”, width)
.attr(“y”, height - 6)
.text(“Time”);

// 4. Call the y axis in a group tag
svg.append(“g”)
.attr(“class”, “y axis”)
.call(d3.axisLeft(yScale)); // Create an axis component with d3.axisLeft

svg.append(“text”)
.attr(“class”, “y label”)
.attr(“text-anchor”, “end”)
.attr(“y”, 6)
.attr(“dy”, “.75em”)
.attr(“transform”, “rotate(-90)”)
.text(“Views”);

// 7. d3’s line generator
var line = d3.line()
.x(function(d, i) { return xScale(i); }) // set the x values for the line generator
.y(function(d) { return yScale(d.y); }) // set the y values for the line generator
.curve(d3.curveMonotoneX) // apply smoothing to the line

// 8. An array of objects of length N. Each object has key -> value pair, the key being “y” and the value is a random number
// var dataset = d3.range(n).map(function(d) { return {“y”: d3.randomUniform(1)() } })
var dataset = [],
n = 30,
a = 20,
b = 1.15;

for (var k = 0; k < n; k++) {
dataset.push({x: 1 * k, y: a * Math.pow(b, k)});
}

// 9. Append the path, bind the data, and call the line generator
svg.append(“path”)
.datum(dataset) // 10. Binds data to the line
.attr(“class”, “line”) // Assign a class for styling
.attr(“d”, line) // 11. Calls the line generator
.attr(“stroke-dasharray”, 100 + “ “ + 100)
.attr(“stroke-dashoffset”, 1000)
.attr(“fill”, “none”)
.transition()
.duration(10000)
.ease(d3.easeLinear)
.attr(“stroke-dashoffset”, 0);

// 12. Appends a circle for each datapoint
svg.selectAll(“.dot”)
.data(dataset)
.enter().append(“circle”) // Uses the enter().append() method
.attr(“class”, “dot”) // Assign a class for styling
.attr(“cx”, function(d, i) { return xScale(i) })
.attr(“cy”, function(d) { return yScale(d.y) })
.attr(“r”, 5);

</script>

<style>
.line {
fill: none;
stroke: #678C1A;
stroke-width: 3;
}

.axis text {
display: none;
}

.dot {
fill: #C7D941;
stroke: #fff;
}
</style>