Consider the following jsfiddle
I am trying to align the gap between title bottom-border and the chart. Preferably the left side and right side of the chart aligns with the left side and right side of title border respectively.
Is there anyway I can do that without hardcoding (my chart width changes relative to screen size)?
You can force the title to have the same width and left offset as the plot area. To make sure it's responsive use the render event:
chart: {
plotBorderWidth: 1,
events: {
render: function() {
var style = this.title.element.style;
style.left = this.plotLeft + 'px';
style.width = this.plotWidth + 'px';
}
}
}
Live working demo: http://jsfiddle.net/kkulig/y3fj6vpq/
API reference:
https://api.highcharts.com/highcharts/chart.events.render
Change these two properties of the title.
left: 77px;
width: 922px;
Related
How can I align Chart title with the bar in highcharts?
The bar length may vary because of the data, so I want my title to end where the bar is ending.
I want to implement something like this:
To adjust the title you can set tittle.attr in the events.redraw event. You need to remember that a bar chart is an inverted column chart and where you have an x-axis there will be a y-axis.
chart: {
events: {
render: function() {
let chart = this,
series = chart.series[0],
title = this.title,
point = series.points[0];
title.attr({
x: chart.plotTop + point.x,
y: chart.plotLeft + point.y
});
}
}
},
API References:
https://api.highcharts.com/highcharts/chart.events.render
https://api.highcharts.com/class-reference/Highcharts.SVGElement
Demo: https://jsfiddle.net/BlackLabel/ud45prLg/
I would suggest adding a padding-right: ##px as you havent provided any code to work with. try applying the method via inspect element and add the code into your css after with the right amount of "px" needed.
I'm doing a project using Highcharts Gantt, and I'm having a little trouble mastering it at the moment, especially the management of its height and Y axis.
Here Sandbox : https://codesandbox.io/s/nice-microservice-fuv76?file=/src/GanttMain.jsx:334-352
Let me explain:
What I want to do is set a maximum height and use scrollablePlotArea to make the y-axis scroll, while keeping the X-axis header.
The problem is: if I define a minHeight in scrollablePlotArea, the Y axis cuts the events until the minimum height defined (see sandbox), if I increase minHeight, it will cut less events, but the number is dynamic, so impossible to put a fixed value...
My question is: How to define a maximum height, while keeping a Y scroll that displays all events, While not changing the line height?
I tried several possibilities with the documentation, but nothing works...
I hope I made myself understood...
Thank you very much for your help.
This problem is a bug in Highcharts Gantt and it is similar to this issue: https://github.com/highcharts/highcharts/issues/13884
As a workaround you can dynamically set minHeight for scrollable plot area, example:
let allowChartUpdate = true;
Highcharts.ganttChart('container', {
chart: {
animation: false,
scrollablePlotArea: {
minHeight: 450
},
events: {
render: function() {
if (allowChartUpdate) {
allowChartUpdate = false;
this.update({
chart: {
scrollablePlotArea: {
minHeight: ...
}
}
});
allowChartUpdate = true;
}
}
}
},
...
});
Live demo: http://jsfiddle.net/BlackLabel/ywt2cmkn/
API Reference: https://api.highcharts.com/gantt/chart.events.render
How to keep the chart from cropping on resize, but instead just change its viewport?
I find it a a bit hard to explain, so please let me know if more explanation is needed.
The chart on the first screenshot look nice, they have a 'normal spacing between them and the bars are not cropped. This one has a 1000px width.
Chart box wide
On the second screenshot, the chart is only 300px wide, and the candlesticks become 'cropped'..
Chart box cropped
Instead I would like to only change the viewport, so that the bars are never cropped and are always te same size.. Only the date-range (Viewport) changes.. You see more bars on a wider chart, but it doesn't meen the bars itself should grow or shrink.
I tried it with simple algoritme, but its very prone to error.
let parentW = this._elementRef.nativeElement.parentNode.clientWidth,
data = this.chart.xAxis[0].series[0].data,
barW = 10,
barsToShow = Math.ceil(parentW / barW),
firstBar = (data[data.length - barsToShow] || data[0]),
lastBar = data[data.length - 1];
this.chart.xAxis[0].setExtremes(firstBar.x, lastBar.x, redraw);
I couldn't find any setting in the Highcharts doc and google didn't help much either. Many thanks
Desired behaviour can be achieved with the changing data grouping groupPixelWidth property.
When the chart has smaller width than, e.g. 300px, groupPixelWdith can be set to a higher value.
responsive: {
rules: [{
chartOptions: {
plotOptions: {
series: {
dataGrouping: {
groupPixelWidth: 30
}
}
}
},
condition: {
maxWidth: 300
}
}]
}
example: http://jsfiddle.net/b894z8ug/1/
I have a scrollable div that I zoom/scale the content of using css3 transform. It works fine if I'm zooming in (scaling up the content) but I've noticed that when scaling down, below 100%, the amount that you can scroll vertically of the container div does not reduce.
I've made a jsfiddle to illustrate this
CSS:
.scrollable
{
height: 250px;
width: 250px;
overflow: auto;
background-color: green;
}
.content
{
height :500px;
width : 500px;
background: linear-gradient(red, blue);
...
}
JS/jquery:
function scaleContent(newScale){
var $content = $("#content");
var scaleString = "scale("+newScale+")";
//var height = (newScale<1)? $("#content").height()/scale*newScale : originalHeight;
$content.css({
'-webkit-transform' : scaleString,
'-webkit-transform-origin' : '0 0',
...
//'height' : height +'px'
});
scale=newScale;
}
The actual scaling and the amount that you can scroll horizontally works perfectly, but the amount you can scroll vertically doesn't change below 100%.
Note: the amount you can scroll vertically appears to change on the first scaledown/zoomout, but this is simply because the horizontal scrollbar is removed.
I tried to manually change the height of the content, but this just messed with the content dimensions (duh). That's the commented-out height code.
The ellipses are where I've repeated things for other browsers.
I've managed to come up with one solution, though it's probably not the best. I introduced another div around the content, which I call the view wrapper. I set its overflow to "hidden" and manually set its width and height to match what the scaled content should be.
CSS:
.viewwrapper{
height :500px;
width : 500px;
overflow: hidden
}
JS:
function scaleContent(newScale){
var $content = $("#content");
var scaleString = "scale("+newScale+")";
var $viewwrapper = $("#viewwrapper");
var height = $content.height()/newScale;
var width = $content.width()/newScale;
$viewwrapper.height(height);
$viewwrapper.width(width);
$content.css({
'-webkit-transform' : scaleString,
'-webkit-transform-origin' : '0 0',
...
});
}
JS Fiddle
Update:
This won't work if you're using jQuery 3.0 or 3.1. The read behaviour of the height and width functions has changed, so they return the scaled values. To fix the above code for those versions you can just say.
function scaleContent(newScale){
var $content = $("#content");
var scaleString = "scale("+newScale+")";
var $viewwrapper = $("#viewwrapper");
$viewwrapper.height($content.height());
$viewwrapper.width($content.width());
$content.css({
'-webkit-transform' : scaleString,
'-webkit-transform-origin' : '0 0',
...
});
}
JSFiddle using jQuery 3.0
However this probably won't make it into future versions of jQuery.
Update 2:
You might see unnecessary scrollbars in Chrome when you zoom out of the content. This is down to a Chrome bug.
you're applying transformations to your #content div, but the outside div, #scrollable has also a fixed height and is not reducing. You have to apply transformations to it too.
Because if you're zooming in, the outside div adapts to the inside content, whereas if you're reducing it does not.
Is it possible to put DIV's Vertical Scroll bar on left of the div with css? what about jscript?
I had a simple use case so opted for a simple css solution:
<div style="direction: rtl; height: 250px; overflow: scroll;">
<div style="direction: ltr; padding: 3px;">
Content goes here
</div>
</div>
You can add a pseudo-scrollbar anywhere you want with JQuery and this plug-in: JScrollPane
Okay, so, I wrote a jQuery plugin to give you a completely-native-looking left scroll bar.
Left Scrollbar Hack Demo
Here's how it works:
Inject an inner div inside the pane to allow calculation of the content width (content_width). Then, using this, the native scrollbar width can be calculated: scrollbar_width = parent_width - content_width - horizontal_padding .
Make two different divs inside the pane, both filled with the content.
One's purpose is being a "poser". It's used solely for the scrollbar. Using a negative left margin, the plugin pulls it left so that only the scrollbar is in view (the content of this div is clipped off at the edge).
The other div is used to actually house the visible scrolling content.
Now, it's time to bind the two together. Every 50ms (window.setInterval), the scrollTop offset from the "poser" div is applied to the visible, scrolling content div. So, when you scroll up or down with the scrollbar on the left, the scroll offset gets applied back on the div with the visible content.
This explanation probably sucks and there's actually a quite a bit more to it that I didn't describe, but, without further ado, here it is:
$.fn.leftScrollbar = function(){
var items = $(this);
$(function(){
items.each(function(){
var e = $(this);
var content = e.html();
var ie = !jQuery.support.boxModel;
var w = e[ie?'innerWidth':'width'](), h = e[ie?'innerHeight':'height']();
//calculate paddings
var pad = {};
$(['top', 'right', 'bottom', 'left']).each(function(i, side){
pad[side] = parseInt(e.css('padding-' + side).replace('px',''));
});
//detect scrollbar width
var xfill = $('<div>').css({margin:0, padding:0, height:'1px'});
e.append(xfill);
var contentWidth = xfill.width();
var scrollerWidth = e.innerWidth() - contentWidth - pad.left - pad.right;
e.html('').css({overflow:'hidden'});
e.css('padding', '0');
var poserHeight = h - pad.top - pad.bottom;
var poser = $('<div>')
.html('<div style="visibility:hidden">'+content+'</div>')
.css({
marginLeft: -w+scrollerWidth-(ie?0:pad.left*2),
overflow: 'auto'
})
.height(poserHeight+(ie?pad.top+pad.bottom:0))
.width(w);
var pane = $('<div>').html(content).css({
width: w-scrollerWidth-(ie?0:pad.right+pad.left),
height: h-(ie?0:pad.bottom+pad.top),
overflow: 'hidden',
marginTop: -poserHeight-pad.top*2,
marginLeft: scrollerWidth
});
$(['top', 'right', 'bottom', 'left']).each(function(i, side){
poser.css('padding-'+side, pad[side]);
pane.css('padding-'+side, pad[side]);
});
e.append(poser).append(pane);
var hRatio = (pane.innerHeight()+pad.bottom) / poser.innerHeight();
window.setInterval(function(){
pane.scrollTop(poser.scrollTop()*hRatio);
}, 50);
});
});
};
Once you've included jQuery and this plugin in the page, apply the left scroll bar:
$('#scrollme').leftScrollbar();
Replace #scrollme with the CSS selector to the element(s) you wish to apply left scrollbars to.
(and, obviously, this degrades nicely)