Canvas force grid cell to be expanded infinitelly - html

ts:
templateStyle = {
display: 'grid',
'grid-template-columns': 'calc(25%-10px) calc(25%-10px) calc(25%-10px) calc(25%-10px)',
'grid-template-rows': '150px auto auto',
'grid-gap': '10px',
border: '1px solid #2196F3',
padding: '10px'
}
widgets = [
{ rowStart: 1, rowEnd: 2, colStart: 1, colEnd: 2, ... },
{ rowStart: 1, rowEnd: 2, colStart: 2, colEnd: 3, ... },
...
{ rowStart: 2, rowEnd: 3, colStart: 1, colEnd: 2, ... },
...
];
getStyle(widget): object {
return {
position: 'relative',
'grid-row-start': widget.rowStart,
'grid-row-end': widget.rowEnd,
'grid-column-start': widget.colStart,
'grid-column-end': widget.colEnd,
'text-align': 'center',
'vertical-align': 'middle',
'min-height': card.height + 'px'
};
}
html
<div [ngStyle]="templateStyle">
<div *ngFor="let widget of widgets" [ngStyle]="getStyle(widget)">
<button (click)="addChart()">Add</button>
<div *ngIf="If chart added by above button action"
style="width: 100%; height: 100%"> // widht/height 100% to give all space of the parent
<canvas style="width: 200px; height: 200px;"
chartType="pie"
[data]="[200, 100]"
[labels]="['A', 'B']"
baseChart>
</canvas>
</div>
</div>
</div>
Eh, the line style="width: 200px; height: 200px; is ignored by the canvas and this will force the grid cell to grow infinitelly outside the grid. I'm thinking that this happening because I declared grid-columns using percentages. If I remove the canvas parent style (width: 100%, height: 100%), the cell will grow how much space is availaible in the grid.
So I need to calculate column width somehow and give absolute values for grid, and not using percentages as: grid-template-columns': 'calc(25%-10px) calc(25%-10px) calc(25%-10px) calc(25%-10px). I also tried to use fr, but have same result. For both cases, I tried to remove canvas and use just a simple container with a background, this will work perfectly, due of this, my opinion is that the canvas force the cell (parent) to be resized each time.
I'm really thinking to use d3 charts instead of chartjs if I can't find a solution for this.

try this
templateStyle = {
....
'grid-template-columns': '1fr 1fr 1fr 1fr',
'grid-gap': '10px',
with 1fr for each column space will be evenly divided between 4 columns.

Related

Is there a way to align the first node at the top instead of at the middle?

I am using BalkanGraph plugin and I'm trying to align the first parent node of the orgchart to the top of the svg instead of the center of it.
I tried to set a negative "margin-top" and increases the height of the whole svg, but then the click goes with it, and it doesn't work well.
My only css is this:
#tree {
width: 100%;
height: 630px;
border: 1px solid lightgray;
background-color: #fff;
}
and the things I am using in Orgchart are these:
var chart = new OrgChart(document.getElementById("tree"), {
mouseScroolBehaviour: BALKANGraph.action.zoom,
nodeMouseClickBehaviour: BALKANGraph.action.none,
scaleInitial: BALKANGraph.match.boundary,
collapse: {
level: 2,
allChildren: true
},
});
Set align option to BALKANGraph.ORIENTATION
var chart = new OrgChart(document.getElementById("tree"), {
align: BALKANGraph.ORIENTATION,
...
});

Adjusting position of google linechart

I need to center a google line chart.
The problem is, I cannot use align = "center" because it causes my tooltip hover to lag behind, I'm not sure why.
I found a way to center the chart in the inspector by removing position: relative two divs deep in my chart div.
I thought to override this with
#electricalLineChart div div{
position: static!important
}
But it ignores this code even with !important
I haven't found anything in the documentation that addresses positioning. I tried using legend just for kicks but it doesn't seem to do anything.
Here is my chart code:
// line chart
var linechart1 = new google.visualization.ChartWrapper({
'chartType': 'LineChart',
'containerId': 'electricalLineChart',
dataTable: joinedData,
options: {
colors: ['#4DC3FA', '#185875'],
animation: {
duration: 1000,
easing: 'out',
},
width: 800,
height: 500,
legend: { position: 'static'},
title: 'Line Chart',
explorer: {},
hAxis: {
title: 'Month'
},
vAxis: {
format: formatPattern
//title: 'Amount Billed ($), Consumption (kWh)',
}
},
});
RELEVENT HTML:
<div style="overflow-x:auto;">
<table class="container">
<tbody id="electrical-tables">
<tr id="odd-cells">
<td>
<div id="electricalLineChart"></div>
</td>
</tr>
.... other rows removed for clarity
</tbody>
</table>
</div>
RELEVENT CSS:
#electricalLineChart, #Request_line_chart1{
width: 80%;
margin: auto;
}
Essentially, the third div down in the image with dir= "ltr" needs to be position: static not position: relative.
the problem, <div> elements are block elements, which means they expand the total width of their parent element.
even though the chart does not take up the entire width,
the <div> still expands to the width of the parent.
to prevent this behavior, add the following css to the <div>,
which will allow it to be centered...
display: inline-block;
e.g.
#electricalLineChart, #Request_line_chart1{
width: 80%;
margin: auto;
display: inline-block;
}

How can I remove the extra width to the right of jquery UI datepicker?

I am using jquery UI datepicker against a div so I can see the months on my screen. The issue is that it seems to add a width attribute that is much wider than it actually needs which creates this extra white space as seen below
here is my code:
HTML
<div id="myCalendar"></div>
Javascript:
$("#myCalendar").datepicker({
numberOfMonths: 6,
showButtonPanel: false,
beforeShowDay: function (date) {
var dateString = $.datepicker.formatDate('yy-mm-dd', date);
if ($.inArray(dateString, highlightDateArray) > -1)
{
return [true, "highlightCell", ''];
}
else
{
return [true, '', ''];
}
}
});
from looking in firebug, I see
element.style {
display: block;
width: 102em;
}
which is way longer than necessary (having it at 82em; would be fine)
What is the best way of eliminating this white space?
The issue is that it seems to add a width attribute that is much wider
than it actually needs which creates this extra white space..
Reason:
This is the way jQuery UI has been designed.
It uses a magic number 17 to calculate the width of the container.
From the code of jquery UI v1.11.4 js at line numbers 4561 thru 4574:
var origyearshtml,
numMonths = this._getNumberOfMonths(inst),
cols = numMonths[1],
width = 17,
activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
if ( activeCell.length > 0 ) {
datepicker_handleMouseover.apply( activeCell.get( 0 ) );
}
inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
if (cols > 1) {
inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
}
It checks if the number of columns (months to show) are more than 1, and calculates the width as (17 * cols) + 'em'.
Rest is taken care of by the core CSS. There are styles ui-datepicker-multi-2 thru to ui-datepicker-multi-4 which have predefined width in %. This causes the inner .ui-datepicker-group to fit within the width calculated in the Javascript code and applied in the same line (see js code above). If you see the core CSS, you will find that it is styled only for only upto 4 months across. If the number of months exceed 4, then the width is not applied to .ui-datepicker-group (although the relevant class is applied via js) and hence they do not expand to the entire width of the container.
From jQuery UI v1.11.4 css at line numbers 333 thru 341:
.ui-datepicker-multi-2 .ui-datepicker-group {
width: 50%;
}
.ui-datepicker-multi-3 .ui-datepicker-group {
width: 33.3%;
}
.ui-datepicker-multi-4 .ui-datepicker-group {
width: 25%;
}
You can see that classes for ...multi-5 and beyond are not defined.
What is the best way of eliminating this white space?
Recommended solution:
Simply add more classes as required in your custom CSS. This is the recommended way (also suggested in the response here: https://forum.jquery.com/topic/datepicket-problem-with-width-when-showing-multiple-months). And also the cleanest solution.
Just add the following lines to your custom CSS:
.ui-datepicker-multi-5 .ui-datepicker-group { width: 20%; }
.ui-datepicker-multi-6 .ui-datepicker-group { width: 16.666%; }
.ui-datepicker-multi-7 .ui-datepicker-group { width: 14.285%; }
.ui-datepicker-multi-8 .ui-datepicker-group { width: 12.5%; }
.ui-datepicker-multi-9 .ui-datepicker-group { width: 11.111%; }
.ui-datepicker-multi-10 .ui-datepicker-group { width: 10%; }
.ui-datepicker-multi-11 .ui-datepicker-group { width: 9.0909%; }
.ui-datepicker-multi-12 .ui-datepicker-group { width: 8.333%; }
This will take care of all possibilities up to 12 months across. Add more classes if required, as per your use-case.
For the sake of completeness, here is a demo:
Snippet:
$("#myCalendar").datepicker({ numberOfMonths: 5, showButtonPanel: false });
.ui-datepicker-multi-5 .ui-datepicker-group { width: 20%; }
.ui-datepicker-multi-6 .ui-datepicker-group { width: 16.666%; }
.ui-datepicker-multi-7 .ui-datepicker-group { width: 14.285%; }
.ui-datepicker-multi-8 .ui-datepicker-group { width: 12.5%; }
.ui-datepicker-multi-9 .ui-datepicker-group { width: 11.111%; }
.ui-datepicker-multi-10 .ui-datepicker-group { width: 10%; }
.ui-datepicker-multi-11 .ui-datepicker-group { width: 9.0909%; }
.ui-datepicker-multi-12 .ui-datepicker-group { width: 8.333%; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://code.jquery.com/ui/1.11.4/themes/ui-lightness/jquery-ui.css" rel="stylesheet"/>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
<div id="myCalendar"></div>
And a customary Fiddle: https://jsfiddle.net/abhitalks/u07kfLaa/1/
Note: Do not attempt to change or forcibly override the core jQuery-UI CSS (unless it is absolutely unavoidable). This is not a recommended best-practice. You may end up with unexpected problems, e.g. like this artefact (shown in red circle) visible in the screenshot below, when you force the components inline-block:
And then, you will end up adding more overrides fighting that and possibly get more problems. Try to keep it clean.
It looks like a jQuery UI design oversight to me - I can't think of a reason why that extra whitespace would be intended. As you said, the widget has a fixed width in em, so this isn't just an issue of the default behavior of display: block.
In any case, we can eliminate that extra whitespace with the following steps:
Set display: inline-block and width: auto on the datepicker widget so its width shrinks to fit its contents.
To each individual calendar element, remove the float and use inline-block positioning instead (set float: none and display: inline-block).
Set white-space: nowrap on the datepicker widget. This keeps all the months on one line, preventing them from wrapping onto a second line.
We will also need to use !important on a few of these rules to get them to override the rules from the default jQuery UI stylesheet.
Here is a screenshot of what the final result looks like:
Here is a Live Demo of the code in action:
$("#myCalendar").datepicker({
numberOfMonths: 6,
showButtonPanel: false
});
.ui-datepicker {
display: inline-block !important;
width: auto !important;
white-space: nowrap;
}
.ui-datepicker-multi .ui-datepicker-group {
float: none !important;
display: inline-block;
}
<link href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
<div id="myCalendar"></div>
And a JSFiddle Version of the code: https://jsfiddle.net/cjpmyp1j/1/
As a side note, on the off-chance you were planning on setting inline styles because you are unable to include a stylesheet in your document head, look into using a scoped stylesheet in your document body alongside the jQuery UI element.

ng repeat with relative position elements not sized correctly

I am using angularjs and zurb foundation. I have ng-repeat creating a row for each item in items. Each row itself has two rows within. I am using position relative to move the second inner row up behind the first inner row. The first row has z-index 1 to move it on top. The goal is to create a menu that is hidden behind a div initially.
Seems to work except for one flaw. The problem I am having is that it seems that the directive has its height set to the initial height of its content. So the directive is 12em tall while the content is only in the top half.
Forcing the directive to be 6em tall works for the first item but the subsequent ones have the content of the back row all jibbly wibbly! (I believe that is the scientific term)
Any help would be appreciated. Smashing my head against the keyboard is usually my 'go to' in these situations, but it hasn't helped in this case.
Sample
//index.html
<div ng-repeat='item in items'>
<div directive></div>//ends up 12em
</div>
//directive.html
<div class="row front">//6em tall
//content
</div>
<div class="row back">//moved 6em up
//Menu with buttons
</div>
//style.css
front: {
height: 6em;
z-index: 1;
}
back: {
height: 6em;
position: relative;
top: -6em;
}
The problem is that you are trying to position two divs with relative positioning. They don't need to be relative since they are intended to occupy the same space.
Make the parent div use relative positioning:
.parent { position: relative; }
.front { position: absolute; top: 0; height: 6em; }
.back { position: absolute: top:0; height: 6em }
https://docs.angularjs.org/api/ng/directive/ngRepeat
This is how I would do it:
app.directive('row front', function() {
return {
restrict: '6pm',
scope: {
collection: '=',
columnCount: '='
},
transclude: true,
template: '<div><div class="column" ng-repeat="col in cols">' +
'<div ng-repeat="item in col" ng-transclude></div>' +
'</div></div>',
link: function( scope ) {
var partition = function partition( size, items ) {
if ( items.length === 0 ) { return []; }
return ([items.slice( 0, size )]).concat( partition( size, items.slice( size )));
};
var relativenize = function() {
if ( !scope.columnCount ) { return; }
scope.cols = partition( scope.columnCount, scope.collection );
};
scope.$watch('columnCount', columnize );
scope.$watch('collection', columnize );
}
};
});

Center Aligning the Google charts

I am trying to center align my google chart but have been unsuccessful in doing so. I have played with padding to move it to the center but I don't want to sit there and play with firebug for long time and figure out the correct position. Is there any simpler such as aligning text text-align: center. Obviously it doesn't work with google charts. (I am new to all of this)
var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
...some code ...
<div id='chart_div' style='width: 900px; height: 400px;'></div>
although I did this padding-left: 140px but is there any better way like align: center
Give the chart_div: display: block and margin: 0 auto;
You could also do <div id='chart_div' align='center'> This worked for me, although now my chart hovering function isn't working. Anyone else get this problem? I'm talking about when you hover the mouse over a point on the graph. It usually shows the point such as Jan Sales 440. Anyone know of a fix?
I have been facing the same issue with a google gauge. Checking the code generated I realized that the next thing inside the <div id='chart_div'> is a table with margin 0 set as inline style.
So in order to override it I used the following css:
div.chart_div table {
width: auto;
margin: 0 auto !important;
}
And this worked.
The accepted answer is broken; you have to use display: inline-block to center align your chart.
Since width is fixed, try setting margin-left and margin-right to auto. It should work assuming that the position is relative.
Any of these answers doesn't work for me so i did that:
<div class="chart_box">
<div id="chart_div" style='width: 900px; height: 400px;'></div>
</div>
.chart_box {
width: 900px;
margin: 0 auto;
}
You need to use same width for chart_div and chart_box.
Set chart_div to following properties:
#chart_div{
display: inline-block;
margin: 0 auto;
}
Notice: when you remove the side menu ("legend: 'none'") the width should be altered.
This happens mostly when you go "legend: 'none'" because it leaves the side space that was there to hold that menu, not adjusting the width automatically. You need to re set the width and NARROW it, to manipulate its alignment:
var options = {
title: 'center alignment',
width: 350,
height: 350,
legend: 'none'
};
I combined a few of the answers here, as follows:
Create a css class:
.customChartStyle{
border:1px solid #eee;
text-align:center !important;
}
and add it to the table's cells by adding the following to my table.draw() call:
'allowHtml': true, 'cssClassNames': {'tableCell': 'customChartStyle'}}
I'm new to google charts but the key for me was adding !important to the text-align style (thanks thanassis). For my case I needed the border style because overriding the tableCell style removed that otherwise. Also I prefer defining the class and letting the charts api apply it instead of overriding the styles generated by the api.
Subscribe to the ready event to modify the CSS with JavaScript. Something like below will do the trick.
google.charts.load('current', {
'packages': ['gauge']
});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
['Memory', 80],
['CPU', 55],
['Network', 68]
]);
var guageOptions = {
width: 400,
height: 120,
redFrom: 90,
redTo: 100,
yellowFrom: 75,
yellowTo: 90,
minorTicks: 5
};
var guage = new google.visualization.Gauge(document.getElementById('my-div'));
// HERE'S HOW TO SUBSCRIBE TO THE EVENT
google.visualization.events.addListener(guage, 'ready', resetTableStyle);
guage.draw(data, guageOptions);
// HERE'S THE JAVASCRIPT TO SET YOUR CSS
// NOTE TOGGLING A CSS CLASS HERE IS PROBABLY CLEANEST
function resetTableStyle(){
var myDiv = document.getElementById('my-div');
var myTable = myDiv.getElementsByTagName('table')[0];
myTable.style.margin = 'auto';
}
Below code works for me:
width:fit-content;
margin:0 auto;
By implementing a class to my div, it can now be centered.
HTML
<div id="chart_div2" class="chart_hum"></div>
CSS
.chart_hum {
margin: 0 auto;
display: inline-block;
}