recharts stacked bar chart with overlapping cells - stacked-chart

I'd like to present a comparison of response times - percentiles for product A and B, example data:
[ { "category": "X", "A.90th": 100, "A.50th": 50, "B.90th": 120, "B.50th": 40 },
{ "category": "Y", "A.90th": 250, "A.50th": 60, "B.90th": 200, "B.50th": 80 } ]
This should display two stacked bars (for product A and B) in each category, total 4 bars, each having two cells (ok, in practice there would be more datapoints than just 90th and 50th percentile). My point is that I don't want the response times be 'summed' (100 + 50, 120 + 40...) but overlapping as the 90th percentile is always > 50th percentile.
Is there a way to achieve this with recharts? I could naturally recalulate the data to be only 'diffs', but then I'd have to heavily customize Tooltip.

Related

Calculate Axis break positions programmatically where gap is larger than X number of ticks

I have a dataset similar to the picture below with some values that make the smaller portions of graph harder to read. I have been asked to put in an axis breaks when there is any continuous data sections longer than X number of ticks. Right now the breaks are calculated and put into the graph manually which doesn't work as the data changes in real time. This is being charted in highcharts although this is more a language and tool agnostic question.
breaks: [{
from: 245,
to: 505,
breakSize: 3
}, {
from: 145,
to: 215,
breakSize: 3
}, {
from: 48,
to: 59,
breakSize: 3
}],

Plot the top X values in DCjs (not grouped/value counted)

I'd like to plot the top X values of a dimension in a row chart, ideally labeled using one dimension but using the value of another for the size of the bars.
Essentially a presentation of data like the following:
Sally: 1
Fred: 0.7
Bob: 0.5
Francis: 0.4
George: 0.2
Sam: 0.18
Susan: 0.16
Sarah: 0.15
Tom: 0.15
Simon: 0.14
...
rowChart1 = dc.rowChart('#id')
valDim = ndx.dimension(function(d) {return d.data});
valGroup = valDim.group().reduceCount();
rowChart1.dimension(valDim).group(valGroup);
Plots the value counts, rather than the values themselves.
Specifically I'm looking to make a rowChart of the top N data points, where the length of the bars is determined by the value of the data points, not the number of data points with that value.
I.e. Sally would have her own bar, and it would be 100% of the x-axis, while Fred's bar would be 70% and Simon's bar would be 14% of the x-axis.
If I understand your question correctly, the conceptual problem may be the distinction between the crossfilter definition of dimension, which means "a column that you bin and filter on", versus the English/math definition of the word, which might mean "any column of data" or might mean a geometric direction on a chart.
There's always at least one geometric "dimension" on every chart which is not associated with a "crossfilter dimension" because it is aggregated. In a line chart Y is driven by a group reduction/aggregation; in the row chart X is.
I understand you have a column in your data which is a unique key, say name, which you want to map to the row Y axis, and you have a second column x, which you want encode in the row X axis without aggregation. You can use crossfilter's group.reduceSum() and since only one record will land in each bin, the sum of x is just x.
Since name is a unique key, there will be only one x per name.
Let's say you have data like this:
const data = [
{name: 'Sally', x: 1},
{name: 'Fred', x: 0.7},
{name: 'Bob', x: 0.5},
{name: 'Francis', x: 0.4},
{name: 'George', x: 0.2},
{name: 'Sam', x: 0.18},
{name: 'Susan', x: 0.16}
// ...
];
Then the crossfilter initialization might look like this:
const xf = crossfilter(data),
dim = xf.dimension(d => d.name), // bin and filter on this
group = dim.group().reduceSum(d => d.x); // here be values
and chart
const rowChart = dc.rowChart('#row');
rowChart
.dimension(dim)
.group(group)
.render();
Demo fiddle
This might sound really complicated if you just want to plot x against some names, but dc.js and crossfilter are optimized for the case where there will be filtering between charts. No matter what they draw, crossfilter will always filter the rows, sort the rows into buckets, and reduce those buckets.
If you don't use filtering, then these libraries are overkill. But if you do want to filter, it's really nice to have a library with a data model that takes care of it.

Color set distance

I parsed images with Color thief and get their domain color and percentages. ex:
const colorSet = [{
r: 15, g:251, b:150, percentage: 50 // cover percentage in image
}, {
r: 150, g:121, b:45, percentage: 31
}, {
r: 43, g:160, b:180, percentage: 19
}]
I already know how to get the distance between two colors, but how about two "Color Sets"? Is there any algorithm to do this?
[EDIT]
I think vector is a way... but not sure about the detail.

How to display the axis to the right?

I have 3 axes (velue-axis)
Can one axis be displayed on the left
Other two axes to display on the right?
http://demos.telerik.com/kendo-ui/line-charts/multiple-axes
(In this example, the axis is located on the right, but I do not know how to configure it)
Thanks.
Granted this isn't entirely clear when you first look at the demo. The important thing to look at is this section:
categoryAxis: {
categories: [],
axisCrossingValues:[]//This is the fella you are looking for.
}
I have tweaked the demo slightly to show you one of the axis in the middle of the chart. http://dojo.telerik.com/ASidu
The number is simply the position column on the chart that the axis should be rendered. By default if this in't set then all axis should be on the left hand side as normal. but if we start applying a number greater than 0 then the axis will shift. So in the example we have 3 value axis set up:
valueAxes: [{
name: "rain",
color: "#007eff",
min: 0,
max: 60
}, {
name: "wind",
color: "#73c100",
min: 0,
max: 60
}, {
name: "temp",
min: -30,
max: 30
}],
so if we look at them from crossing the y-axis (i.e. the bottom axis) we have 31 columns available to us 1- 31 so in my tweak I have applied this to the crossingAxis:
axisCrossingValues: [32, 15, 0]
This is effectively telling each of the value axes where they should be positioned:
so:
"rain" should be at position 32
"wind" should be at position 15
"temp" should be at position 0
So the order in which you add your value axes will determine which setting they take based on the order you include them.
Hopefully that helps clear things up for you. If you need any more info let me know and I will update accordingly

Kendo UI Zoom Lock Y Axis Not Working

I am trying to lock the Y axis when zooming in Kendo UI. According to the docs, I should be able to do it like this:
zoomable: { mousewheel: { lock: "y" } }
But somehow it is not working, even the demo in Kendo has the same problem, see
http://demos.telerik.com/kendo-ui/bar-charts/pan-and-zoom
When I zoom in, you can see y axis max change from 12 to 10 and lower.
Am I understanding the docs correctly or there is a bug with kendo?
Thank you!
You can see that if you zoom on a bar with a height of 10, the y axis max remains at 12.
The behavior you're seeing is not zooming but changing the axis max to better suit the heights of the bars you see in the view. You can see the difference in the fact that the minimum value of the axis remains 0 but when you enable zooming in the y axis, the minimum value also changes.
You can avoid this behavior by setting a permanent axis max value:
valueAxis: {
max: number
}
The reason for this behavior is that if you add/remove/change your values, you'll want the grid to accommodate the new bars and not have them exceed the top of the chart. Setting the max y axis value is a good idea only if your data isn't going to change after the chart is shown for the first time.
The y-axis is not zooming, rather the max value is being auto-calculated depending on which bars are currently visible. You can avoid this be setting the valueAxis.max value. In the example, add
valueAxis:{
max: 12
},
The answer of setting the valueAxis.max is nearly there. But the issue I have with this is when you reach maximum zoom decimals appear because the y-axis changes based on which bars are currently visible. If I do a valueAxis.labels.format: '{0:0}', yes the decimals are gone but on maximum zoom it would appear that the bars are not leveled correctly to the y-axis. In fact the bar height/level is correct, the y-axis label is wrong, it's missing a decimal. The key is setting valueAxis.majorUnit. To demostrate, here is my options for a Kendo Chart for jQuery. Comment/uncomment the valueAxis.labels and valueAxis.majorUnit to see the difference.
{
series: [{
name: 'Grand Total',
data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
type: 'column',
}],
zoomable: {
mousewheel: {
lock: 'y',
},
selection: {
lock: 'y',
},
},
pannable: {
lock: 'y',
},
valueAxis: {
max: 12,
// labels: {
// format: '{0:0}',
// },
majorUnit: 1,
},
categoryAxis: {
categories: ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
},
}
Hope this helps.

Resources