I have read the documentation so many times https://vega.github.io/vega-lite/docs/config.html#custom-format-type. I still don't understand how to implement this in react vega. What confuses me the most is this vega object.
view = new vega.View(...);
view.expressionFunction('customFormatA', function(datum, params) {
...
return "<formatted string>";
});
What I am currently doing in React:
import React from "react";
import ReactDOM from "react-dom";
import { createClassFromSpec } from "react-vega";
const spec = {}
const BarChart = createClassFromSpec({ mode: "vega-lite", spec: spec });
export default function TestPage2({ data }) {
return <BarChart data={{ table: data }} />;
}
Is there any example of implementing a custom format type that I can learn from?
There was an error in the documentation and a pull request has been submitted.
You should use vega instead of vega.View like so:
import { expressionFunction } from 'vega';
expressionFunction('customFormatA', function(datum, params) {
return datum;
});
However, note that custom formats do not work with binning; an issue has been opened for this.
Related
I'm trying to use the useParallax hook on an element in my js file. I'm using NextJs with ReactJs as well as styled components. I used the hook in the following way:
Mainland.js
import React, { useEffect, useRef } from 'react';
import styled, { keyframes } from 'styled-components';
import { useParallax } from 'react-scroll-parallax';
const Mainland = () => {
const { parallaxRef } = useParallax({ speed: 20 }); // set up the hook to use with useRef
const StyledDiv = styled.div`` //Styled Component
return (
<StyledDiv ref={parallaxRef}>
...
</StyledDiv>
The error here is the following:
Error: You must assign the ref returned by the useParallax() hook to an HTML Element.
So I tried to use it without styled components and straight to an HTML element and it still didn't work.
Extra Information: I used the parallax provider in my _app.js file in the following way:
import Layout from '../Components/Layout';
import '../styles/globals.css';
import { ParallaxProvider } from 'react-scroll-parallax';
function MyApp({ Component, pageProps, ...appProps }) {
const isLayoutNeeded = [`/Contact`].includes(appProps.router.pathname);
return (
<>
<Layout state={isLayoutNeeded}>
<ParallaxProvider>
<Component {...pageProps} />
</ParallaxProvider>
</Layout>
</>
);
}
export default MyApp;
Additional info:
https://react-scroll-parallax.damnthat.tv/docs/usage/hooks/use-parallax
Install module inside your project folder. That fixed it for me
npm i install react-scroll-parallax
The useParallax hook returns { ref, controller, element }.
So try this:
const { ref: parallaxRef } = useParallax({ speed: 20 });
I would like to show data from a single API to different components as I want to hit the API only once and distribute the data to multiple small components. I know I can do this by using redux state but not sure how to do it. Need your help to achieve this. Below is the code done so far.
homepage/index.js
import SlidingBanner from './banner/BannerList';
import Celebslider from './celebrityslider/CelebSlider';
class HomePage extends Component {
render() {
return (
<div>
<SlidingBanner />
<anotherslider />
</div>
);
}
}
export default HomePage;
BannerList.js
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { itemsFetchData } from '../../../actions/items';
class BannerList extends Component {
componentDidMount() {
this.props.fetchData();
}
render() {
let bannerArray = [];
let banner = this.props.items.banner
for (let key in banner) {
bannerArray.push(banner[key]);
return (
<div>
<Slider {...slidersettings}>
{this.props.items.banner.map((item) => (
<div key={item.id}>
<img src={item.image_url} className="img-responsive"/>
</div>
))}
</Slider>
</div>
);
}
if (this.props.hasErrored) {
return <p>Sorry! There was an error loading the items</p>;
}
if (this.props.isLoading) {
return <p>Loading…</p>;
}
return (null);
}
}
BannerList.propTypes = {
fetchData: PropTypes.func.isRequired,
items: PropTypes.object.isRequired,
hasErrored: PropTypes.bool.isRequired,
isLoading: PropTypes.bool.isRequired
};
const mapStateToProps = (state) => {
return {
items: state.items,
hasErrored: state.itemsHasErrored,
isLoading: state.itemsIsLoading
};
};
const mapDispatchToProps = (dispatch) => {
return {
fetchData: (url) => dispatch(itemsFetchData(url))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(BannerList);
anotherslider.js
Now in this file, i want to fetch another array of objects or object from the same API.
I tried to mount the API in container component but did not worked, I hope i am doing some mistake. Please correct.
If you want to fetch data in anotherslider.js file you must connect reducer to class/function inside it as well as you are making it in BannerList.js file.
Now before render call componentWillReceiveProps(nextProps) function and you will get your data here.
If you want to call data in both of the sliders, you have 2 ways to handle it.
Make your redux requests in HomePage.js component and bind the data to the other components.
When you get the data on BannerList.js component, your state will be updated. Just add the redux connection to your anotherslider.js component and get data when updated.
const mapStateToProps = (state) => {
return {
items: state.items,
hasErrored: state.itemsHasErrored,
isLoading: state.itemsIsLoading
};
};
export default connect(mapStateToProps, mapDispatchToProps)(HomeList);
Apart from all these options, you can also use react's Context API as Provider/consumer to distribute your data among small components... this will save you passing props to all small components and directly access the value in component using Context.Consumer .. moreover if you do not want to store this state in global redux store, context API will save you from it...
I have a file for configuring my OpenID Connect authentication
export const authMgr = new Oidc.UserManager({
userStore: new Oidc.WebStorageStateStore(),
authority: **appsetting.oidc**
})
I want to access my state in order to get the value of appsetting.
I did this:
import store from './store'
const appsetting = () => store.getters.appsetting
but my appsetting is always returning undefined
what I my missing?
Store:
app.js
const state = {
appsetting: appsetting,
}
export {
state
}
getters.js
const appsetting = state => state.appsetting
export {
appsetting
}
index.js
export default new Vuex.Store({
actions,
getters,
modules: {
app
},
strict: debug,
plugins: [createLogger]
})
when I print the value of store.getters, it returns this:
{
return __WEBPACK_IMPORTED_MODULE_2__store__["a" /* default */].getters;
}
No the actual store objects
Try to import 'store' with curly brackets
import {store} from '../store/index'
store.getters.appSettings
Another option is to access from the vue property
import Vue from 'vue'
Vue.store.getters.appSettings
As for 2023 accesing store with
import {store} from '../store/index'
store.getters.appSettings
wasnt working for me but after removing curly brackets like so:
import store from '../store/index'
store.getters.appSettings
It started working as intended
I got list of components that I would like to replace on certain conditions:
List of navigation components:
import {navigationDefaultComponent} from '';
import {navigationSmoothComponent} from '';
import {navigationMobileComponent} from '';
navigations: [
{component: navigationDefaultComponent},
{component: navigationSmoothComponent},
{component: navigationMobileComponent},
]
I have an object that comes from API and tel's me what component I should show
const X = {
name: 'John Smith',
navigation: 'navigationDefaultComponent'
}
I have done it this way, as I can't store the component in the api. The API can not return me a component. If there is a way please do let me know.
So my goal is is to have a const that will go through navigation object and based on x.navigation string will map and return me the component.
const nav = ????
Well, this is a typical situation.
You would need to make one of your component to listen to ** route and then use dynamic component loading. https://angular.io/guide/dynamic-component-loader
You can create an array having string and Component
let mapping = [
{'name':'name1', 'component':Component1},
{'name':'name2', 'component':Component2},
{'name':'name3', 'component':Component3},
{'name':'name4', 'component':Component4},
{'name':'name5', 'component':Component5},
];
Please Note that Component1, Component2 are direct reference to the Component and not their string representations.
Create a directive, to be included in your AppComponent
import { Directive, ViewContainerRef } from '#angular/core';
#Directive({
selector: '[app-directive]',
})
export class AppDirective {
constructor(public viewContainerRef: ViewContainerRef) { }
}
Include the directive in your template
<ng-template app-directive></ng-template>
Get the reference to your directive in ts file
#ViewChild(AppDirective) appDirective: AppDirective;
Now load the desired component after getting the response from the API
// let's assume name1 is what API returned
let component = this.mapping['name1'];
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(mapping[component);
let viewContainerRef = this.appDirective.viewContainerRef;
viewContainerRef.clear();
let componentRef = viewContainerRef.createComponent(componentFactory);
I hope this solves your problem...
Context:
I have an Angular 2+ application that makes calls to a web API containing URLs for a src attribute on a script tag that is created by a loadScript function in the AfterViewInit lifecycle hook.
The web API returns a JsonResult and is yielding the data I expect. I was able to interpolate some of the data in the component's template.
Additionally, before I added the call to the web API, the loadScript function was working with a hard-coded argument.
Reading a thread on github. A "member" stated that scripts are not supposed to be loaded on demand. So what I implemented with the loadScript function is essentially a work around, but how else would load them? I don't want to have a seemingly endless amount of script tags sitting in the index.html file.
import { Component, OnInit, AfterViewInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
import { Http } from '#angular/http';
#Component({
selector: 'app-agriculture-roadmap',
templateUrl: './agriculture-roadmap.component.html',
styleUrls: ['./agriculture-roadmap.component.css']
})
export class RoadmapComponent implements OnInit, AfterViewInit {
constructor(private _httpService: Http, private _route: ActivatedRoute)
{
}
apiRoadmaps: { roadmapName: string, pdfRoadmapURL: string, jsRoadmapURL: string };
ngOnInit() {
this._httpService
.get('/api/roadmaps/' + this._route.params)
.subscribe(values => {
this.apiRoadmaps = values.json() as { roadmapName: string, pdfRoadmapURL: string, jsRoadmapURL: string };
});
}
async ngAfterViewInit() {
await this.loadScript(this.apiRoadmaps.jsRoadmapURL);
}
private loadScript(scriptUrl: string) {
return new Promise((resolve, reject) => {
const scriptElement = document.createElement('script')
scriptElement.src = scriptUrl
scriptElement.onload = resolve
document.body.appendChild(scriptElement)
})
}
}
If you are using angular cli .
Then place these scripts in
angular-cli.json file under scripts array
scripts:[
.....
]
Please refer this [link] (https://rahulrsingh09.github.io/AngularConcepts/faq)
It has a question on how to refer third party js or scripts in Angular with or without typings.