Overlapping bar charts where stacks start from y axis - dc.js

Is it possible, using dc.js, to construct a bar chart where the stacks are not placed on top of each other? Currently, my code produces charts that look like this:
Instead I'd like each of the stack bars to start from y axis and not from the value where the previous stack value ends. This may/will lead to the bars overlapping, so perhaps adding transparency will help here. A simple css rule will probably work here:
.dc-chart rect.bar { opacity: 0.75; }

You likely want to build a composite chart that includes a bar chart for each category.
You can build a group for each color in your chart like this:
usaGroup = categoryDimension.group().reduceSum(dc.pluck('usa')),
russiaGroup = categoryDimension.group().reduceSum(dc.pluck('russia'));
Here is a jsFiddle to demsonstrate this: http://jsfiddle.net/djmartin_umich/nK6K7/
composite
.width(400)
.height(300)
.x(d3.scale.ordinal().domain([1,2,3]))
.xUnits(dc.units.ordinal)
.yAxisLabel("User Count")
.renderHorizontalGridLines(true)
.compose([
dc.barChart(composite)
.centerBar(true)
.gap(100)
.colors('red')
.dimension(categoryDimension)
.group(russiaGroup),
dc.barChart(composite)
.centerBar(true)
.gap(100)
.colors('blue')
.dimension(categoryDimension)
.group(usaGroup)])
.brushOn(false)
.render();
You'll need to play around with the styling... the blue and red combine into a purple color when the opacity is lowered.

Related

Anchor Graphics elements to bars in amCharts

I want to draw Graphics elements in an amCharts 5 stock chart, for example Lines. I would like to use the Line class but have only managed to draw using the lower level line api below. I have not managed to find anything in the documentation about how to anchor Graphics elements to bars.
The lines should be anchored to bars, ie:
start on a certain date and end on another date,
are horizontal,
should move with the chart in zoom and pan events,
there can be hundreds of lines on the chart.
What I have done so far is to take the stock chart example https://www.amcharts.com/docs/v5/charts/stock/ and now I want to draw lines anchored to bars, which I'm failing to do. I did manage to draw a line but it is not anchored to any bar and does not move on zoom or pan.
How can I anchor Lines to bars, please?
Here is the code to draw a horizontal line:
mainPanel.plotContainer.children.push(am5.Graphics.new(root, {
stroke: am5.color(0x000000),
fill: am5.color(0x990000),
x: 20,
y: 70,
centerX: am5.percent(50),
centerY: am5.percent(50),
position: 'relative', // this did not do anything
draw: function(display) {
display.moveTo(0, 50);
display.lineTo(50, 50);
},
}));

Label auto resizing for the bar charts dc.js

I have a bar chart with in dc.js. The x axis is dimension and y is the measure ranging from 1 - 10k. I want to show all the bars and their labels not overlapping each other. Chart looks fine when there are few bars when the number of bars starts to increase they look not okay. I am looking to auto resize the labels for the bar-chart.
Sample Chart
I tried this method of renderlet to change the fontsize automatically
stackedBarChart.on('renderlet', function(chart) {
chart.selectAll('text.barLabel')
.attr('transform', function(d) {
//How do i get/set the width of the label here ?
});
I tried the below and I am able to do dynamic label sizing. I used pretransistion and inside that fetched all bar lables and altered their font-size. The font sizing is altered according to Gordon's Idea, Getting each bar's size and and assigning the font size dynamically. For testing I have used .2 as a factor to reduce the font size.
.on('pretransition', function(chart) {
var chart_width = chart.width();
chart.selectAll("text.barLabel").attr('font-size', function(data) {
let total_bars = chart.group().all().length;
let sing_bar_width = Math.floor(chart_width / total_bars);
return (sing_bar_width * .2) + "px";
});
});

How to change tick's text with ordinal axis

I have chart with next properties:
barChart
.width(width)
.height(height)
.dimension(dim)
.group(group)
.x(d3.scale.ordinal())
.xUnits(dc.units.ordinal)
My axis tick looks like "ZZxBob", "PxBob"
How to use split function by 'x' to each tick?
The axes are generated entirely by D3.
You can use chart.xAxis() to retrieve the x axis object, and then axis.tickFormat() to change the way it's displayed.
So, e.g. to display the part before x:
barChart.xAxis()
.tickFormat(function(l) { return l.split('x')[0]; })

Making bar widths and gaps consistent in dc.js when using a large dataset and d3.scale.linear()

When creating a barchart using dc.js and a smaller dataset, I can get the bars and gaps to look pretty consistent.
When using a larger dataset and d3.scale.linear(), I haven't been able to get the bars and gaps to look anywhere as nice as when using a Date chart and d3.time.scale().
The bars are either too thin or thick without a gap - http://neil-s.com/unison/crossfilter/test/Crossfilter.jpg
Here is some sample code for one of the top bar charts from my image above:
var tempDim = xFilter.dimension(function(d) {return d.temp;});
var tempCount = tempDim.group().reduceCount(function(d) {return d.temp;});
var minTemp = tempDim.bottom(1)[0].temp;
var maxTemp = tempDim.top(1)[0].temp;
tempBarChart
.width(375).height(157)
.dimension(tempDim)
.group(tempCount)
.x(d3.scale.linear().domain([minTemp, maxTemp]))
.centerBar(true)
.elasticX(true)
.gap(15)
.xUnits(function(){return 15;})
.xAxis().ticks(6)
I've experimented with the gap, xUnits, and ticks values, but no luck. Any suggestions?
Not pretty!
This is a known bug with dc.js.
https://github.com/dc-js/dc.js/issues/952
I think it works slightly better in 1.7 than in the 2.0 development branch, but it is still not perfect.
The only thing I can think of as a workaround for now is to create a renderlet which adjusts the widths after the fact. :-(

dc.js pieChart set specific x axis value

I am working on dc.js, i have draw pieChart
pieChart.width(300)
.height(200)
.transitionDuration(1500)
.dimension(startValue)
.group(startValueGroup, "StartValue")
.radius(100)
.minAngleForLabel(0.5)
.legend(dc.legend().x(230).y(0))
.title(function(d) {
return d.key + ": " + d.value;
})
.renderTitle(true)
.on("filtered", function (chart) {
dc.events.trigger(function () {
//console.log(total_payment);
});
});
Now, I want to set specific x axis value. Currently, pieChart taking center position of define width and height. That mean it's taking position of (150,100). I want to change this position to (100, 100).
How can i change position of x axis as per above code?
You can't set this directly in the dc options, but you can modify these values after the chart has been rendered. Assuming that "pie" is the ID of the DOM element that you rendered the pie chart into, you can do
d3.select("#pie > svg > g").attr("transform", "translate(100,100)");
I know it is an old post and that the answer works perfectly but when the chart is part of a bigger system (several charts) I found easier to add the above command directly to the chart by doing this:
pieChart.on('renderlet', function (chart) {
chart.select("svg > g").attr("transform", "translate("100,100)");
});
Edit:
Actually I just found out you can do:
.cx(100)
.cy(100)
which will set the centre of the pie chart to 100, 100 before render.

Resources