I'm having an issue where the display of the max value on a HighCharts chart is changing depending on the display width of the chart.
For example, the largest value in the series is chart.series[0].yData[426]
When the chart is displayed in a smaller sized browser window I get the following values from the browsers Developer Tools:
> chart.series[0].yData[426]
> 446.528
> chart.series[0].yAxis.dataMax
> 223.43449999999999
And the chart shows the peak value at the 223 point with the y axis to match.
When I maximize the window and run the same commands I get:
> chart.series[0].yData[426]
> 446.528
> chart.series[0].yAxis.dataMax
> 446.528
And the chart displays correctly (y Axis is scaled for max value of ~446, max value shown on the chart is correct).
I am changing the the chart size with the following function:
var chartContainer = $("#highstock-chart"); // #highstock-chart is where the chart is located
var resizeChart = function() {
window.chart.setSize(chartContainer.width(), chartContainer.height());
};
$(".fullscreen").click(function() {
chartContainer.css("z-index", 100);
chartContainer.css("position", "fixed");
chartContainer.css("top", 0);
chartContainer.css("left", 0);
chartContainer.css("padding", 0);
chartContainer.css("width", "100%");
chartContainer.css("height", "100%");
resizeChart();
});
Is this an issue with the way I'm resizing the chart? Is this a quirk in HighCharts?
It's dataGrouping from Highstock, you can disable it (I don't advice that): http://api.highcharts.com/highstock#plotOptions.series.dataGrouping
Related
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
I am using Line Charts Library from ANYCHARTS to display some dynamic data(data fetched from csv file).
I am facing some issues when the data is 100%. The line does not display properly. I tried adding padding to the line chart configuration but it adds padding to whole chart rather than just giving padding to the data-line.
I wish if someone could help me on this.
enter image description here
Here is the code if it helps;
anychart.onDocumentReady(function() {
var dataSet = anychart.data.set(AnyData);
var Q6_Trend_AnyChart = anychart.line();
Q6_Trend_AnyChart.animation(true);
Q6_Trend_AnyChart.padding([15, 20, 5, 20]);
Q6_Trend_AnyChart.title();
Q6_Trend_AnyChart.yScale().minimum(0);
Q6_Trend_AnyChart.yScale().maximum(100);
Q6_Trend_AnyChart.contextMenu().itemsFormatter(function(items) {
// Disable save as image option
// delete about and separator
delete items["full-screen-separator"];
delete items["about"];
delete items["anychart-credits"];
delete items["share-with"];
delete items["select-marquee-start"];
// return modified array
return items;
});
var seriesData_1 = dataSet.mapAs({'x': 0, 'value': 1});
var series_1 = Q6_Trend_AnyChart.line(seriesData_1);
series_1.name('');
series_1.hovered().markers()
.enabled(true)
.type('circle')
.size(4);
series_1.tooltip()
.position('right')
.anchor('left-center')
.offsetX(5)
.offsetY(5);
series_1.stroke("3 white");
Q6_Trend_AnyChart.tooltip().format("\nPercent:{%Value}%");
Q6_Trend_AnyChart.background().fill("transparent");
var labelsx = Q6_Trend_AnyChart.yAxis().labels();
labelsx.fontSize(12);
labelsx.fontColor("#fff");
labelsx.useHtml(true);
labelsx.fontWeight(600);
var labels = Q6_Trend_AnyChart.xAxis().labels();
labels.enabled(false);
series_1.markers(true);
Q6_Trend_AnyChart.legend()
.enabled(false)
.fontSize(13)
.padding([0, 0, 10, 0]);
// set container id for the chart
Q6_Trend_AnyChart.container(id);
// initiate chart drawing
Q6_Trend_AnyChart.draw();
});
}
if I increase the top padding from 15px to 45px in the given code, it results this; but still the line is not displaying perfectly
enter image description here
The scale max means the top edge of the data plot. When the yScale maximum is auto-calculated chart adds a gap as a default. This allows avoiding this issue.
But the default gap is dropped if the yScale maximum applied manually.
In this case, to add some gap you should increase the scale maximum value. Also, you can define required ticks manually too. For details, check the sample.
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 page that dynamically loads a google timeline chart onto a div. The timeline increases in height as you add items on to it. If the chart is smaller than the div, it will be visible with empty space at the bottom. If the chart is larger, it will show scrollbars on the side.
What I would like is for the container div to always show the full chart or, another way, I would like the container div height to dynamically match the height of the chart.
I have tried to approximate the average size of each chart line and then adjust the div height when I load the chart with:
$("#gantt_chart").height(data['num_contents']*46);
But, although that somehow works, it's far from perfect because the approximation on height starts to accumulate with each additional line and the empty space at the bottom of the div increases which is not an elegant solution at all.
How would I ensure that the container div always shows the full chart?
I hope this is clear enough.
Many thanks.
The chart determines its height by either checking the height option passed into the draw call, or by checking the container height if the height option is not specified. I would suggest using the option instead of changing the div height via jQuery. I find the best method for dynamically calculating the chart height is to take the height of a row (typically 41px) times the number of rows, plus some padding for the top and bottom:
var height = data.getNumberOfRows() * 41 + 30;
Though in the doc they have shown to adjust height of div from where we are specifying the id of timeline but I recommend you to have set the height from the internal method.
// set the height for padding(padding height)
var pH = 40;
// get total height of rows (row height)
var rH = dataTable.getNumberOfRows() * 15;
// total chart height (chart height)
var cH = rH + pH;
// Now set this chart height to the timeline via option object
// apart from height, other attributes are just optional
var options = {
height: chartHeight,
colors: ['#339900', '#e6e600', '#B00000'],
tooltip: {
isHtml: true
},
timeline: {
colorByRowLabel: false
},
avoidOverlappingGridLines: true
};
Been trying to do the same thing myself. The top answer wasn’t exactly right and caused an inner scroll bar to appear at times.
Here’s what worked for me:
var barLabelFontSize = 12; //default font size for bar labels
try{barLabelFontSize = options.timeline.barLabelStyle.fontSize; //bar height is dependent on the bar label's font size that you set...
}catch(e){}
var barHeight = barLabelFontSize * 1.196; //found in google api as: this.PU = 1.916 * this.UF.fontSize;
var barMargin = barLabelFontSize * 0.75; //found in google api as: this.Rfa = .75 * this.UF.fontSize;
var rowHeight = barHeight + barMargin * 2; //found in google api as: b.height = 2 * this.Rfa + this.PU (+additional complication for grouped bars, if anyone wants to try work that out it was: b.height = 2 * this.Rfa + this.PU * a.SI.length + this.Qfa * (a.SI.length - 1); (where Qfa is 0.583 * font size, and a.SI.length is the number of grouped bars displayed on the row)
var chartAreaHeight = rowHeight * dataTable.getNumberOfRows();
var axisHeight = 24; //worked out by querying: document.getElementById('timelineChart') getElementsByTagName('svg')[0].getBBox().height;
var whiteSpaceHeight = 28; //trail-and-error to find how much whitespace was required to stop a scroll bar appearing, 27 works too, but I rounded up to play it safe
var chartHeight = chartAreaHeight + axisHeight + whiteSpaceHeight;
You can also reverse engineer this to set the height of the bars using the bar label font size.
Here, I have used line chart from nvd3. I am trying to fix a few issues with this chart
1. This is an interactive chart, but even if i hover over a point where there are no points from the data, it still shows up the x and y-points.
2. x-axis and y-axis lines do NOT show up. Also the interactive guide doesn't come up in a rectangular box outlined.
3. The x-axis gets cut off at the end (see 14:29:19 being cut off at the end) no matter how much i increase the width to.
4. I am trying to remove the fill that we see above the line graph but styling changes made by me resulted in no success.
code that i use to fetch the line chart
var redraw = function(testData) {
var dataT = [{
key : 'Character Count',
values : testData,
color : '#00AEEF',
area : false
}];
var margin = {
top : 80,
right : 20,
bottom : 80,
left : 50
}, width = 1000 - (margin.left + margin.right), height = 600 - (margin.top + margin.bottom), x = d3.time.scale().range([0, width]), y = d3.scale.linear().range([height, 0]);
x.domain(d3.extent(dataT[0].values, function(d) {
return d3.time.format('%X')(new Date(d.TimeStamp));
}));
y.domain([0, d3.max(dataT[0].values, function(d) {
return d.CharCount;
})]);
nv.addGraph(function() {
chart = nv.models.lineChart().transitionDuration(350).useInteractiveGuideline(true)
.showLegend(true).showYAxis(true).showXAxis(true).x(function(d) {
return new Date(d.TimeStamp);
}).y(function(d) {
return d.CharCount;
});
chart.xAxis.axisLabel('Time').tickFormat(function(d) {
return d3.time.format('%X')(new Date(d));
}).scale(x).orient("bottom");
chart.yAxis.axisLabel('Character Count').tickFormat(d3.format(',')).scale(y);
chart.lines.forceY([0]);
d3.select('#chart2 svg')//.append("g")
.datum(dataT).attr('height', height).attr('width', width).call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
};
redraw(data)--data fetched froma service ith dateTimeStamp in x-axis and integer in y-axis points.
Please help!
This is an interactive chart, but even if i hover over a point where there are no points from the data, it still shows up the x and
y-points. 2. x-axis and y-axis lines do NOT show up. Also the
interactive guide doesn't come up in a rectangular box outlined.
Adding corresponding javascript file in nvd3 zip file should solve the problem(line.js, linechart.js and corresponding css file)
3.The x-axis gets cut off at the end (see 14:29:19 being cut off at the end) no matter how much i increase the width to.
This is because you have not set the width and height of the chart in your codes to generate the chart
you should do
chart.width(width).height(height)
4.I am trying to remove the fill that we see above the line graph but styling changes made by me resulted in no success
This I am not sure how to solve as I do not have your dataset, so I not able to reproduce the problem
Here is my test code