What I would like to do is plot a single series with two y-axes "locked" to the same data -- for instance, °F and °C temperatures (or feet and meters, etc.) that could be read off either axis, but only one set of points would be plotted.
Things I have tried:
1) Create two series, the second with the converted values, and plot on "on top" of the other (in this case, there's a constant conversion value of 1.51):
date,unit1,converted_unit2
2012-03-19,1.598333,3.108333
2012-03-20,1.542083,3.052083
2012-03-21,1.483333,2.993333
Generally works; however, Dygraphs dynamically scales both y-axes independently to be "pretty", and so the two series don't always plot directly on top of each other.
2) Set visibility of the second series to FALSE:
series: { 'converted_unit2': { axis: 'y2' } },
visibility: [true, false]
Doesn't work: Dygraphs defaults to scaling secondary y-axis for invisible series to 0-to-1.
3) OK, keep them both visible, but set the second series to transparent:
series: { 'converted_unit2': { axis: 'y2' } },
colors: ['#000080','rgba(0,0,0,0)']
This almost works -- however it has the side effect that the label for the second series in the dynamic legend is now transparent. And, since the axes are still being independently calculated to be "pretty", they are not exactly aligned -- the secondary y-axis is potentially a few percentage off the first y-axis.
(I also tried setting the second series visibility to FALSE and manually setting the second y-asix using the values obtained from yAxisRange(), which works well, but the second y-axis doesn't respond correctly to zooming the graph.)
Is there a way to easily create two y-axes for a single series which are "locked" together?
Thanks,
-bryan
same problem here ;)
we used to add a second (dependent) axis by using a single data point in a second series (which allowed a second axis) and fixed axis ranges for both axes (the second range calculated from the first range). Second color was set to transparent, second label was hidden ... worked fine until we had to switch to dynamically scaled axis ...
the second series in the dynamic legend is now transparent
hm, you can change this with css (as it's an inline style, you'll have to use !important to override it) or js (remove the inline style or change it).
Yes, an option for a second (dependent) axis would be great!
Jean
Set the stroke width of the second series to 0:
series: {
converted_unit2: {
axis: 'y2',
strokeWidth: 0
},
}
Related
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:
In my highstock charts i required label on the left side of the graphs. When i used opposite: false + align: left for labels they are positioned above graph. But i want to start graph rendering after labels ends.
Left side labels without required graph render
I saw solution for my problem in Highcharts not in highstock some time before. But now i cant find it to show what exactly i need
Expected result
Thanks in advance
OK, so you want the labels inside the plot area.
You can do this by adding
labels: {
align: 'left',
x: 0
}
to your yAxis properties.
This moves the starting point of the labels to the axis line, and extends the labels to the right from that point. If you want them pushed further inside, just increase x.
The problem that you'll run into is that the plot will not respect the label placement - your line will still start at the same point, as if the labels weren't there.
Normally, you could just use the minPadding setting on the xAxis to increase the space for the labels, but this doesn't work in the case of the navigator, as explained here:
http://api.highcharts.com/highstock/xAxis.minPadding
When the axis' min option is set or a min extreme is set using axis.setExtremes(), the minPadding will be ignored
I am sure there is some work around for this problem, but I do not have the solution currently.
Updated fiddle:
http://jsfiddle.net/d6mre68v/
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 have a Highcharts datetime column chart, with several series that which are added and updated dynamically. It appears that the library is producing the chart with a large chunk of space before the first column and after the last column. It's as if the columns are grouped into the center of the chart, while they should be arranged evenly across the space. I have tried adjusting the minPadding and maxPadding of the axis options with no success:
xAxis: {
type: 'datetime',
minPadding: 0,
maxPadding: 0,
labels:{
formatter:function () {
return Highcharts.dateFormat('%b %e', this.value);
}
}
},
Here is an example adapted from the Highcharts demo page which is behaving correctly:
http://jsfiddle.net/ricksuggs/8Gt2y/
While this example which is written by myself, is showing the extra padding:
http://jsfiddle.net/ricksuggs/PRKAJ/36/
Thank you.
You can modify pointWidth and groupPadding/pointPadding parameter
http://jsfiddle.net/PRKAJ/37/
EDIT: You should define pointRange
http://jsfiddle.net/PRKAJ/41/
http://api.highcharts.com/highcharts#plotOptions.series.pointRange
From what I'm seeing, example http://jsfiddle.net/ricksuggs/PRKAJ/36/ is showing to me without extra padding; unlike on the screenshot by #ricksuggs above, where there is extra padding.
I believe the "problem" lies within multiple series with single data points vs. a single series with multiple data points.
With multiple series (=sets) with single data point in each set, columns are grouped together, expecting another grouped data points from another set, thus creating the padding. However, with a single set containing multiple data points, those are distributed evenly creating no additional padding.
To answer your question, I believe that's why there is extra spacing. However, I could not find a way how to get rid of it as grouping multiple series into single set with multiple data points has other limitations (hiding series in legend, coloring, ...).
I was wondering if there is a way to prevent Highcharts from recalculating and redrawing the scale of the Axis when I add a new serie.
What I need to do is the following: I have a scatter chart with a lot of data; when the user selects a point, I add a new series with a "line" type. This series' points are a limited sample from the previous ones, so no "real" new points are added, but the scale of the xAxis changes.
Setting xAxis' min and max value, startOnTick and endOnTick to true did not solve the problem. Any idea?
Edit:
As I wrote, the way Highcharts handles axis' scales is still a mistery to me. In my case, I was rendering one scatter and one column graph on the same canvas. In response to a user click, I was adding 2 new series: a line serie and a column serie each one based on a subset of the original data. The problem was caused by the column graph: when you add a new serie to a column graph, bars are not overlapped, but redistributed, thus creating the scale change effect.
Try to create the line series but hidden, and when you want to show it use chart.series[1].show().