Vue ChartJS get data from a chart in component - vue.js

I have a chart in a modal and i want to get the value of the bar when i click on it, to send a request and get more informations.
I saw in documentation https://www.chartjs.org/docs/latest/configuration/interactions.html
when i click i got the event.
my chart options
chartOptions: {
responsive: true,
maintainAspectRatio: false,
interaction:{
mode: 'nearest',
},
onClick: this.handleChartClick,
},
the method
handleChartClick(e){
console.log(e);
},
But how to reference my own chart like in this other example :
How to access or get value of specific graph on chart plot by click event?
I'm sure it's obvious but it's my first try with chartJS.

Indeed it was obvious.
just need a ref attribute in my chart.
<Bar v-if="!is_loading"
:chart-options="chartOptions"
:chart-data="chartData"
:chart-id="chartId"
:dataset-id-key="datasetIdKey"
:plugins="plugins"
:css-classes="cssClasses"
:styles="styles"
:width="width"
:height="height"
ref="myBarChart"
/>
and in the method:
handleChartClick(e){
var chart = this.$refs.myBarChart.$data._chart;
}

Related

CSS selector in Swiper js breaks

I have my swiper component:
<swiper [config]="slideOpts">
<ng-template swiperSlide *ngFor="let unit of Units" class="peeking-slide">
<fs-reserved-unit-card [router]="router" [activatedRoute]="activatedRoute" [doRefresh]="doRefresh" [Unit]='Unit' ></fs-reserved-unit-card>
</ng-template>
</swiper>
with slideOpts being:
slideOpts = {
slidesPerView: 'auto',
spaceBetween: 10
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
};
or:
slideOpts = {
slidesPerView: 'auto',
spaceBetween: 10
pagination: {
el: '.swiper-pagination',
type: 'bullets',
},
};
it seems that as soon as I seem to target the CSS selector it breaks, with the pagination if I have "el: x" the pagination bullets simply do not display. With the Navigation "theprevEl: x" and "nextEl: x" also does not display.
is there anything Im missing perhaps?
I believe you don't need to pass any css selectors at all as it is swiper angular component not vanilla js as far as i understand based on your code. It creates all elements and attaches all handlers itself.
Basically when you create pagination you just need to pass true or configuration and it works immediately - pagination renders without you providing classes.
Here is an example https://codesandbox.io/s/great-robinson-meeogx

How to setup initial position of target element in anime.js?

Target
On click "Open menu" button:
Dim overlay appearing with fade-in animation
Once dim overlay animation done, from the top, dim overlay is appearing with the sliding animation from the top to bottom:
Solution attempt and problem
<template>
<transition #enter="animateOpening" #leave="animateClosing">
<div
class="SearchProductsPane-DimUnderlay"
v-if="isOpen"
:ref="elementsReferencesIDs.overlay"
>
<div
class="SearchProductsPane-Body"
:ref="elementsReferencesIDs.body"
>
<!-- ... -->
</div>
</div>
</transition>
</template>
import { Vue, Component } from "vue-property-decorator";
import Animation from "animejs";
#Component
export default class SearchProductsPane extends Vue {
private elementsReferencesIDs: Record<"overlay" | "body", string> = {
overlay: "Overlay", body: "Body"
};
private animateOpening(_element: Element, done: () => {}): void {
Animation
.timeline({
easing: "linear",
duration: 500,
complete: done
})
.add({
targets: this.$refs[this.elementsReferencesIDs.overlay],
opacity: [0, 1]
})
.add({
targets: this.$refs[this.elementsReferencesIDs.body],
translateY: "100%"
})
}
private animateClosing(): void {
}
}
With current solution, the .SearchProductsPane-Body will move from the normal position to the downward outside of the screen. Instead of it, I need it move from the upward outside of the screen to it normal position.
I tried reach it by adding of below class:
.SearchProductsPane-Body__InitialPosition {
transform: translateY(-100%);
}
However, the animejs animation starts from the 0%, not -100%. How to change it?
You can use From Value in animeJs, which allows you to define you'r animation origin:
anime.stagger(100, {from: 'center'})
you'r options are:
first: animation starts from the first element(Default from value)
last: animation starts from the last element
center: animation starts from the center
index: you choose which element the animation starts from
here is the docs.
Or you can use From to which forces the animation to start at a specified value.
In you'r code:
anime({
targets: '.SearchProductsPane-DimUnderlay'
});
docs here

How to disable transition-group only on page load?

I have a transition-group that renders a div, and within that is a component with a v-for attribute that renders several items. I then have a button that adds a new item to the beginning of the array. That transition works perfectly.
The only thing I don't like, is that the entire list loads with the transition on page load, and I'd like to disable it only on page load. I've searched Stack and Google but couldn't find a way. Is there a way to do this, so that transitions still works on button click, but is disabled for page load?
<transition-group
name="item-list"
tag="div">
<item-row
v-for="item in items"
:key="item.id"
:item="item" />
</transition-group>
.item-list-enter-active,
.item-list-leave-active,
.item-list-move {
transition : 250ms cubic-bezier(0.59, 0.12, 0.34, 0.95);
transition-property: opacity, transform;
}
.item-list-enter {
opacity : 0;
transform: translateX(50px) scaleY(0.5);
}
.item-list-enter-to {
opacity : 1;
transform: translateX(0) scaleY(1);
}
.item-list-leave-active {
position: absolute;
}
.item-list-leave-to {
opacity : 0;
transform : scaleY(0);
transform-origin: center top;
}
I wish I could've found a more "Vue-y" way of handling this, however I ended up going this route. Essentially I added a class to the body and removed all transitions. Then on the created lifecycle of my component, I remove that class. This removes the transition on page load, but still keeps the transition on click of the button like I want.
You can dynamically change the name value of the transition-group. Maybe on page load have a value different from the value that has the correct class name that the CSS targets. Then in the mounted lifecycle hook you can change it back to the correct class name.
You need to bind the duration for transition-group
template:
<transition-group
:duration="duration"
name="item-list"
tag="div">
<item-row
v-for="item in items"
:key="item.id"
:item="item" />
</transition-group>
script:
data() {
return {
duration: 0,
items: [
{id: 1},
{id: 2}
]
}
},
methods: {
add() {
if(this.duration===0) this.duration = 250
this.items.push({id: 'xxx'})
}
}
In case anyone comes across this like I did.
I ended up achieving this by having a transitionsOn flag added to the data (didn't seem to matter what it was initialised to), and a computed name for the transition, i.e.
<transition-group :name="transitionName">
in computed, I then had, for a transition called 'flash'
computed: {
transitionName() {
return this.transitionsOn ? 'flash' : 'disabled';
},
},
I would then set this.transitionsOn = true when I wanted it to fire.
Took a lot of fiddling about to figure this out but it seems to work OK

How can I get CKEditor 5 "Link" dialog box to pin to custom DOM element instead of 'document.body'

I'm building a Vue.js web application. I'm using CKEditor in a form that is placed inside a modal window. By design, the user's focus is "trapped" in the modal. In CKEditor, when user clicks the "Link" icon in toolbar, the editor opens a dialog box and attaches the new DOM element to 'document.body'. With respect to the DOM, the "Link" dialog is now outside of trapped focus. The user cannot click or tab his way to the "Link" dialog input.
I dug into the ckeditor5-ui source and found relevant code in balloonpanelview.js. I've unsuccessfully tried to configure CKEditor based on https://ckeditor.com/docs/ckeditor5/latest/api/module_utils_dom_position-Options.html
In my Vue.js component, I have:
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
...
data: () => ({
editor: ClassicEditor,
editorConfig: {
toolbar: ['bold', 'italic', 'bulletedList', 'numberedList', 'link'],
},
...
})
...
I want the CKEditor "Link" dialog DOM element to be attached to a DOM element id that I specify.
In Vuetify dialog component is required to disable retain-focus
<v-dialog :retain-focus="false" />
There may be much time since you opened the issue. However... This issue was happening to me too. This is happening because Bootstrap modal trap the focus in the active modal. If you're using bootstrap-vue, do this.
In your <b-modal> add the prop no-enforce-focus.
no-enforce-focus is reactive. To properly apply this workaround you can use this prop with a variable, that detects when your CKeditor have focus. If have focus, disable the enforce focus. If doesn't have, restore it. You can apply it by the following way:
<template>
<b-modal
...
:no-enforce-focus="editorFocus">
<ckeditor
...
#focus="toggleEditorFocus(true)"
#blur="toggleEditorFocus(false)"
/>
</b-modal>
</template>
<script>
export default {
...
data () {
return {
editorFocus: false
}
},
methods: {
toggleEditorFocus (val = !this.editorFocus) {
setTimeout(() => {
this.editorFocus = val
}, 10)
}
}
}
</script>
I know the setTimeout is a tricky method, but at least is working now for me.

Disable closing of sideNav when click outside the sideNav

I am using sideNav of MaterializeCSS in my application. I do not want to close sideNav while clicking outside. It can be achievable in modals like this:
{ dismissible: false }
How to do this in sideNav?
MaterializeCSS doesn't have a built-in method for achieve this task, but you can use a workaround, unbinding the click event from sideNav overlay:
$(function(){
$(".button-collapse").sideNav();
$(".drag-target").unbind('click');
$("#sidenav-overlay").unbind('click');
});
Update:
As of late, you can modify options of the sidenav by doing the following
$(".button-collapse").sideNav({
menuWidth: 300, // Default is 300
edge: 'left', // Choose the horizontal origin
closeOnClick: false, // clicking outside of the nav will not close it
draggable: true, // Choose whether you can drag to open on touch screens,
onOpen: function(el) { }, // A function to be called when sideNav is opened
onClose: function(el) { }, // A function to be called when sideNav is closed
});
});
you can take a look here to learn more: http://materializecss.com/side-nav.html