Plotly tick labels misaligned in stacked horizontal bar chart - reactjs

I am having trouble getting the yaxis tick labels to align to the bars properly when stacking horizontal bars by using base (my use case is a timeline view so i need empty spaces in between the stacked bars, thus why i am using base)
here is a codepen showcasing the issue: https://codepen.io/dan-wiegand/pen/GRMwKGP?editors=0010
var data = [{
type: 'bar',
x: [0, 10, 10, 0],
base: [0, 10, 20, 30],
y: ['trace 1', 'trace 1', 'trace 1', 'trace 1'],
orientation: 'h'
}, {
type: 'bar',
x: [0, 10, 0, 10],
base: [0, 10, 20, 30],
y: ['trace 2', 'trace 2', 'trace 2', 'trace 2'],
orientation: 'h'
}, {
type: 'bar',
x: [10, 0, 10, 0],
base: [0, 10, 20, 30],
y: ['trace 3', 'trace 3', 'trace 3', 'trace 3'],
orientation: 'h'.
}];
const layout = {
yaxis: {
showgrid: true
}
};
Plotly.newPlot('myDiv', data, layout);
(code required to post codepen link)
for those familiar with flex box, it's visually like the difference between space-around and space-between (bars being space between and ticks being space around)
My issue is visible below
and here it is in my actual case - if they all looked like "Copy Valence" that would be perfect
i dont care if the labels are along the axis lines or in the empty spaces, as long as the labels and the bars are aligned! In a perfect world the chart would be aligned like below, with the tick labels in the space between the ticks and the bars between ticks

question is tagged with python and javascript. Solution on python but concept same across languages
for each trace use a separate yaxis y, y2, y3
in layout set domain of each yaxis
import plotly.graph_objects as go
data = [
{
"type": "bar",
"x": [0, 10, 10, 0],
"base": [0, 10, 20, 30],
"y": ["trace 1", "trace 1", "trace 1", "trace 1"],
"orientation": "h",
"yaxis": "y",
},
{
"type": "bar",
"x": [0, 10, 0, 10],
"base": [0, 10, 20, 30],
"y": ["trace 2", "trace 2", "trace 2", "trace 2"],
"orientation": "h",
"yaxis": "y2",
},
{
"type": "bar",
"x": [10, 0, 10, 0],
"base": [0, 10, 20, 30],
"y": ["trace 3", "trace 3", "trace 3", "trace 3"],
"orientation": "h",
"yaxis": "y3",
},
]
go.Figure(data).update_layout(
{
ax: {"showgrid": True, "domain": [i * 0.33, (i + 1) * 0.33]}
for i, ax in enumerate(["yaxis", "yaxis2", "yaxis3"])
}
)

Related

React HighChart, apply different gradient color for each dataset

I have a highchart table, I want to apply a gradient for underneath the graph line for each data set. Each data set already has the line coloured differently, but it seems impossible to apply a gradient color for each dataset.
I cannot apply areaSpline for each series of the chart:
c.series?.forEach((s, index) => {
s.type = 'areaspline';
s.color = colors.spline[index];
});
c.chart = { type: 'areaspline' };
c.plotOptions = {
series: {
stacking: isStacked ? 'normal' : undefined,
connectNulls: true,
marker: {
enabled: false,
radius: 14,
},
},
areaspline: {
// fillOpacity: 0.5,
fillColor: {
linearGradient: { x1: 0, x2: 0, y1: 0, y2: 1 },
stops: [
[0, 'red'],
[1, 'transparent'],
],
},
},
};
Any idea on how to achieve that?
You need to define the gradient for each series, not in plotOptions. For example:
series: [{
...,
fillColor: {
linearGradient: { x1: 0, x2: 0, y1: 0, y2: 1 },
stops: [
[0, 'blue'],
[1, 'transparent'],
]
}
}, {
...,
fillColor: {
linearGradient: { x1: 0, x2: 0, y1: 0, y2: 1 },
stops: [
[0, 'red'],
[1, 'transparent'],
]
}
}]
Live demo: http://jsfiddle.net/BlackLabel/kczgb4Lv/
API Reference: https://api.highcharts.com/highcharts/series.areaspline.fillColor

How to make Chart JS ignore the scale between DatasSets

I'm trying to create a multi-bar chart where one of the bars is really lower than the other ones. (I'm comparing low numbers X high numbers X high numbers)
This is my dataSet:
[
{
"label": "# Negócios Fechados",
"data": [ 8, 5, 3, 12 ],
"backgroundColor": "rgba(255, 99, 132, 1)"
},
{
"label": "# Valor Total",
"data": [ 16000, 25000,4500, 36000 ],
"backgroundColor": "rgba(54, 162, 235, 1)"
},
{
"label": "# Ticket Médio",
"data": [ 2000, 5000, 1500, 3000 ],
"backgroundColor": "rgba(255, 206, 86, 1)"
}
]
This is what my chart looks like:
The "# Negócios Fechados" one is there, but It's so low that It's impossible to mouse hover it.
I want to know if it is possible to make this single bar ignore the scale of the rest.
You can define a multi-axis chart, similar to this sample.
Please take a look at the following runnable code and see how it works.
new Chart('myChart', {
type: 'bar',
data: {
labels: ['A', 'B', 'C', 'D'],
datasets: [{
label: "# Negócios Fechados",
data: [8, 5, 3, 12],
backgroundColor: "rgba(255, 99, 132, 1)",
yAxisID: 'y2',
},
{
label: "# Valor Total",
data: [16000, 25000, 4500, 36000],
backgroundColor: "rgba(54, 162, 235, 1)"
},
{
label: "# Ticket Médio",
data: [2000, 5000, 1500, 3000],
backgroundColor: "rgba(255, 206, 86, 1)"
}
]
},
options: {
scales: {
y: {
position: 'right',
beginAtZero: true
},
y2: {
grid: {
drawOnChartArea: false
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
<canvas id="myChart" height="100"></canvas>

Chart js bar with the highest value is a different color among the rest - React

I'm trying to make a chart for Peak Hours and I want the hour with the highest value to be of a different color, how do I do that? For example, in the data array, ideally the one that should have a different bar color would be the one with the value "12". Currently I've only set one color in the data.datasets.backgroundColor and I'm not sure how to add a backgroundColor conditionally. I'm using React so I've installed chartjs in my project. Ideally it should look something like
render() {
return (
<div
style={{ padding: "0 15px" }}
className="chart"
>
<div>
<span>1 PM usually busy</span>
</div>
<Bar
height={145}
responsive={false}
data={{
labels: [
"00",
"",
"",
"03",
"",
"",
"06",
" ",
"",
"09",
"",
"",
"12",
"",
"",
"15",
"",
"",
"18",
" ",
"",
"21",
" ",
"",
"24",
],
fontSize: 1,
datasets: [
{
label: "Time",
data: [
2,
0,
3,
4,
5,
8,
7,
8,
9,
10,
11,
12,
11,
10,
9,
6,
7,
8,
7,
5,
4,
3,
2,
8,
],
backgroundColor: ["#33AF4F"],
borderWidth: 0,
},
],
}}
options={{
barThickness: 10,
borderRadius: 10,
plugins: {
legend: {
display: false,
labels: {
fontSize: 9,
boxWidth: 5,
usePointStyle: true,
},
},
},
scales: {
x: {
ticks: {
font: {
size: 10,
},
},
stacked: true,
grid: {
display: false,
},
},
y: {
ticks: {
display: false,
},
stacked: true,
grid: {
borderDash: [2, 3],
color: "#bdbdbd",
},
},
},
}}
/>
</div>
);
}
You have to call function giving conditional array of colors for in the place of backgroundColor: ["#33AF4F"]
taking into consideration that you want highest value with different color create this function before rendering component.
function getBgColors() {
var array = [2,0,3,4,5,8,7,8,9,10,11,12,11,10,9,6,7,8,7,5,4,3,2,8];
var maxValue = Math.max.apply(this, array);
var bg = array.map(a => a === maxValue ? "#0f7d28" : "#33AF4F");
return bg;
}
and call this function at backgroundColor: getBgColors()

Working with Charts in motion [Animating chart]

I have created a areaspline chart using highcharts library and making it animated with play/pause button transition between weeks of data
Ref. https://www.highcharts.com/blog/tutorials/176-charts-in-motion/
jsfiddle Ref. https://jsfiddle.net/larsac07/wkev75nL/?utm_source=website&utm_medium=embed&utm_campaign=wkev75nL
in the above example, we are animating the chart week wise
dataSet used :
dataSequence = [
{
name: 'Week 1',
data: [1, 2, 2, 1, 1, 2, 2]
}, {
name: 'Week 2',
data: [6, 12, 2, 3, 3, 2, 2]
}, {
name: 'Week 3',
data: [4, 5, 6, 5, 5, 4, 9]
}, {
name: 'Week 4',
data: [5, 5, 6, 6, 5, 6, 6]
}, {
name: 'Week 5',
data: [6, 7, 7, 6, 6, 6, 7]
}, {
name: 'Week 6',
data: [8, 9, 9, 8, 8, 8, 9]
}, {
name: 'Week 7',
data: [9, 10, 4, 10, 9, 9, 9]
}, {
name: 'Week 8',
data: [1, 10, 10, 10, 10, 11, 11]
}, {
name: 'Week 9',
data: [11, 11, 12, 12, 12, 11, 11]
}
]
I don't want change chart
on play button click I want animate the data points 11 data point for week1 to same data point but different value on y axis for week2
xAxis = ["week1", "Week2", ..... ],
yAxis = [[1,2,3,4,5,6,7,8,9,10,11], [3,5,7,8,2,1,5,7,6,1,10], ....]
on the play button it would transit between week1 then will go to week 2 and so till last week number available.
Trying to have something like this Ref. https://aatishb.com/covidtrends/
this chart is plotted using this dataset for series
Highcharts.chart("container", {
chart: {
type: "areaspline"
},
tooltip: {
shared: true,
valueSuffix: " units"
},
xAxis: {
categories: [
"Week 1",
"Week 2",
"Week 3",
"Week 4",
"Week 5",
"Week 6",
"Week 7"
]
},
yAxis: {
title: {
text: "Index"
}
},
legend: {
layout: "horizontal",
align: "right",
verticalAlign: "top",
x: 50,
y: 50,
floating: true,
borderWidth: 1,
backgroundColor:
(Highcharts.theme && Highcharts.theme.legendBackgroundColor) ||
"#FFFFFF"
},
plotOptions: {
areaspline: {
fillOpacity: 0.5
}
},
credits: {
enabled: false
},
series: [
{
name: "By week",
data: dataSequence[value].data.slice()
},
{
type: "spline",
name: "Topic 1",
data: [3, 2, 1, 3, 4, 7, 8]
},
{
type: "spline",
name: "Topic 2",
data: [1, 5, 1, 3, 4, 7, 8]
},
{
type: "spline",
name: "Topic 3",
data: [3, 7, 1, 3, 4, 7, 8]
},
{
type: "spline",
name: "Topic 4",
data: [5, 1, 1, 3, 4, 7, 8]
},
{
type: "spline",
name: "Topic 5",
data: [7, 3, 1, 3, 4, 7, 8]
},
{
type: "spline",
name: "Topic 6",
data: [9, 2, 1, 3, 4, 7, 8]
},
{
type: "spline",
name: "Topic 7",
data: [11, 8, 1, 3, 4, 7, 8]
},
{
type: "spline",
name: "Topic 8",
data: [13, 11, 1, 3, 4, 7, 8]
},
{
type: "spline",
name: "Topic 9",
data: [15, 7, 1, 3, 4, 7, 8]
},
{
type: "spline",
name: "Topic 10",
data: [7, 5, 1, 3, 4, 7, 8]
}
],
title: {
text: ""
},
subtitle: {
text: "Efficiency Index of Topics"
}
});
this my update function in react
update(increment) {
var input = $("#play-range")[0];
var output = $("#play-output")[0];
if (increment) {
input.value = parseInt(input.value) + increment;
}
output.innerHTML = this.state.dataSequence[input.value].name;
this.setState({
value: input.value
});
if (input.value >= input.max) {
// Auto-pause
this.pause();
this.setState(
{
value: 0
},
() => {
output.innerHTML = this.state.dataSequence[0].name;
}
);
}
}
the whole chart is plotted at once, I need something that it should transit
first, it plots all data points for week1 then week 2 after that week 3 when I click on the play button
You need to start with an empty data and use addPoint method in the update function:
function update(increment) {
var input = $('#play-range')[0],
output = $('#play-output')[0],
increment;
chart.series[0].addPoint(dataSequence[input.value].data[actualPointIndex]);
actualPointIndex += increment;
if (actualPointIndex === 6) {
actualPointIndex = 0;
input.value = parseInt(input.value) + increment;
}
output.innerHTML = dataSequence[input.value].name; // Output value
if (input.value >= input.max) { // Auto-pause
pause($('#play-pause-button')[0]);
}
}
Live demo: https://jsfiddle.net/BlackLabel/stpxyfca/
API Reference: https://api.highcharts.com/class-reference/Highcharts.Series#addPoint

Adding labels to both ends of axis google charts

I've built a bubble chart on quadrant graph using google-charts in reactjs but I can only had two labels on my axis and I need four.
I've tried fiddling with the code but unsuccessfully. I don't want to append dummy data and additional series elements. Is overlay the only option to add axis?
<Chart
width={"800px"}
height={"600px"}
chartType="BubbleChart"
loader={<div>Loading Chart</div>}
data={[
["Age", "Weight", "4", "Group", "Size"],
["Name", -12, 34, 1, 7],
["Name", -5.5, 6, 1, 8],
["Name", 22, 35, 1, 4],
["Name", 14, 4, 2, 5],
["Name", -5, -5, 2, 6],
["Name", 15, 34, 3, 1],
["Name4", 7, -21, 4, 22]
]}
options={{
bubble: {},
chartArea: { left: 20, top: 0, width: "90%", height: "95%" },
colors: ["red", "green", "yellow", "blue"],
hAxis: {
title: "Low Importance",
ticks: "none",
baseline: 0,
ticks: ["none"],
minValue: -50,
gridlines: { count: 0 },
maxValue: 50
},
vAxis: {
title: "Low Urgency",
baseline: 0,
ticks: ["none"],
minValue: -50,
gridlines: { count: 0 },
maxValue: 50
},
legend: "none"
}}
/>;
As you can see in the graph below, I can only get left and bottom labels but not top and right. Any ideas how I could achieve that using google-chart library for reactjs?

Resources