Access State variable in highcharts event load function - react-native

export class GraphComponent extends React.Component{
constructor(){
super();
this.state={data:[],data20:[]};
}
render(){
var Highcharts='Highcharts';
let self=this;
var conf={
chart: {
type: 'spline',
animation: Highcharts.svg,
marginRight: 10,
events: {
load: function () {
var series = this.series[0],i=0,j=1,k=0;
var p=self.state.data; // Access State variable here
}
}
}
series: [{
name: 'Random data',
data: this.state.data20 / Accessible Here
}]
}
return (<ChartView style={{height:300}} config={conf} options={options}></ChartView>);
}
}
{"data":[{"x":154745486745,"y":0.5} // some 50-60 objects like this]}
I am getting this data from JSON/SERVER into state.data20(first 20) and state.data(rest of them). state.data20 are plotted. state.data is not Accessible in the Charts event load function. I have tried few methods but still failed.
With Self reference Image
Without Self reference Image

Try saving a reference do this on a variable. Check it out:
export class GraphComponent extends React.Component{
constructor(){
super();
this.state={data:[],data20:[]};
}
render(){
var Highcharts='Highcharts';
// Declare a variable to keep a reference to react context
let self = this;
var conf={
chart: {
type: 'spline',
animation: Highcharts.svg,
marginRight: 10,
events: {
load: function () {
var series = this.series[0],i=0,j=1,k=0;
var p = self.state.data; // Access State variable using self
}
}
}
}
return (<ChartView style={{height:300}} config={conf} options={options}></ChartView>);
}
}

Related

The $store i is not defined on the instance but referenced during render in vue, why?

I need to create an instance and then return it as $el. nodeTemplate is a function in mounted hook. But i have an error that in VisualComponent $store is not defined on the instance but referenced during render.
import router from "../../router";
import store from "../../store";
...
const nodeTemplate = (n, parent, cyn) => {
// parent is the same as window
const Card = Vue.use(store).use(router).extend(Visual);
const instance = new Card({
propsData: {
vis: n.graphData ? n.graphData : {},
visualType: n.visualType ? n.visualType : {},
size: '',
className: cyn.classes(),
},
});
instance.$mount();
return instance.$el;
};
...
cy1.nodeHtmlLabel([
{
query: 'node',
tpl: function (n) {
n.el = nodeTemplate(n, parent, cy1.$(`#${n.id}`));
return n.el
}
}
])

Custom directive to check list length for input types

I tried my best to write a custom directive in apollo server express to validate if an input type field of type [Int] does not have more than max length but do not know if its the right way to do. Appreciate if somebody could help me correct any mistakes in the code below.
// schema.js
directive #listLength(max: Int) on INPUT_FIELD_DEFINITION
input FiltersInput {
filters: Filters
}
input Filters {
keys: [Int] #listLength(max: 10000)
}
// Custom directive
const { SchemaDirectiveVisitor } = require('apollo-server-express');
import {
GraphQLList,
GraphQLScalarType,
GraphQLInt,
Kind,
DirectiveLocation,
GraphQLDirective
} from "graphql";
export class ListLengthDirective extends SchemaDirectiveVisitor {
static getDirectiveDeclaration(directiveName) {
return new GraphQLDirective({
name: directiveName,
locations: [DirectiveLocation.INPUT_FIELD_DEFINITION],
args: {
max: { type: GraphQLInt },
}
});
}
// Replace field.type with a custom GraphQLScalarType that enforces the
// length restriction.
wrapType(field) {
const fieldName = field.astNode.name.value;
const { type } = field;
if (field.type instanceof GraphQLList) {
field.type = new LimitedLengthType(fieldName, type, this.args.max);
} else {
throw new Error(`Not a scalar type: ${field.type}`);
}
}
visitInputFieldDefinition(field) {
this.wrapType(field);
}
}
class LimitedLengthType extends GraphQLScalarType {
constructor(name, type, maxLength) {
super({
name,
serialize(value) {
return type.serialize(value);
},
parseValue(value) {
value = type.serialize(value);
return type.parseValue(value);
},
parseLiteral(ast) {
switch (ast.kind) {
case Kind.LIST:
if (ast.values.length > maxLength) {
throw {
code: 400,
message: `'${name}' parameter cannot extend ${maxLength} values`,
};
}
const arrayOfInts = ast.values.map(valueObj => parseInt(valueObj['value']));
return arrayOfInts;
}
throw new Error('ast kind should be Int of ListValue')
},
});
}
}
Does this look right?
Thanks

updating the state in componentWillMount

i want to create a object with multiple object. the data is something like this
dataList = [{inputFieldId: 1, dataField:{...}, data: '120'}, {inputFieldId: 2, dataField:{...}, data: '120'} ]
what is want like this.
res = [{1: '120'}, {2: '120'}]
i write a code for this but its giving me the last object data only.
constructor(){
super()
this.state = {
inputValue:{},
datalist = [],
}
}
componentDidMount() {
console.log(this.state.inputValue)
this.props.navigation.setParams({ sendDataToServer:
this._sendDataToServer });
}
async componentWillMount(){
for(var key in dataList){
this.setState({
inputValue: {
...this.state.inputValue,
[dataList[key].inputFieldId]: dataList[key].data
}
})
}
}
code output = { 2: '120'}
thanks in advance
setState work asynchronously. Instead of this
this.setState({
inputValue: {
...this.state.inputValue,
[dataList[key].inputFieldId]: dataList[key].data
}
})
Try to change to this
this.setState((previousState) => ({
inputValue: {
...previousState.inputValue,
[dataList[key].inputFieldId]: dataList[key].data
}
}))

Gauge.js Component under Vue.js 3.2.1 not Creating

"Hi, I'm trying to get a simple gauge.js to work under Vue.js v3.2.1. The document reference get is always returning a null so that the mounted function never completes. This should be a simple thing, but I fear I am missing knowledge somewhere as I am new to Vue.js & can't find anything to help. "
<template >
<canvas ref="foo"></canvas>
</template>
<script>
import { Gauge } from 'gauge.js'
export default
{
name: 'vcGaugeJs',
props:
{
value: {type: Number, default: 0},
//options: { type: Object, default: () => ({}) }
},
data()
{
return
{
gauge: null
}
},
mounted: function ()
{
this.initGauge();
},
watch:
{
value: function (val)
{
this.gauge.set(val);
},
},
updated: function()
{
if (this.gauge == null)
{
this.initGauge();
}
},
methods:
{
initGauge ()
{
let opts =
{
angle: 0, // The span of the gauge arc
lineWidth: 0.35, // The line thickness
radiusScale: 1, // Relative radius
pointer:
{
length: 0.53, // // Relative to gauge radius
strokeWidth: 0.057, // The thickness
color: '#000000' // Fill color
},
limitMax: false, // If false, max value increases automatically if value > maxValue
limitMin: false, // If true, the min value of the gauge will be fixed
colorStart: '#6F6EA0', // Colors
colorStop: '#C0C0DB', // just experiment with them
strokeColor: '#EEEEEE', // to see which ones work best for you
generateGradient: true,
highDpiSupport: true // High resolution support
}
var target = this.$refs.foo;
if (target == null)
{
console.log ("Null target ref!");
}
else
{
this.gauge = new Gauge(this.$refs.foo);
this.gauge.maxValue = 3000; // set max gauge value
this.gauge.setMinValue(0); // Prefer setter over gauge.minValue = 0
this.gauge.animationSpeed = 62; // set animation speed (32 is default value)
this.gauge.set(1700); // set actual value
this.gauge.setOptions(opts); // create gauge!
}
}
},
}
Here's what the dev team says:
If you look at the lifecycle digram you can see that when the created() hook is called, the component’s template/render function has not been compiled.
So in your case, you should be able to instantiate the gauge at mounted hook on vm.$el instead, with it being the canvas element.
mounted() {
this.initGauge();
},
methods: {
initGauge() {
let opts = { /* options */}
this.gauge = new Gauge(this.$el).setOptions(opts);
this.gauge.maxValue = 3000; // set max gauge value
this.gauge.setMinValue(0); // Prefer setter over gauge.minValue = 0
this.gauge.animationSpeed = 62; // set animation speed (32 is default value)
this.gauge.set(1700); // set actual value
}
}

Mithril.js multiple css class

I'm new at mithril.js. I have a div, I want to add class "invalid" if ctrl.invalid()==true, and "hidden" if ctrl.hidden()==true.
If I use m('div', {class: ctrl.invalid() ? 'invalid' : '', class: ctrl.hidden()? 'hidden' : ''}), they override each other.
I can use m('div', {class: [ctrl.invalid()?'invalid':'', ctrl.focused()?'focused':''].join(' ')}), and it'll work, but it looks messy.
Is there an elegant solution for this? Thanks.
I recommend you to use classnames - a simple utility for that. You can define your classes in a nice way and it will merge everything for you. In your case it will be:
const myMergedClasses = classNames({
invalid: ctrl.invalid(),
focused: ctrl.focused()
});
m('div', { class: myMergedClasses })
Beautiful?!
Very late to the game, but as an inspiration for others ending up here, I often do something like the following, just because it is:
simple to implement
easy to extend
easy to understand
view(): {
const classes =
`${ctrl.invalid() ? '.invalid' : ''}` +
`${ctrl.hidden()? '.hidden' : ''}`;
return m(`div${classes}`);
}
You can add a helper method to your Mithril component:
const myComponent = {
css() {
// Add some logic
return 'class1 class2';
},
view() {
return m('div', { class: this.css() });
},
};
Or to the controller:
const ctrl = {
css() {
// Add some logic
return 'class3';
},
};
const myComponent = {
view() {
return m('div', { class: ctrl.css() });
},
};
Choose whichever suits your case better.
You can also use the classnames utility, as suggested by Ross Khanas in his answer:
const myComponent = {
css() {
return classNames({
invalid: ctrl.invalid(),
focused: ctrl.focused(),
});
},
view() {
return m('div', { class: this.css() });
},
};
Or:
const ctrl = {
css() {
return classNames({
invalid: this.invalid(),
focused: this.focused(),
});
},
invalid() { /* ... */ },
focused() { /* ... */ },
};
const myComponent = {
view() {
return m('div', { class: ctrl.css() });
},
};