How to use HighChart.getOption() with react-native-highchart - javascript

I am using highchart on react-native with this library. I have created simple activity gauge component from high chart official site. Here is the code of component.
import ChartView from 'react-native-highcharts';
import React, { Component } from 'react';
export default class Speedometer extends Component {
render() {
var Highcharts='Highcharts';
var conf={
chart: {
type: 'solidgauge',
height: '110%',
},
....
series: [{
name: 'Move',
data: [{
color: Highcharts.getOptions().colors[0],
radius: '112%',
innerRadius: '88%',
y: 80
}]
}, {
name: 'Exercise',
data: [{
color: Highcharts.getOptions().colors[1],
radius: '87%',
innerRadius: '63%',
y: 65
}]
}, {
name: 'Stand',
data: [{
color: Highcharts.getOptions().colors[2],
radius: '62%',
innerRadius: '38%',
y: 50
}]
}]
};
const options = {
global: {
useUTC: false
},
lang: {
decimalPoint: ',',
thousandsSep: '.'
}
};
return (
<ChartView style={{height:300}} more guage config={conf} options={options}></ChartView>
);
}
}
When i render this component on my screen i get the error
TypeError: TypeError: TypeError: TypeError: undefined is not a function (evaluating 'Highcharts.getOptions()')
How can i use getOptions or colors or theme or other variable with highchart inside react-native component.

You need to understand a few things here:
react-native-highcharts library create a dynamic html content and then inject into webview. Whatever is passed in the config props of ChartView is converted in to string content after flattenObject function inside the library.
If you look at the starting code of html content inside the library you would see that some javascript dependencies has been included and one of them is highcharts. This highcharts library will make the variable Highcharts in the local scope of javascript inside webview.
You are getting this error because React thinks that Highchart must be define somewhere in the component and define Highchart as a string, so if you access string.function it will throw error.
(Solution) you have two option here either to tweak the code inside the library and make it to accept flat string as props and pass this string directly to the ChartView, or you can create dummy Highchart object inside your root component to make the React stop complaining about the Highchart object. Once this object is passed through CharView highchart would be available in javascript scope inside webview and BOOM you Charts are loading.
Now you know the problem you can come up with more solutions. Hope this helps!

Related

maximum calstack size exceeded on vuex commit

I have this error here
I could limit the error to this line here
mounted() {
this.$nextTick(() => {
let ctx = this.$refs.canvas.getContext('2d')
let { chartType, dataOptions } = this.module
this.chart = new Chart(ctx, {
type: chartType,
data: dataOptions,
options: minimizeOptions,
})
})
},
The error comes from dataOptions. If i set data to {} everything works ok, but obviously my chart has no data then.
this.module is an prop that is being passed to my component. The component itself gets rendered in an v-for loop
<module
v-for="mod in modules"
:module="mod"
:key="mod._id.toString()"
/>
I am using here Chart.js.
I cannot find the reason for this call stack exceed error.
Maybe somebody had similar problems?
I also need to mention that this error happens when i want to toggle an global component that is placed in an layout layout
dataOptions:
{
datasets: [
{
backgroundColor: "#34495e",
borderColor: "bdc3c7",
data: [0],
label: "My first dataset"
}
],
labels: ["Start"]
}
I actually does not need reactivity on this prop, so i decided to freeze it up.
let { chartType, dataOptions } = Object.freeze(this.module);
Reactivity is gone an the error aswell. This fixed my problem.
Maybe somebody has an solution for reactive data

Unable to add any module without WebPack

I'm using a basical Vue Routing
const routes = [
{ path: "/home", component: Home }
];
const router = new VueRouter({
routes // short for `routes: routes`
});
const app = new Vue({
router
}).$mount("#app");
Took from this green exemple :
Can we make vue.js application without .vue extension component and webpack?
Everything is working flawless . I 'm not using webpack.
Now, I'm adding the APEXCHARTS library inside of index.html
<script src="https://cdn.jsdelivr.net/npm/apexcharts" type="module"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-apexcharts" type="module"></script>
This is one my component , using literals
const Home = {
data: function() {
return {
options: {
chart: {
id: 'vuechart-example'
},
xaxis: {
categories: [1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998]
}
},
series: [{
name: 'series-1',
data: [30, 40, 45, 50, 49, 60, 70, 91]
}]
}
},
template:
'<div><apexchart width="500" type="bar" :options="options" :series="series"></apexchart></div>'
};
and this is the error
[Vue warn]: Unknown custom element: <apexchart> - did you register the component correctly? For recursive components, make sure to provide the "name" option
My question is : how can I import this module, or any other module, without using WEBPACK, and using the vue 2 router ? I can't use 'IMPORT', it is not working, is there any way to mention the module name inside of the vue instantiation new Vue ?
Back in the days, ANGULARJS needed the modules names , but there, i dont know where to add the module name , I can not use the IMPORT syntax, please help.
Thank you
EDIT :
I've done a FIDDLE :
https://jsfiddle.net/nicolas1000/rke9xadq/
Try this:
Where you need the <apexchart> tag, you can do the following:
Vue.component('apexchart', VueApexCharts)

D3.js V4 Zoom not working in Angular

I'm using D3 v4 and Datamaps in my angular project.
I try to make the zoom working but I have no clue what's the problem.
I have a function that creates the map:
public createChart() {
this.geoChart = new Datamap({
element: this.geolocationChart.nativeElement,
scope: 'world',
width: null,
height: null,
projection: 'mercator',
responsive: true,
geographyConfig: {
hideAntarctica: true,
borderWidth: 1,
borderOpacity: 1,
borderColor: '#ffffff',
popupTemplate: function(geo, data) {
return ['<div class="hoverinfo"><strong>', geo.properties.name, ': ' + data.countryData, '</strong></div>'].join('');
},
popupOnHover: true,
highlightOnHover: true,
highlightFillColor: '#ff4200',
highlightBorderWidth: 2,
highlightBorderOpacity: 1
},
fills: {
defaultFill: '#f5f5f5',
highlight: '#5005a0'
},
data: this.convertData(this.defaultCountryData),
done: function(datamap) {
datamap.svg.call(d3.zoom().on('zoom', redraw));
function redraw() {
datamap.svg.selectAll('g').attr('transform', d3.event.transform);
}
}
});
}
I trigger it in ngAfterContentInit.
When I try to use the mouse wheel to zoom or drag the map, I receive this error message in the console:
"Cannot read property 'button' of null"
I'm importing D3 and Datamaps like this:
import * as d3 from 'd3';
import Datamap from 'datamaps/dist/datamaps.world.min.js';
I'm really clueless what could be the problem. I've seen other posts and everyone mentioned to import D3 just like I did. Any ideas?
So after more research I write this code:
function(datamap) {
d3.select('.datamap').call(
d3
.zoom()
.scaleExtent([0.7, 6])
.on('zoom', function() {
datamap.svg.selectAll('g').attr('transform', d3.event.transform);
})
);
}
It runs after the chart has loaded, and fortunately it works. For some reason when you call the zoom() function on the datamap.svg it cause an error while datamap.svg and d3.select('.datamap') creates a similar array but d3.select create a selection. If anyone know why it doesn't work the other way please explain it.

Highcharts annotations not rendering

I'm trying to dynamically add annotations to my high charts in React. I'm using the addAnnotation function to add a new annotation whenever a hover event is triggered on my app, but the annotation does not render. I dropped a debugger into my code, and when I call chart.annotations I can see there is currently an array of annotations, but they are not rendering. I even have make a call to the addPlotLine in this function and the plotline is rendered on the chart. My config file looks like this
chart: {
annotations: [{
labelOptions: {
backgroundColor: 'rgba(0, 0, 0, 0.5)',
verticalAlign: 'top',
align: 'right',
}
}],
annotationsOptions: {
},
.... some lots more config options
}
and my on hover function to add the annotation is as follows
if( isNumber(value) )
//this renders a plotline
chart.xAxis[0].addPlotLine(baseChartHandle.generateInteractivePlotLine(value));
// this doesn't render my annotation however
chart.addAnnotation({
linkedTo: value,
title: {
text: "It works!"
}
});
}
I found that when I added annotations using Highcharts that the "linkedTo" function never worked despite my trials.
Despite adding a guid to my point, it never was able to apply it. I would suggest in your case adding it by x and y value, then finding the point that way instead. Here is how I have added annotations in the past successfully:
series.data.forEach(function (point) {
var annotationObject =
{
id: point.id,
labelOptions: {
y: 15,
verticalAlign: 'bottom',
distance: 25
},
labels: []
};
}
var text = <get text you want to push>;
annotationObject.labels.push(
{
point: {
xAxis: 0,
yAxis: 0,
x: point.x,
y: point.y
},
text: text
}
);
_chart.addAnnotation(annotationObject);
});
I also found a bug in HighCharts when using remove annotations, as a heads up. Each point will need an id like above, but it should be called by this line:
_chart.removeAnnotation(id);
It will remove the annotation, however you will get lots of complaints from highcharts if you try to do anything after, and it will break. I found the answer here, in annotations.js :
The red box is code I added. If you do removeAnnotation(ann.id), and it rerenders, it will fail because the labels object is null. Adding this check lets you do that without the labelCollectors failing.
Happy charting.

Modifying Kendo UI chart markers using Angular

I need to change the styling (background & size) of a Kendo UI line chart markers dynamically using Angular.
I know this is possible with a function like this:
markers: {
background:function(e) {
return 'blue';
}
This works great when I use it on my controller, or anywhere else outside the html file after
$("#chart").kendoChart(...);
I am working with Angular, so the series options is inside my html tag with k-serias directive.
When I try to add a function there I get an error.
Error: [$parse:lexerr] Lexer Error: Unexpected next character at columns 237-237 [#] in expression [[
Here is the directive I put:
k-series="[{
type: 'line',
field: 'score',
markers: {
type: 'square',
background: function(e) { return #ffffff; }
}
}]"
All I want to do is to set a function for both background and size attributes inside the k-serias directive.
Thanks!
You can bind the directive k-series to your angular $scope.series.
In the HTML file:
k-series="series"
In JS file
$scope.series = [{
type: 'line',
field: 'score',
markers: {
type: 'square',
background: function(e) { return "#ffffff"; }
}
}];

Categories

Resources