How to align the bar in stack chart in d3 js? - javascript

HI as i'm trying to align the horizontal stacked bar chart using d3.js.
Here i'm using d3.stack() method to generate the stacked bar. This works fine with set of data
dataset = [{
"goodRating": 12,
"avgRating": 12,
"badRating": 12,
}]
But when im trying to change the data to
dataset = [{
"goodRating": 2344412,
"avgRating": 23234434,
"badRating": 443333,
}]
This works but alignment doesn't fit into the chart width.
As i want to fit the bar chart inside the svg to 100%. Please check my fiddle
Can please suggest me what i have missed. Thank you

Try setting width and x of rect as percentage
attr('width', function(d) {
return (d[1] - d[0]) + '%';
})
.attr('x', function(d) {
return d[0] + '%';
})
Demo
https://jsfiddle.net/aswinkumar863/7bnmr9cd/

Related

How can I align Chart title with the bar dynamically?

How can I align Chart title with the bar in highcharts?
The bar length may vary because of the data, so I want my title to end where the bar is ending.
I want to implement something like this:
To adjust the title you can set tittle.attr in the events.redraw event. You need to remember that a bar chart is an inverted column chart and where you have an x-axis there will be a y-axis.
chart: {
events: {
render: function() {
let chart = this,
series = chart.series[0],
title = this.title,
point = series.points[0];
title.attr({
x: chart.plotTop + point.x,
y: chart.plotLeft + point.y
});
}
}
},
API References:
https://api.highcharts.com/highcharts/chart.events.render
https://api.highcharts.com/class-reference/Highcharts.SVGElement
Demo: https://jsfiddle.net/BlackLabel/ud45prLg/
I would suggest adding a padding-right: ##px as you havent provided any code to work with. try applying the method via inspect element and add the code into your css after with the right amount of "px" needed.

Center Highcharts tooltip in the middle of donut chart in a responsive way

In Highcharts, I know you can put your tooltip in a fixed position using:
tooltip: {
positioner: function () {
return { x: 50, y: 50 };
},
},
But how would I center it in the same way that margin: 0 auto would center it? I am trying to get the tooltip text to stay in the middle of a donut chart. The solution is probably something obvious but I have yet to figure out what it is. Thanks in advance!
You can make use of chart plotHeight and plotWidth to get access to current chart height and width and adjust the tooltip x and y accordingly as below:
positioner:function(){
return { x: chart.plotWidth/2, y: chart.plotHeight/2 };
}
A working demo here: https://angular-raebwk.stackblitz.io

Can't draw barchart using d3.js in React

I am trying to draw barchart with each bar next to its corresponding checkbox. I have several <div className="geneCountBar">s and I try to select all of them, append the data and then draw bars using the following function:
createBarChart = () => {
let datum = this.props.datum.map((geneObj) => {
return geneObj["values"].length;
});
d3.selectAll("div.geneCountBar")
.data(datum)
.enter()
.append("div")
.attr("class", "bar")
.attr('transform', 'rotate(-90)')
.style("height", function(d) {
var barHeight = d * 5;
return barHeight + "px";
});
}
I just took it from the most basic tutorial on barchart creation with d3:
http://alignedleft.com/tutorials/d3/making-a-bar-chart
Somehow after the function runs - I trigger it with the button when the DOM has already been rendered - no DOM manipulation happens at all. I checked datum and it is correct: just an array of several values. The number of elements in the datum corresponds to the number of the selected divs. I checked whether d3.selectAll(div.geneCountBar) actually selects the right elements and it is. The DOM looks like that:
To further clarify what I actually want to achieve. Here you can see checkboxes:
Next to each one of them I want to draw a bar which would represent the amount of each item present in the dataset.
What am I doing wrong here? Any suggestions will be greatly appreciated.
On this case you are not using svg. Need to Style your divs. Try this:
Remove Transform, style width intead heigh
Style background-color for div,
add & nbsp; to prevent colapse empty div
change
createBarChart = () => {
let datum = this.props.datum.map((geneObj) => {
return geneObj["values"].length;
});
d3.selectAll("div.geneCountBar")
.data(datum)
.enter()
.append("div")
.attr("class", "geneCountBar") // <----CHANGE class
.style("background-color","red")
.style("width", function(d) { return (d*5)+"px";})
.html(" ")
}
Every bar must look like this:
<div class="geneCountBar" style="backgroud-color:red;width:50px;"> </div>
Or, on CSS define .geneCountBar{background-color:red;}
<div class="geneCountBar" style="width:50px;"> </div>
I've not access to your rig. Here a working code.
var myData=[15, 30, 20, 10]
var graph = d3.select("#graph")
graph.selectAll("div#graph")
.data(myData) // maybe this's data(myData), not data(datum)
.enter()
.append("div")
.attr("class", "geneCountBar") // <----CHANGE class
.style("width", function(d) {return (d*5)+"px";})
.html(" ")
.geneCountBar {
background-color: red;
margin:3px}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<div id="graph">
</div>
Hope this help
I ended up drawing bars without the use of d3s entering the data.
I put the following divs on the page:
<div className="geneCountBar"
style={{width: this.getHeightForGeneBar(idx, innerIdx), height:"10px",
backgroundColor: getColorForGene(this.getGeneIdx(idx, innerIdx)),
borderRadius: "2px"}}> </div>
And set up individual bars height and color in code with the two functions: getHeightForGeneBar(idx, innerIdx) and getColorForGene(this.getGeneIdx(idx, innerIdx)).

How to redraw chart : d3.js chaining function and crossfilter filtering

Edit : JSBin dont work go to JS fiddle to see my code
I'm training my self with d3 and crossfilter and i face some difficulties.
I'm trying to make a chaining function to create bar chart. The idea is to not write all the code again and again for each bar chart i want to create.
I was inspired by the example Fast Multidimensional Filtering for Coordinated Views which is what i wanted to do (you can find code Here).
But I want to bring some personal touches in my generic barChart function.
I decided to do it with chaining function like in the example.
I understood how to create as many graphics as you wish, but i dont understand, (when brushes event appears), how to redraw all the bar depending on the filter.
If i wanted to do it outside a function i would define again the all the properties like x, y, axis etc. depending on the new data which is the filtered data like this:
var updateRange = function(filt){
data = dimension.filter(filt) //assuming dimension is a crossfilter dimension
// Scale the range of the data again
x.domain([0, d3.max(data, function(d) { return d.key; })+1]);
// Select the section we want to apply our changes to
var chart = d3.select(".chart")
//Update all rects
chart.selectAll("rect.hidden")
.data(data)
.transition()
.delay(function(d, i) {
return i * 50;
})
.duration(500)
.attr("y", function(d) {
return y2(d.value);
})
.attr("height", function(d) {
return height - y2(d.value);
});
I made a JSBin to discuss on how we can make the chart updated.
And this is the brush functions i use.
brush.on("brushstart", function() {
var div = d3.select(this.parentNode.parentNode.parentNode);
div.select(".title a").style("display", null);
});
brush.on("brush", function() {
var g = d3.select(this.parentNode),
extent = brush.extent();
if (round) g.select(".brush")
.call(brush.extent(extent = extent.map(round)))
.selectAll(".resize")
.style("display", null);
g.select("#clip-" + id + " rect")
.attr("x", x(extent[0]))
.attr("width", x(extent[1]) - x(extent[0]));
dimension.filter(extent);
});
brush.on("brushend", function() {
if (brush.empty()) {
var div = d3.select(this.parentNode.parentNode.parentNode);
div.select(".title a").style("display", "none");
div.select("#clip-" + id + " rect").attr("x", null).attr("width", width);
dimension.filterAll();
}
)};
waiting for your comments,
Chris.
Edit : some clarification
To be clearer, when i render the chart and use the brush the data are correctly filtered. (if i put some console.log i see the data filtered depending on the brush)
But the chart are not updated depending on the brush. I know the issue come from th way i used the brush event (brush.on().
I think i need to call the render function in some way but dont know how to do it with chaining function to be applied to all the charts.
Edit : Chart updated with external brush
The chart are now successfully updated when the brush is set externally (by clicking on the link).
Just adding this lines
if (brushDirty) {
brushDirty = false;
g.selectAll(".brush").call(brush);
div.select(".title a").style("display", brush.empty() ? "none" : null);
if (brush.empty()) {
g.selectAll("#clip-" + id + " rect")
.attr("x", 0)
.attr("width", width);
} else {
var extent = brush.extent();
g.selectAll("#clip-" + id + " rect")
.attr("x", x(extent[0]))
.attr("width", x(extent[1]) - x(extent[0]));
}
}
In order to update charts you can remove it and then redraw with new filters.
Something like this :
d3.selectAll(".chart").selectAll("svg").remove();
Or
$('#chart'+chart_id+' svg').remove();
and then redraw it by calling again your drawing function with updated data.
Hope this will help you. Sorry If I misunderstood you. I need to train my english =P
EDIT :
I found these examples without remove. It might help you.
http://jsfiddle.net/sx9myywh/
https://bl.ocks.org/RandomEtc/cff3610e7dd47bef2d01
I found where the problem was. And i feel stupid.
The brush.onevent was placed incide the function which generate the chart and have to be outside.
function my(div){
}
brush.on(...
I have updated the JS Fiddle with the correct answer.
I will create a github repository it will be cleaner.

nvd3 line chart issue

Here, I have used line chart from nvd3. I am trying to fix a few issues with this chart
1. This is an interactive chart, but even if i hover over a point where there are no points from the data, it still shows up the x and y-points.
2. x-axis and y-axis lines do NOT show up. Also the interactive guide doesn't come up in a rectangular box outlined.
3. The x-axis gets cut off at the end (see 14:29:19 being cut off at the end) no matter how much i increase the width to.
4. I am trying to remove the fill that we see above the line graph but styling changes made by me resulted in no success.
code that i use to fetch the line chart
var redraw = function(testData) {
var dataT = [{
key : 'Character Count',
values : testData,
color : '#00AEEF',
area : false
}];
var margin = {
top : 80,
right : 20,
bottom : 80,
left : 50
}, width = 1000 - (margin.left + margin.right), height = 600 - (margin.top + margin.bottom), x = d3.time.scale().range([0, width]), y = d3.scale.linear().range([height, 0]);
x.domain(d3.extent(dataT[0].values, function(d) {
return d3.time.format('%X')(new Date(d.TimeStamp));
}));
y.domain([0, d3.max(dataT[0].values, function(d) {
return d.CharCount;
})]);
nv.addGraph(function() {
chart = nv.models.lineChart().transitionDuration(350).useInteractiveGuideline(true)
.showLegend(true).showYAxis(true).showXAxis(true).x(function(d) {
return new Date(d.TimeStamp);
}).y(function(d) {
return d.CharCount;
});
chart.xAxis.axisLabel('Time').tickFormat(function(d) {
return d3.time.format('%X')(new Date(d));
}).scale(x).orient("bottom");
chart.yAxis.axisLabel('Character Count').tickFormat(d3.format(',')).scale(y);
chart.lines.forceY([0]);
d3.select('#chart2 svg')//.append("g")
.datum(dataT).attr('height', height).attr('width', width).call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
};
redraw(data)--data fetched froma service ith dateTimeStamp in x-axis and integer in y-axis points.
Please help!
This is an interactive chart, but even if i hover over a point where there are no points from the data, it still shows up the x and
y-points. 2. x-axis and y-axis lines do NOT show up. Also the
interactive guide doesn't come up in a rectangular box outlined.
Adding corresponding javascript file in nvd3 zip file should solve the problem(line.js, linechart.js and corresponding css file)
3.The x-axis gets cut off at the end (see 14:29:19 being cut off at the end) no matter how much i increase the width to.
This is because you have not set the width and height of the chart in your codes to generate the chart
you should do
chart.width(width).height(height)
4.I am trying to remove the fill that we see above the line graph but styling changes made by me resulted in no success
This I am not sure how to solve as I do not have your dataset, so I not able to reproduce the problem
Here is my test code

Categories