I have a two column vertical bar chart.
I dont want the left hand bar to be flush with the Y axis.
So I used PaddingOuter() to specify an inset as follows:
var x = d3.scaleBand().rangeRound([0, width]).paddingInner(0.1).paddingOuter(0.5).align(0.1);
I works nicely.
Except that the right hand bar (its a two column chart) is also inset.
I only want the left hand bar inset.
Is there a solution to this..?
Start the range at the amount you want to offset by, e.g., rangeRound([10, width])
Related
I'm in the final portion of my project and we just need to make a graph showing the number of shows and movies with their rating trend. I have 4 different bar graph items and I was wondering if there's a way to add labels to each individual bar? For example here's one of the bars
y4 = [fourth]
x4 = [4.33]
bg4 = pg.BarGraphItem(x=x4, height=y4, width=0.2, brush='red', setLabel="Shows Down")
bg4.setX(0)
bg4.setY(0)
You could use a group of TextItem and set the bar as their parent:
text = pg.TextItem('Some bar', angle=90, color='#ffff00')
# reparent the item and make it a child of the bar
text.setParentItem(bg4)
# set the position to the x of the bar
text.setX(x4[0])
# use the x as left of the text and the y as vertical middle (referenced
# to the text orientation)
text.setAnchor(QPointF(0, .5))
Note that you don't need to create individual bars as long as they are part of the same group and share the same colors: just add the x and height as lists of their positions and values.
I want to put the same legend top center of the chart. Legend items will be dynamic, likes sometimes 2,5 or 9, etc.
So, it should take space dynamically like how it is acting on the bottom.
I tried with inset functionality but it seems this is not looking better like the bottom one.
and there are few more complexity like I want it like a flat, so now if I define step size 3 then maybe, for now, it looks good for 9 items. but when there will be 2 items, it will show as a list!!
Although I solved that problem through the following solution:
// get parent elements
let parentEle = d3.selectAll("#chartID svg");
let childrenEle = parentEle
//Convert selection to selection representing the children
.selectAll(function () { return this.childNodes; })
.filter('g');
// putting legends position on TOP
d3.select(childrenEle._groups[0][2]).attr('transform', 'translate(0, 5)');
you have to keep eye on chart width - height and according to this, you may have to control padding in TOP for the chart.
might be this is not a good solution but it works fine for me :D
I'm using d3.scale.threshold() to achieve color change that is correlated with a value, and I'm not sure how to flip colors, so that bar chart that is completely red will be positioned on the bottom of the chart, and bar chart that is mostly green is positioned on the top.
This is my Plunker.
Right now very top bar chart is completely red and positioned at the top. However, I would like it to see it on the bottom.
Any suggestions are appreciated.
This is the sort function you want:
data.sort(function(a, b) {
return d3.descending(b.total, a.total);
});
Here is your updated plunker: https://plnkr.co/edit/uyrf66RA6Qhc3bhOmdwH?p=preview
Is there a way in d3 to not draw overlapping tick labels? For example, if I have a bar chart, but the bars are only 5 pixels wide and the labels are 10 pixels wide, I end up with a cluttered mess. I'm currently working on an implementation to only draw the labels when they do not overlap. I can't find any existing way to do that, but wasn't sure if anyone else had dealt with this problem.
There is no way of doing this automatically in D3. You can set the number of ticks or the tick values explicitly (see the documentation), but you'll have to figure out the respective numbers/values yourself. Another option would be to rotate the labels such that there is less chance of them overlapping.
Alternatively, like suggested in the other answer, you could try using a force layout to place the labels. To clarify, you would use the force layout on the labels only -- this is completely independent of the type of chart. I have done this in this example, which is slightly more relevant than the one linked in the other answer.
Note that if you go with the force layout solution, you don't have to animate the position of the labels. You could simply compute the force layout until it converges and then plot the labels.
I've had a similar problem with multiple (sub-)axis, where the last tick overlaps my vertical axis in some situations (depending on the screen width), so I've just wrote a little function that compares the position of the end of the text label with the position of the next axis. This code is very specific to my use case, but could adapted easily to your needs:
var $svg = $('#svg');
// get the last tick of each of my sub-axis
$('.tick-axis').find('.tick:last-of-type').each(function() {
// get position of the end of this text field
var endOfTextField = $(this).offset().left + $(this).find('text').width();
// get the next vertical axis
var $nextAxis = $('line[data-axis="' + $(this).closest('.tick-axis').attr('data-axis') + '"]');
// there is no axis on the very right, so just use the svg width
var positionOfAxis = ($nextAxis.length > 0) ? $nextAxis.offset().left : $svg.offset().left + $svg.width();
// hide the ugly ones!
if (endOfTextField > positionOfAxis) {
$(this).attr('class', 'tick hide');
}
});
The ticks with color: aqua are the hidden ones:
What are the properties that control the width of the X-axis labels on a horizontal bar RadChart? Here's what it looks like now:
I need the labels on the left to be wider.
I actually, just needed to keep the auto layout doing its thing, and disable auto wrapping this way:
var item = new ChartAxisItem();
item.Appearance.RotationAngle = AutoTextWrap.False