How to assign value to another javascript library with Vue? - javascript

With Vue, I get json values ​​from a remote page and I can print it to the page.
But I have to transfer these values ​​to another javascript library. How can I do that?
Data in the page v-for="dta in dataTable" or {{dataTable.height}} etc. I can use it the way. But it is not possible to use the "var graph like = {{dataTable.height}}" in another javascript, how can I do it?
I think I will have to give a work order one at a time. Because first the vue get remote data and then the other javascript should work because the values ​​will come from vue.
index.html
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="vue.min.js"></script>
<script src="apex/apexcharts.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.js"></script>
<style>
textarea {position: fixed;right: 0;top: 0;width: 300px;height: 400px;}
#testGraph1 {width:400px;position: fixed;top:0;right:0;margin-right:500px;}
</style>
</head>
<body>
<div id="app">
<form id="urlParameterForm">
<input type="date" name="startDate" id="startDate" />
<input type="date" name="endDate" id="endDate" />
<input
type="number"
name="pageNumber"
id="pageNumber"
value="1"
v-on:input="changePage"
/>
<input
type="button"
value="Filter"
id="Filter"
v-on:click="changeFilter"
/>
<p>Page : {{ pageActive }}</p>
</form>
<h3>{{title}}</h3>
<div v-for="dta in dataTable">
Height: {{dta.height}}, Type: {{dta.type}}
<h3>Categories</h3>
<ul v-for="dta2 in dta.graphData">
<li>{{dta2.categorie}}</li>
</ul>
<h3>Series</h3>
<ul v-for="dta2 in dta.graphData">
<li>{{dta2.serie}}</li>
</ul>
</div>
<div id='testGraph1'></div>
<textarea>
{{dataTable}}
</textarea>
</div>
<script src="getData.js"></script>
</body>
</html>
getData.js
const app = new Vue({
el: "#app",
devtools: true,
data: {
dataTable: [],
pageNumber: 1,
pageActive :0,
title:'Graph-1'
},
computed: {
url() {
return './dataSql.asp?pg=' + this.pageNumber
}
},
methods: {
changePage: function (event) {
console.log('Change Page',this.pageNumber);
this.pageNumber = event.target.value;
this.init();
},
changeFilter: function (event) {
console.log('Change Filter');
this.init();
},
init() {
let that = this;
console.log('init call');
$.ajax({
type: "POST",
url: that.url,
data:{
startDate:$('#startDate').val(),
endDate:$('#endDate').val(),
pageNumber:$('#pageNumber').val()
},
success: function (data) {
console.log('data remote call');
console.log(data.sqlData);
that.dataTable = data.sqlData;
}
});
}
},
mounted() {
this.init()
}
})
var barBasicChart = {
chart: {
height: 350, /*dta.height !Problem...*/
type: 'bar', /*dta.bar !Problem...*/
},
plotOptions: {
bar: {
horizontal: true,
}
},
dataLabels: {
enabled: false
},
series: [{
data: [10,5,3] /*dta.graphData.serie !Problem...*/
}],
xaxis: {
categories: ['Test-1','Test-2','Test-3'], /*dta.graphData.categorie !Problem...*/
},
fill: {
colors: '#ffcc33'
}
}
var bar_basic_chart = new ApexCharts(
document.querySelector("#testGraph1"),
barBasicChart
);
bar_basic_chart.render();
dataSql.asp
{"sqlData":[{"height":350,"type":"bar","graphData":[{"categorie":"Bursa","serie":4},{"categorie":"Tekirdağ","serie":3}]}]}
Question Update (2021-04-12)
As "var app = new Vue ({...})", I assigned the vue code to a variable called app.
I can reach "data: {title}" by typing app._data.title.
But interestingly, I cannot access json by typing "data: {....dataTable: []....}".
"var vueDatas = [];vueDatas = app._data.dataTable; "

As a follow up to my comment, I am posting components from a sample Chart.js project that I built recently. It demonstrates the idea that I was describing in my comment. It was written in Vue.js 2 using the Vue CLI.
chart-configurations.js
const samplePieConfig = {
type: 'pie',
data: {
datasets: [{
data: [],
backgroundColor: [
'rgba(255, 0, 0, 0.8)',
'rgba(0, 255, 0, 0.8)',
'rgba(0, 0, 255, 0.8)',
]
}],
// These labels appear in the legend and in the tooltips when hovering different arcs
labels: [
'Red',
'Green',
'Blue'
]
},
options: {
responsive: false
}
}
export {
samplePieConfig
}
ChartTest.vue
<template>
<div class="chart-test">
<h3>Chart Test</h3>
<canvas id="chart-canvas" width="500" height="500" ref="chartref"></canvas>
</div>
</template>
<script>
import Chart from 'chart.js';
import { samplePieConfig } from '#/chart-configurations.js'
export default {
data() {
return {
chartObj: null,
chartConfig: samplePieConfig
}
},
props: {
chartData: {
type: Array,
required: true
}
},
methods: {
setChartData() {
this.chartConfig.data.datasets[0].data = this.chartData;
}
},
mounted() {
this.setChartData();
this.chartObj = new Chart(this.$refs.chartref, this.chartConfig);
},
// beforeDestroy() {
// // This necessary if canvas is reused for a new chart
// this.chartObj.destroy();
// }
}
</script>
App.vue
<template>
<div id="app">
<chart-test v-if="dataReady" :chartData="pieChartData" />
</div>
</template>
<script>
import ChartTest from '#/components/ChartTest'
export default {
name: 'App',
components: {
ChartTest
},
data() {
return {
barChartData: [12, 19, 3, 5, 2, 3],
pieChartData: [10, 20, 30],
dataReady: true
}
},
methods: {
getData() {
this.dataReady = true;
}
},
mounted() {
// Simulate API call
setTimeout(this.getData(), 2000);
}
}
</script>

since you have an asynchronous request, so you can not access dataTable until it fetched
change your ajax request like this:
$.ajax({
type: "POST",
url: that.url,
data:{
startDate:$('#startDate').val(),
endDate:$('#endDate').val(),
pageNumber:$('#pageNumber').val()
},
success: function (data) {
console.log('data remote call');
console.log(data.sqlData);
that.dataTable = data.sqlData;
that.$emit('data-fetched'); // fire an event when data was ready to use
}
});
and outside your Vue instance you can listen that event like this:
app.$on('data-fetched', function(){
console.log(app.$data.dataTable)
});
and it's should work

Related

Bind plotly on click to vue.js data

I am creating project with vue.js and plot.ly javascript graph library.
How can I bind in "pts" to vue's data's "TestSentences"?
Here is my code ,
thank you to everyone who contributed
My goal is to create an interactive dashboard using this variable. In this way, I can change the data by clicking anywhere on the chart.
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="app">
<div id="grafik"></div>
</div>
<!-- Vue-->
<script>
var app = new Vue({
el: '#app',
data: {
TestSentences: "",
},
methods: {
grafikCiz() {
var trace1 = {
x: [1, 2, 3],
y: ["book", "pencil", "bag"],
mode: 'markers',
marker: {
color: ['#6886c5', '#f40552', '#1b1b2f'],
size: [10, 20, 30]
}
};
var data = [trace1];
var layout = {
height: 400,
width: 400,
};
Plotly.newPlot('grafik', data, layout);
},
},
mounted: function () {
this.grafikCiz();
},
});
</script>
<!-- Vue -->
<script>
var my_graph = document.getElementById('grafik');
my_graph.on('plotly_click', function (data) {
for (var i = 0; i < data.points.length; i++) {
pts = 'x = ' + data.points[i].x + '\ny = ' + data.points[i].y + '\n\n';
};
alert('Closest point clicked:\n\n' + pts);
});
</script>
Use plolty wrapper for vue.js https://github.com/David-Desmaisons/vue-plotly
You can add ref to the component
<vue-plotly v-show="display" :data="graphData" :layout="calculatedLayoutSizes" id="3dPlot"
:display-mode-bar="false" ref="crazyPlotly"></vue-plotly>
then use the ref within your mount point or similar method
this.$refs.crazyPlotly.$on('click', d => {
console.log(d);
});
"d" is an obj with values like x and y datapoint, index...etc
source: https://github.com/statnett/vue-plotly/issues/23
As Alagappan A already pointed out, https://github.com/David-Desmaisons/vue-plotly can make working with plotly in javascript much easier. For me it was sufficient to just:
<vue-plotly :data="data" :layout="layout" #click="temp"> </vue-plotly>
which can directly be utilized in a method:
methods: {
temp (value) {
console.log(value)
}
}

Vue wrapper component not working properly with axios

Hi I'm trying to change my vue wrapper component dropdown with axios. This is my code.
<html>
<head>
<title>title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</style>
</head>
<body>
<div id="el"></div>
<script type="text/x-template" id="demo-template">
<div>
<p>Selected: {{ input.selected }}</p>
<select2 :options="options" v-model="input.selected">
<option disabled value="0">Select one</option>
</select2>
</div>
</script>
<script type="text/x-template" id="select2-template">
<select>
<slot></slot>
</select>
</script>
<script src="http://themestarz.net/html/craigs/assets/js/jquery-3.3.1.min.js"></script>
<script src="https://unpkg.com/vue#2.5.17/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
Vue.component('select2', {
props: ['options', 'value'],
template: '#select2-template',
mounted: function () {
var vm = this;
$(this.$el)
// init select2
.select2({data: this.options})
.val(this.value)
.trigger('change')
// emit event on change.
.on('change', function () {
vm.$emit('input', this.value)
})
},
watch: {
value: function (value) {
// update value
$(this.$el)
.val(value)
.trigger('change')
},
options: function (options) {
// update options
$(this.$el).empty().select2({data: options})
}
},
destroyed: function () {
$(this.$el).off().select2('destroy')
}
});
var vm = new Vue({
el: '#el',
template: '#demo-template',
data: {
input: {
selected: "all"
},
options: []
},
created: function () {
this.mymethod();
},
methods: {
mymethod: function () {
var vm = this;
axios.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(function (response) {
vm.options = [
{id: 'all', text: 'All'},
{id: 1, text: 'Hello'},
{id: 2, text: 'World'},
{id: 3, text: 'Bye'}
];
vm.input.selected = 2;
})
.catch(function (error) {
console.log(error);
});
}
}
});
</script>
</body>
</html>
The problem I have is when I try to add selected item it's not working inside axios. And it's working properly outside axios.
vm.input.selected = 2;
I got selected the all initially as the image shows. Think ajax call does not matter so I reduced the code complexity a bit. Thanks.
You need to recreate the input object inside the axios:
vm.input = { selected: 2 };
axios.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(function (response) {
vm.options = [
{id: 'all', text: 'All'},
{id: 1, text: 'Hello'},
{id: 2, text: 'World'},
{id: 3, text: 'Bye'}
];
// recreate the 'input' object for reactivity
vm.input = { selected: 2 };
})
.catch(function (error) {
console.log(error);
});
You've encountered change detection caveat.
Use Vue.set(vm.input, 'selected', value) (or vm.$set) to update properties of your objects.
seems like I had issues with with wrapper component. After I changed the order of options and value in the component's watch this was fixed. I'm adding this in case anyone in the future faced the same issue.
watch: {
options: function(options) {
// update options
$(this.$el).empty().select2({
data: options
})
},
value: function(value) {
// update value
$(this.$el)
.val(value)
.trigger('change')
}
},

vue pagination total didn't work

<template>
...
<div class="pagination">
<el-pagination
#current-change="handleCurrentChange"
layout="prev, pager, next"
:total="totalCount">
</el-pagination>
</div>
</template>
<script>
import Vue from 'vue';
Vue.use(ElementUI);
export default {
data() {
return {
tableData: [],
orderTableUrl: setting.orderTableUrl,
width: 110,
page_size: 10,
page_num: 1,
messages: [],
totalCount: 100,
}
},
created() {
this.getTableData()
},
methods: {
getTableData: function () {
let self = this;
axios.Get({
url: self.orderTableUrl,
params: {
'page_size': self.page_size,
'page_num': self.page_num
},
callback: function (res) {
self.tableData = res.data.orders;
self.totalCount = res.data.orders_total_pages;
console.log(self.totalCount)
}
});
},
}
}
the pagination part use element.ui .
Here is my problem: in method callback, console.log can echo real num of total page, but it cannot display on template, and only can see the num 1 of page on window.
I'm so puzzled for that.
Is it said that vue can immediately show data on change on view
finish the question. the ':total' does work, just surprised that it means the count of objects instead of pages ...

How to pass VueJS data to another script?

I'm converting an established site over to VueJS but hit a stumbling block on the best way to achieve this.
It's using D3-Funnel (https://github.com/jakezatecky/d3-funnel) to draw a funnel chart but how do I pass VueJS data variables to the charts constructor?
<script>
const data = [
{ label: 'Step 1', value: this.step1 },
{ label: 'Step 2', value: this.step2 },
.......
];
const options = {
block: {
dynamicHeight: true,
minHeight: 15,
},
};
const chart = new D3Funnel('#funnel');
chart.draw(data, options);
</script>
So I need to pass vue data variables into the values. My first thought is to move this into it's own function in the VueJS methods object and use the variables there using this.
Is there a better way of achieving this?
---------- Edit -------------
As per comments people wanted to see how I achieved this currently in vue. As already mentioned above I just created a function in the vue methods object and then call it.
methods : {
drawChart(){
const data = [
{ label: 'Step 1', value: 99999 },
{ label: 'Step 2', value: 9999 },
.......
];
const options = {
block: {
dynamicHeight: true,
minHeight: 15,
},
};
const chart = new D3Funnel('#funnel');
chart.draw(data, options);
}
},
mounted(){
this.drawChart();
}
Data is coming from an API and put into the vue data object.
data:{
step1: 0,
step2: 0,
....
},
methods:{
getData(){
axois.post......
response{
this.step1 = response.data.step1
this.step2 = response.data.step2
....
}
}
}
As I understand it you are trying to pass information down to a component and use it. If you are using single file components and webpack you can do something like this which is put together with examples listed on the vue website.
You can also take a look at this guys approach
App.vue
...
<my-d3-component :d3data="d3Data"></my-d3-component>
...
<script>
import d3Component from 'path/to/component'
var app = new Vue({
el: '#app',
data: {
d3Data: {}
},
components: {
'my-d3-component': d3Component
}
})
</script>
d3Component.vue
<template>
d3 html stuff goes here
</template>
<script>
export default {
props: ['d3Data'],
data() {
return {}
},
mounted: {
const options = {
block: {
dynamicHeight: true,
minHeight: 15,
},
};
const chart = new D3Funnel('#funnel');
chart.draw(this.d3Data, options);
}
}
</script>

Can I use iron-localstorage and iron-ajax with highcharts

I have a polymer element that uses iron-ajax to create a highchart. Could I now incorporate iron-localstorage so the chart will render from the data in ls unless ls is empty in which case it will call iron-ajax to load the data from an api?
My working element is as follows:
<dom-module id="sales-chart">
<template>
<iron-ajax id="ajax" url="{{url}}" last-response="{{data}}"></iron-ajax>
<div id="container" style="max-width: 600px; height: 360px;"></div>
</template>
<script>
Polymer({
is: "sales-chart",
properties: {
url: String,
data: Object
},
observers: [
// These functions only run once the observed properties contain
// something other than undefined.
'_requestData(url)',
'_chartData(data)'
],
_requestData: function(url) {
// Note: Use `generateRequest()` instead of the `auto` property
// because `url` may not be available when your element is
// first created.
this.$.ajax.generateRequest();
},
_chartData: function (data) {
$(this.$.container).highcharts({
chart: {
type: 'spline',
renderTo: 'container'
},
series: [{
data: (data.series)
}]
});
}
});
</script>
</dom-module>
Something along these lines should work (did't test it tough):
<dom-module id="sales-chart">
<template>
<iron-ajax id="ajax" url="{{url}}" last-response="{{data}}"></iron-ajax>
<div id="container" style="max-width: 600px; height: 360px;"></div>
<iron-localstorage name="{{url}}"
value="{{data}}"
on-iron-localstorage-load-empty="_requestData">
</iron-localstorage>
</template>
<script>
Polymer({
is: "sales-chart",
properties: {
url: String,
data: Object
},
observers: [
// These functions only run once the observed properties contain
// something other than undefined.
'_chartData(data)'
],
_requestData: function() {
// Note: Use `generateRequest()` instead of the `auto` property
// because `url` may not be available when your element is
// first created.
this.$.ajax.generateRequest();
},
_chartData: function (data) {
$(this.$.container).highcharts({
chart: {
type: 'spline',
renderTo: 'container'
},
series: [{
data: (data.series)
}]
});
}
});
</script>
</dom-module>

Categories