I'm trying to do a standard translation for highcharts with Vue2, but I'm having difficulty because I can not access the setOptions option. I do not find much documentation of vue2 with Highcharts, so I'm having some difficulties working with it, if anyone can also provide me with that content, thank you.
import VueHighcharts from 'vue2-highcharts'
export default{
components: {
VueHighcharts
},
props: ['title', 'subtitle', 'initoptions'],
data(){
let initOptions = JSON.parse(this.initoptions);
let tmpSeries = [];
let count = 0;
$.each(initOptions, function(key, value) {
let data = [];
$.each(value, function(key2, value2){
let date = key2.split('-');
data.push([Date.UTC(date[2], date[1], date[0]), value2]);
});
tmpSeries.push({'name': key, 'data': data});
count++;
});
return{
options: {
/* ***
I can not set this setOptions property to lang
*** */
lang: {
loading: 'Aguarde...',
months: ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'],
weekdays: ['Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado'],
shortMonths: ['Jan', 'Feb', 'Mar', 'Abr', 'Maio', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'],
exportButtonTitle: "Exportar",
printButtonTitle: "Imprimir",
rangeSelectorFrom: "De",
rangeSelectorTo: "Até",
rangeSelectorZoom: "Periodo",
downloadPNG: 'Download imagem PNG',
downloadJPEG: 'Download imagem JPEG',
downloadPDF: 'Download documento PDF',
downloadSVG: 'Download imagem SVG'
},
chart: {
type: 'spline'
},
title: {
text: this.title || ''
},
subtitle: {
text: this.subtitle || ''
},
xAxis: {
type: 'datetime',
dateTimeLabelFormats: {
day:'%e/%m',
week:'%e/%m',
month: '%m/%y',
year: '%m'
},
title: {
text: 'Date'
}
},
yAxis: {
title: {
text: 'Total'
},
labels: {
formatter: function () {
return this.value;
}
}
},
tooltip: {
crosshairs: true,
shared: true
},
credits: {
enabled: false
},
plotOptions: {
spline: {
marker: {
radius: 8,
lineColor: '#666666',
lineWidth: 1
}
}
},
series: tmpSeries
}
}
}
}
I hope someone can help me, thank you.
I'm not sure with this package but with the Official Vue Highcharts you can set options like that :
import Highcharts from 'highcharts';
import HighchartsMore from 'highcharts/highcharts-more';
HighchartsMore(Highcharts);
Highcharts.setOptions({
lang: {
decimalPoint: '.',
drillUpText: 'Back',
noData: "Check your options please",
resetZoom: 'Reset',
thousandsSep: ' '
}
});
import HighchartsVue from 'highcharts-vue';
Vue.use(HighchartsVue);
Related
I have an application with nuxt.js as a framework and it's running well in development mode. However, when I deployed to the server for production, it's show "window is not defined".
I think it's because highcharts-vue.min.js module not loaded in components so shows this error but I'm not sure about that. I attach some code and screen shoot results after deploying on the server
<template>
<highcharts class="hc" :options="chartOptions" ref="chart">
</highcharts>
</template>
<script>
import {Chart} from 'highcharts-vue'
export default {
name:"ForecastCuaca",
components: {
highcharts: Chart
},
data() {
return {
data_cuaca:[],
chartOptions: {
chart: {
type: 'spline',
backgroundColor: 'transparent',
marginTop:100
},
title: {
text: 'Prakiraan Cuaca Kota Kupang',
style:{
"color": "#ebeefd",
"fontSize": "22px"
}
},
subtitle: {
text: 'Source: openweathermap.org',
style:{
"color": "#ebeefd",
}
},
xAxis: {
categories: ['Tanggal'],
labels:{
style:{
color:"#ebeefd"
}
}
},
yAxis: {
title: {
text: 'Suhu'
},
labels: {
formatter: function () {
return this.value + '°';
},
style:{
color:"#ebeefd"
}
},
style:{
"color": "#ebeefd",
}
},
tooltip: {
formatter: function () {
return 'Suhu : ' + this.y + '° C<br /><b>' + this.x + '</b>';
}
},
plotOptions: {
spline: {
marker: {
radius: 4,
lineColor: '#666666',
lineWidth: 1
}
}
},
series: [{
name: 'Kota Kupang',
marker: {
symbol: 'square'
},
data: [
10
],
style:{
"color": "#ebeefd",
}
}
],
credits:{
enabled:false
}
},
title: '',
}
},
methods:{
generate_data(datax){
const self = this;
self.data_cuaca = datax
self.chartOptions.xAxis.categories = []
self.chartOptions.series[0].data = []
let ganjil = 0;
for (let index = 0; index < self.data_cuaca.length; index++) {
ganjil++;
const element = self.data_cuaca[index];
self.chartOptions.xAxis.categories.push(element.waktu_indonesia)
if (ganjil % 2 == 1) {
const iconx = element.weather[0].icon+'.png';
const data_series = {
y:element.main.temp,
marker: {
symbol: "url(http://openweathermap.org/img/w/"+iconx+")"
}
}
self.chartOptions.series[0].data.push(data_series)
}else{
self.chartOptions.series[0].data.push(element.main.temp)
}
}
}
}
}
</script>
I'm attempting to export the chart as a picture. I just joined eCharts. Can someone explain how the export button operates? I need to download charts as image.
Here's what I try : Do I have something wrong?
<template>
<b-card title="Data Science">
<app-echart-bar:option-data="option"/>
</b-card>
</template>
<script>
import { BCard } from 'bootstrap-vue'
import AppEchartBar from '#core/components/charts/echart/AppEchartBar.vue'
export default {
components: {
BCard,
AppEchartBar,
},
data() {
return {
option: {
toolbox: {
show: true,
orient: 'vertical',
left: 'right',
top: 'center',
feature: {
mark: { show: true },
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar', 'stack'] },
restore: { show: true },
saveAsImage: { show: true }
}
},
xAxis: [
{
type: 'category',
data: ['FB', 'IN', 'TW', 'YT',],
},
],
yAxis: [
{
type: 'value',
splitLine: { show: false },
},
],
grid: {
left: '40px',
right: '30px',
bottom: '30px',
},
series: [
{
name: 'Available',
type: 'bar',
barGap: 0,
emphasis: {
focus: 'series'
},
data: [22, 24, 20, 18]
},
{
name: 'Not Available',
type: 'bar',
barGap: 0,
emphasis: {
focus: 'series'
},
data: [12, 10, 14, 16]
},
],
},
}
},
}
</script>
Comp:
<template>
<e-charts
ref="line"
autoresize
:options="option"
theme="theme-color"
auto-resize/>
<script>
import ECharts from 'vue-echarts'
import 'echarts/lib/component/tooltip'
import 'echarts/lib/component/legend'
import 'echarts/lib/chart/bar'
import theme from './theme.json'
ECharts.registerTheme('theme-color', theme)
export default { components: {
ECharts,
}, props: {
optionData: {
type: Object,
default: null,
}, }, data() {
return {
option: {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
},
toolbox: {
show: true,
orient: 'vertical',
left: 'right',
top: 'center',
feature: {
mark: { show: true },
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar', 'stack'] },
restore: { show: true },
saveAsImage: { show: true }
}
},
legend: {
left: 0,
},
grid: this.optionData.grid,
xAxis: this.optionData.xAxis,
yAxis: this.optionData.yAxis,
series: this.optionData.series,
},
} }, }
</script>
The chart created by eCharts is shown below :
Can somebody assist me with adding a button or tell me whether I need to add a script to download an image.
I have built a vue component to show a PIE chart in echart library as showed below. The PIE chart will be initialized with a default value.
pieChart.vue
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
},
chartData: {
type: Object,
required: true
}
},
watch: {
chartData: function(val){
console.log('chartdata handler',val);
this.setOptions(val.legend, val.data);
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons');
this.setOptions(
['group_a','group_b','group_c'],
[
{ value: 1, name: 'group_a' },
{ value: 2, name: 'group_b' },
{ value: 3, name: 'group_c' },
]
);
},
setOptions( lengend, data ) {
this.chart.setOption({
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
left: 'center',
bottom: '10',
data: lengend
},
series: [
{
name: 'WEEKLY WRITE ARTICLES',
type: 'pie',
roseType: 'radius',
radius: '50%',
data: data,
animationEasing: 'cubicInOut',
animationDuration: 2600
}
]
});
}
}
}
</script>
then I use this component in a view.
<template>
<pie-chart :chartData="updateData"/>
</template>
<script>
export default {
name: 'Personalinforadm',
components: {
PieChart,
},
data() {
return {
updateData: {
data:[
{ value: 33, name: 'group_a' },
{ value: 17, name: 'group_b' },
{ value: 3, name: 'group_c' },
],
legend:['group_a','group_b','group_c']
}
}
},
created() {
this.updateData = {
data:[
{ value: 3, name: 'group_a' },
{ value: 17, name: 'group_b' },
{ value: 3, name: 'group_c' },
],
legend:['group_a','group_b','group_c']
}
}
}
</script>
however the view doesn't update the PIE chart component with the new values in created methods. why the new values doesn't pass to the PIE component and trigger the watch methods, any ideas what goes wrong with the code?
take a look at https://github.com/ecomfe/vue-echarts or solution below may help you.(if you use version >4.x)
sample.vue
<template>
//...
<v-chart
class="chart mt-7"
:option="botChartData"
:update-options="updateOpts"
/>
//...
</template>
<script>
export default {
data() {
return {
updateOpts: {
notMerge: true,
},
botChartData: {
tooltip: {
trigger: "item",
formatter: "{a} <br/>{b} : {c} ({d}%)",
},
series: [
{
name: "Active Bots",
type: "pie",
center: ["50%", "50%"],
radius: ["75%", "90%"],
itemStyle: {
borderRadius: 8,
},
data: [],
}
],
},
};
},
methods: {
connect() {
this.bots = [
{
value: 0,
name: "a",
},
{
value: 1,
name: "b",
},
{
value: 2,
name: "c",
},
];
this.botChartData.series[0].data = this.bots;
}
},
};
</script>
I called "connect" in "created" you can call it in mounted or on events!
if you need to set your chart as a child component you can easily pass this.botChartData like below
child.vue
<template>
<v-chart
class="chart mt-7"
:option="botData"
:update-options="updateConf"
/>
</template>
<script>
export default {
props: {
botChartData: {
type: Object
},
updateOpts: {
type: Object
}
},
computed: {
botData() {
return this.botChartData
},
updateConf() {
return this.updateOpts
}
}
};
</script>
in parent.vue
<template>
//...
<sample :botChartData="botChartData" :updateOpts="updateOpts" />
//...
</template>
<script>
//...the same as sample.vue js
</script>
By the way if you have multiple charts in one page dont forget notMerge then your charts will reinitialize after switching between them
I'm trying to enable some operations on my grid such as grouping, filtering and sorting, individually they works as shown in the docs but there is no an example of those functionality working together.
By myself I was able to combine sorting and filtering but grouping does not work when i'm adding it as it shown in the docs. look at at my code
<template>
<div>
<Grid :style="{height: '100%'}"
ref="grid"
:data-items="getData"
:resizable="true"
:reorderable="true"
#columnreorder="columnReorder"
:filterable="true"
:filter="filter"
#filterchange="filterChange"
:sortable="true"
:sort= "sort"
#sortchange="sortChangeHandler"
:groupable="true"
:group= "group"
#dataStateChange="dataStateChange"
:columns="columns">
</Grid>
</div>
</template>
<script>
export default {
data() {
return {
items: [],
editID: null,
columns: [
{ field: 'AbsenceEmployeID', filterable:false, editable: false, title: '#'},
{ field: 'Employe', title: 'Employer', cell: DropDownEmployes},
{ field: 'Remarque', title: 'Remarque'},
{ field: 'Type', title: 'Type', cell: DropDownTypes},
{ field: 'CreatedDate', filter:'date', editable: false, editor: 'date', title: 'créé le', format: '{0:d}'},
{ title: 'Actions', filterable:false, cell: CommandCell}
],
filter: {
logic: "and",
filters: []
},
sort: [
{ field: 'CreatedDate', dir: 'desc' }
],
group: [],
gridData: []
}
}
mounted() {
this.loadItems()
},
computed: {
absencesList() {
return this.items.map((item) => Object.assign({ inEdit: item.AbsenceEmployeID === this.editID}, item));
},
getData() {
return orderBy(filterBy(this.absencesList, this.filter), this.sort);
},
...mapState({
absences: state => state.absences.absences
})
}
methods: {
loadItems () {
this.$store.dispatch('absences/getAbsences')
.then(resp => {
this.items = this.absences.map(item => item)
})
},
filterChange: function(ev) {
this.filter = ev.filter;
},
columnReorder: function(options) {
this.columns = options.columns;
},
sortChangeHandler: function(e) {
this.sort = e.sort;
},
// the following is for grouping but not yet used, read more
groupedData: function () {
this.gridData = process(this.getData, {group: this.group});
},
createAppState: function(dataState) {
this.group = dataState.group;
this.groupedData();
},
dataStateChange: function (event) {
this.createAppState(event.data);
},
}
}
</script>
The last three methods are not used yet, so filtering and sorting is working perfectly as of now. then in other to enable grouping I want to replace :data-items="getData" by :data-items="gridData" and run this.groupedData() method after the items are loaded but grouping doesn't work.
I think everything should be handle by the dataStateChange event and process() function but I also tried but without success
If you define the filterchange and sortchange events they are being triggered for filter and sort and you will have to updated data in their handlers. If you rather want to use datastatechage event for all the changes you have to remove the filterchange and sortchange events and the datastatechage event will be triggered instead of them. In this case you will have to update the data in its handler.
You can use the process method of #progress/kendo-data-query by passing the respective parameter each data change that is needed as in the example below:
const result = process(data, {
skip: 10,
take: 20,
group: [{
field: 'category.categoryName',
aggregates: [
{ aggregate: "sum", field: "unitPrice" },
{ aggregate: "sum", field: "unitsInStock" }
]
}],
sort: [{ field: 'productName', dir: 'desc' }],
filter: {
logic: "or",
filters: [
{ field: "discontinued", operator: "eq", value: true },
{ field: "unitPrice", operator: "lt", value: 22 }
]
}
});
Hers is a sample stackblitz example where such example is working correctly - https://stackblitz.com/edit/3ssy1k?file=index.html
You need to implement the groupchange method to handle Grouping
I prefer to use process from #progress/kendo-data-query
The following is a complete example of this
<template>
<Grid :style="{height: height}"
:data-items="gridData"
:skip="skip"
:take="take"
:total="total"
:pageable="pageable"
:page-size="pageSize"
:filterable="true"
:filter="filter"
:groupable="true"
:group="group"
:sortable="true"
:sort="sort"
:columns="columns"
#sortchange="sortChangeHandler"
#pagechange="pageChangeHandler"
#filterchange="filterChangeHandler"
#groupchange="groupChangeHandler"
/>
</template>
<script>
import '#progress/kendo-theme-default/dist/all.css';
import { Grid } from '#progress/kendo-vue-grid';
import { process } from '#progress/kendo-data-query';
const sampleProducts = [
{
'ProductID': 1,
'ProductName': 'Chai',
'UnitPrice': 18,
'Discontinued': false,
},
{
'ProductID': 2,
'ProductName': 'Chang',
'UnitPrice': 19,
'Discontinued': false,
},
{
'ProductID': 3,
'ProductName': 'Aniseed Syrup',
'UnitPrice': 10,
'Discontinued': false,
},
{
'ProductID': 4,
'ProductName': "Chef Anton's Cajun Seasoning",
'UnitPrice': 22,
'Discontinued': false,
},
];
export default {
components: {
Grid,
},
data () {
return {
gridData: sampleProducts,
filter: {
logic: 'and',
filters: [],
},
skip: 0,
take: 10,
pageSize: 5,
pageable: {
buttonCount: 5,
info: true,
type: 'numeric',
pageSizes: true,
previousNext: true,
},
sort: [],
group: [],
columns: [
{ field: 'ProductID', filterable: false, title: 'Product ID', width: '130px' },
{ field: 'ProductName', title: 'Product Name' },
{ field: 'UnitPrice', filter: 'numeric', title: 'Unit Price' },
{ field: 'Discontinued', filter: 'boolean', title: 'Discontinued' },
],
};
},
computed: {
total () {
return this.gridData ? this.gridData.length : 0;
},
},
mounted () {
this.getData();
},
methods: {
getData: function () {
this.gridData = process(sampleProducts,
{
skip: this.skip,
take: this.take,
group: this.group,
sort: this.sort,
filter: this.filter,
});
},
// ------------------Sorting------------------
sortChangeHandler: function (event) {
this.sort = event.sort;
this.getData();
},
// ------------------Paging------------------
pageChangeHandler: function (event) {
this.skip = event.page.skip;
this.take = event.page.take;
this.getData();
},
// ------------------Filter------------------
filterChangeHandler: function (event) {
this.filter = event.filter;
this.getData();
},
// ------------------Grouping------------------
groupChangeHandler: function (event) {
this.group = event.group;
this.getData();
},
},
};
</script>
Here's the sample code
I tried with update and other functions, none of them worked
launch: function() {
var categories = ['EMEA','APAC','AMERICAS'],
name = 'Browser brands',
data = [{
y: 55.11,
drilldown: {
name: 'EMEA versions',
categories: ['Cost', 'TechMe', 'disc', 'Matt'],
data: [
{
y: 40.11,
drilldown: {
name: 'Cost Drill',
categories: ['Page 1', 'Page 2', 'Page 3.0', 'Page 4.0'],
data: [0.20, 0.83, 1.58, 13.12, 5.43]
}
},
{
y: 40.11,
drilldown: {
name: 'Techme Drill',
categories: ['Page 1', 'Page 2', 'Page 3.0', 'Page 4.0'],
data: [1.58, 13.12, 5.43,0.20, 0.83]
}
},
{
y: 40.11,
drilldown: {
name: 'dISC Drill',
categories: ['Page 1', 'Page 2', 'Page 3.0', 'Page 4.0'],
data: [0.83, 1.58, 13.12,0.20, 5.43]
}
}
]
}
}, {
y: 21.63,
drilldown: {
name: 'Firefox versions',
categories: ['Firefox 2.0', 'Firefox 3.0', 'Firefox 3.5', 'Firefox 3.6', 'Firefox 4.0'],
data: [0.20, 0.83, 1.58, 13.12, 5.43]
}
}, {
y: 11.94,
drilldown: {
name: 'Chrome versions',
categories: ['Chrome 5.0', 'Chrome 6.0', 'Chrome 7.0', 'Chrome 8.0', 'Chrome 9.0',
'Chrome 10.0', 'Chrome 11.0', 'Chrome 12.0'],
data: [0.12, 0.19, 0.12, 0.36, 0.32, 9.91, 0.50, 0.22]
}
}, {
y: 7.15,
drilldown: {
name: 'Safari versions',
categories: ['Safari 5.0', 'Safari 4.0', 'Safari Win 5.0', 'Safari 4.1', 'Safari/Maxthon',
'Safari 3.1', 'Safari 4.1'],
data: [4.55, 1.42, 0.23, 0.21, 0.20, 0.19, 0.14]
}
}, {
y: 2.14,
drilldown: {
name: 'Opera versions',
categories: ['Opera 9.x', 'Opera 10.x', 'Opera 11.x'],
data: [ 0.12, 0.37, 1.65]
}
}];
Here's the setChart function which is called on click event of the chart
function setChart(chart,name, categories, data, color) {
var newchart=mychart;
var chartConfig={
chart: {
type: 'column'
},
title: {
text: 'Browser market share, April, 2011'
},
subtitle: {
text: 'Click the columns to view versions. Click again to view brands.'
},
xAxis: {
categories: categories
},
yAxis: {
title: {
text: 'Total percent market share'
}
},
plotOptions: {
column: {
cursor: 'pointer',
point: {
events: {
click: function() {
var drilldown = this.drilldown;
if (drilldown) { // drill down
setChart(this,drilldown.name, drilldown.categories, drilldown.data, drilldown.color);
} else { // restore
setChart(this,name, categories, data);
}
}
}
},
dataLabels: {
enabled: true,
style: {
fontWeight: 'bold'
},
formatter: function() {
return this.y +'%';
}
}
}
},
tooltip: {
formatter: function() {
var point = this.point,
s = this.x +':<b>'+ this.y +'% market share</b><br/>';
if (point.drilldown) {
s += 'Click to view '+ point.category +' versions';
} else {
s += 'Click to return to browser brands';
}
return s;
}
}
}
console.log("Before ",newchart.chartConfig);
newchart.setChartConfig(chartConfig);
console.log("After ",newchart.chartConfig);
var chartSeries={
name: name,
data: data,
color: 'white'
}
newchart.setChartData(chartSeries);
chart.remove('#myChart');
//chart.update(newchart);
//redrawChart(this,mychart);
//console.log(mychart);
// console.log(chart.setChartConfig());
//chart.x.setCategories(categories, false);
//chart.chartData.series[0].remove(false);
/*chart.chartData.addSeries({
name: name,
data: data,
color: color || 'white'
}, false);*/
//chart.redraw();
// mychart.update();
//mychart.updateLayout();
// mychart.show();
console.log("After " , mychart);
}
Main chart is here ...
var mychart=Ext.create('Rally.ui.chart.Chart', {
autoRender:true,
autoShow:true,
id:'myChart',
storeType : 'Rally.data.WsapiDataStore',
storeConfig : {
model: 'Defect'
//fetch : ["_ValidFrom", "_ValidTo", "10778908645", "ScheduleState", "Name"]
//filters : this.getColumnFilters()
},
calculatorType: 'My.Calculator',
calculatorConfig: {},
chartConfig: {
chart: {
type: 'column'
},
title: {
text: 'Browser market share, April, 2011'
},
subtitle: {
text: 'Click the columns to view versions. Click again to view brands.'
},
xAxis: {
categories: categories
},
yAxis: {
title: {
text: 'Total percent market share'
}
},
plotOptions: {
column: {
cursor: 'pointer',
point: {
events: {
click: function() {
var drilldown = this.drilldown;
if (drilldown) { // drill down
setChart(this,drilldown.name, drilldown.categories, drilldown.data, drilldown.color);
} else { // restore
setChart(this,name, categories, data);
}
}
}
},
dataLabels: {
enabled: true,
style: {
fontWeight: 'bold'
},
formatter: function() {
return this.y +'%';
}
}
}
},
tooltip: {
formatter: function() {
var point = this.point,
s = this.x +':<b>'+ this.y +'% market share</b><br/>';
if (point.drilldown) {
s += 'Click to view '+ point.category +' versions';
} else {
s += 'Click to return to browser brands';
}
return s;
}
}
},
chartData:{ // this works
series: [{
name: name,
data: data,
color: 'white'
}],
exporting: {
enabled: false
}
}
});
// add your code here
this.add(mychart); // add the component to rally interface
}
I want data to get changed on clicking
I have an example of chart update triggered by a button click in a github repo here.
Unlike a AppSDK2 grids that have a reconfigure method, AppSDK charts do not. In this example I delete a chart this.down("#myChart").removeAll() , modify metric definition of the calculator and then re-add the chart to the app.
You may also want to see this post.