Why is react-sparklines chart rendered differently on firefox than on chrome? - css

I am using react-sparklines to draw charts for 5 day weather data for a given city.
This is my React container (not yet complete) that displays the weather data for each city the user searches for -
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Sparklines, SparklinesLine } from 'react-sparklines';
class WeatherList extends Component {
constructor(props) {
super(props);
this.renderWeather = this.renderWeather.bind(this);
}
renderWeather(cityData) {
const name = cityData.city.name;
const temps = cityData.list.map(w => w.main.temp);
console.log(temps);
return (
<tr key={name}>
<td>{name}</td>
<td>
<Sparklines height={40} width={80} data={temps}>
<SparklinesLine color="red" />
</Sparklines>
</td>
</tr>
)
}
render() {
return (
<table className="table table-hover">
<thead>
<tr>
<th>City</th>
<th>Temperature</th>
<th>Pressure</th>
<th>Humidity</th>
</tr>
</thead>
<tbody>
{this.props.weather.map(this.renderWeather)}
</tbody>
</table>
)
}
}
function mapStateToProps(state) {
return {weather: state.weather};
}
export default connect(mapStateToProps, null)(WeatherList);
And, I've given specific measuresments that state the width and height for each sparkline chart -
<Sparklines height={40} width={80} data={temps}>
However, while the measurements seem right when it it is rendered on chrome, the chart is completely out of proportion on Firefox. Here are the screenshots -
The top one is chrome, Firefox is below -
Next, I inspected the sparkline chart with React Dev Tools on both Firefox and Chrome. Here are the results:
Firefox -
Chrome-
The project uses only Bootstrap, and no other CSS. For this particular table, only table and table-hover classes are used. So, why is the chart rendered differently on Firefox than on Chrome, even when the width and height is constant across both? How can I fix it?

This looks like Stephen Grider's course on React, which is extremely excellent and I recommend you do all especially the GraphQL and JWT auth ones.
There is a minor issue in that one where his project shows correct and yours will probably have one that is incorrect sizing. Later in the video series, he introduces some CSS that fixes it.
If I recall correctly, it is some CSS on the SVG graphic that gives it proper styling. I played with Sparklines after, and I noticed it has a tendency to bleed with what I might call some eratic sizing, so I suspect it is a matter of getting the CSS correct.
I'm looking at my project now, try putting this in the CSS:
svg {
height: 150px;
}

Related

How to set Height of p-table to window height

Problem:
I'm trying to set the height of a prime p-table in angular. I already searched the net and found so many results but none worked so far (probably due to this problem beeing around for many years and changes to the framework disabled certain solutions).
I already tried two approaches the first is in the code below. The second is setting the height of the parent div of the p-table to innerWindowHeight and setting scrollheight of p-table to flex (doesn't work either).
Tools: Angular 14.2.0 and PrimeNG 14.1.1 in a fresh project
I have the following html code in app.component.html:
<div>
<p-table #table
(window:resize)="onResize()"
[value]="data"
[paginator]="true"
[showCurrentPageReport]="true"
[scrollable]="true"
[scrollHeight]="tableScrollHeight"
[rows]="10"
[rowsPerPageOptions]="rowsPerPage"
styleClass="p-datatable-gridlines p-datatable-striped p-datatable-sm"
currentPageReportTemplate="{first} to {last} of {totalRecords} records">
<ng-template pTemplate="header">
<tr>
<th>Date</th>
<th>ID</th>
<th>Description</th>
<th>Value</th>
<th>Tax</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-entry>
<tr>
<td>{{entry.date}}</td>
<td>{{entry.id}}</td>
<td>{{entry.description}}</td>
<td>{{entry.value}}</td>
<td>{{entry.tax}}</td>
</tr>
</ng-template>
</p-table>
</div>
And the following app.component.ts :
import {Component} from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Testapp';
data: any[];
tableScrollHeight: string = "700px";
rowsPerPage: number[] = [5, 10, 20, 50];
constructor() {
this.data = [];
let entry: any = {};
entry.description = "First entry";
this.data.push(entry);
}
onResize() {
this.tableScrollHeight = window.innerHeight + 'px';
}
}
Behaviour I want to implement:
What I want is, that the Paginator stays at the bottom of the window even if the table is empty or dosen't have enough entries to fill the window and that the table is scrollable (header staying at top) as soon as the table rows are bigger than the screen size.
To clarify what I want to acomplish here a screenshot how it looks:
How it looks right now
And here a screenshot how I want it to look:
What it should look like
Question:
Is it possible to acomplish this in a clean way?
Like suggested in the comment I added a stackblitz : https://angular-ivy-sfk7pw.stackblitz.io
Edit:
I found that if you set scrollHeight of table a div inside the table (generated from primeng) with class p-datatable-wrapper gets the style "max-height: XXXpx" where as XXX is the value from tableScrollHeight. I could probably write a CSS selector to change the style to min-width but that's probably not a good Idea since I would have to access the dom from the typscript file and search for the auto generated div.
Maybe you can try to add this style to your css/scss, but this is not a best practice.
.p-datatable-wrapper {
min-height: calc(100vh - 90px);
}
Note: 100vh is your screen height and 90px it's an example your pagination height.
That's it. I hope it can help.

How to give preference to a my stylesheet over bootstrap in REACT(which is included in index.js file)?

I am trying to override some properties of bootstrap by defining my own stylesheet and then importing it in my xyz.js file(for some component) like this:
Xyz.js
import React, {Component} from 'react';
import axios from 'axios';
import qs from 'qs';
import '../css/company.css'
export default class Xyz extends Component{
constructor(props){
.....
}
render(){
return(
<div className="container" style={{float: "left"}}>
<table className = "table">
<tbody>
<tr>
<td>{this.props.index + 1}</td>
<td>{this.props.company.name}</td>
<td>{this.props.company.type}</td>
</tr>
</tbody>
</table>
</div>
)
}
}
// I am trying to set border-top of <td> to 0px which is set to 1px
//by default by bootstrap.css but I am not able to do so
xyz.css
td {
border-top-width: 0px;
height: 2px;
}
I am trying to set border-top of 'td' tag to 0px which is set to 1px
by default by bootstrap.css but I am not able to do so.
CSS chooses which rule to use when there are multiple rules available based on a few different criteria which you should definitely Google and read more about. But in this case two things can help:
Specifity: again I hope you research this more on yourself. But basically adding a class to your td and styling td.classname will increase the specifity of your rule and make it override the less specific type selector provided by Bootstrap
!important: you can put !important after your rule to make sure it overrides everything. However there are also a lot of really cool criteria based on which multiple !important rules get ordered and applied.
You can use important for your styles.
Another option is to use styled-components. In which you can make your own styles for different tables as below.
import { styled } from 'styled-components';
const UserTD = styled.td`
border-top-width: 0px;
height: 2px;
`
<UserTD>{this.props.index + 1}</UserTD>

mPDF: workaround for heading [h1-hx] margins in table

Question:
How can I add margins and/or paddings to headings (h1 - h4) that are part of a TD or TH?
Current Situation:
I have a pre-generated HTML document that is being generated by JIRA. The structure of this document is as follows:
<tr class="rowAlternate">
<td class="jira-macro-table-underline-pdfexport">
<h1><a name="StandardizedInterface"></a>Standardized Interface</span></h1>
<h2><a name="ShortDescription"></a>Short Description</h2>
<ul> ... </ul>
</td>
</tr>
I programmatically extend this document with <tocentry> and other mPDF-specific elements so it can be used as a handout, the generated PDF looks quite good but there is one major issue I have with headings in tables.
This is how the document shows up in the browser:
Inside generated PDF:
As can be see the margins of the headings have disappeared in the PDF export. All my tests with adding inline CSS to the headings or to wrap them with other elements have failed so far.
The mPDF documentation says:
Block-level tags (DIV, P etc) are ignored inside tables, including any
CSS styles.
This will most likely mean that this can't be done with pure CSS or wrapping.
I hope that someone else encountered this problem before and could share some insights as how to achieve spacing around block elements.
You'll want to convert the mark-up to a format similar to the following:
<table>
<tr>
<td class="h1">Report</td>
</tr>
<tr>
<td class="h2">Description</td>
</tr>
<tr>
<td>Body</td>
</tr>
</table>
You can then apply appropriate padding to the <td> elements by targeting the class name:
<style>
table, th, td {
border: none;
}
td.h1 {
padding: 30px 0;
}
td.h2 {
padding: 15px 0;
}
</style>
Use a DOM parser like the one from Symfony to help you traverse your current mark-up and rebuild it in the proper format automatically.
Workaround / solution
I used a workaround that solved the problem in my case by using preg_replace_callback() that I needed anyways to format my document properly. Whenever the callback handles a heading, I add a transparent image right after the text of the heading whose height I define by doing a bit of math.
Code
function formatHeading($p) {
// I only want headings for h1-h3:
$tocEntry= '';
if (is_numeric($p[2]) && $p[2] >= 1 && $p[2] <= 3) {
$tocEntry= "<tocentry level=\"{$p[2]}\" content=\"{$p[3]}\" />";
}
// calculates the heights of the vertical spacer
$spacerHeight= ((6-$p[2]) * 10);
return
"{$p[1]}{$tocEntry} {$p[3]} {$p[4]}
<img src=\"../assets/images/transparent.png\" height=\"{$spacerHeight}\" style=\"vertical-align:middle;\" width=\"1\" border=\"0\"/>";
}
// Matches e.g. "<h2><a name="SimpleTest"></a>Simple test</h2>"
$buffered= preg_replace_callback('|(<h(\d)+>?<a?[\w\s\d="%>]+<\/a>)(.+?[\s\r\n\']*.*)(<\/h\d+>)|',
"formatHeading", $buffered);
Result
To illustrate the position of the spacer I used a non-transparent image to generate the PDF:

Overflow the PrimeNG DialogModule with the CalendarModule

I want to build an Edit popup dialog with an input form in Angular2 using the PrimeNG widgets. I run into trouble with dynamic content of that dialog box (see screenshot).
I've naïvely been trying to wrap the CalendarModule in a div that is positioned above the other elements. (see Angular Template HTML below)
<p-dialog [(visible)]="display" [modal]="true" [resizable]="false">
...
<table class="ui-datatable-responsive">
<tbody>
<tr>
...
</tr>
<tr>
<td class="ui-cell-data">Start By:</td>
<td class="ui-cell-data">
<div [style]="generateSafeStyle('position:relative; z-index:1000')">
<p-calendar dateFormat="dd.mm.yy" [(ngModel)]="value"></p-calendar>
</div>
</td>
</tr>
</tbody>
...
</table>
</p-dialog>
However it seems the DialogModule frames all its content. Is there a hack to overflow that frame?
How would you handle that?
Thank you.
P.S: The generateSafeStyle Function just uses an injected DomSanitizer and works fine.
generateSafeStyle(style:string):SafeStyle{
return this.sanitizer.bypassSecurityTrustStyle(style);
}
just use appendTo="body", it will show calendar above all, even if it is in table, popup or scroll panel
<p-calendar [(ngModel)]="invariable.value" dateFormat="mm/dd/yy" required appendTo="body" readonly></p-calendar>
So I would guess things have changed since this was originally asked, but I found that if I added
[contentStyle]="{'overflow': 'visible'}"
to the p-dialog it allowed the calendar popup to overflow the dialog border.
The only thing that worked so far were the following style options:
<p-calendar dateFormat="dd.mm.yy" [(ngModel)]="dueDate" [style]="{'position': 'fixed', 'overflow': 'visible', 'z-index': '999'}">
This however smashed up the table. So I got rid of the table and used flexboxes to align the elements. Looks better anyway like this.
It's related to overflow:auto on .ui-dialog-content
In dialog there is a div with class .ui-dialog-content make overflow:visible in that div and it will fix this problem.
If you check official PrimeNG Calendar documentation, you will find list of attributes for calendar component, among them there's style attribute which you can use to add needed CSS:
<p-calendar dateFormat="dd.mm.yy" [(ngModel)]="value"
[style]="{ 'position': 'relative', 'z-index': '1000' }"></p-calendar>
I found a better solution for this. Just add a method on click listeners and select element ui date picker
(click)="modifyStyle()"
In ts file import elementRef and Renderer2
constructor(private ele: ElementRef, private ren: Renderer2)
{}
modifyStyle()
{
let ui = this.ele.nativeElement.querySelector(".ui-datepicker");
if(ui)
this.ren.setStyle(ui, "top", "unset")
}
That's it.

Unable to change MUI table padding

I am using the Table component from the react library material-ui.
For some reason, each row, including the header, has a 24px padding, top and bottom, which I can't override.
I already tried changing the style on all the underlying components with no success. Here is the code:
<Table>
<TableHeader adjustForCheckbox={false} displaySelectAll={false} fixedHeader={true}>
<TableRow>
<TableHeaderColumn>id</TableHeaderColumn>
<TableHeaderColumn>name</TableHeaderColumn>
<TableHeaderColumn>number</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody showRowHover={true} displayRowCheckbox={false}>
{data.map(item => {
return (
<TableRow key={item.id}>
<TableRowColumn>{item.id}</TableRowColumn>
<TableRowColumn>{item.name}</TableRowColumn>
<TableRowColumn>{item.number}</TableRowColumn>
</TableRow>
);
})}
</TableBody>
</Table>
Any idea how which component's style needs to be changed in order to override this styling?
This kind of requirements can be handled with overrides in Material UI as per below example:
Step 1: include following dependencies
import { ThemeProvider } from '#material-ui/core'
import { createMuiTheme } from '#material-ui/core/styles';
Step 2: Define custom css related changes as
const theme = createMuiTheme({
overrides: {
MuiTableCell: {
root: { //This can be referred from Material UI API documentation.
padding: '4px 8px',
backgroundColor: "#eaeaea",
},
},
},
});
Step 3: Wrap your component or your code block with
<ThemeProvider theme={theme}>
<Table>
<TableRow>
<TableCell component="td" scope="row">
</TableCell>
</TableRow>
</Table>
</ThemeProvider>
This is how we can override the Material UI style from our custom style.
Happy Coding :)
The issue was with the height property of both the TableRow and TableHeaderColumn/TableRowColumn. For some reason this property manifested itself as padding-top/bottom.
To make a long story short, set the height property on the row and columns.
you can set size and paading props in material ui table
import {Table,} from '#material-ui/core';
<Table size="small" aria-label="a dense table"></Table>
refer this for more details : https://material-ui.com/api/table/
and make sure that elements inside the table row has small sizes .
Indeed, there is a padding added in the Table component, as seen here in the code of that component.
It cannot be overridden in material-ui API, and the context Theme variable desktopGutter is used in many places so I suggest not to change it.
What you can do is override that with a custom CSS item, that you will bundle with the rest of your CSS, either classic stylesheets or "react stye" with Radium or similar.
For example:
<Table id="mytable">...your material-ui JSX...</Table>
In the CSS:
#mytable .table {
padding: 0 !important;
}
Edit: my mistake, this is for the main table component, not the rows, but you can do something similar with the other components by watching in the developper tools which CSS path needs to be overriden.

Resources