How do you output the HTML from GrapesJs in a VueJS application? - vue.js

I have set up a VueJS application including GrapesJS using grapesjs & grapesjs-preset-webpage. The editor works perfectly, but I cannot see in the documentation how to render just the HTML created by the editor without the editor controls being present.
The editor displays this, which is perfect for a CMS when in editor mode :
However, I wish to be able to display the result of the editor design as a finished webpage like this:
It is not clear to me from the GrapesJS documentation how this would be achieved in a VueJS application??
My code is:
<template>
<div>
<div id="gjs"></div>
</div>
</template>
<script>
import grapesjs from 'grapesjs'
import 'grapesjs/dist/css/grapes.min.css'
import 'grapesjs/dist/grapes.min.js'
import 'grapesjs-preset-webpage/dist/grapesjs-preset-webpage.min.css'
import 'grapesjs-preset-webpage/dist/grapesjs-preset-webpage.min.js'
export default {
name: 'WebBuilder',
mounted(){
grapesjs.init({
container: '#gjs',
height: '100vh',
width: '100%',
plugins: ['gjs-preset-webpage'],
storageManager: {
id: 'gjs-',
type: 'local',
autosave: true,
storeComponents: true,
storeStyles: true,
storeHtml: true,
storeCss: true,
},
deviceManager: {
devices:
[
{
id: 'desktop',
name: 'Desktop',
width: '',
},
{
id: 'tablet',
name: 'Tablet',
width: '768px',
widthMedia: '992px',
},
{
id: 'mobilePortrait',
name: 'Mobile portrait',
width: '320px',
widthMedia: '575px',
},
]
},
pluginsOpts: {
'grapesjs-preset-webpage': {
blocksBasicOpts: {
blocks: ['column1', 'column2', 'column3', 'column3-7', 'text', 'link', 'image', 'video'],
flexGrid: 1,
},
blocks: ['link-block', 'quote', 'text-basic'],
},
}
})
},
}
</script>

Related

Annotations are not displayed in Chart.js

I'm sorry for my poor English.
I'm trying to display a horizontal line in a graph using vue-chartjs and chartjs-plugin-annotation.
The graph appears and the options are applied, but the horizontal line does not appear because the settings in the annotation are not working.
If anyone knows how to fix this, please let me know.
The version and code is as follows
Chart.js v2.9.4
chartjs-plugin-annotation v0.5.7
Chart.js
import { Bar } from 'vue-chartjs'
import chartjsPluginAnnotation from 'chartjs-plugin-annotation'
export default {
extends: Bar,
props: ["chartData", "options"],
mounted() {
this.addPlugin(chartjsPluginAnnotation),
this.renderChart(this.chartData, this.options)
}
}
**Vue**
<template>
<Chart :chartData="chartItems" :options="chartOptions"/>
</template>
<script>
import Chart from './Chart.js'
export default {
components: {
Chart
},
data() {
return {
chartItems: {
labels: ["12月", "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月"],
datasets: [{
label: "月ごとの数",
data: [9500, 12000, 19000, 15000, 9500, 5000, 10000, 14000, 9500, 8000, 4500, 7000],
backgroundColor: 'lightblue'
}]
},
chartOptions: {
legend: {
display: false
},
scales: {
xAxes: [{
display: true,
gridLines: {
display:false
}
}],
yAxes: [{
display: true,
id: 'y-axis-0',
position: 'right',
ticks: {
beginAtZero: true,
maxTicksLimit: 5,
userCallback: (label, index, labels) => label.toLocaleString()
},
}]
},
annotation: {
annotations: [{
type: 'line',
id: 'hLine',
mode: 'horizontal',
scaleID: 'y-axis-0',
value: 9000,
borderWidth: 2,
borderColor: 'black'
}]
},
tooltips: {
enabled: false
},
animation: {
duration: 0
}
}
}
}
}
</script>
It seems like there might be problems with the annotations library in chartjs 2.9.4, try downgrading to 2.9.3
Git issue: https://github.com/chartjs/chartjs-plugin-annotation/issues/276

How to get data to Quasar tree node from local JSON file

I am very new to Quasar, I want to display Quasar tree nodes from a Local JSON file and with on click of a particular node item I want to show some text.
As of now I am using Quasar tree like this.
<template>
<q-page class="flex fixed-left">
<q-tree
:nodes="simple"
node-key="label"
no-connectors
:expanded.sync="expanded"
text-color="blue"
></q-tree>
</q-page>
</template>
<style>
</style>
<script>
export default {
name: 'HelloWorld',
data () {
return {
expanded: [ 'Resources' ],
simple: [
{
label: 'Resources',
children: [
{
label: 'Projects',
children: [
{
label: 'Data sets' ,
children: [
{
label: 'Items',
}
]
},
{ label: 'Good recipe' }
]
},
{
label: 'Good service (disabled node with icon)',
icon: 'room_service',
disabled: true,
children: [
{ label: 'Prompt attention' },
{ label: 'Professional waiter' }
]
},
{
label: 'Pleasant surroundings (with icon)',
icon: 'photo',
children: [
{
label: 'Happy atmosphere (with image)',
img: 'https://cdn.quasar.dev/img/logo_calendar_128px.png'
},
{ label: 'Good table presentation' },
{ label: 'Pleasing decor' }
]
}
]
}
]
}
}
}
</script>
It was coming like this
Now I wanted to get these nodes from a local JSON file and on click on Items should display some text .
Please help me with this.
To import JSON in ECMAScript:
If you don't have a lot of JSON files and you have the permission to modify and convert them into JS files, you can follow this answer: https://stackoverflow.com/a/39855320/3241933
Then you should import the vanilla JS object into data().
Example solution:
<template>
<q-page class="flex fixed-left">
<q-tree
:nodes="simple"
node-key="label"
no-connectors
:expanded.sync="expanded"
text-color="blue"
></q-tree>
</q-page>
</template>
<style>
</style>
<script>
import jsonData from './data.js'
export default {
name: 'HelloWorld',
data () {
return {
expanded: [ 'Resources' ],
simple: jsonData
}
}
}
</script>
Make sure that your import is an array of object.

Customize vue2-editor toolbar

This is the dependency I'm using for the editor and they have an example where they modify the default toolbar to remove certain options, I would like to remove some options but the example is very lacking and doesn't show how to add all the options I would like and I don't know how to add them.
This is the example from the dependency page
<template>
<div id="app">
<vue-editor v-model="content" :editorToolbar="customToolbar"></vue-editor>
</div>
</template>
<script>
import { VueEditor } from "vue2-editor";
export default {
components: {
VueEditor
},
data() {
return {
content: "<h1>Html For Editor</h1>",
customToolbar: [["bold", "italic", "underline"], [{ list: "ordered" }, { list: "bullet" }], ["image", "code-block"]]
};
}
};
</script>
I would like in my toolbar something like this
customToolbar: [["bold", "italic", "underline"], [{ list: "ordered" }, { list: "bullet" }],
[{ align: "left" }, { align: "center" }, { align: "right"}, { align: "justify"}],
[{ color: "color-picker" }]],
However this is the result, the align: left is not showing up and the color: color-picker doesn't work. If I click on the color picker nothing happens and no menu shows up
I'm not sure how I could get this to work
This is the CodeSandBox my current setup that doesn't work
Using the following configuration should fix the issues:
customToolbar: [
["bold", "italic", "underline"],
[{ list: "ordered" }, { list: "bullet" }],
[
{ align: "" },
{ align: "center" },
{ align: "right" },
{ align: "justify" }
],
[{ color: [] }]
]
Here is the code for the standard configuration of the toolbar:
https://github.com/davidroyer/vue2-editor/blob/master/src/helpers/default-toolbar.js

Create highcharts vue component

in my page i need to show many charts, so i would like to create an Highcharts component and use it inside my .vue file within a v-for cicle.
how could i achieve this? here is what i did:
in my .vue page I have:
<v-flex ma-3 v-for="(el,index) in Items">
<my-chart-component
:series="el.series"
:xlabels="el.Labels"
:height="'300px'"
width="100%"
></my-chart-component>
</v-flex>
inside my component i have:
<template>
<chart
:series="mySeries"
:xlabels="myXlabels"
:options="myChartOptions"
:height="height"
width="100%"
></chart>
</template>
<script>
import VWidget from '#/components/VWidget';
import {Chart} from 'highcharts-vue'
import Highcharts from 'highcharts/highcharts';
import loadExporting from 'highcharts/modules/exporting';
import brokenAxis from 'highcharts/modules/broken-axis';
export default {
name: 'my-chart-component',
components: {
VWidget,
Chart,
Highcharts,
loadExporting,
brokenAxis,
},
props: {
mySeries:Array,
myXlabels:Array,
height:String
},
data() {
return {
myChartOptions: {
chart: {
type: 'column'
},
legend: {
align: 'left',
verticalAlign: 'top',
layout: 'vertical',
x: 100,
y: 30,
floating: true
},
navigation: {
buttonOptions: {
enabled: true
}
},
credits: {
enabled: false
},
xAxis: {
xAxis: {
categories: props.myXlabels
},
},
yAxis: [{
title: {
text: '%',
align: 'middle',
rotation: 0,
},
type: 'linear',
}],
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
}
},
series: {
pointWidth: 15,
borderWidth: 0,
dataLabels: {
enabled: false,
format: '{point.y:.0f}%'
},
cursor: 'pointer',
point: {
events: {
click: ''
}
}
}
},
exporting: {
sourceWidth: 1000,
sourceHeight: 600,
},
tooltip: {
shared: true,
valueSuffix: ' %',
followPointer: false,
},
title: {
text: '',
align: 'left',
margin: 30
},
colors: [
'#00c104',
'#d45087',
],
series: props.mySeries
},
};
},
created(){
loadExporting(Highcharts);
},
methods: {
}
};
</script>
now, i have many errors in the console, i have this error:
Error in data(): "ReferenceError: props is not defined"
in
at src/components/MyChartComponent.vue
and then [Vue warn]: Property or method "myChartOptions" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property
it seems i can't pass the chartOptions by props, how can i workaround this?
thank you
The props that you are passing to your child component should be named as props in the child component.
If props are called mySeries, myXlabels and height, than you should pass it like :my-series, :my-xlabels and :height.
<v-flex ma-3 v-for="(el,index) in Items">
<my-chart-component
:my-series="el.series"
:my-xlabels="el.Labels"
:height="'300px'"
width="100%"
></my-chart-component>
</v-flex>
need to define
<script>
export default {
props: {
Items: Array,
},
}
</script>
then need to pass your variable from parent vue page into this page or component:
<MegaMenu :categories="categories"/>

How To Use Api Data With Vue Chart.js

So I am new to using data visualization in an application and I am trying to set my data coming from my api as the data the doughnut chart uses to display however I cannot figure out how to properly access the data
I have installed vue-chartjs as a way to simplify it for component use
Here is the Chart component
<script>
import { Doughnut } from 'vue-chartjs'
import {mapGetters} from 'vuex'
export default {
name: 'FirmChart',
extends: Doughnut,
computed: {
...mapGetters(['chartEngagements']),
},
mounted () {
this.renderChart({
labels: ['Scanned', 'Recieved', 'Preparation', 'Review', '2nd Review', 'Complete'],
datasets: [
{
label: 'Data One',
borderColor: 'black',
pointBackgroundColor: 'white',
borderWidth: 1,
pointBorderColor: 'white',
backgroundColor: [
'#0077ff',
'#0022ff',
'#1133bb',
'#0088aa',
'#11ffdd',
'#aabbcc',
'#22aabb',
],
data: [
10,
10,
10,
10,
10,
10,
]
},
]
}, {responsive: true, maintainAspectRatio: false});
},
created() {
this.$store.dispatch('retrieveEngagementsChartData')
}
}
</script>
now my data is coming from the chartEngagements getter and this is the display of that data in the console
{Complete: Array(1), Review: Array(3), 2nd Review: Array(1), Recieved: Array(7), Preparation: Array(1), …}
My question is how do I set the Complete: Array(1) etc to the data[] attribute in my this.renderChart() method??
I have tried doing something like this but It will not display anything
mounted () {
this.renderChart({
labels: ['Scanned', 'Recieved', 'Preparation', 'Review', '2nd Review' 'Complete'],
datasets: [
{
label: 'Data One',
borderColor: 'black',
pointBackgroundColor: 'white',
borderWidth: 1,
pointBorderColor: 'white',
backgroundColor: [
'#0077ff',
'#0022ff',
'#1133bb',
'#0088aa',
'#11ffdd',
'#aabbcc',
'#22aabb',
],
data: [
this.chartEngagements.complete,
this.chartEngagements.review,
this.chartEngagements.2ndreview,
this.chartEngagements.preparation,
this.chartEngagements.recieved,
this.chartEngagements.scanned,
]
},
]
}, {responsive: true, maintainAspectRatio: false});
However it doesn't display anything.. any help would be greatly appreciated or a point in the right direction!
Have you checked out the examples in the docs?
https://vue-chartjs.org/guide/#chart-with-api-data
Your problem is, that your data api call is async. So your chart is rendered, even if your data is not fully loaded.
There is also an example with vuex which is a bit outdated https://github.com/apertureless/vue-chartjs-vuex
You have to make sure that your data is fully loaded before you render your chart.
I faced similar issue while implementing Charts with API data in one of my Vue JS apps I was working on. I am using Vuex for state management, a simple solution for this problem is to move "chartData" from "data" to "computed" which would make it reactive. Below is the sample code from my app.
<template>
<line-chart v-if="chartData"
style="height: 100%"
chart-id="big-line-chart"
:chart-data="chartData"
:extra-options="extraOptions"
>
</line-chart>
</template>
<script>
import { mapActions, mapGetters } from 'vuex';
import * as expenseTypes from '../../store/modules/expense/expense-types';
import * as chartConfig from "../../components/reports/chart.config";
import BarChart from "../../components/reports/BarChart";
export default {
components: {
BarChart,
},
data () {
return {
extraOptions: chartConfig.chartOptionsMain
}
},
computed: {
...mapGetters({
allExpenses: expenseTypes.GET_ALL_EXPENSES,
expenseCount: expenseTypes.GET_EXPENSE_COUNT,
}),
expenseAmount() {
let expenseAmount = [];
this.allExpenses.map((item) => {
expenseAmount.push(item.amount);
})
return expenseAmount;
},
expenseLabels() {
let expenseLabels = [];
this.allExpenses.map((item) => {
expenseLabels.push(item.note);
})
return expenseLabels;
},
chartData() {
return {
datasets: [
{
data: this.expenseAmount
},
],
labels: this.expenseLabels
}
}
},
async mounted() {
await this.getAllExpenses();
await this.fillChartData();
},
methods: {
...mapActions({
getAllExpenses: expenseTypes.GET_ALL_EXPENSES_ACTION,
}),
},
};
</script>