I'm using Angular2 + D3 to create a chart.
I'd like to apply an svg filter to the bars in order to create a drop-shadow effect.
While the filter is created and the bars have a filter: url("#dropshadow") style applied, the shadow does not render.
Could this be due to Angulars single page and the url() not finding the filter? What would be the correct way to work around this issue?
I finally figured it out. The best solution seems to be to inject the Location via
import { Location } from '#angular/common';
...
constructor(private location: Location)
and then use it to specify the path for the url()
.style('filter', 'url(' + this.location.path() + '#drop-shadow)')
Now it works as expected.
In case some one arrives here and this isn't clear enough here is what i did for any url used in <svg> with Safari:
In my components i import Location
import { Location } from '#angular/common';
...
constructor(private location: Location) {
}
url(id: string) {
return `url(${this.location.path()}${id}`;
}
}
Then use it in the inline <svg> tags as follows
[attr.filter]="url('#filter-11')"
[attr.clip-path]="url('#clip')"
Related
I have 2 different pages which is going to display the same data and both are sharing the same components. But both pages has different resolution one is the size with the alert box and one is similarly A4 size. how to set dynamic height and width for them. I tried using ngstyle not sure how to implement it correctly
in normal html
<tbody class="classname" style="height: 60px; width: fit-content;">
i added this and it works but both pages taking the same resolution.
so with ngstyle i tried this again same thing both pages has been set to same 60
[ngStyle]="{'height.px': 'Height' ? '60' : '200' }"
or it there any solution using ngclass?
So your problem breaks-down in two steps. One is to calculate the page height which is not an angular field and rather browser-specific issue. Although browsers do expose clientHeight or scrollHeight properties but there is a difference on how different browsers understand the actual height of the page.
So the best practice (as its also used by famous jQuery library) is to get the different document-level height properties and get the maximum value out of those.
You'll have to inject the DOCUMENT constant to access the DOM document into your component. Please find the below example angular component code.
import { Component, OnInit, Inject } from '#angular/core';
import { DOCUMENT } from '#angular/common';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
public height = 0;
constructor(#Inject(DOCUMENT) private document: any){
}
ngOnInit() {
this.height = Math.max( this.document.body.scrollHeight, this.document.body.offsetHeight,
this.document.documentElement.clientHeight, this.document.documentElement.scrollHeight, this.document.documentElement.offsetHeight );
}
}
Now simply on the html side you could test the height property of component and apply the style as desired. Somethink like this..
<div [ngStyle]="{'height': height>=200 ? '200px' : '60px' }"></div>
Thanks.
I know this problem sounds a bit complex but it's not.
I'll try my best to explain it in a simple way:
I'm making a list of blog posts for the homepage of my Gatsby website.
The list is made of "boxes", every box that links to a post has a background-image.
I pass this background-image to a styled-component, it gets the image from a prop value that I inserted in the main < div > element (you'll find the example bellow).
It works fine, till I try use an image from my local folder under src (instead of using an online link that I simply putted on frontmatter).
Here's what I did in the past, and worked:
I put the url of the image on the frontmatter of the markdown file:
---
slug: "/post/my-post"
[...]
imghero: "https:/path/to/image-online.jpg"
---
Then query it with graphql:
const LISTING_QUERY = graphql`
query BlogPostListing {
allMarkdownRemark(limit: 10, sort: {
order: DESC,
fields: [frontmatter___date]
}) {
edges {
node {
excerpt
frontmatter {
title
slug
date(formatString: "MMMM DD, YYYY")
imghero
}
}
}
}
}
`
After that I insert the {node.frontmatter.imghero} it on a prop on the main div:
const Listing = () => (
<StaticQuery
query={LISTING_QUERY}
render={({allMarkdownRemark}) => (
allMarkdownRemark.edges.map(({node}) => (
<Article img_background={node.frontmatter.imghero} key={node.frontmatter.slug}>
[... etc ...]
</Article>
))
)}
/>
)
export default Listing
And finally I call that img_background prop in the styled-component:
const Article = styled.article`
background-image: url(${props => props.img_background};);
[... etc ...]
`
This method works.
Now I want to get the image from my "images" folder and not from a random url.
I installed gatsby-remark-images
Set it on gatsby-config.js and put the path of some image on frontmatter.
Test everything with http://localhost:8000/___graphql (and worked)
Insert the additional query throught graphql:
[...]
frontmatter {
date(formatString: "DD MMMM, YYYY")
title
imghero
hero {
childImageSharp{
fluid(maxWidth: 630) {
...GatsbyImageSharpFluid
}
}
}
[...]
I modify the node on the component with the new path:
<Article img_background={node.frontmatter.hero.childImageSharp.fluid} [...]>
[...]
</Article>
Gatsby Develop compiles fine.
But then my homepage is completely white.
And the console of the browser says that node.frontmatter.hero is "null".
I don't know that else to do.
Thanks for the help.
I think a bit more info is necessary to resolve your issue, none of the thing you listed out looks wrong in itself. However so many folks got tripped off by image handling in gatsby that I'm writing a check list. It's meant to be generic, but I think no.5, 8, 9, 12 might help you locate the problem.
Using image with gatsby-transformer-remark + gatsby-transformer-sharp troubleshooting
Setup
Is there any error at all? Sometimes gatsby will still compile successfully despite something's wrong. Check the console for anything that's... red.
Did you restart gatsby i.e turn it on and off again? Try removing cache & public folder (.cache and public) if you suspect something's wrong with them.
Did you list your image folder, or any of its parent folders in gatsby-source-filesystem?
In your frontmatter, is the path to the image relative to the markdown file itself? i.e path starts with a dot ./relative/path/to/image.png
Does all markdown has a hero field in frontmatter? If a file doesn't have a hero field, it will be null.
If the image path in frontmatter is not relative or doesn't link to a file, it'll be treated as a regular string.
Query & Fragments
Does your query work? Test your query in http://localhost:8000/___graphql. Make sure the image field show up as a File node. Try something simple like
query {
allMarkdownRemark {
frontmatter {
title
hero {
id
name <-- just enough to know the file exists
}
}
}
}
If your hero shows up as a string, something's wrong, check the setup again.
Are you using fragments? Currently fragments can't be test in the graphiql tool, so you might need to find the definition of that fragment and test it manually. Here's a list of the default ones that come with gatsby-transformer-sharp and their definitions.
If you're using a custom fragment, make sure to define & export it somewhere.
Usage
If image doesn't show up in the browser, inspect & try to find what's shown up in place of your image.
Are you using gatsby-image? If so, make sure you're passing in something it can work with.
Make sure your image component receives what it should. If your component's expecting a path, don't pass in an object, like result of a fragment.
Some side note
gatsby-remark-images only handle relative links in markdown image & html <img>, so if your image is living in frontmatter, it won't do anything.
i have encountered an issue, when making a text editor with support of image based tags. There is a need to move those tags around freely in the text, which is being made impractical by this issue.
Basically when I start dragging an image, and then drop it on desired location, one of two results can happen: A) it works as intended and B) the image is dropped to the end/beginning of the sentence. You can see the behaviour in attached gif. Resulting behavior
I'm using react and typescript combination for creating the page with quill being inserted in a component.
// TextEditor/index.tsx
import * as React from 'react';
import * as Quill from 'quill';
import { TextEditorState, TextEditorProps } from '../#types';
import { generateDelta } from '../#utils/generateDelta';
const formats = [
'image'
];
class TextEditor extends React.Component<TextEditorProps, TextEditorState> {
constructor(props: TextEditorProps) {
super(props);
this.state = {
Editor: undefined
}
}
componentDidMount() {
const self = this;
this.setState({Editor: new Quill('#editor-container', {formats: formats, debug: 'warn'})});
}
changeText(text: string) {
if(typeof(this.state.Editor) !== 'undefined') {
this.state.Editor.setContents(generateDelta(text), 'api');
}
}
render() {
return (
<div id="editor-container"></div>
);
}
}
export default TextEditor;
And the usage of this component in another component is just
// editor.tsx
import TextEditor from '../QuillEditor/TextEditor';
...
onUpdate(text: string) {
this.refs.targetEditor.changeText(text);
}
...
render() {
return (
...
<TextEditor
ref={'targetEditor'}
/>
...
)
}
I have tried to change the text editor to just contentEditable div and that worked flawlessly, so it shouldn't be because of some css glitch.
Has anyone some idea of what could be causing this?
EDIT Feb 6:
I have found out, that this issue is manifesting only in Chrome, as IE and MS Edge did not encountered this issue. I have tried to switch off all extensions, yet the issue is still there. Private mode also didn't help.
After few days of research I have figured out what is causing the issue.
The combination of Quill and React won't work, because of the way React 'steals' input events, while creating the shadow DOM. Basically, because it tries to process my input in contenteditable div created by Quill, it causes some actions to not fire, resulting in the weird behaviour. And because Quill tries to do it by itself, outside of React DOM.
This I have proved in my simple testing project, where adding a simple input tag anywhere on the page broke down the Quill editor.
Possible solution would be to use react-quill or some other component container, however I haven't managed to make it successfully work, or write some yourself, which would incorporate Quill to React in its DOM compatible way.
I am getting started with NativeScript + Angular 2 and I'd like to implement a component that activates different routes depending on the device orientation. After much search, I was able to get this working but I haven't yet figured out how to get the initial device orientation, which sounds like it should be easier.
Here's my AppComponent code. Look at ngAfterViewInit:
import {Component, OnInit, OnDestroy, AfterViewInit} from "#angular/core";
import {Router} from "#angular/router";
import _application = require('application');
#Component({
selector: "my-app",
templateUrl: "app.component.html",
})
export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
constructor(private router: Router) {}
ngOnInit() {
_application.on(_application.orientationChangedEvent, this.setOrientation.bind(this));
}
ngAfterViewInit() {
// How do I get the initial orientation here instead of hardcoding to 'portrait'?
this.setOrientation({newValue: 'portrait'})
}
ngOnDestroy() {
_application.off(_application.orientationChangedEvent, this.setOrientation);
}
setOrientation(args) {
if (args.newValue === 'landscape') {
this.router.navigate(['/landscape']);
} else {
this.router.navigate(['/portrait']);
}
}
}
private activity:any = application.android.foregroundActivity;
this.activity.getResources().getConfiguration().orientation;
You could use this plugin. In order to get access to the up-to-date version, you will need to pay a monthly subscription to the developers that maintain ProPlugins.
You can installed the last free version of it using:
npm i nativescript-orientation
This comes with no guaranties that it will work, especially in {N} 6+.
Once installed, you can get the current screen orientation like this:
const orientation = require("nativescript-orientation");
console.log(orientation.getOrientation());
While there is no helper to determine the initial orientation that I know of, you can still get the current screen dimensions. You may import the screen module from the core library.
import { screen } from 'tns-core-modules/platform';
Then on application initialization determine the orientation by determining if the screen height is larger than the width:
this.orientation = screen.mainScreen.heightPixels > screen.mainScreen.widthPixels ? 'portrait' : 'landscape';
Edit: This may be inconsistent and is not fully tested (meaning the screen height might not always be the height of the screen in portrait mode). If this is the case, on page load, you may use the same strategy to measure the main Page element and compare the height and width of the view to determine orientation.
I can't understand why I cannot change picture (background of field and image of imageview) from this method:
private void loginCheck(String loginText){
String login = loginText.trim();
if(login == null || login.equals("")) {
loginField.setStyle("-fx-background-image:url('images/registration_login_wrong.png');");
logoTick.setStyle("-fx-image:url('images/registration_wrong.png');");
logoTick.setVisible(true);
}else{
loginField.setStyle("-fx-background-image:url('images/registration_login_right.png');");
logoTick.setVisible(false);
}
}
CSS code for logoTick is:
.login_tick{
-fx-image:url("images/registration_tick.png");
visibility:false;}
Everything besides -fx-image and -fx-background-image seems to work fine. I also changed background image in another class(of a label) and didn't encounter any problems. That's why I can't understand what can be possibly wrong. I checked images location and name everything seems correct. If I manually replace the image path in CSS it is working, but from the code images just disappear.
The paths in the CSS url(...) function are treated as relative paths; the location to which they are relative is different in a stylesheet and in an inline style. From the CSS documentation:
If the style appears in a stylesheet, the path is relative to the base
URI of the stylesheet. If the style appears in an inline style, the
path is relative to the root of the classpath.
Without knowing your project layout, it's not possible to give you the correct paths for the images, but that should be enough to figure it out.
Alternative Solution
An alternative solution is to define all the styles in CSS, and to manipulate the style class in the Java code to select the appropriate style. I like to use JavaFX 8 CSS PseudoClasses to do this:
.login-field:login-incorrect {
-fx-background-image: url('images/registration_login_wrong.png');
}
.login-field:login-correct {
-fx-image:url('images/registration_login_right.png');
}
.login_tick {
-fx-image:url("images/registration_tick.png");
visibility:false;
}
.login_tick:login-incorrect {
-fx-image:url('images/registration_wrong.png');
visibility: true ;
}
And then the Java code looks like:
private void loginCheck(String loginText){
String login = loginText.trim();
boolean loginIncorrect = (login == null || login.equals("") ;
PseudoClass loginIncorrectPsuedoClass = PseudoClass.getPseudoClass("login-incorrect");
PseudoClass loginCorrectPsuedoClass = PseudoClass.getPseudoClass("login-correct");
loginField.psuedoClassStateChanged(loginIncorrectPseudoClass, loginIncorrect);
loginField.pseudoClassStateChanged(loginCorrectPseudoClass, !loginIncorrect);
logoTick.psuedoClassStateChanged(loginIncorrectPseudoClass, loginIncorret);
}
The advantage of this approach is that all style information is stored in the CSS file; the Java code just changes the selector used for the UI elements.