Custom locale in vis.js timeline using vue.js - vue.js

I am using vis.js timeline in a Vue.js project. Although it seems pretty easy to customize the locale using vanilla javascript (see codepen and documentation), I just can't get it done with Vue. I have already added moment.js and moment-with-locales-es6 to my project. Is this the right way to apply the locale to moment.js so it also applies to vis timeline?
This is my vue.js component:
<template>
<div className="wrapper">
<div id="visualization"></div>
</div>
</template>
<script>
import {Timeline} from 'vis-timeline/standalone';
import tr from 'moment/locale/tr'
import moment from "moment-with-locales-es6";
export default {
data() {
return {
items: [
{
id: 1,
content: "1",
start: new Date(2021, 2, 23),
group: 0
},
options: {
locale: "tr",
locales: {
tr: {
current: "geçerli",
time: "kere",
},
},
},
timeline: null
}
},
mounted() {
this.timeline = new Timeline(document.getElementById('visualization'));
this.timeline.setOptions(this.options);
this.timeline.setItems(this.items);
moment.locale('tr')
}
}
</script>

I managed to do it by adding this to my index.html file:
<script src='https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/locale/tr.js'></script>
I am pretty sure there's a better solution for this...

Related

How to pass custom data in FullCalender Vue with eventDataTransform

I have custom data points for each event (for example event.organizer). I want this included in the calendar within the event section.
I looked over the documentation (https://fullcalendar.io/docs/eventDataTransform), but it is pretty slacking, especially in regards to the Vue component (https://fullcalendar.io/docs/vue)
Can anyone assist in how the Vue Component should look? Do I need to add a prop? The following did not work.
import { resources, events } from "/mockdata.js";
<FullCalendar #eventDataTransform="eventDataTransform" :options="calendarOptions" />
export default {
components: {
FullCalendar,
},
data() {
return {
calendarOptions: {
plugins: [dayGridPlugin, interactionPlugin, resourceTimelinePlugin],
initialView: "resourceTimeline",
initialDate: "2021-06-18",
resources,
events,
},
};
},
methods: {
eventDataTransform: function(json) {
console.log(json)
},
},
};
Found within example. https://github.com/fullcalendar/fullcalendar-example-projects/blob/master/vue3-typescript/src/Demo.vue#L115
<FullCalendar :options="calendarOptions">
<template v-slot:eventContent='arg'>
<i>{{ arg.event.extendedProps.organizer }}</i>
</template>
</FullCalendar>

vue2-editor not working for nuxt js. reference error: document is not defined

I tried to use vue2-editor. so when i tried with basic process which is in the documentation
import { VueEditor } from "vue2-editor";
export default {
components: {
VueEditor
},
<template>
<div id="app">
<vue-editor v-model="content"></vue-editor>
</div>
</template>
it gives me reference error document is not defined...
so then i tried to use it as plugin...in plugin, i defined
import Vue from "vue";
import { VueEditor } from "vue2-editor";
Vue.use(VueEditor);
and in nuxt.config.js
plugins: [
{ src: '~/plugins/vueditor', mode: 'client'},
]
now it doesnt show any error but editor doesnt show up.
i have also tried with { src: '~/plugins/vueditor', mode: 'client', ssr: false},
anyone who can help me with this.?

Create dynamic Google Map Markers with SVGs

I am trying to create Google Map Markers with dynamic information in it. For that feature I am using a Vuejs-Component with a SVG as template and add a "text"-Tag.
Example:
<template>
<svg width="40px" height="56px" viewBox="0 0 40 56" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<text>{{ text }}</text>
</svg>
</template>
<script>
export default {
name: "DynamicGMapMarker",
props: {
text: {
type: String,
required: true
}
}
}
</script>
Then I am creating the SVG via a helper function and create a base64 data url:
import Vue from 'vue'
import DynamicGMapMarker from './DynamicGMapMarker'
const DynamicGMapMarkerConstructor = Vue.extend(DynamicGMapMarker)
export const getDynamicMarkerIcon = (text) => {
const iconComponent = new DynamicGMapMarkerConstructor({
propsData: {
text
}
});
iconComponent.$mount();
const iconDom = iconComponent.$el;
const iconString = new XMLSerializer().serializeToString(iconDom);
return 'data:image/svg+xml;charset=UTF-8;base64,' + btoa(iconString);
}
Now, I can use the getDynamicMarkerIcon() function. This is working in vue.js, but not in nuxt.js. In nuxt.js we need to add a XML-Serializer from npm, since nuxt can not use the Browser's XMLSerializer. For that I am using teclone/xml-serializer.
Now, the Problem seems to be that Nuxt can not create a DOM, because of SSR. When I am trying to use this method:
<template>
<div id="app">
<GmapMap
:center="center"
:zoom="15"
:options="options"
id="map"
>
<GmapCluster :zoomOnClick="true">
<GmapMarker
:key="index"
v-for="(marker, index) in markers"
:position="marker.coordinates"
:clickable="true"
:draggable="false"
:title="marker.name"
:icon="getMarker(marker)"
/>
</GmapCluster>
</GmapMap>
</div>
</template>
<script>
import GmapCluster from 'vue2-google-maps/dist/components/cluster'
import {getMarkerIcon} from "./MapIconUtil"
export default {
name: 'App',
components: {
GmapCluster
},
methods: {
getMarker(marker) {
return getDynamicMarkerIcon(marker.text);
}
},
data() {
return {
options: {
zoomControl: false,
mapTypeControl: false,
scaleControl: false,
streetViewControl: false,
rotateControl: false,
fullscreenControl: false,
disableDefaultUi: true,
clickableIcons: false
},
center: {
lat: 11,
lng: 11
},
"markers": [
{
coordinates: {
name: "Test",
lat: 11.0001,
lng: 11.0001,
text: "101"
}
}
]
}
}
}
</script>
I get an error that iconComponent.$el is undefined. I can not mount the SVG inside a DOM.
Are there any possibilities to tell Nuxt, that this component should run on browser side only?
I have already tried to wrap GmapMarker in <client-only>-Tag. That did not work. Can I use something like a "virtual DOM"? Any other ideas how to make it work?
I did it. You can selectively change the "mode" in which nuxt will render a specific url. Here you can see what configurations are possible.
You have to create a server middleware and tell nuxt if a path should be rendered in spa. Otherwise just default to your mode specified in your nuxt.config.js.
Check this out for an example.

Highmaps(HighCharts) loads same map when drilling down

I'm faced with a problem while implementing Highmaps.
In my vue project with Webpack, I followed each step explained https://github.com/highcharts/highcharts-vue to use Highmaps.
Here's my main.js file
//highchart
import HighchartsVue from 'highcharts-vue'
import Highcharts from 'highcharts'
import WorldMap from '#highcharts/map-collection/custom/world.geo.json'
import USMap from '#highcharts/map-collection/countries/us/us-all.geo.json'
import mapInit from 'highcharts/modules/map.js'
import DrillDown from 'highcharts/modules/drilldown.js'
mapInit(Highcharts);
DrillDown(Highcharts);
Highcharts.maps['world'] = WorldMap;
Highcharts.maps['us'] = USMap;
And, here's my vue file
<template>
<div>
<mymap :mapOptions="mapOptions.options"></mymap>
</div>
</template>
<script>
export default{
data(){
return {
mapOptions: {
options: {
chart: {
map: 'us',
events: {
drilldown: function(e){
var chart = this;
this.addSeriesAsDrilldown(e.point, {
data: 'world',
dataLabels: {
enabled: true,
format: '{point.name}'
}
})
},
drillup: function(){
}
}
},
series: [{
data: data,
joinBy: ['postal-code', 'code'],
dataLabels: {
enabled:true,
color: '#FFFFFF',
format: '{point.name}'
}
}],
}
}
}
},
}
</script>
Because the chart has 'chart': 'us' option, it renders US map first. Then, when I click any state (just for a test) it switches US map to world map.
It renders world map. However, it also render US map too. That is, it renders both two maps. How can I fix it??

Vue-i18n Single File Component Not Working

I am trying to implement v-i18n to my project with sfc method. I couldn't make it work. I will not make you confuse with my project, that's why just modified with adding 10-15 lines of code to official v-i18n sfc example.
This is very simply shows my question.
For those who prefer check this very tiny question project on github
https://github.com/berkansivri/V-i18n-Question
Component1.vue
<template>
<p>{{$t('lang')}}</p>
</template>
<i18n>
{
"en":{
"lang" : "English"
},
"es":{
"lang": "Espanol"
}
}
</i18n>
App.vue
<template>
<div id="app">
<label for="locale">locale</label>
<select v-model="locale">
<option>en</option>
<option>es</option>
</select>
<p>message: {{ $t('hello') }}</p>
<Comp1></Comp1>
</div>
</template>
<i18n>
{
"en": {
"hello": "hello"
},
"es": {
"hello": "hola"
}
}
</i18n>
<script>
import Comp1 from './components/component1'
export default {
components:{
Comp1
},
name: 'App',
data () { return { locale: 'en' } },
watch: {
locale (val) {
this.$i18n.locale = val
}
}
}
</script>
So, multiple <i18n>tag in multiple components. I just modified $i18n.locale from App.vue but it did not fire related i18n function $t('lang') on Component1, just modifies $t('hello') on itself.
How can I make it work?
using vue devtools u will find out that messages of $i18n in single file component is different from each other, so they are different objects.
u need to do is:
i18n.js
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import messages from '#/lang'
Vue.use(VueI18n)
const i18n = new VueI18n({
locale: 'cn',
fallbackLocale: 'en',
messages
})
export default i18n
App.vue
import i18n from "./i18n.js"
i18n.locale = "en"
This is intended behavior of Single file components. If you want to change all locales of all components you can use:
locale (val) {
// this.$i18n.locale = val
this.$root.$i18n.locale = val
}
See this issue.