For a statistics/monitoring tool we use google charts graphs to show messages and errors from an application. Those messages are shown in labels of a graphics on the vertical axis but most of the times the messagetexts are too long, having too much characters to be fit in the label. They get shortcutted by ... in the end but what we actually want is that they are wordwrapped or if that is not possible, manually linebreaked with html br tags. Too bad, those are just ignored by the google chart labels.
My question is, is there a way to break the messagetexts over multiple lines instead of getting shortcutted with ... at the end? If so, how can this be done? I already found the possibility for this for the horizontal axis here, but we want it to have it for the vertical axis. If it is possible of course.
I also tried to make a fiddler example but it seems fiddler can't handle google graphs that well. When I made the text as long as in our tool, the whole graphics just disappeared.
The text labels for tick values of axes, both horizontal and vertical, cannot currently be wrapped across multiple lines. The best you can do is arrange that there is more space for the labels by using a combination of the width and chartArea: { width and left } options, for the vertical axis, or height and chartArea: { height and top } options.
Here is a jsfiddle that demonstrates this: http://jsfiddle.net/dlaliberte/cNRn3/ with a bar chart. The key option is this:
chartArea: { left: 300 }
I tried to decrease the font size and it worked for me. adjust font size according to your need, making font small will make it automatically multi-line
<Chart
chartType='ColumnChart'
width="100%"
height="800px"
data={this.state.graphData}
options={{
fontSize: 11
}}
/>
Related
To get labels on Chart.js Pie and Doughnut charts, there are plugins to do so, like: chartjs-plugin-labels but after doing so I noticed a big problem for my UI design:
The size of the actual chart shrinks so that the labels fit within the canvas. It makes sense that the labels need to be able to fit within the canvas they're rendered on, and thus the shrinking of the chart. But sometimes I may use labels, and other times not, and I need my pie charts to render the same size regardless.
Is there a solution in the settings of either Chart.js (the label plugin I'm using is compatible with < 3.0, I'm using 2.9) or chartjs-plugin-labels to maintain consistent chart size, regardless of whether labels are applied?
I tried applying an empty label to every chart, but the size of the chart actually shrinks based on the specific size of the labels being rendered, so aside from being a hacky solution, it doesn't consistently solve the uniformity problem.
For example maybe a way to make charts start off taking 50% of the canvas?
Yes, this is fairly simple actually. The chartjs-plugin-labels.js file contains several lines which force the chart to become smaller when the label settings set the position to either "border" or "outside". Download the script to your own server, comment out the lines below, and everything should work as expected. CodePen demo
Comment/remove these lines:
if (this.options.position === 'border') {
offset = (lines.length - 1) * this.options.fontSize / 2;
}
if (label.options.position === 'outside') {
someOutside = true;
var padding = label.options.fontSize * 1.5 + label.options.outsidePadding;
if (padding > maxPadding) {
maxPadding = padding;
}
}
Here is the updated JS file you can use: https://pastebin.com/raw/gSffqqKu
Just download it as chartjs-plugin-labels.js and use it in your project instead of the original plugin file.
I am developing an application which allows a user to select dynamically queried data which can then be used in Recharts visualizations. There are certain edge cases where the default formatting / rendering within recharts produces an ugly result. For example, if there are many unique values passed to the <XAxis /> component then the chart produced will likely have overlapping text for the ticks.
There does not seem to be any good "render as many ticks as possible, without overlapping" option described in the documentation. These appear to be the only options:
Render all ticks (obviously leads to too many ticks)
<XAxis
dataKey={xAxisField.name}
name={getXAxisLabel(xAxisField, chartType)}
tickFormatter={
getMetaDataType(xAxisField) ===
"DATE"
? tickEpochFormatter // force numbers to be displayed as 'YYYY-MM-DD'
: tickNumberFormatter
}
allowDataOverflow={false}
ticks={xValues.sort()} // gets all of the values
interval={0} // display all of values, instead of the default 5
angle={-90} // force text to be 90, reading towards the graph
textAnchor="end" // rather than setting "dy={50}" or something
>
Render only the start / end / start & end, which depends (seemingly) entirely on the width of the text, prior to rotation.
<XAxis
dataKey={xAxisField.name}
name={getXAxisLabel(xAxisField, chartType)}
tickFormatter={
getMetaDataType(xAxisField) ===
"DATE"
? tickEpochFormatter // force numbers to be displayed as 'YYYY-MM-DD'
: tickNumberFormatter
}
allowDataOverflow={false}
ticks={xValues.sort()} // gets all of the values
interval="preserveStart" // ensure that everything can be read, giving preference to the "left"???
angle={-90} // force text to be 90, reading towards the graph
textAnchor="end" // rather than setting "dy={50}" or something
>
Hardcode the number of intervals to ensure a maximum? I'm not sure if this is a viable option since I would need to know how many ticks are truly overlapping. Just seems like a crude approach.
Is it even possible to have Recharts render as many things as possible, even if they are rotated 90 degrees, and then selectively choose what has enough space to display? Is it possible to have the angle property dynamically update based on the length of the tick mark texts?
Here is a list of links, none of which seems to answer these questions:
Recharts Docs
Recharts XAxis Docs
Recharts LineChartAxisInterval Docs
Github Recharts repo
Show all ticks
Vertical Axis Label
Rotated Axis Labels
Rotate tick text
Axis Labels Display Over Data
Axis Labels Look Awful
Last XAxis label not aligned with tick mark when rotated -45 degrees
Prevent hiding of tick labels
Missing ticks on x-axis
Long strings in labels generate overlap in YAxis for horizontal barchart
StackOverflow Posts
Scalable YAxis Label
Display all XAxis ticks
YAxis Ticks don't auto calculate
Set Label Margin
Here's a picture of the problematic rendering I want to clean up:
Also, please note that normally I would prefer to stick to the same library that I have been using, but if another library is better suited for this use-case, I would like to consider switching!
I had the same problem, ended up removing the interval property which set the ticks to be sort-of-dynamic but had only 4 or 5 ticks.
So I set the minTickGap to some negative value. the result was that more ticks appeared on the axis
<XAxis dataKey="date"
angle={45}
dx={15}
dy={20}
minTickGap={-200}
axisLine={false}/>
before
after:
I've been playing around with a highcharts bar chart and noticed some strange behavior. If I have a long name in the x axis (the categories), and if I have labels enabled to show up on the bars, not all the labels will appear. If I remove the long x axis name, then the label that wasn't appearing on the bar before will suddenly appear. I have a working Jsfiddle example here:
https://jsfiddle.net/p55t0bmf/ (notice label isn't appearing for one of the bars, should say 5 but nothing is there)
I placed a long name in the categories section to trigger this behavior:
xAxis: {
categories: ["LONG NAME THAT WILL BREAK US"]
}
Does anyone know why this would be happening, and is there a way to fix this behavior (without resorting to short x axis names of course)?
Set allowOverlap to true. When you have longer xAxis labels, then you have less horizontal space. Labels have padding which can overlap and hide some of them. Anyway, your demo works for me exactly the same way with or without long xAxis category.
Demo with all labels: https://jsfiddle.net/p55t0bmf/1/
stacking option cause this problem. If you set the stacking, then highchart change the label opacity automatically.
Solution : Remove stacking options from chart, if you dont need or write css to override label opacity.
I'm attempting to use a highcharts in conjunction with Bootstrap. The pie chart is placed inside a column of 6 for example, so it takes up half the page. What has been happening is the datalabels are too long and so are being cropped out of the containing div.
A fix that has been proposed for this is to set a width on the datalabels.
like so:
pie: {
size: '60%',
allowPointSelect: true,
dataLabels: {
style:{
width:100
color:'black'
}
}
}
}
This works flawlessly for Chrome and mozilla, the width is set and the position of the datalabel changes so its all drawn closer to the pie chart. But when testing in IE8, (and I have to account for it unfortunately) the width is set, but it appears that the position of the datalabel is not changing, so I get even less of the data label visible on the screen.
I'll try get a jsfiddle or a screenshot up shortly so you can see what I mean, but initially I was just seeing if anyone had come across this issue before, or if there's a simple fix I am just missing.
Jsfiddle
I've commented out the width in the plot options so you can see what's happening.
When I uncomment the width, it renders perfectly in Chrome and mozilla. But in IE8, the position of the label doesn't change, so the left labels end up far away from the pie chart and still cropped.
Here is the set up using google charts api:
<div id="dashboard">
<div id="columnchart1" />
<div id="linechart" />
<div id="columnchart2" />
<div id="chartrangefiltercontrol" />
</div>
All charts and the control use the same datatable and are managed with the wrapper classes and the horizontal axis are time (dates). The data needs to line up vertically so the data point on linechart at 1 Jan 2014 must line up with the data points on columnchart1 and columnchart2 for 1 Jan 2014. But they do not.
Attempted to fix the problem by setting the 3 charts options.hAxis.viewWindow.(min, max) values to the same for each chart, but that posed a different problem: the rangefiltercontrol would not zoom the charts (it would still pan side to side).
How do you make the charts scales the same and zoom with the control?
Thank you in advance.
The axis values will not align precisely because ColumnCharts add padding on the left and right of the axis end points to account for the width of the column groups. This padding varies in size and is largely unpredictable, so you have to wait for the charts to render, get the axis ranges, set options appropriately for each chart, and redraw. I would suggest reducing your dashboard to controlling a single chart from the ChartRangeFilter, and using a "ready" event handler on that chart to set the data for the other charts and redraw them. This dramatically cuts down on the inter-chart event coordination that would otherwise be necessary (this does not completely eliminate coordination, but it does reduce the amount you have to do).
If you would be so kind as to update your question with your chart code and sample data, I will flesh out my answer with specifics on how you can achieve this.