Recharts X-Axis auto not showing most values in ticks for times? - recharts

I've just converted my project from using react vis over to recharts. I'm currently looking into why the ticks aren't showing as expected. There are 96 datapoints that should be showing up and the cartesian grid shows them, but no tick labels appear other than the few at weird times not aligned to the datapoints I provide. (The tick marks should be at a 30 minute interval.)
Is there a way to have the ticks show up just where I specify them in the data?
This is what I currently have (I thought "interval" was supposed to make all the ticks appear). I have the time specified as milliseconds and then format them, which seems to work for the most part.
<LineChart data={datapoints}>
<XAxis dataKey="x"
domain = {['auto', 'auto']}
name = 'Time'
tickFormatter = {(unixTime) => moment(unixTime).format('HH:mm')}
interval={0}
type = 'number'/>
<YAxis />
<CartesianGrid/>
<Tooltip/>
<Legend/>
{this.props.yLines.map(lineKey => {
return <Line dot={false} type="monotone" dataKey={lineKey} isAnimationActive={false}/>
})}
</LineChart>
And this is what is showing up:
Vs what I would expect (all intervals showing)
Update: I have since added tickCount={96} (like I had with react-vis) but the times are still at weird increments. Like 6:33, 8:20, etc. instead of 30 minute increments.
Any help would be appreciated!

You can use interval={0} in your XAxis. It will show all tick

Use scale="time" in your XAxis.

Related

Recharts - How to preserve edge value of Y-Axis?

I have a chart with proper display of data, but my Y-Axis is linear (should be) and it crops data (see screenshot).
I expect Y-Axis to show linear data AND respect the edge (max) value of the chart.
I was trying to work with d3-scale but I failed - don't know how to "append" max value to the scale. The only way I figured is to manually calculate all the ticks which I'd like to avoid.
My Y-Axis code is
<YAxis
domain={[data.yAxis.min, data.yAxis.max]}
scale="linear"
tickFormatter={formatEnergyAxis}
/>
Where min is 0 and max is 3200 (unit conversion happens in formatters).
Is there a way to adjust the scale?
If possible, call the function .nice() inside YAxis. Otherwise, call it before passing the values to the binding:
d3.scaleLinear().domain([0, 3200]).nice().domain()
// [0, 3500]
That would be
<YAxis
domain={d3.domain([data.yAxis.min, data.yAxis.max]).nice().domain()}
scale="linear"
tickFormatter={formatEnergyAxis}
/>
On your Y-Axis, you can specify your last tick to be visible with the props interval set to preserveEnd, like this:
<YAxis
domain={[data.yAxis.min, data.yAxis.max]}
scale="linear"
tickFormatter={formatEnergyAxis}
interval="preserveEnd"
/>
You can also use the value preserveStartEnd to be have the root & edge values visible.

DC.js Choropleth filtering Issue

I am trying to filter data on my choropleth chart from a bargraph. Strange thing is that it is not showing correct value on selecting a bar from the accompanying bar chart.
Here is the jsfiddle: https://jsfiddle.net/anmolkoul/jk8LammL/
The script code begins from line 4794
If i select WIN004 from the bar chart, it should highlight only five states and the tooltip should reflect the values for the data. Some states are highlighted for whom WIN004 does not exist.
I changed the properties of the choropleth from
.colors(d3.scale.quantize().range(["#F90D00", "#F63F00", "#F36F01", "#F09E01", "#EDCB02", "#DDEA03", "#ADE703", "#7EE404", "#50E104", "#24DE05", "#05DB11"]))
.colorDomain([-1, 1])
To
.colors(d3.scale.linear().range(["green", "white", "red"]))
.colorDomain([-2, 0, 2])
But i get a lot of white states where its hard to discern what has been highlighted. The tool tip for some white-ed-out states show -0.00 :/
Here is the fiddle http://jsfiddle.net/anmolkoul/jk8LammL/1/
So i guess either its a problem with my color range or how my data is getting parsed.
I would ideally like to specify the data ranges in the .colorDomain based on the top and bottom values of the riskIndicator dimension. My functions are not working though. Should i use d3.max or riskIndicator.top here?
EDIT:
I got the color domain dynamic by using the min and max values but still the graph is not performing as expected? Could this be an issue with the geochoropleth chart? I further took a working geochoropleth example and ported my data to it and even that gave me the same issue of representing data incorrectly. I thoughit could be a data problem but i validated using a couple of good BI tools and their map charts displayed data correctly.
Could this be an issue with the dc choropleth?
Thank you.
Anmol
This has the same root cause as the issue in this question:
Crossfilter showing negative numbers on dc.js with no negative numbers in the dataset
In short, floating point numbers don't always cancel out to zero when added and subtracted. This "fake group" will ensure they snap to zero when they get close:
function snap_to_zero(source_group) {
return {
all:function () {
return source_group.all().map(function(d) {
return {key: d.key,
value: (Math.abs(d.value)<1e-6) ? 0 : d.value};
});
}
};
}
Added it to the FAQ!

Line Plus Bar with Multi Bars?

I'm trying to make an chart using the default line plus bar chart, but I want to use two or more streams in the bars, is it possible?
Currently, when I try to do this, I got some trouble with the effects of the chart, and so I can't show properly the hover balloon of the bars, he always display the data of just one of the streams. But the main problem is the dates of x axis, displaying 1970's dates, when I remove the second stream of bars, the dates display well:
Anyone already tried to do this kind of chart successfully?
EDIT
Adding Fiddles:
Fiddle with two columns stream and messy dates
Fiddle with just one column stream and ok dates
I'm calling this kind of graph:
linePlusBarChart()
The problem with the dates is that your data contains timestamps (i.e. in seconds), but Javascript expects milliseconds. This is easily fixed by multiplying the values by 1000:
series.values = series.values.map(function (d) {
return {
x: d[0]*1000,
y: d[1]
}
});
The tooltip problem is actually a bug in NVD3 -- it's not meant to be used this way. The problem boils down to the mouseover handler assuming that the first item of the data is representative of what you want. You can fix this for your case by selecting the item by data point number modulo 2 (because there're two bars):
.on('mouseover', function(d,i) {
d3.select(this).classed('hover', true);
dispatch.elementMouseover({
point: d,
series: data[i%2],
pos: [x(getX(d,i)), y(getY(d,i))],
pointIndex: i,
seriesIndex: i%2,
e: d3.event
});
})
This will only work for exactly two bar series though. Updated jsfiddle with the modified NVD3 code here.

Flex Chart Sorting ColumnSeries Order

I am trying to create a BarChart that will display values within a ColumnSeries in an order dependant of there value.
So for instance, If I had a ColumnSeries in a BarChart , one showing profit, the other showing expenses, it will render correctly if the profit is more than the expenses because the expenses series is rendered on top.
However, if the expenses is more than profit, the profit will not be viewable as it will be rendered underneath expenses.
At this point I am going to try and include an image to display my problem...
OK it turns out that I am not allowed to display an image :(
The image did show that profit in February is 500 but the profit of 300 in January is hidden because the Expenses of 500 is displaying over it.
You can run the code below to create the example:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script><![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var expenses:ArrayCollection = new ArrayCollection([
{Month:"Jan", Profit:300, Expenses:500},
{Month:"Feb", Profit:500, Expenses:300}
]);
]]></mx:Script>
<mx:Panel title="Bar Chart">
<mx:BarChart id="myChart" dataProvider="{expenses}" showDataTips="true" type="overlaid" >
<mx:verticalAxis>
<mx:CategoryAxis dataProvider="{expenses}" categoryField="Month" />
</mx:verticalAxis>
<mx:series>
<mx:BarSeries yField="Month" xField="Profit" displayName="Profit" />
<mx:BarSeries yField="Month" xField="Expenses" displayName="Expenses" />
</mx:series>
</mx:BarChart>
<mx:Legend dataProvider="{myChart}"/>
</mx:Panel>
An obvious solution to this would be to make the BarChart type 'clustered' as both values will be seen, however my client requires the BarChart to be 'overlaid', so currently some smaller values are hidden.
I would expect that there is a way to sort the order of the BarSeries but I cant seem to find how and I would really appreciate someone's superior knowledge on charting. ;)

Viewing Part of a figure

I made a simulation of 10000 times and want to view part of simulation between 5000-5200. I am able to view it with the code below, but the x-axis says 0-250. I want the x-axis to display the exact figure of 5000-5200. Also there seems to be a small gap at the end of the figure as the axis runs up to 250 for some reason. I just want to view the figure in for this set time with the x-axis showing the exact labels and without the gap at the end.
Thanks
N=10000;%Number of simulation
P=0.02;
Q = zeros(N,1); %current value of queue
X=zeros(N,1);%simulation data
Ci=0;
L=0.9;
Bu=zeros(N,1);
Bs=30;
Bd1=50;
Bd2=270;
Ti=0;
for Ti=2:N
U=rand(1);
a=log10(U);
b=log10(1-P);
c=(a/b);
d=1+c;
X(Ti)=round(d);
Ci=Ci+1;
if X(Ti)< (L)*(Bs)
Bu(Ti)=Bs;
else if X(Ti) < (L)*(Bs+Bd1)
Bu(Ti)=Bs+Bd1;
else
Bu(Ti)=Bs+Bd1+Bd2;
end
end
Ti=Ti+1;
end
plot(X(5000:5200,1),'r');
set (gca,'ylim',[0 400]);
hold on;
plot(Bu(5000:5200,1),'b');
set (gca,'ylim',[0 400]);
hold off
Plot expects two inputs, the first depicting the horizontal axis and the second depicting the vertical axis. When you do not supply two inputs, then it computes the length of the single input (in this case that length is 5200-5000 = 200), and it just uses 1 through that length (1:200 in this case) as if it is the values for the horizontal axis variable.
I think you want to issue the command:
plot(5000:5200, X(5000:5200,1), 'r')
Often Matlab will adjust plot axes for better default views, so it's probably showing the axis out to the index 250 just by virtue of some default plotting convention. You can similarly use set(gca, 'xlim', [5000 5200]) if you wish.

Resources