Long tick labels getting cut off in plotly.js chart - javascript

Is it possible to give more room for tick labels in plotly.js? Long labels in my charts are getting cut off.
HTML:
<div id="plot"></div>
JavaScript:
var data = [{
type: 'bar',
x: [20, 14, 23],
y: ['giraffes', 'orangutans', 'a looooooooong string'],
orientation: 'h'
}];
var layout = {
title: 'Bar Chart'
};
Plotly.newPlot('plot', data, layout);
I can't see how to do this in the API for y-axes tick settings.
Given the nature of my charts, I need to use a horizontal orientation. So a solution I can't use is a vertical orientation with ticks rotated 90 degrees.

Update: plotly added support for automargins (see https://github.com/plotly/plotly.js/pull/2243), via the .axis.automargin configuration option.
To use, you'd change:
var layout = {
title: 'Bar Chart'
};
to:
var layout = {
title: 'Bar Chart',
yaxis: {
automargin: true
}
};
For more information, see https://plot.ly/javascript/axes/
Original Answer:
You can adjust the margins of plotly charts to give yourself some more space. For instance, change:
var layout = {
title: 'Bar Chart'
};
to
var layout = {
title: 'Bar Chart',
margin: {
l: 200
}
};
you can read more about adjusting margins here: https://plot.ly/javascript/setting-graph-size/
and overall layout options here: https://plot.ly/javascript/#layout-options

You can also set margin dynamically, based on label length:
var maxLabelLength = d3.max(data, d => d3.max(d.y, label => label.length));
const letterWidth = 7;
var layout = {
title: 'Bar Chart',
margin:{
l: maxLabelLength * letterWidth
}
};

Related

ChartJS 3 get height of stacked vertical bar

Ok. So I'm trying to use ChartJS with Datalabels 2.0 (RC) to show labels for stacked vertical bars. When the bar is small, I want those labels to appear outside of it.
Now here is the code I'm using: https://codepen.io/meexo/pen/xxqpELL
The problem I have is that using getProps on dataset, I am unable to retrieve the height of each bar. In the example above I tried to get height by using the getProps() introduced in ChartJS 3. If I console.log it, I see all kind of params, height included (though undefined). What am I doing wrong that height parameter is undefined?
I also tried to use getProps().y param for the code, but in that case it seems to apply only to one section of the stacked bar, not all. And what I want is for labels to appear above the stacked bar when the full height if it is lower than my threshold.
Any ideas?
BTW, though its my first question, its definitely not the first answer I found on StackOverflow :)
My code:
var ctx = document.getElementById("myChart");
Chart.register(ChartDataLabels);
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: 'red'
}, {
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: 'blue'
}]
},
options: {
scales: {
x: {
stacked: true
},
y: {
stacked: true
}
},
plugins: {
datalabels: {
anchor: context => {
let bar = context.chart.getDatasetMeta(context.datasetIndex).data[context.dataIndex].getProps().height;
document.getElementById('myHeight').innerHTML = bar;
const threshold = 6;
if (bar + threshold > context.chart.chartArea.bottom) {
return 'end'
}
return 'center'
}
}
}
}
});
The behaviour comes from this part in the code:
const properties = {
horizontal,
base: vpixels.base,
enableBorderRadius: !stack || isFloatBar(parsed._custom) || (me.index === stack._top || me.index === stack._bottom),
x: horizontal ? vpixels.head : ipixels.center,
y: horizontal ? ipixels.center : vpixels.head,
height: horizontal ? ipixels.size : undefined,
width: horizontal ? undefined : ipixels.size
};
It sets the height on undefined for normal bar charts and the width on undefined on horizontal bar charts. Putted in a pr (https://github.com/chartjs/Chart.js/pull/9208) for fix so this should be fixed by the next release of chart.js
Then to get the bar height you have to change your mode to index and then you can use this function to get the total bar height:
onClick: function(event) {
var bar = this.getElementsAtEventForMode(event, 'index', {intersect: true}, true);
if (!bar.length) return; //return if not clicked on bar
var barHeight = bar.reduce((acc , val) => (acc + val.element.height), 0)
document.getElementById('myHeight').innerHTML = barHeight;
}
Example: https://codepen.io/leelenaleee/pen/qBrpLjX

How can I enlarge text size of google bar chart and show x value on each bar?

Good morning everyone,
I have a problem about the size of bar chart values. The x values goes like 0,5,10,15,20,23 five by five but I want it to be like 0,1,2,3 one by one.
Another issue is, I want y values to be shown on top of each bar. If 23th bar's value is 10 it must be shown on the top of 23th bar because people should easily see the chart values from the distant.
And my last question is I want to enlarge the size of x and y values of chart but I could only enlarge labels. I couldn't find the right option.
Oh almost I forgot, I have another problem about legend. If legend is on the right side, the chart is getting smaller but I can't move legend to top or bottom. Even in the code says legend bottom it shows on the right.
my codes are here
function drawPaLoChart() {
var data = [['Hours', 'Label1', 'Label2']];
for (var i=0; i<pageload.length;i++){
data.push([pageload[i][0], pageload[i][1], pageload[i][2] ]);
}
var data = google.visualization.arrayToDataTable(data);
var options = {
'fontSize': 30,
chart: {
'width': 600,
title: 'Hourly Page Load Times',
},
legend: { position: 'bottom' },
bar: { groupWidth: "100%" },
backgroundColor: {fill: 'transparent'},
chartArea: {
backgroundColor: 'transparent'
},
'tooltipFontSize':22
};
var chart = new google.charts.Bar(document.getElementById('palochart'));
chart.draw(data, google.charts.Bar.convertOptions(options));
}
to add labels to the bar, you need to add an annotation column role to the data table.
however, you are using a material bar chart.
column roles, along with several other options, are not supported by material charts.
see --> Tracking Issue for Material Chart Feature Parity
material = google.charts.Bar -- packages: ['bar']
classic = google.visualization.ColumnChart -- packages: ['corechart']
using a classic chart, we can use a data view to add the annotation column role.
see following snippet...
function drawPaLoChart() {
var data = [
['Hours', 'Label1', 'Label2']
];
for (var i = 0; i < pageload.length; i++) {
data.push([pageload[i][0], pageload[i][1], pageload[i][2]]);
}
var data = google.visualization.arrayToDataTable(data);
var options = {
fontSize: 30,
width: 600,
title: 'Hourly Page Load Times',
legend: {
position: 'bottom'
},
bar: {
groupWidth: "100%"
},
backgroundColor: {
fill: 'transparent'
},
chartArea: {
backgroundColor: 'transparent'
},
tooltipFontSize: 22
};
var chart = new google.visualization.ColumnChart(document.getElementById('palochart'));
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: 'stringify',
sourceColumn: 1,
role: 'annotation',
type: 'string'
}]);
// use data view to draw chart
chart.draw(view, options);
}

google chart double axis, set format

I have created a Google bar chart, with two x-axis.
My problem is that I cannot seem to get the correct format on the bottom axis, which should be shown in percentage.
I have tried to use the following
axes:{{},{format:'#%'}}}
And in general inserting format:'#%' at places that would make sense, but nothing seems to work.
Is there anyone who has an idea for this?
See the entire code here: https://jsfiddle.net/laursen92/azr4kfn0/1/
google.charts.load('current', {
'packages': ['bar']
});
google.charts.setOnLoadCallback(drawStuff);
function drawStuff() {
var data = new google.visualization.arrayToDataTable([
['Slave number', 'Voltage', '%'],
['Slave 1', 12.15, 0.40],
['Slave 2', 12.18, 0.50],
['Slave 3', 11.80, 0.60],
['Slave 4', 13.12, 0.70],
]);
var formatter = new google.visualization.NumberFormat({
pattern: '##0.00'
});
var formatter2 = new google.visualization.NumberFormat({
pattern: '##0%'
});
formatter.format(data, 1);
formatter2.format(data, 2);
var options = {
width: 800,
chart: {
title: 'Status of slaves',
subtitle: 'Overview of the voltage and SOC of connected slaves. '
},
bars: 'horizontal', // Required for Material Bar Charts.
series: {
0: {
axis: 'voltage'
}, // Bind series 0 to an axis named 'voltage'.
1: {
axis: 'percent'
} // Bind series 1 to an axis named 'soc'.
},
axes: {
x: {
voltage: {
side: 'top',
label: 'Voltage'
}, // Top x-axis.
percent: {
label: 'Percent',
} // Bottom x-axis.
}
},
};
var chart = new google.charts.Bar(document.getElementById('dual_x_div'));
chart.draw(data, options);
};
Here's an update to your fidde: https://jsfiddle.net/Balrog30/azr4kfn0/4/
I used the a little codepen I wrote to reverse-engineer the changes to the material chart options, which are still mostly undocumented. You can find that here: http://codepen.io/nbering/pen/Kddvge
Here's how the option should be formatted:
var options = {
axes: {
x: {
yourAxis: {
format: {
pattern: "#%"
}
}
}
};
-- Or --
options.axes.x.yourAxis.format.pattern = "#%";

How to plot two plots in the same figure in plotly.js

I want to plot 2 plots in the same figure using plotly.js. I have gone through the documentation of plotly.js but was unable to find it. Can any body help?
Here is the code snippet:
First Plot:
var data4 = [ {
z: z,
x: x,
y: y,
type: 'contour'
}
];
var layout = {
title: 'Simple Contour Plot'
}
Plotly.newPlot('visualization2', data4, layout);
Second Plot:
var trace = {
x: x11,
y: x21,
mode: 'lines+markers'
};
var data3 = [ trace];
var layout = {
title:'Line and Scatter Plot',
height: 400,
width: 480
};
Plotly.newPlot('visualization3', data3, layout);
I want to plot these two in one figure. Note: The first one is a contour plot and the second one is a Line plot.
You have the ability to put a number of traces into your data that you wish to plot and it will plot them.
You also can only have 1 title per graph, however, you can have multiple axis titles.
var firstPlotTrace = {
z: z,
x: x,
y: y,
type: 'contour'
name: 'yaxis data'
};
var secondPlotTrace = {
x: x11,
y: x21,
mode: 'lines+markers'
name: 'yaxis2 data'
};
var plotData = [firstPlotTrace, secondPlotTrace];
var layout = {
title: 'Double Plot Title',
height: 400,
width: 400,
yaxis: {title: 'Simple Contour Plot Axis', range: [-20, 20]}
yaxis2: {title: 'Line and Scatter Plot Axis', range: [-20, 20]}
};
Plotly.newPlot('plotDiv', plotData, layout);
HTML -
<div id="plotDiv" style="height: 400px; width: 400px;"></div>

How do I color plot.ly js legend and why is it black?

When my graph renders, everything is great EXCEPT the legend only shows the colors black. The grouped bar chart graph is displaying how I would expect. All of the data and colors are wonderful, but the legend is not right.
I am loading a plotly graph into a salesforce Visualforce page as follows:
<apex:panelGroup styleClass="charts" layout="block">
<div id="myDiv" style="width: 480px; height: 400px;"><!-- Plotly chart will be drawn inside this DIV --></div>
</apex:panelGroup>
<script>
var trace1 = {
y: ['B2B', 'Commercial', 'Retail'],
x: [20, 14, 23],
marker: {
color: ['#f8b98d', '#f8b98d', '#f8b98d']
},
name: 'Annual Quota',
type: 'bar',
orientation: 'h'
};
var trace2 = {
y: ['B2B', 'Commercial', 'Retail'],
x: [12, 18, 29],
marker: {
color: ['#f58b3f', '#f58b3f', '#f58b3f']
},
name: 'Current Market Size',
type: 'bar',
orientation: 'h'
};
var data = [trace1, trace2];
var layout = {barmode: 'group'};
Plotly.newPlot('myDiv', data, layout, {displayModeBar: false});
</script>
I had a similar problem to this - custom colours on stacked bars looked great, but the legend swatches all black.
I couldn't find an official solution, so manually set the colours in the legend after the chart was generated using Plotly's built in d3, e.g:
var legendBoxes = document.getElementById("div-id-for-plot").getElementsByClassName("legendbar");
Plotly.d3.select(legendBoxes[0]).style("fill", "put your colour definition here");
(this example just styles a single box)

Categories

Resources