How can I use morris.js in React.js? - javascript

import React, { useEffect } from "react";
import Raphael from "raphael/raphael";
import "morris.js/morris.js";
import "morris.js/morris.css";
const Test = () => {
useEffect(() => {
window.Raphael = Raphael;
Morris.Donut({
element: "test",
data: [
{
label: "a",
value: 49,
},
{
label: "b",
value: 51,
},
],
colors: ["#5f76e8", "#01caf1"],
formatter: function (value, data) {
return value + "%";
},
});
}, []);
return <div id="test" />;
};
export default Test;
I want to use morris.js in React.js.
But this code returns an error.
(Line 9:9: 'Morris' is not defined)
However, just before this error phrase appears, the pie chart is briefly visible, but soon the error phrase appears immediately.
How can I use it?

There are a few ways to approach on this one. If the package you mentioned is type of umd or commonjs you can require to use directly:
const yourModule = import('morris.js/morris.js')
Or if you load your package as external such as CDN site, I assume you're now webpack as a bundler, then you just simply configure it in your webpack.config.js:
externals : {
morris: "Morris"
},
And in your html template index.html would look like:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.min.js"></script>
Then you just simply import to use in your module:
import morris from "morris"

Related

Vuejs implementing Vue-Select2 not showing on result

After installing vue3-select2-component with their document when i implementing that. it doesn't show in output on html but i have the html of that in source code
BTW: i'm using inertiajs on Laravel framework
install:
// npm install
npm install vue3-select2-component --save
Use as component:
import {createApp, h} from 'vue'
import BootstrapVue3 from 'bootstrap-vue-3'
import IconsPlugin from 'bootstrap-vue-3'
import {InertiaProgress} from "#inertiajs/progress";
import {createInertiaApp, Head} from '#inertiajs/inertia-vue3'
import {Link} from "#inertiajs/inertia-vue3"
///...
import Select2 from 'vue3-select2-component';
import {createStore} from "vuex"
///...
createInertiaApp({
resolve: async name => {
return (await import(`./pages/${name}`)).default;
},
setup({el, App, props, plugin}) {
createApp({render: () => h(App, props)})
.use(plugin)
.use(bootstrap)
.use(BootstrapVue3)
.use(IconsPlugin)
.use(VueSweetalert2)
.component('Link', Link)
.component('Select2', Select2)
.mount(el)
},
title: title => 'azizam - ' + title
}).then(r => {
});
vuejs page which i want to use into that:
<template>
<Select2 v-model="myValue" :options="myOptions"
:settings="{ settingOption: value, settingOption: value }"
#change="myChangeEvent($event)"
#select="mySelectEvent($event)" />
</template>
<script>
import menubar from "./menubar";
import emulator from "./emulator";
import {mapActions} from "vuex";
import notification from "../../../partials/notification";
export default {
name: "image",
data() {
return {
caption: '',
myValue: '',
myOptions: ['op1', 'op2', 'op3']
}
},
components: {
menubar,
emulator,
notification
},
methods: {
...mapActions([
'changeBreadcrumb'
]),
myChangeEvent(val){
console.log(val);
},
mySelectEvent({id, text}){
console.log({id, text})
}
},
mounted() {
const payload = {
title: 'محصولات',
subTitle: 'ایجاد محصول تک عکس در سامانه'
};
this.changeBreadcrumb(payload);
}
}
</script>
console log:
Warning - slinky.min.js is not loaded. application.js:336:21
[Vue warn]: A plugin must either be a function or an object with an "install" function. vendor.js:10544:17
[Vue warn]: Plugin has already been applied to target app. vendor.js:10544:17
Use of Mutation Events is deprecated. Use MutationObserver instead. content.js:19:11
Source map error: Error: request failed with status 404
Resource URL: http://127.0.0.1:8000/js/vendor.js?id=594b688c9609a79fb52afd907a69c736
Source Map URL: tooltip.js.map
in console as you can see i don't get any error for this component
html source code:
<select2 options="op1,op2,op3" settings="[object Object]"></select2>
and then webpack:
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
//.sass('resources/scss/app.scss','public/css')
.extract()
.vue({
version: 3,
options: {
compilerOptions: {
isCustomElement: (tag) => ['Select2'].includes(tag),
},
},
})
.postCss('resources/css/app.css', 'public/css', [
//
])
.version();
The problem is you've configured Vue to treat <Select2> as a custom element, so the actual component does not get rendered.
The fix is to remove that configuration:
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
//.sass('resources/scss/app.scss','public/css')
.extract()
.vue({
version: 3,
//options: {
// compilerOptions: {
// isCustomElement: (tag) => ['Select2'].includes(tag), ❌ remove this
// },
//},
})
.postCss('resources/css/app.css', 'public/css', [
//
])
.version();

How to resolve npm error needing an appropriate loader?

I created a Vue.js project with vue-chartjs. I tried reinstalling the library, however I still got this error:
error in ./node_modules/chart.js/dist/chart.esm.js
Module parse failed: Unexpected token (6613:12)
You may need an appropriate loader to handle this file type.
| if (intermediateIndex1 !== startIndex && intermediateIndex1 !== lastIndex) {
| decimated.push({
| ...data[intermediateIndex1],
| x: avgX,
| });
# ./node_modules/vue-chartjs/es/BaseCharts.js 1:0-29
# ./node_modules/vue-chartjs/es/index.js
App.vue:
<template>
<div id="app"></div>
</template>
<script>
import axios from "axios";
import moment from "moment";
import LineChart from "./components/LineChart";
export default {
name: "App",
components: {
LineChart
},
}
LineChart.vue
<script>
import { Line } from "vue-chartjs";
export default {
extends: Line,
props: {
label: {
type: String
},
chartData: {
type: Array
},
options: {
type: Object
},
},
mounted() {
const dates = this.chartData.map(d => d.date).reverse();
const totals = this.chartData.map(d => d.total).reverse();
this.renderChart(
{
labels: dates,
datasets: [
{
label: this.label,
data: totals
}
]
},
this.options
);
}
};
</script>
........................................................................................................................................................................................................................................................................................................................
High chance you installed chartjs version 3. The vue wrapper is incompatibele with this version of chart.js and only supports the older version 2.
If you downgrade to version 2.9.4 by changing the version number in your package.json to 2.9.4 and run your install command again or remove the package and use the command install chart.js#2.9.4 . This will most likely resolve your issue

React-Image-Annotate - SyntaxError: Cannot use import statement outside a module

I'm trying to use react-image-annotate but it's giving me this issue when I first try to set it up.
And here's how I'm using it:
import React from 'react'
import ReactImageAnnotate from 'react-image-annotate'
function ImageAnnotator() {
return (
<ReactImageAnnotate
selectedImage="https://images.unsplash.com/photo-1561518776-e76a5e48f731?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80"
// taskDescription="# Draw region around each face\n\nInclude chin and hair."
// images={[
// { src: 'https://example.com/image1.png', name: 'Image 1' },
// ]}
// regionClsList={['Man Face', 'Woman Face']}
/>
)
}
export default ImageAnnotator
I'm using Next.js if that matters
UPDATE 1
I tried using this babel plugin as suggested by Alejandro Vales. It gives the same error as before. Here's the babel key in my package.json:
"babel": {
"presets": [
"next/babel"
],
"plugins": [
[
"#babel/plugin-proposal-decorators",
{
"legacy": true
}
],
[
"#babel/plugin-transform-modules-commonjs",
{
"allowTopLevelThis": true
}
]
]
}
I would say that the issue relies in the library itself by what they replied in here (similar bug) https://github.com/UniversalDataTool/react-image-annotate/issues/90#issuecomment-683221311
Indeed one way to fix it I would say is adding babel to the project so you can transform the imports in your project to require automatically without having to change the code on your whole project.
This is the babel package you are looking for https://babeljs.io/docs/en/babel-plugin-transform-modules-commonjs
Another reason for this could be an outdated version of your package, as some people report to have this fixed after using a newer version of Create React App (https://github.com/UniversalDataTool/react-image-annotate/issues/37#issuecomment-607372287)
Another fix you could do (a little crazier depending on your resources) is forking the library, creating a CJS version of the lib, and then pushing that to the library, so you and anybody else can use that in the future.
I got a tricky solution!
Problem is that react-image-annotate can only be imported in client-side(SSR got error for import keyword)
So, let react-image-annotate in Nextjs be imported only in client side
(https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr)
in Next Page that needs this component, You can make component like this
import dynamic from "next/dynamic";
const DynamicComponentWithNoSSR = dynamic(() => import("src/components/Upload/Annotation"), { ssr: false });
import { NextPage } from "next";
const Page: NextPage = () => {
return (
<>
<DynamicComponentWithNoSSR />
</>
);
};
export default Page;
Make component like this
//#ts-ignore
import ReactImageAnnotate from "react-image-annotate";
import React from "react";
const Annotation = () => {
return (
<ReactImageAnnotate
labelImages
regionClsList={["Alpha", "Beta", "Charlie", "Delta"]}
regionTagList={["tag1", "tag2", "tag3"]}
images={[
{
src: "https://placekitten.com/408/287",
name: "Image 1",
regions: [],
},
]}
/>
);
};
export default Annotation;

Injecting highlight.js to work with vue2-editor (Quill)

I have a trouble connecting vue2-editor (based on quill) with highlight.js
No matter what I do, I get an error saying:
Syntax module requires highlight.js. Please include the library on the page before Quill.
I'm using nuxt if it changes anything.
I've tried adding this line at the beginning of script tag:
import hljs from'highlightjs';
So it looks like:
<script>
import hljs from'highlightjs';
export default {
middleware: 'hasPermissions',
permissions: [ 'createPosts' ],
...
}
</script>
My plugin where I require vue2-editor:
import Vue from'vue';
import VueEditor from'vue2-editor';
Vue.use(VueEditor);
VueEditor component in my page:
<VueEditor
class="my-4"
v-model="content"
:editor-options="{ modules: { syntax: true } }"
placeholder="Post content" />
EDIT:
I've tried creating my own component and it shows the same error:
<template>
<v-layout
row
wrap>
<v-flex xs12>
<div ref="editor" />
</v-flex>
</v-layout>
</template>
<script>
import Quill from'quill';
export default {
data() {
return {
editor: null
};
},
mounted() {
window.hljs = require('highlight.js');
this.editor = new Quill(this.$refs.editor, {
modules: {
toolbar: [
[{ header: [ 1, 2, 3, 4, false ]}],
[ 'bold', 'italic', 'underline' ]
],
syntax: true
},
theme: 'snow',
formats: [ 'bold', 'underline', 'header', 'italic' ]
});
this.editor.root.innerHTML = this.value;
}
};
</script>
I can successfully print hljs in console in development tools in my browser. What's wrong?
This one should be a better solution, works for me.
https://github.com/surmon-china/vue-quill-editor/issues/39
In fact, this is because quill internal self-closure caused by the
problem, the solution is as follows: modules.syntax from true to
replace a function:
import hljs from 'highlight.js'
import 'highlight.js/styles/monokai-sublime.css'
editorOption: {
modules: {
syntax: {
highlight: text => hljs.highlightAuto(text).value
}
}
}
I struggled with this for a long time too and this answer worked for me!
// highlight.js component
import Vue from 'vue'
import Hljs from 'highlight.js'
import 'highlight.js/styles/googlecode.css'
let Highlight = {}
Highlight.install = function (Vue, options) {
Vue.directive('highlight', function (el) {
let blocks = el.querySelectorAll('pre code');
blocks.forEach((block) => {
Hljs.highlightBlock(block)
})
})
}
export default Highlight
// in main.js
import Highlight from 'path/to/Highlight.js'
Vue.use(Highlight)
I changed import 'highlight.js/styles/googlecode.css'
to import 'highlight.js/styles/monokai-sublime.css' seems to be a more popular and pleasing style.
you could also probably add a
hljs.configure({ // optionally configure hljs
languages: ['javascript', 'ruby', 'python']
});
to select certain languages, but I haven't tried.
Although I still haven't figured out how to change the background color. it shows up white in other places and black background in the quill window.

Cannot Import ES6 module into Vue single file component

I am learning (tinkering with) ES6 modules and Vue.js, single file components (SFC). I built my project with the Vue CLI via the webpack-simple template. I get an error "TypeError: Cannot read property 'name' of undefined" at the line with "settings.mainAlarm.name". "npm run dev" does not throw any errors so I believe the build step is finding (and perhaps ignoring) the settings.js file. What is the best way to import reusable JavaScript into a Vue SFC?
Root.vue file:
<template>
<div id="app">
<h1>{{ msg }}</h1>
<h4>{{ alarmName }}</h4>
</div>
</template>
<script>
//const settings = mainAlarm;
import settings from './lib/settings.js'
export default {
name: 'app',
data () {
return {
msg: 'Welcome to Blah Blah Blah!',
alarmName: settings.mainAlarm.name
}
}
}
//console.log(this.alarmName);
</script>
<style>
</style>
./lib/settings.js file:
export default function () {
var rtn = {
mainAlarm: {
name: "overdueCheckAlarm",
info: { delayInMinutes: .01, periodInMinutes: .25 }
},
notificationAudioFile: "ache.mp3",
baseUrl: "www.xxx.com/xx/xxxx-xxx/"
}
return rtn;
}
Either your settings file should look like this
export default {
mainAlarm: {
name: "overdueCheckAlarm",
info: { delayInMinutes: .01, periodInMinutes: .25 }
},
notificationAudioFile: "ache.mp3",
baseUrl: "www.xxx.com/xx/xxxx-xxx/"
}
in which case, your component will work as is, or your component should look like this and you can leave the settings file alone
<script>
import settings from './lib/settings.js'
// settings.js exports a function as the default, so you
// need to *call* that function
const localSettings = settings()
export default {
name: 'app',
data () {
return {
msg: 'Welcome to Blah Blah Blah!',
alarmName: localSettings.mainAlarm.name
}
}
}
</script>
I expect it's the first option you really want (I'm not sure why you would want a unique settings object every time you use settings, which is what the code in your question would do).

Categories