When using Chart.js i cant find a way to evenly scale the Y axis. Overiding and using manual scaling( scaleOverride: true ) for every chart is not really an option since there are alot of them and they have different data. Some one have an idea how to fix the scaling of the data?
This is the scaling i want:
Sometimes the scaling gets uneven depending on the data.
You can set the options globally - this will apply to every chart instance. For instance
Chart.defaults.global.scaleOverride = true;
...
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 am using chart.js to try to create a timeline of events relative to current date.
The horizontal bar chart is close but would like to show only the tips of the bars eg as points which would pretty much be a horizontal line chart.
I have shown my horizontal bar chart along with a mock-up of what it would look like as horizontal line chart.
Is this possible with chart.js ?
You first need to know that every information that you can edit about the chart is stored in the variable containing your chart (called myChart usually, but my2Bar in your fiddle).
If you want to globally change the graph, you will need to edit attributes in myChart.config.options.
If you want to change a specific chart, you will need to edit attributes in myChart.config.data.
In this case, you need to change a specific chart (which is the horizontal bar).
If you happen to check the logs of your graph, and go very deep in the config, you will finally see that bars in your chart are drawn using attributes stored in myChart.config.data.datasets[0]._meta[0].data[n]._model (n being the nth rectangle drawn, top to bottom).
Some attributes you can find there :
base : The X position where the rectangle is starting to be drawn (0 in your xAxe for instance).
x : The rectangle is being drawn until this X position.
height : The height of the drawn rectangle.
and so on ...
To edit these values, you just need to loop in your different rectangles (the n in the above path).
But you just can't do it manually on the config of your variable. If you do this, it won't work since your chart is responsive (on resize, it will redraw the chart using the former options).
What you must use are Chart.js plugins.
Plugins let you handle all the events that are triggered while creating, updating, rendering your graph.
Then, in your beforeRender event (triggered after the initialisation, but before the drawing), you need to loop in your different rectangles to edit the values to affect how they will be drawn :
beforeRender: function(chart) {
for (var i = 0; i < chart.config.data.datasets[0]._meta[0].data.length; i++) {
// Change both `3` values to change the height & width of the point
chart.config.data.datasets[0]._meta[0].data[i]._model["base"] = chart.config.data.datasets[0]._meta[0].data[i]._model["x"] + 3;
chart.config.data.datasets[0]._meta[0].data[i]._model["height"] = 3;
}
}
Here is a jsFiddle with the final result.
Unfortunately, I wasn't able to make round dots, instead of squared ones.
Update :
I have also made another jsFiddle where all the dots are linked together which makes it look like it is a horizontal line chart (can be improved of course, but it is a good start).
What is the correct way to set the grid parameters for JSXGraph? According to here,
... [default] values have to be overwritten before the initialization of the JSXGraph board.
So, currently I'm trying the following:
JXG.Options.grid.strokeColor = "pink";
JXG.Options.grid.strokeWidth = 14.0;
board = JXG.JSXGraph.initBoard('box', {boundingbox: [-5,5,5,-5], axis: true});
which doesn't affect anything.
However, I can create a grid on existing board, but this draws underneath the existing grid for some reason. The board seems to ignore if initialize with grid: false as well, so I can't seem to work around it. Any ideas?
small update
I found that
JXG.JSXGraph.initBoard('box', {boundingbox: [-5,5,5,-5], axis: true, grid: true})
draws an additional grid on top of the grid drawn by the axis: true argument. However, the colors for the first grid drawn by the axis:true argument are coupled to the
JXG.Options.axis.ticks.strokeColor
parameter. For odd some reason, this parameter changes both the tick color and and the grid drawn by the axis (which is drawn even in the case of axis: true and grid: false). Here is an example of what I mean.
In JSXGraph there are two type of grid lines:
A grid object which can be displayed with grid:true and whose attributes can be set with JXG.Options.grid. The distance between two grid lines is set with JXG.Options.grid.gridX and JXG.Options.grid.gridY.
The ticks of an axis can stretch infinitely. This is the case for the major ticks of the default axis. One can set the pixel length of the minor and mayor ticks of an axis with
JXG.Options.axis.ticks.majorHeight = 20;
JXG.Options.axis.ticks.minorHeight = 10;
If these attributes have negative values the tick will stretch infinitely and thus will appear as grid line. The default value of JXG.Options.axis.ticks.majorHeight is -1. Minor ticks and major ticks will have the same color.
The lines of the (true) grid will always have the same distance in user coordinates, independent from the zoom level, while the infinite ticks lines will adapt to the zoom level.
If the user choose a high zoom level, the browser may freeze because of the many grid lines.
I've created a series of plots using the flot library, which are all displayed on a single page. Is there a way to update the X axis min and max options (options.xaxis.min, options.axis.max) values WITHOUT re-plotting the plots ($.plot('placeholder',data,options))?
I found this solution: http://osdir.com/ml/flot-graphs/2012-02/msg00064.html
Which suggests that the following line would do it, but it does not work for me - the plots visible min and max are not modified based on this call.
monitorGraph.getOptions().xaxis[0].max = xaxis.max;
Any tips on updating the graphs xaxis max and min values would be greatly appreciated!
EDIT: Solution Below
The following code will take an existing plot, update the range that is visible, and redraw it in a very light and efficient way.
plot.getOptions().xaxis[0].min = time.start;
plot.getOptions().xaxis[0].max = time.end;
plot.setupGrid();
plot.draw();
After you set the value of the yaxis max height, try
yourPlot.setupGrid();
Not sure if it'll be as smooth as you want but I think it does the trick.
You can also dynamically modify MIN/MAX parameters in axis options:
plot.getAxes().xaxis.options.min = 0;
plot.getAxes().xaxis.options.max = 999;
plot.setupGrid();
plot.draw();