I have an API end point that returns an array of 24 values that I want to use in my chartjs within a vue component.
when the page loads I get no errors but the bars on the charts just don't show and I don't know why.
EDIT: I noticed that the async function returns a promise instead of the actual data:
async filterData() {
await this.$axios.get('/api/data_app/job_count_by_hour/')
.then(response => {
return this.chart_data = response.data;
})
}
here is the data return code, I have a function that populates the chart_data array :
data(){
return {
form:{
day: 'select day',
workspace:'',
machine_family: [],
duration: []
},
res: [],
total:[],
chart_data: [],
url: '/api/jobs/job_count_by_hour/',
days: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "sunday"],
barChart2: {
labels: ["6h", "7h", "8h", "9h","10h","11h", "12h", "13h", "14h", "15h", "16h", "17h", "18h", "19h", "20h", "21h","22h", "23h", "00h"],
datasets: [{
label: ["popularity"],
backgroundColor:"#f93232" ,
data: this.chart_data
},],
},
}
},
methods: {
async filterData() {
let _url = `${this.url}`
await this.$axios.get(_url)
.then(response => {
this.chart_data = response.data;
})
return this.chart_data
},
},
mounted() {
this.filterData()
}
}
this is the chart component:
<script>
import { Line } from 'vue-chartjs'
export default {
extends: Line,
props: {
chartdata: {
type: Object,
default: null
},
options: {
type: Object,
default: null
}
},
mounted () {
this.renderChart(this.chartdata, this.options)
}
}
in the parent component It looks like this:
en <BarChart :labels="barChart2.labels"
:datasets="barChart2.datasets"
:height="100"
>
</BarChart>ter code here
Turns out that when you try to update nested data, the component doesn't re-render.
This is how I solved it, I put the entire object in an update function and call that function when i get my data from the back end, I hope this helps!:
methods: {
onInput(value) {
this.filterData()
},
updateChart(data) {
this.datasets = [{
label: ["popularity"],
backgroundColor:"#f93232",
data: data
}]
},
async loadData() {
await this.$axios.get(this.url)
.then(response => {
this.updateChart(response.data)
})
},
},
mounted() {
this.loadData()
},
Related
I have a line chart that gets data from the back end. I am able to plot the data but not the labels from the back end. This is my code:
import {Line} from 'vue-chartjs'
import axios from 'axios';
export default {
extends: Line,
props: ["data"],
methods: {
getScore() {
axios({
method: 'get',
url: 'http://localhost:5000/time',
}).then((response) => {
this.renderChart(
{
labels: [],
datasets: [
{
labels: response.data.score,
label: 'Stream',
backgroundColor: "#42c9d5",
data: response.data.score
}
]
},
{responsive: true, maintainApsectRatio: false}
)
})
.catch((error) => {
// eslint-disable-next-line
console.error(error);
});
}
},
mounted() {
this.getScore();
}
}
because I am getting the data from the getScore method. how Can I get the labels from another method? Or do I need to send two json responses? Also how do I loop through the json responses inside the this.renderchart?
I figured out how to do it. For those interested I passed a list of of dictionaries from the back end:
#app.route('/time')
def timeData():
response_object = {'status': 'success'}
SCORES = []
score = {}
score["value"] = [23,38,12]
score["date"] = ["Jan", "Feb", "Mar"]
SCORES.append(score)
response_object['score'] = SCORES
return jsonify(response_object)
I then added ... before the date key value pair:
import {Line} from 'vue-chartjs'
import axios from 'axios';
export default {
extends: Line,
props: ["data"],
methods: {
getScore() {
axios({
method: 'get',
url: 'http://localhost:5000/time',
}).then((response) => {
this.renderChart(
{
labels: [...response.data.score[0].date],
datasets: [
{
label: 'Stream',
backgroundColor: "#42c9d5",
data: response.data.score[0].value
}
]
},
{responsive: true, maintainApsectRatio: false}
)
})
.catch((error) => {
// eslint-disable-next-line
console.error(error);
});
}
},
mounted() {
this.getScore();
}
I am using chartjs in a nuxt component.
The problem is, I am getting referrence error, chartLabels and chartDataPoints are not defined.
If I replace chartLabels and chartDataPoints with this.$store.state.chartLabels and this.$store.state.chartDataPoints, my chart gets rendered, but then, it is no longer reactive since I need to use computed for that.
The store has been set up properly, and I am getting the correct data in vue devtools so the store doesn't seem to be the issue.
What am I doing wrong?
<canvas id="daily-chart"></canvas>
The chart is getting called in mounted() as so:
mounted() {
const ctx = document.getElementById("daily-chart")
new Chart(ctx, this.chartData)
},
Here is the chartData:
chartData: {
type: "line",
data: {
labels: chartLabels,
datasets: [
{
data: chartDataPoints,
},
],
},
options: {
responsive: true,
lineTension: 1,
},
}
chartDataPoints and chartLabels are being fetched from the store's state:
computed: {
...mapState(['chartDataPoints', 'chartLabels'])
},
If you are using vue-chart-js you may want to declare your chartData inside a specific js file that you would put in your template file.
Here is an example :
import {Line} from "vue-chartjs"
export default {
extends: Line,
data: function(){
return {
datacollection: {
labels: chartLabels,
datasets: [{
data: chartDataPoints,
}],
},
options: {
responsive: true,
lineTension: 1,
},
},
props:{
chartDataPoints : Array,
},
}
Then put the line chart in your template as :
<template>
<line-chart
:chartDataPoints="charData"
>
</line-chart>
</template>
I would also recommand using MapGetters from vuex instead of mapState and putting this in to a computed properties.
computed: {
...mapGetters({
chartDataPoints : 'chartData/getChartDataPoints'
})
},
And in your chartData.js (store) :
export const state = () => ({
charData: [],
})
export const getters = {
getChartDataPoints: (state) => () => {
return this.charData
}
}
Then, you would change your template to :
<template>
<line-chart
:chartDataPoints="chartDataPoints()"
>
</line-chart>
</template>
I'm not sure as to why the labels doesn't work but series works when fetching data from the database. I'm using vue and laravel.
Here is my code
<div id="chart">
<apexchart type="pie" width="380" :options="chartOptions" :series="series"></apexchart>
</div>
export default {
data: () => ({
employees: [],
series: [],
chartOptions: {
chart: {
width: 380,
type: 'pie',
},
labels: [],
responsive: [{
breakpoint: 80,
options: {
chart: {
width: 200
},
legend: {
position: 'bottom'
}
}
}]
}
}),
methods: {
kpiProgress () {
axios.get('/api/employee-kpi-progress', {
params: { employee_id: this.$store.state.authUser.employee_id }
})
.then(response => {
this.series = response.data
})
.catch(error => console.log(error))
},
kpaInfo () {
axios.get('/api/employee-kpa-info', {
params: { employee_id: this.$store.state.authUser.employee_id }
})
.then(response => {
this.chartOptions.labels = response.data
console.log(this.chartOptions.labels)
})
.catch(error => console.log(error))
},
}
}
Made it work. This is a really weird solution since this is my first time directly calling data from a response.
kpaInfo () {
axios.get('/api/employee-kpa-info', {
params: { employee_id: this.$store.state.authUser.employee_id }
})
.then(response => {
this.chartOptions = {
labels: response.data,
}
})
.catch(error => console.log(error))
},
When I call a mutation on my client I get the following warning:
writeToStore.js:111 Missing field updateLocale in {}
This is my stateLink:
const stateLink = withClientState({
cache,
resolvers: {
Mutation: {
updateLocale: (root, { locale }, context) => {
context.cache.writeData({
data: {
language: {
__typename: 'Language',
locale,
},
},
});
},
},
},
defaults: {
language: {
__typename: 'Language',
locale: 'nl',
},
},
});
And this is my component:
export default graphql(gql`
mutation updateLocale($locale: String) {
updateLocale(locale: $locale) #client
}
`, {
props: ({ mutate }) => ({
updateLocale: locale => mutate({
variables: { locale },
}),
}),
})(LanguagePicker);
What am I missing?
I was getting the same warning and solved it by returning the data from the mutation method.
updateLocale: (root, { locale }, context) => {
const data = {
language: {
__typename: 'Language',
locale,
}
};
context.cache.writeData({ data });
return data;
};
At the moment, apollo-link-state requires you to return any result. It can be null too. This might be changed in the future.
I need a way to unit test the "edit" function in the code below. It is different form the other questions because my function returns no value.
class QslTable extends React.PureComponent {
this.state = {
data: [{
key: '0',
callSign: {
editable: true,
value: 'F1ABD',
},
QSODate: {
editable: true,
value: '10-05-31',
},
band: {
editable: true,
value: '32',
},
mode: {
editable: true,
value: 'Phone',
},
dxccEntity: {
editable: true,
value: 'France',
},
delete: {
editable: false,
value: 'Delete',
},
}],
};
edit(index) {
const { data } = this.state;
Object.keys(data[index]).forEach((item) => {
if (data[index][item] && typeof data[index][item].editable !== 'undefined') {
data[index][item].editable = true;
}
});
this.setState({ data });
}
}
This doesn't work:
it('should render the component', () => {
const renderedComponent = shallow(<QslTable />);
expect(renderedComponent.find('edit')).toBeDefined();
});
The function doesn't return any value. I have no clue how to test the function. I have looked at the documentation for Jest, but couldn't figure it out. Any help would be appreciated!