Hide textinfo of piechartjs which are extended outside the piechart - plotly js - javascript

I am using Plotly to show a pie chart. My code looks like:
let dataKeyValue = {
'ADA': 660,
'Affordable': 49,
'Balcony': 2546,
'Bathroom': 157,
'Ceiling': 337,
'Closet/Storage': 23,
'Corner': 577,
'DOM': 321,
'Finishes': 1455,
'Floor Level': 6205,
'Floor Plan or Layout': 569,
'Flooring': 242,
'Kitchen': 4543,
'Location': 3462,
'Loft': 12,
'Renovation': 1438,
'Rent': 658,
'Square Feet': 2114,
'Unclear': 1692,
'Unit Features': 2544,
'View/Exposure': 4703,
'Washer/Dryer': 2037,
'Windows': 340,
'private entry': 8
};
let dollarSign = "$";
let pieData = [{
values: Object.values(dataKeyValue),
labels: Object.keys(dataKeyValue),
type: 'pie',
textinfo: "label",
hoverinfo: "label+percent",
// texttemplate: "%{label}<br>"+dollarSign+"%{value}<br>%{percent}",
hovertemplate: "%{label}<br>"+dollarSign+"%{value}<br>%{percent}"
}];
var layout = {
margin: {"t": 0, "b": 0, "l": 0, "r": 0},
showlegend: false,
};
Plotly.newPlot('myDiv', pieData, layout);
<head>
<!-- Load plotly.js into the DOM -->
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>
</head>
<body>
<div id='myDiv'><!-- Plotly chart will be drawn inside this DIV --></div>
</body>
The pie chart is working fine, but the labels of each slice are showing outside the pie chart. I am trying to get rid of those labels which are not inside the pie chart.
To remove the labels, I have found the options as textinfo: "none", but this is removing the labels completely, which means it is removing labels inside the pie chart as well. However, I want to hide only those which are outside the pie chart.
I want to hide that section shown on top right corner. Here is a jsfiddle.

One solution is to set the outside text color to transparent:
let pieData = [{
//...
outsidetextfont: { color: 'transparent' },
}]
Plotly.newPlot('myDiv', pieData, layout)
let dataKeyValue = {
'ADA': 660,
'Affordable': 49,
'Balcony': 2546,
'Bathroom': 157,
'Ceiling': 337,
'Closet/Storage': 23,
'Corner': 577,
'DOM': 321,
'Finishes': 1455,
'Floor Level': 6205,
'Floor Plan or Layout': 569,
'Flooring': 242,
'Kitchen': 4543,
'Location': 3462,
'Loft': 12,
'Renovation': 1438,
'Rent': 658,
'Square Feet': 2114,
'Unclear': 1692,
'Unit Features': 2544,
'View/Exposure': 4703,
'Washer/Dryer': 2037,
'Windows': 340,
'private entry': 8
};
let dollarSign = "$";
let pieData = [{
values: Object.values(dataKeyValue),
labels: Object.keys(dataKeyValue),
type: 'pie',
textinfo: "label",
outsidetextfont: { color: 'transparent' }, // 👈
hoverinfo: "label+percent",
// texttemplate: "%{label}<br>"+dollarSign+"%{value}<br>%{percent}",
hovertemplate: "%{label}<br>"+dollarSign+"%{value}<br>%{percent}"
}];
var layout = {
margin: {"t": 0, "b": 0, "l": 0, "r": 0},
showlegend: false,
};
Plotly.newPlot('myDiv', pieData, layout);
<head>
<!-- Load plotly.js into the DOM -->
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>
</head>
<body>
<div id='myDiv'><!-- Plotly chart will be drawn inside this DIV --></div>
</body>

Related

Want to reduce padding/space between Plotly.JS heatmap and text from another div - need CSS

I have a Plotly.JS heatmap that's working great and I have some descriptive text I want to put above it in a separate div, however the gap looks a bit awkward. Somehow I am struggling to reduce the padding so that my text (e.g., My description) and the heatmap and closer together. I tried using CSS, but I am clearly off. I'm sure this is an easy answer and that I'm overlooking something simple. Any help is appreciated.
Codepen: https://codepen.io/tenebris_silentio/pen/eYzgZMw
<!DOCTYPE html>
<head>
<!-- Load plotly.js into the DOM -->
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>
</head>
<br>
My description.
<div id='myDiv'><br> </div>
</div>
</div><script>
var colorscaleValue = [
[0, '#ADD8E6'],
[1, '#000080']
];
var data = [
{
z: [[41, 60, 25, 24, 28], [56, 27, 14, 45, 17], [47, 17, 12, 47, 17]],
x: ['Geographical', 'Temporal', 'Cultural', 'Digital', 'Financial'],
y: ['Category 1', 'Category 2', 'Category 3'],
colorscale: colorscaleValue,
type: 'heatmap',
hovertemplate: '<b># of %{y} Projects with a %{x} classification</b>: %{z}' + '<extra></extra>',
hoverongaps: true
}
];
var layout = {
title: '',
width: 900,
height: 560,
autosize: false,
yaxis: {automargin: true}
};
Plotly.newPlot('myDiv', data, layout);
</script><!-- Plotly chart will be drawn inside this DIV --></div></div></div>
<style>
.myDiv{
padding: -1px;
}
</style>
You can use the margin configuration in your layout:
var layout = {
// ...
margin: {
t: 10
},
// ...
<!DOCTYPE html>
<head>
<!-- Load plotly.js into the DOM -->
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>
</head>
<br>
My description.
<div id='myDiv'><br> </div>
</div>
</div><script>
var colorscaleValue = [
[0, '#ADD8E6'],
[1, '#000080']
];
var data = [
{
z: [[41, 60, 25, 24, 28], [56, 27, 14, 45, 17], [47, 17, 12, 47, 17]],
x: ['Geographical', 'Temporal', 'Cultural', 'Digital', 'Financial'],
y: ['Category 1', 'Category 2', 'Category 3'],
colorscale: colorscaleValue,
type: 'heatmap',
hovertemplate: '<b># of %{y} Projects with a %{x} classification</b>: %{z}' + '<extra></extra>',
hoverongaps: true
}
];
var layout = {
title: '',
width: 900,
height: 560,
autosize: false,
margin: {
t: 10
},
yaxis: {automargin: true}
};
Plotly.newPlot('myDiv', data, layout);
</script><!-- Plotly chart will be drawn inside this DIV --></div></div></div>
<style>
.myDiv{
padding: -1px;
}
</style>
Why not add the text in the layout itself?
var layout = {
"title": {"text": "My description."},
...
};
Because Plotly.JS is generating a SVG its not easy to style it. A solution is to style a element with position absolute so you can make it "overlap" with the SVG.
For example:
var colorscaleValue = [
[0, '#ADD8E6'],
[1, '#000080']
];
var data = [
{
z: [[41, 60, 25, 24, 28], [56, 27, 14, 45, 17], [47, 17, 12, 47, 17]],
x: ['Geographical', 'Temporal', 'Cultural', 'Digital', 'Financial'],
y: ['Category 1', 'Category 2', 'Category 3'],
colorscale: colorscaleValue,
type: 'heatmap',
hovertemplate: '<b># of %{y} Projects with a %{x} classification</b>: %{z}' + '<extra></extra>',
hoverongaps: true
}
];
var layout = {
title: '',
width: 900,
height: 560,
autosize: false,
yaxis: {automargin: true}
};
Plotly.newPlot('myDiv', data, layout);
</script><!-- Plotly chart will be drawn inside this DIV --></div></div></div>
.myDiv{
padding: -1px;
}
p {
position: absolute;
z-index: 10;
margin-top: 45px;
margin-left: 80px;
}
<p>My description.</p>
<div id='myDiv'></div>
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>

Is it possible to outline a pie piece using plotly.js?

Suppose I'm just using the basic pie chart from plotly's documentation:
var data = [{
values: [19, 26, 55],
labels: ['Residential', 'Non-Residential', 'Utility'],
type: 'pie'
}];
var layout = {
height: 400,
width: 500
};
Plotly.newPlot('myDiv', data, layout);
I want to know how I can outline a specific slice. I'm envisioning something like this:
I don't see anything in the plotly.js documentation that suggests how this might be done, which is why I'm asking here. Thanks!
You can set the width of the line for each of the parts (in the marker).
marker: {
line: {
color: '#444',
width: [0, 5, 0]
},
}
Here is an example:
var data = [{
values: [19, 26, 55],
labels: ['Residential', 'Non-Residential', 'Utility'],
type: 'pie',
marker: {
line: {
color: '#444',
width: [0, 5, 0]
},
}
}];
Plotly.newPlot('myDiv', data);
<!-- Plotly.js -->
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<!-- Numeric JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/numeric/1.2.6/numeric.min.js"></script>
<div id="myDiv">

stepSize being ignored in radar chart Chart.js version 2

[Update: This may have been fixed in version 2.1.5]
In Chart.js version 1 I used to be able to set the spacing between the scale lines on a radar chart. The desired behaviour was lines from 0 to 100 in steps of 5. I used the following version 1 options:
{
scaleOverride: true,
scaleStartValue: 0,
scaleSteps: 20,
scaleStepWidth: 5
}
Since upgrading to version 2 (2.1.4) I can't seem to get the same behaviour. Below is a minimal chart based on the documentation for a radar chart with my best guess for how it should work. The stepSize argument seems to be ignored.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Radar Chart Test</title>
<script src="Chart.js"></script>
</head>
<body>
<canvas id="myChart" width="400px" height="400px"></canvas>
<script>
var ctx = document.getElementById("myChart").getContext("2d");
var data = {
labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
datasets: [
{
label: "My First dataset",
data: [65, 59, 90, 81, 56, 55, 40]
},
{
label: "My Second dataset",
data: [28, 48, 40, 19, 96, 27, 100]
}
]
};
var myChart = new Chart(ctx, {
type: 'radar',
data: data,
options: {
scale: {
ticks: {
min: 0,
max: 100,
stepSize: 5,
}
}
}
});
</script>
</body>
</html>
Any thoughts most appreciated.

Add a horizontal line to the chart

I have a requirement to have horizontal lines in Kendo Line Chart to denote maximum and minimum values as well as high limit and low limit.
Another solution would be to add plotbands.
Example:
<div id="chart"></div>
<script>
$("#chart").kendoChart({
valueAxis: {
plotBands: [
{ from: 89, to: 90, color: "red" }
]
}
});
</script>
Adding striplines or Horizontal Lines (Min/Max/Average) via Kendo-chart Render Event Handler
I wanted to add a complete solution here so it can be used for variety reasons.
Using kendo 2015.3.1111 version, IE11/10
I had the same challenge to add upper and lower limit lines similar to MS-Chart strip lines. Kendo 2015.3.1111 and prior versions don't support this feature.
My solution is
Add a stripline property to kendo-chart value-axis property
Use render event handler to draw lines provided by the stripline property per value axis
A value axis (y-axis) may have multiple striplines
Make sure have the following references in the <head>
<link href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.common.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.714/js/kendo.all.min.js"></script>
Here is the stripline property. I leave the implementation of level position up to you.
valueAxis: [{
name:..
labels:{..}
stripLine: [{
value: 78,
color: "blue",
borderwidth: "1px",
//"dot", "dash", "solid", "dashDot", "longDash", "longDashDot"
dashstyle: "dot",
label: "In Max",
labelposition: "",
labelfont: "12 sans-serif"
},
{
value: 70,
color: "blue",
borderwidth: "1px",
dashstyle: "dot",
label: "In Min",
labelposition: "",
labelfont: "12 sans-serif"
}]
}
Second Important point is the number of value axes (y-axes). Kendo-chart "value-axis" property has either the value axis or the array of value axes. Render event handler should figure out object versus array
render: function (e) {
if (e.sender.options.valueAxis.length) {
$.each(e.sender.options.valueAxis, function (i, value) {
drawStriptLine(e.sender, value);
});
}
else {
drawStriptLine(e.sender, e.sender.options.valueAxis);
}
}
You can see the drawStripline in the Code snippet below. Here are some notes about the code.
Make sure the axis names match
axis.slot is the data point. If you know how many data point you have, your data axis starts from 0 to your last data point number. Putting a higher number will return the last point. Otherwise line will be drawn from 0 to last point you specified in the end slot.
KendoChart property renderAs is optional, however canvas doesn't raise the render event handler, so use VML or SVG
Chrome (tested version Version 52.0.2743.116 m) doesn't support dotted and dashed lines yet (solid line only), IE11/10 supports all the dash styles
plotBands implementation is also demonstrated as an alternative to Render Event Handler
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<link href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.common.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.714/js/kendo.all.min.js"></script>
<!--<link href="http://kendo.cdn.telerik.com/2015.3.1111/styles/kendo.common.min.css" rel="stylesheet" />-->
<!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>-->
<!--<script src="http://kendo.cdn.telerik.com/2015.3.1111/js/kendo.all.min.js"></script>-->
</head>
<body>
<div id="chart" />
<script>
var mPlotBands = [];
mPlotBands.push({
from: 60,
to: 61,
color: "red",
borderwidth: "3px",
borderstyle: "dashed",
label: "Min",
labelposition: ""
})
mPlotBands.push({
from: 95,
to: 94,
color: "red",
borderwidth: "3px",
borderstyle: "dashed",
label: "Max",
labelposition: ""
});
$("#chart").kendoChart({
renderAs: "VML", //"canvas", "SVG", "VML"
title: {
text: "Average In/Out Temperatures"
},
legend: {
position: "bottom"
},
seriesDefaults: {
type: "line"
},
series: [{
name: "In Temperature",
data: [74, 74, 76, 78, 74, 70],
axis: "intemperature"
}, {
name: "Out Temperature",
data: [45, 65, 75, 95, 80, 70],
axis: "outtemperature"
}],
categoryAxis: {
name: "CategoryAxis",
categories: ["May", "June", "July", "Aug", "Sep", "Oct"]
},
valueAxis: [{
name: "intemperature",
labels: {
format: "{0}F"
},
min: 50,
max: 110,
plotBands: [],
stripLine: [{
value: 78,
color: "blue",
borderwidth: "1px",
dashstyle: "dot", //"dot", "dash", "solid", "dashDot", "longDash", "longDashDot"
label: "In Max",
labelposition: "",
labelfont: "12 sans-serif"
}, {
value: 70,
color: "blue",
borderwidth: "1px",
dashstyle: "dot", //"dot", "dash", "solid", "dashDot", "longDash", "longDashDot"
label: "In Min",
labelposition: "",
labelfont: "12 sans-serif"
}]
}, {
name: "outtemperature",
labels: {
format: "{0}F"
},
plotBands: mPlotBands,
stripLine: [{
value: 75,
color: "green",
borderwidth: "3px",
dashstyle: "dot", //"dot", "dash", "solid", "dashDot", "longDash", "longDashDot"
label: "Out Avg",
labelposition: "",
labelfont: "italic 12 sans-serif"
}]
}],
render: function(e) {
if (e.sender.options.valueAxis.length) {
$.each(e.sender.options.valueAxis, function(i, value) {
drawStriptLine(e.sender, value);
});
} else {
drawStriptLine(e.sender, e.sender.options.valueAxis);
}
}
});
function drawStriptLine(chart, yaxis) {
var axis = chart.getAxis(yaxis.name);
var stripline;
$.each(yaxis.stripLine, function(i, stripline) {
// Locate value slot
var slot = axis.slot(stripline.value);
// Locate last category slot. Trying to get the last slot on the right given data x-axis plots
var categoryAxis = chart.getAxis("CategoryAxis");
var categorySlotBeg = categoryAxis.slot(0);
var categorySlotEnd = categoryAxis.slot(100000);
// Render a line element
var line = new kendo.drawing.Path({
stroke: {
color: stripline.color,
width: stripline.borderwidth,
dashType: stripline.dashstyle
}
});
line.moveTo([categorySlotBeg.origin.x, slot.origin.y]).lineTo([categorySlotEnd.origin.x, slot.origin.y]);
var labelPos = [categorySlotEnd.origin.x - 50, slot.origin.y - 20];
var label = new kendo.drawing.Text(stripline.label, labelPos, {
fill: {
color: stripline.color
},
font: stripline.labelfont
});
var group = new kendo.drawing.Group();
group.append(line, label);
chart.surface.draw(group);
});
}
</script>
</body>
</html>
Hope this helps.
References
http://docs.telerik.com/kendo-ui/controls/charts/how-to/custom-plot-bands
Simply add one more line series with the chart. This will create a hr line in chart. We will be able to manage the line position also.

Google Chart -- add "recession bars"

I have a Google Chart that works great. To add context to this chart, I need to add a series in the background that distinguishes weekends visually. The desired effect shown as applied to recession periods rather than weekends is at the bottom. Is it possible to create this effect using Google Visualization?
Here is the chart:
<div id="chart_div" style="width: 100%; height: 500px;"></div>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
... DATA ...
]);
var formatter = new google.visualization.NumberFormat(
{prefix: '$', negativeColor: 'red', negativeParens: true});
formatter.format(data, 1); // Apply formatter to second column
formatter.format(data, 2); // Apply formatter to second column
formatter.format(data, 3); // Apply formatter to second column
var options = {isStacked: true, vAxis: {format: '$#,###'}, title:"MTS Revenue" };
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
Yes, you can accomplish this effect with a ComboChart.
The general concept is to make your stacked bar chart, and then add a series that shows the max value of your chart as a separate column on weekends, and plot that series as a steppedArea chart. This will make it look like a background for certain series.
Here is an example (copy paste in to Google Playground):
function drawVisualization() {
// Create and populate the data table.
var data = google.visualization.arrayToDataTable([
['Month', 'Bolivia', 'Ecuador', 'Madagascar', 'Papua New Guinea', 'Rwanda', 'Average'],
['2004/05', 165, 938, 522, 998, 450, 0],
['2005/06', 135, 1120, 599, 1268, 288, 4000],
['2006/07', 157, 1167, 587, 807, 397, 0],
['2007/08', 139, 1110, 615, 968, 215, 4000],
['2008/09', 136, 691, 629, 1026, 366, 0]
]);
// Create and draw the visualization.
var ac = new google.visualization.ComboChart(document.getElementById('visualization'));
ac.draw(data, {
title : 'Monthly Coffee Production by Country',
width: 600,
height: 400,
vAxis: {title: "Cups", minValue: 0, maxValue: 4000},
hAxis: {title: "Month"},
seriesType: "bars",
isStacked: true,
series: {5: {type: "steppedArea", lineWidth: 0, showInLegend: false}}
});
}

Categories