Vue.js: How to retrieve css var under <script> - javascript

I'm using chartJs to add a Doughnut chart on my app, but I need to setup it's color under <script> and I'd like to get the color from theme/variables.css .
In the code below, I have a hardcoded backgroundColor, but I'd like to get it from --ion-color-secondary and --ion-color-secondary-contrast instead. How can I achieve that?
Here is the code:
<template>
<Doughnut
:chart-data="chartData"
:chart-options="chartOptions"
/>
</template>
<script lang=ts>
import { defineComponent, PropType } from 'vue'
import { Doughnut } from 'vue-chartjs'
import {
Chart as ChartJS,
Title,
Tooltip,
Legend,
ArcElement,
CategoryScale,
Plugin
} from 'chart.js'
ChartJS.register(Title, Tooltip, Legend, ArcElement, CategoryScale)
export default defineComponent<{fastdata: any}>({
name: 'MrProgress',
components: {
Doughnut
},
inject: ["fastdata"],
setup() {
const chartOptions = {
responsive: true,
maintainAspectRatio: true,
cutout: "90%",
borderWidth: 0,
}
return {
chartOptions,
};
},
computed: {
chartData() {
const pts = this.fastdata.user.pts;
const missing = this.fastdata.user.proximo_nivel - pts;
return {
datasets: [
{
backgroundColor: ['#41B883', '#e4e0d8'],
data: [pts, missing]
}
]
}
}
}
})
</script>

Following the tip from #EstusFlask in the comment regarding userCssVar, I manged to solve it in the following way:
npm i #vueuse/core
...
import { useCssVar } from '#vueuse/core'
import { ref } from 'vue'
<script>
...
const color_pts = useCssVar(ref('--ion-color-secondary'), ref(null)).value;
const color_missing = useCssVar(ref('--ion-background-color'), ref(null)).value;
return {
datasets: [
{
backgroundColor: [color_pts, color_missing],
data: [pts, missing]
}
]
}
...
</script>

Related

Reactive data with vue-chartjs and Pinia stores

I am new at combining the use of a Pinia store data and vue-chartjs to create reactive charts. I'm using this example as a guide but struggling to have the chart reactive to changes in the store.
I change the Pinia store data in another component using a reactive form, and can see the store data changing, but the chart not updating.
I am rendering a chart with the following component:
<script setup>
import { storeToRefs } from 'pinia'
import { useStore} from '#/store/pinia-store-file';
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend
} from 'chart.js';
import { Line } from 'vue-chartjs';
ChartJS.register(
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend
);
const store = useStore();
const storeData= storeToRefs(store);
const labels = [...Array(storeData.arr.value.length).keys()];
const data = {
labels: labels,
datasets: [
{
label: 'Data One',
backgroundColor: '#f87979',
data: storeData.arr.value
}
]
}
const options = {
responsive: true,
maintainAspectRatio: false
}
</script>
<template>
<Line :data="data" :options="options" />
</template>
I've tried wrapping the store variable in ref() but I think I need to re-render the chart? I'm struggling to apply the above example to a Pinia store state and updating when the store is change.
You don't set data as response. Please use computed
This code can solve the problem:
<script setup>
import { storeToRefs } from 'pinia'
import { useStore} from '#/store/pinia-store-file';
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend
} from 'chart.js';
import { Line } from 'vue-chartjs';
import { computed } from "vue"
ChartJS.register(
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend
);
const store = useStore();
const storeData= storeToRefs(store);
const data = computed(() => ({
labels: [...Array(storeData.arr.value.length).keys()],
datasets: [
{
label: 'Data One',
backgroundColor: '#f87979',
data: storeData.arr.value
}
]
}))
const options = {
responsive: true,
maintainAspectRatio: false
}
</script>
<template>
<Line :data="data" :options="options" />
</template>

How to emit an event with vue-chartjs?

I use vue js and I display a graph with chartjs. When I click on the graph I want emit an event for get data in parent component. My onClick function works but not the event.
Do you have an idea of my problem ?
Component Line2.vue
<script>
import { mixins, Line } from "vue-chartjs";
const { reactiveProp } = mixins;
export default {
extends: Line,
mixins: [reactiveProp],
props: ["options"],
mounted() {
const self = this;
console.log(self);
this.options.onClick = function (e, tooltipItems) {
console.log(tooltipItems[0].__ob__); //.logged
self.$emit("sendIndex", tooltipItems[0]._index);
};
this.renderChart(this.chartData, this.options);
},
};
</script>
<style scoped></style>
My main component
...
<h1 v-on:sendIndex="getIndexCoord($event)">{{ indexCoord }}</h1>
...
methods: {
getIndexCoord: function (e) {
console.log("rrr", e); //Not logged
this.indexCoord = e;
},
}
Regards
1.first you create EventBus.js file
import Vue from 'vue';
export const EventBus = new Vue();
2.In your char.js file code like below
import { EventBus } from "../EventBus.js";
import { mixins, Line } from "vue-chartjs";
const { reactiveProp } = mixins;
export default {
extends: Line,
mixins: [reactiveProp],
props: ["options"],
mounted() {
const self = this;
console.log(self);
this.options.onClick = function (e, tooltipItems) {
console.log(tooltipItems[0].__ob__); //.logged
EventBus.$emit("sendIndex", tooltipItems[0]._index);
};
this.renderChart(this.chartData, this.options);
},
};
where you want to access your data in that file like below
import { EventBus } from "../EventBus.js";
mounted() {
EventBus.$on('sendIndex', data => {
console.log(data)
});
},

React Invalid hook call while using chartJS

I attempted to add a chartJS line chart to my application and got 'Invalid Hook Call' errors. I figured I might be doing something wrong, so I started a fresh application and attempted to follow a tutorial. After following this VERY basic youtube tutorial for using ChartJS in React, I get a blank page.
If I go to inspect->console. I see errors for 'Invalid Hook Call'.
I have checked both versions of react-native and react-dom; versions do not seem to be the issue. This is my output from npm ls for reference.
My ./App.js code - its literally almost a copy of the tutorial . If i remove the <Bar /> from the return at the bottom, application runs fine. :
import './App.css';
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend,
} from 'chart.js'
import { Bar } from 'react-chartjs-2'
import React, {useState, useEffect} from 'react'
ChartJS.register(CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend);
function App() {
const [chartData, setChartData] = useState({
datasets: [],
});
const [chartOptions, setChartOptions] = useState({});
useEffect(() => {
setChartData({
labels: ["Greg", "Chuck", "Kevin", "Sam", "Seth"],
datasets: [
{
label: "Votes",
data: [50,1,1,0,1000],
borderColor: "rgb(53, 162, 235)",
backgroundColor: "rgba(53, 162, 235, 0.3)",
},
],
})
setChartOptions({
responsive: true,
plugins: {
legend: {
position: "top",
},
title: {
display: true,
text: "Who does the most work?",
},
},
});
}, []);
return (
<div className="App">
<h2>BarChart</h2>
<Bar options={chartOptions} data={chartData} />
</div>
);
}
export default App;
Does anyone see something I'm not as to why I could be getting this error?

ReactJS + Material Design: How to get theme colors outside component?

In my ReactJS app.js I defined a theme:
const theme = createMuiTheme({
palette: {
primary: {
main: "#54BD40",
},
},
});
I am using the React wrapper for Chart.js and I want to set-up a chart graph. But I am not sure how I can use the primary/main color from my theme:
import React, { Component } from 'react';
import { Line } from 'react-chartjs-2';
let data = []; //data here
const MONTHS = ['Jan', 'Feb', 'Mrt', ...];
const WEEK = ['Sun', 'Mon', 'Tue', ...];
let chart = {
labels: MONTHS,
datasets:[{
borderColor: ['#XXX'], //THEME COLOR HERE
}],
};
class LineChart extends Component{
constructor(props){
super(props);
this.state = {
chartData: chart,
usage: false,
generation: true,
}
}
render(){
return (
<div>
<Line data={ this.state.chartData } options={} />
</div>
)
}
}
export default LineChart;
For using theme palettes inside render(), I know I can import withTheme() and use this.props.theme. But how this work now outside the component? (I just started using ReactJS)
Well as I understand you can import constant into your main js file after doing
export in app.js. Example. -
export const theme = createMuiTheme({ palette: { primary: { main: "#54BD40", }, }, });
Then import
Import { theme } from "app"
And use it anywhere in your main js file.

Vue chart.js not displaying data on load

I'm using vue-chartjs with Laravel, and I have a problem where the data isn't loaded when on load. But when I click 3x on Legend the data shows up.
Here is gif: https://gfycat.com/gifs/detail/SimilarShockedAffenpinscher
My code:
<template>
<Chart :chartData="this.data" :width="800" :height="500"></Chart>
</template>
<script>
import Chart from './Chart.vue';
export default {
name: 'home',
components: {
Chart
},
data() {
return {
data: {},
weights: [],
dates: []
}
},
mounted () {
this.render()
},
methods: {
render() {
self = this
axios.get('/api/data')
.then(function (response) {
for (var i = 0; i < response.data.data.length; i++) {
self.weights.push(response.data.data[i].kg)
self.dates.push(response.data.data[i].created_at)
}
console.log(response)
})
.catch(function (error) {
console.log(error);
});
// Overwriting base render method with actual data.
self.data = {
labels: self.dates,
datasets: [
{
label: 'Data One',
data: self.weights,
}
]
}
}
}
}
</script>
Chart.vue:
<script>
import VueCharts from 'vue-chartjs'
import { Bar, Line, mixins } from 'vue-chartjs'
import moment from 'moment'
import axios from 'axios'
export default {
extends: Bar,
mixins: [mixins.reactiveProp],
props: ['chartData', 'options'],
data() {
return {
}
},
mounted () {
this.renderChart(this.chartData, this.options)
},
methods: {
}
}
</script>
I suspect this is your problem:
self.data = {
labels: self.dates,
datasets: [
{
label: 'Data One',
data: self.weights,
}
]
}
Self is referencing this so self.data = this.data. it's assigning directly to your components data property.

Categories

Resources