Is there any way of showing a 1:1 diagonal line in Highcharts? I am looking for a line which X and Y values always match.
I know how to render a line in Highcharts using the renderer, however, I don't want an independent line but one that reacts to the chart resizing/zooming. A series with [(0,0),(1,1)] is not really an option (it would affect zooming).
Something like this except x and y axis might vary their value due to zooming.
You can do it by detecting the setExtremes() event on you axes, and fire a function to get the axis extremes and draw a line.
(or, in this case, I used the afterSetExtremes() function)
In my example I did it by using a line series. I assume you can adapt it to use the renderer since you've already used the renderer to draw the line initially.
function redrawLine(chart) {
var xExt = chart.xAxis[0].getExtremes();
var yExt = chart.yAxis[0].getExtremes();
chart.series[1].setData([
{'x':xExt.min,'y':yExt.min},
{'x':xExt.max,'y':yExt.max}
]);
}
Example:
http://jsfiddle.net/jlbriggs/feLdzpux/
Of course, if your intent is to compare observed values to predicted values, then re-drawing the line when you zoom in is counter productive and misleading - the line should not move based on the zoom level - it should always be constant.
Related
Suppose I have a linechart with multiple lines (the number is dynamic) and I would need to always scale the Y so that all lines are shown - so the scale should always be based on the range with highest values. Is there a way how to it automatically? I found some example with automatic yScaling using d3.max but that is done for a known dataset. In my case, I do not know what range will be the one to use.
I am using NVD3 (a wrapper of d3) to draw a line graph. I want the data in the graph to be within the range of the axis. However, it looks inconsistent with the other labels, as the chart displays the max value of my data set on its own. See screenshot:
In this exanple, 18,554.41 is my highest data point. What I would like to see is the ticks/axis-lables to be in the same order of rounding throughout, with no overflow. i.e. 20,000,18000,16000 etc.
The caveat is that my dataset can vary quite differently - so I can't just set a max. Is there a way of just increasing the tick count by one or something?
Current relevant code:
var chart = nv.models.lineChart()
.showYAxis(true)
.forceY([0]);
chart.yAxis
.axisLabel('£')
.tickFormat(d3.format(','))
.ticks(8);
EDIT: added https://jsfiddle.net/60equ79h/2/
on the fiddle, I would like the first data set's topmost label to be 10,000. the second would be 80. i.e I would like to the y-axis to be increased by one tick
If I understand your question correctly, you can force the yAxis to have the values you define. You can hard code the values or write something clever to identify the min & max for your yAxis.
Update your chart to have the following:
chart.forceY([0, 20000]); // [min, max]
Hope it helps
I'm using d3.js v4.
Is there a more convenient way to find the minimum and maximum values of a brush selection. This is meant to resize the y axis when I select a period in my brush area below.
Here is my method (everything is inside my function called when the brush is used) :
I find the extent limits of my selection
extent = d3.event.selection.map(chartComponent.x2().invert))
Then I have to redo an array containing all my selected points: I go on each point and compare it to the extent[0] or extent[1] to see if it is in the limits. I store the beginning and end point indices and then I use data.slice(begin, end) on my original data to get a new array.
Then apply d3.min and d3.max on the new array to find the min and the max level.
Then set the y axis to use theses limits.
chart.y().domain([chartComponent.ymin, chartComponent.ymax]);
chart.yaxisGraph.call(chartComponent.yAxis(true));
Do someone have a better idea ?
I'm using Highstock (v4.2.3) to present data in a StockChart with a number of different Y axes, all plotted against time on the X axis. The data has gaps in it, and I'd like to depict those gaps, but when I turn on gapSize (with any value other than zero), there's a weird quirk that causes line rendering issues--when using the navigator to zoom in on certain date ranges (not all), in some cases (whose pattern I've yet to discern) the chart fails to fully render the line across the entire x axis.
This annotated screenshot depicts the issue.
When I turn gapSize off (or explicitly set it to zero), this problem goes away. Note that the gaps themselves appear correctly on the chart (when navigating to a date range that doesn't present the line rendering issue).
plotOptions: {
series: {gapSize:2}
}
Any ideas?
jsFiddle with your issue:
http://jsfiddle.net/2N52H/109/
As you can read in our API:
http://api.highcharts.com/highstock#plotOptions.line.gapSize
A gap size of 5 means that if the distance between two points is
greater than five times that of the two closest points, the graph will
be broken
As far as I know data you have has random gaps so you will never know what is the distance between two closest points. For example if you will have data in every one hour, distance between two closest points will be 15 minutes and your gapSize will be set to 2, you will see only your closest points.
When you are using zoom sometimes your visible data closest distance is changing so the gaps are changing as well.
See this example:
http://jsfiddle.net/2N52H/111/
Maybe you can use xAxis.ordinal parameter to visualise your gaps:
http://api.highcharts.com/highstock#xAxis.ordinal
You can also change standard functionallity by using wrapper. Here you can read about it:
http://www.highcharts.com/docs/extending-highcharts/extending-highcharts
For example you can change gappedPath function:
(function(H) {
H.wrap(H.Series.prototype, 'gappedPath', function(proceed) {
var gapSize = this.options.gapSize,
xAxis = this.xAxis,
points = this.points.slice(),
i = points.length - 1;
if (gapSize && i > 0) { // #5008
// extension for ordinal breaks
while (i--) {
if (points[i + 1].x - points[i].x > gapSize) {
points.splice( // insert after this one
i + 1,
0, {
isNull: true
}
);
}
}
}
return this.getGraphPath(points);
})
}(Highcharts))
example:
http://jsfiddle.net/2N52H/113/
Kind regards.
When I apply a dimension filter to a dc.js graph, there are ugly lines where the line plummets
towards the y axis.
Is it possible in dc/d3 to not do this, i.e I would expect the graph to more resemble the following;
You can call defined directly on the dc created chart.
chart
.chart((c) ->
dc.lineChart(c)
.interpolate('linear')
.defined((d) ->
return !isNaN(d.y)
)
)
The condition !isNan(d.y) can be anything you like that evaluates to true/false.
Note that the d passed by defined is a d3 object and is worth inspecting.
Two possible solutions, depending whether you want the line connected or in sections:
Pre-filter the data so that instead of having groups that sum to zero, there aren't groups there at all. This will connect the points with a line segment over the missing data. https://github.com/dc-js/dc.js/wiki/FAQ#filter-the-data-before-its-charted
Use lineChart.defined to put gaps/breaks in the line where there is no data. https://github.com/dc-js/dc.js/blob/master/web/docs/api-latest.md#definedvalue