I have a mix of a line chart and bar chart in D3. Though the y-axis(dates) mapped to 'usageDate' is incremental in nature, the resulting line graph seems to plot in the reverse direction.
Image
LineChart
The Line chart plots 'usageTrendDetails' on the X and usageDate on Y. Attaching a link with the code.
Clickhere
The line chart is plotting from left to right, however as highlighted in the image, it suddenly begins plotting from right to left and then goes back in the right direction. Any idea why this happening?
Sort your data before making the line:
data = data.sort(function(a,b){return a.date.getTime() - b.date.getTime();})
working code here
The data is sorted, the issue was with the way dates were being formatted after September. The logic for pre-pending a zero for months 0(Jan) to 8(Sep) wasn't handling Oct, Nov and Dec correctly, resulting in the months after September plotting backwards.
OLD CODE :
if(month<= 8){
month = "0"+(month+1);
}
NEW CODE : Handling Oct - Dec
if(month<= 8){
month = "0"+(month+1);
}else{
month = month + 1;
}
Here's the graph after the issue is fixed.
Click Here
Related
I've done this scatter with plotly express and added an animation. Also, I adjusted the scatter to make it appears as such as a bubble chart. All works great, except for one issue. When I press the button to start the graph animation and one bubble is 'reached' and 'overtaken' by another bubble, they cross each other. By itself, it doesn't create a wrong result, but it's an undesired effect. I've showed the situation in the gif reachable with this link:
https://github.com/TheHextech/start2impact/blob/master/Data_Science/Food_Project_DataVisualization_DataManipulation/normal_animation.gif
However, if I manually drag the spinbox of the animation this effect doesn't show up (check this other link to see the gif https://github.com/TheHextech/start2impact/blob/master/Data_Science/Food_Project_DataVisualization_DataManipulation/dragged_spinbox.gif).
Why does this happen? And how can I fix this problem avoiding the 'overtake' during the normal animation? I share here the entire code of the graph:
fig = px.scatter(
data_frame=chn_food_feed,
x='production',
y='item',
size='production',
size_max=80,
animation_frame='years',
color='element',
color_discrete_map={
'Feed':'brown',
'Food':'orange'},
hover_name='item',
hover_data=dict(
item = False,
element = False),
range_x=[chn_food_feed.production.min()-5000, chn_food_feed.production.max()+50000],
range_y=[-1, 5.5])
fig.update_layout(
title="Storyline of China's top 3 Food and Feed items produced in 2013",
title_x = 0.5,
title_y = 0.95,
title_xanchor='center',
title_yanchor='top',
legend_title_text='Elements',
xaxis = dict(title='Production (1000 tons)'),
yaxis = dict(title=None))
# Speed up the animation
fig.layout.updatemenus[0].buttons[0].args[1]['frame']['duration'] = 250
fig.layout.updatemenus[0].buttons[0].args[1]['transition']['duration'] = 250
fig.show(renderer='notebook_connected') # For VS Code visulization of animation
I am building a timeline chart - that will change its date scale at the top when the brush becomes small to the scope of 1 day -- but when it hits this mode -- the labels overlap and it looks messy until you get to a 12 hour spread.
What is the best way of cleaning this functionality up so it doesn't overlap. I thought about having 1 line that shows date -- and another line under it that shows the hours at that level.
https://jsfiddle.net/aLh9d51t/
var tFormat = '%Y-%m';
var tTick = 'timeMonth';
if (days < 40) {
tFormat = '%Y-%m-%d';
tTick = 'timeWeek';
}
if (days <= 7) {
tFormat = '%Y-%m-%d';
tTick = 'timeDay';
}
if (days <= 1) {
tFormat = '%Y-%m-%d %H%p';
tTick = 'timeHour';
}
First, you can hide redundant parts of date when possible: show years, months, days only if there are more than one visible. So you definitely do not need years and months when you show hours and minutes.
Just look how default d3 axis handles this (e.g. https://bl.ocks.org/mbostock/1166403).
Second, considering your chart has fixed width, you can fine-tune different formats for different zoom levels (you already do this in your code snippet).
Take a look at this example: http://bl.ocks.org/oluckyman/6199145
It has similar logic as in your code snippet:
https://gist.github.com/oluckyman/6199145#file-axisdaysview-js-L33-L58
But the decision which format to choose depends on chart width:
https://gist.github.com/oluckyman/6199145#file-axisdaysview-js-L72-L75
And third, if you restricted to long labels for some reason, you can rotate them to 30°-45°
Also this could be useful: https://bl.ocks.org/mbostock/4149176
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!
Good day all
I am having a bit of trouble. I have a graph that ranges from 2012 to 2015. I need my year to display at my origin once I zoom in. At this stage my the year only displays at the beginning of every year. It takes the place of January. Is it possible to do this?
chart3.addListener("zoomed", function(e) {
var date = $( ".chartdiv3 .amChartsPeriodSelector .amChartsInputField" )
.map(function() {
return $(this).val();
}).get();
$(this).html(date.join(' <i style="color: #F47C00;">to</i> '));
chart3.panels[0].titles[1].text = "period - " + date[0] + " to " + date[1];
chart3.panels[0].validateData();
});
chart3.write('chartdiv3');
Ok. So changing the labelFunction depending on zoom is pretty easy.
Just take a look at this fiddle. (I used this as template).
The other approach is not as easy as i thought. You can modify the labels when the zoomed event is fired, however i haven't found a way to get the year for the first label. (it's an amcharts object containing the svg but no date, just the plain text for the label)
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.