chart.xAxis.tickFormat(function(d) {
...
}
Is it possible to get array of "d" variables which will be passed to this callbacks before it even executed? I need to analyze this array first to know which values to show on chart and which I should hide.
Or maybe I could correct this array and pass it to tickValues.
NVD3 doesn't expose the D3 method for getting tick values from a scale/axis, but overwrites it with its own method that doesn't set the tick values...
From the source code, it looks like you should be able to get the tick values that are set automatically with
chart.xAxis.scale()
.ticks(Math.abs(chart.xAxis.scale().range()[1] - chart.xAxis.scale().range()[0]) / 100)
Note that this will only work for horizontal axes (i.e. x axes like in your case).
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 want to draw a linear chart of currency rates. There are some days when there are no rates from the market (holidays). I would like to remove these days from the chart but without ugly gaps or straight lines between the days with rates.
You can see an example on this chart:
On 3rd of May there is no data, the chart is linked and the missing date is removed from the legend.
How do I get such effect using Chart.js?
I figured out a workaround. It requires some hacking but it works:
1) First, modify your dataset. Iterate over all your points and mutate x values so that they correspond to new position on your chart. Save the original x value in some property for future use (in tooltips)
2) Now you can draw the data on the chart and they look properly. The problem is with tooltips and ticks.
How to deal with the ticks:
The ticks are a list of mutated numbers (they don't correspond to their original values). You have utilize a hack. Temporarily overrite chartController.ticks in afterBuildTicks method with array of objects (instead of plain numbers) with original corresponding x values. You have to approximate original x value for every tick.
Having that you can use this information in ticks callback to return correct labels for ticks.
With such mutated data the chart won't plot. You have to revert it to the state before mutation. In the method afterTickToLabelConversion restore the ticks. Bear in mind that now they are stored in property ticksAsNumbers
The similar hack should be done with tooltips callbacks. You have access to the dataset and utated x value. Approximate original x value for mutated x and that's it.
You can use the spanGap attribute. From the documentation:
If [spanGaps is set to] true, lines will be drawn between points
with no or null data. If false, points with NaN data will create a
break in the line
I will try to explain my problem as much accurate as possible. I am looking for a javascript chart library filling the two following conditions:
From an ajax request retrieving time series,
display dynamically data when changing the time window.
such as it is perfectly done on highstocks: http://www.highcharts.com/stock/demo/basic-line
And
plot an horizontal line corresponding to the mean,
changing when the user update the time window on the chart.
Actually it is possible to display an horizontal line. But they are fixed on the whole data and do not change accordingly when the time window is modified:
http://www.highcharts.com/stock/demo/yaxis-plotlines
I am quite new to the topic and would like to know if it'sp ossible to modify Highstock classes to have such a result. Or maybe some other js libraries exists?
Using a combination of the answer here:
Highchart, get total of visible series data after setExtremes
And an example of dynamic average using all visible series that I made for a previous question, here:
http://jsfiddle.net/jlbriggs/gweuLegq/
I put together this example, using the afterSetExtremes event, like this:
xAxis : {
events:{
afterSetExtremes:function() {
var ext = this.getExtremes();
getAverage(this.chart, ext.min, ext.max, show, width, avgColor, dashStyle);
}
}
},
Working example here:
http://jsfiddle.net/jlbriggs/c93543yL/
The idea is:
1) capture the afterSetExtremes event
2) get the resulting axis min and max
3) loop through the series data
4) if a point is between the min and max, increment the count, and add the
point's y value to the sum
5) calculate the average accordingly, check for existence of average series, if exists, update, if not, add
It could as easily use a plot line that you add/remove as needed instead of a series, but I like having it as a series so that it has a legend entry.
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
While generating a track with the help of dygraph library, I have set the legend: always (this display the legend with series name present on that particular track even without mouseover). But when I move to certain graph, the legend changes and shows the value of each series at that particular mouse pointer. I don't want the legend to change and it should just show the series name and not the values. I am using javascript to implement my app. Any way to do the same?
One trick that might be good enough is to supply a custom valueFormatter function for each axis which simply returns an empty string:
axes: {x: {valueFormatter: function (x) {return ''}},
y: {valueFormatter: function (y) {return ''}},
y2: {valueFormatter: function (y2) {return ''}}
}
This prevents the values from being shown, but still switches between line samples and ':' characters depending on the position of the mouse.
At the moment there's no easy way to do this. Your best bets are to either generate the legend yourself using dygraphs' API or to throw a transparent div over your chart which captures all the mouse events.
Well! it might be not a good way but I have found an alternative to do it. Declared a new boolean variable in dygraph.js which checks whether user wish to see x-y values on legend. Using this variable in function generateLegendHTML (defined in legend.js), i have made the control to always go in the first if loop. This makes the dygraph to always show static legend.
You can do the following -
Step 0 - Add a few necessary options and tags -
labelsDiv: document.getElementById("labels"),// in the dygraph options
<div id="labels"></div> <!-- Add this somewhere in your HTML-->
Step 1 - Declare a variable -
var defaultLabelHTML = undefined;
Step 2 - Use drawCallback option -
drawCallback: function(dygraph, is_initial){
if (is_initial)
{
defaultLabelHTML = document.getElementById("labels").innerHTML;
}
},
Step 3 - Use highlightCallback option -
function(e, x, pts, row)
{
document.getElementById("labels").innerHTML = defaultLabelHTML;
}