Chart.js doughnut text visibility - reactjs

Chart.js doughnut text visibility. Tell me how to make it so that when the values intersect, the text comes out and changes its position.
const myChart = new Chart(canvas,
{
type: 'doughnut',
data: {
labels: dataNameDB,
datasets: [{
data: dataCountDB,
backgroundColor: backgroundColor,
borderWidth: 0,
}],
},
plugins: [ChartDataLabels, DoughnutLabel],
options: {
cutout: 340,
responsive: true,
animation: false,
plugins: {
legend: {
display: false,
},
datalabels: {
formatter: (val, ctx) => {
return Math.round((ctx.chart.data.datasets[0].data[ctx.dataIndex] * 100) / summChart()) + "%";
},
display: (val,ctx) =>{
return 'auto';
},
clamp: true,
clip: true,
anchor: 'center',
align: 'center',
offset: 1,
font: {
size: 65,
weight: 'bold',
color: '000000'
},
color: '000000',
labels: {
value: {
color: '#000000'
}
}
},
doughnutlabel: {
labels: [{
text: summChart,
font: {
size: 140,
weight: 'bold',
color: '000000'
}
}]
}
}
}
},
);
Now it outputs something like this, but I need it to be like this:
Although the documentation says that display 'auto' is responsible for this, how to catch it when the text is hidden in order to move it?

Related

change chart canvas size move mouse point over the chart using chart.js

I create some chart in dashboard using react-chart-js.
exmaple
but I have problem now chart not clear. I decided do change chart canvas size move mouse point over the chart . but i can't find solution for that.
i currently use "react-chartjs-2": "3.3.0" and "chart.js": "^3.6.0" packages
i use this option list for draw charts
const options = {
responsive: true,
animation: {
duration: 0,
},
plugins: {
legend: {
fullSize: false,
position: "bottom" as const,
labels: {
display: true,
},
},
title: {
display: true,
color: "white",
font: {
size: 14,
family: "tahoma",
weight: "normal",
style: "italic",
},
text: axis.thresholdValues.sensorName,
},
subtitle: {
display: true,
text: `average: x-axis: ${axis.average.x} y-axis: ${axis.average.y} z-axis: ${axis.average.z}`,
color: "white",
align: "end",
font: {
size: 12,
family: "tahoma",
weight: "normal",
style: "italic",
},
// padding: {
// bottom: 20,
// },
},
zoom: {
pan: {
// pan options and/or events
enabled: true,
speed: 0.01,
},
limits: {
// axis limits
},
zoom: {
// zoom options and/or events
wheel: {
enabled: true,
},
pinch: {
enabled: true,
},
speed: 0.01,
},
},
annotation: {
annotations: {
min: {
// type: 'line',
yMin: axis.thresholdValues.min,
yMax: axis.thresholdValues.min,
borderColor: "#D8D8D8",
// borderWidth: 2,
},
max: {
// type: 'line',
yMin: axis.thresholdValues.max,
yMax: axis.thresholdValues.max,
borderColor: "#DB00FF",
// borderWidth: 2,
},
},
},
tooltip: {
mode: "index",
intersect: false,
},
},
spanGaps: true,
datasets: {
line: {
pointRadius: 0, // disable for all `'line'` datasets
},
},
elements: {
point: {
radius: 0, // default to disabled in all datasets
},
},
transitions: {
zoom: {
animation: {
duration: 0,
},
},
},
scales: {
x: {
title: { display: true, text: "Time", align: "end" },
type: "time",
},
y: {
title: { display: true, text: "second", align: "top" },
},
},
events: ["click"],
hover: {
mode: "nearest",
intersect: false,
},
};
<Line data = {data} option = {option} />
Any one can suggest solution for it.

React HighCharts Custom Legend

I'm trying to customise my chart's legend. My current legend needs to look like this legend.
Basically I need to make the circular icons rectangular and change the legend text color to correspond with the icon.
I've looked everywhere in the docs but I'm not finding a solution. This is how I configured the graph below (legend > itemStyle):
useEffect(() => {
Highcharts.chart(chart.current, {
chart: {
type: 'column',
style: {
fontFamily: '"Roboto", sans-serif',
},
height: 312,
},
credits: {
enabled: false,
},
title: {
text: null,
},
xAxis: {
categories,
labels: {
step: 1,
style: {
fontSize: '8px',
color: '#808992',
},
useHTML: true,
formatter() {
const day = this.value.format('D');
if (moment().isSame(this.value, 'd')) {
return `<strong style="font-weight: 900; color: #0E2C47;">${day}</strong>`;
}
return day;
},
},
gridLineWidth: 1,
},
yAxis: {
min: 0,
title: {
text: `Collections ${showValue ? 'value' : 'count'}`,
style: {
color: '#0E2C47',
fontWeight: '500',
fontSize: '12px',
letterSpacing: '0.3px',
lineHeight: '14.4px',
},
},
labels: {
style: {
fontSize: '8px',
color: '#808992',
},
useHTML: true,
formatter() {
// eslint-disable-next-line react/no-this-in-sfc
const collection = this.value;
const format = Math.abs(collection) > 999 ? `${Math.sign(collection) * ((Math.abs(collection) / 1000).toFixed(1))}K` : Math.sign(collection) * Math.abs(collection);
return `${format}`;
},
},
useHTML: true,
},
legend: {
title: {
text: 'Status',
style: {
fontSize: '12px',
letterSpacing: '0.3px',
color: '#0A1944',
fontWeight: '500',
},
},
itemStyle: {
fontSize: '10px',
letterSpacing: '0.25px',
fontWeight: '500',
color: '#0A1944',
},
reversed: 'true',
layout: 'vertical',
align: 'right',
verticalAlign: 'bottom',
itemMarginBottom: 8,
x: -30,
y: -2,
},
plotOptions: {
series: {
stacking: 'normal',
},
},
tooltip: {
formatter() {
// eslint-disable-next-line react/no-this-in-sfc
return `<b>${this.y} ${this.series.name}</b><br/>${this.x.format('D MMM YYYY')}`;
},
},
series: [{
name: 'Draft',
data: chartData.draft, // [...times(() => null, 30), ...times(random, 31)],
color: collectionStateColors.draft, // processed
legendIndex: 0,
}, {
name: 'Approved',
data: chartData.approved,
color: collectionStateColors.approved, // orange
legendIndex: 1,
}, {
name: 'Expired',
data: chartData.expired,
color: collectionStateColors.expired, // purple
legendIndex: 2,
}, {
name: 'Submitted',
data: chartData.submitted,
color: collectionStateColors.submitted, // purple
legendIndex: 3,
}, {
name: 'Tracking',
data: chartData.tracking,
color: collectionStateColors.tracking, // light blue
legendIndex: 4,
}, {
name: 'Processed',
data: chartData.processed,
color: collectionStateColors.processed, // dark blue
legendIndex: 5,
}],
});
});

Chartjs: Draw chart with only yAxis zero tick

Hell, all,
I would like to draw the chart like this:
Currently, I can use afterBuildTicks to get only zero yAxis. But the problem is that the whole other ticks were removed also. So Not sure if we have a way to draw zero tick and keep other ticks hidden except the label.
var ctx = document.getElementById("myChart").getContext("2d");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['Value 1', 'Value 2', 'Value 3', 'Value 4'],
datasets: [{
label: "Dataset",
data: [20, 15, 27, 18],
backgroundColor: 'rgba(54, 162, 235,0.5)',
}],
},
options: {
responsive: true,
elements: {
line: {
fill: false
}
},
scales: {
xAxes: [
{
position: 'top',
display: true,
gridLines: {
display: true,
},
stacked: true,
ticks: {
fontColor: "#C4C4C4",
fontSize: 10,
}
}
],
yAxes: [
{
type: 'linear',
display: true,
position: 'right',
id: 'y-axis-1',
gridLines: {
display: true,
},
labels: {
show: true
},
stacked: false,
ticks: {
fontColor: "#C4C4C4",
fontSize: 10,
precision: 0,
suggestedMax: 100,
suggestedMin: -100
},
afterBuildTicks:function (axis) {
axis.ticks = [0]
}
}
]
},
tooltips: {
mode: 'label',
bodySpacing: 10,
titleMarginBottom: 10,
titleFontSize: 14,
titleFontStyle: 'bold',
footerAlign: 'right',
callbacks: {
label: (tooltipItem, data) => {
const label = data.datasets[tooltipItem.datasetIndex].label || ''
const value = tooltipItem.value
return ` ${label}: ${value}`
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<canvas id="myChart" height="100"></canvas>
Thanks so much
I found the solution that use: gridLines options to draw chart with width is zero:
gridLines: {
display: true,
tickMarkLength: 10,
lineWidth: 0
}

ApexCharts Donut make the legend show all the items

Is there a way to make it so that all the legend options show on a donut apexchart. Currently it's using a scrollbar and I don't want this, I want all the legend options to be visibile in a vertical formation.
Image of the donut chart with a scrollbar legend
Ideally I'd want it to look something like this, but not sure what settings need to be changed.
Ideal donut chart
These are the current options I am using:
const options = {
chart: {
events: {
dataPointSelection: onClick,
markerClick: onClick,
legendClick: onClick
},
type: 'donut',
animations: {
enabled: true,
easing: 'easeinout',
speed: 80,
animateGradually: {
enabled: true,
delay: 1500
},
dynamicAnimation: {
enabled: true,
speed: 350
}
}
},
stroke: {
colors: [theme.colors.backgroundPrimary]
},
theme: {
mode: 'light',
monochrome: {
enabled: true,
color: '#B9B9B9',
shadeTo: 'dark',
shadeIntensity: 0.9
},
},
dataLabels: {
enabled: false,
foreColor: '#fff',
padding: 4,
borderRadius: 2,
borderWidth: 1,
borderColor: '#fff',
opacity: 0.5
},
legend: {
show: true,
labels: {
colors: [theme.colors.textPrimary],
useSeriesColors: false
}
},
tooltip: {
custom: (stuff: any) => {
const index = stuff.seriesIndex;
return (
`<div class="apex-tool">
<span>${labels[index]}</span>
</div>`
);
}
},
labels: labels,
responsive: [{
breakpoint: 480,
options: {
chart: {
width: 200
},
legend: {
position: 'bottom',
}
}
}, {
breakpoint: 1200,
options: {
chart: {
height: '150px',
width: '100%',
events: {
dataPointSelection: onClick,
markerClick: onClick,
legendClick: onClick
},
type: 'donut',
animations: {
enabled: true,
easing: 'easeinout',
speed: 80,
animateGradually: {
enabled: true,
delay: 1500
},
dynamicAnimation: {
enabled: true,
speed: 350
}
}
},
stroke: {
colors: [theme.colors.backgroundPrimary]
},
theme: {
mode: 'light',
monochrome: {
enabled: true,
color: '#B9B9B9',
shadeTo: 'dark',
shadeIntensity: 0.9
},
},
dataLabels: {
enabled: false,
foreColor: '#fff',
padding: 4,
borderRadius: 2,
borderWidth: 1,
borderColor: '#fff',
opacity: 0.5
},
legend: {
height: '200px',
width: '100%',
show: true,
labels: {
colors: [theme.colors.textPrimary],
useSeriesColors: false
}
},
tooltip: {
custom: (stuff: any) => {
const index = stuff.seriesIndex;
return (
`<div class="apex-tool">
<span>${labels[index]}</span>
</div>`
);
}
},
labels: labels,
}
}, {
breakpoint: 992,
options: {
chart: {
height: '250px',
events: {
dataPointSelection: onClick,
markerClick: onClick,
legendClick: onClick
},
type: 'donut',
animations: {
enabled: true,
easing: 'easeinout',
speed: 80,
animateGradually: {
enabled: true,
delay: 1500
},
dynamicAnimation: {
enabled: true,
speed: 350
}
}
},
stroke: {
colors: [theme.colors.backgroundPrimary]
},
theme: {
mode: 'light',
monochrome: {
enabled: true,
color: '#B9B9B9',
shadeTo: 'dark',
shadeIntensity: 0.9
},
},
dataLabels: {
enabled: false,
foreColor: '#fff',
padding: 4,
borderRadius: 2,
borderWidth: 1,
borderColor: '#fff',
opacity: 0.5
},
legend: {
show: true,
labels: {
colors: [theme.colors.textPrimary],
useSeriesColors: false
}
},
tooltip: {
custom: (stuff: any) => {
const index = stuff.seriesIndex;
return (
`<div class="apex-tool">
<span>${labels[index]}</span>
</div>`
);
}
},
labels: labels,
}
}],
}
Generally speaking it would be a better approach do use the chart height option, which you mention, to adjust what is visible in the chart area.
If this for whatever reason is not suitable for your use, then you'll need to start overriding the default CSS.
The following should do the trick:
.apexcharts-canvas svg {
/* Allow the legend to overflow the chart area */
overflow: visible;
}
.apexcharts-canvas svg foreignObject {
/* Allow the legend to overflow the legend container */
overflow: visible;
}
Here's a codepen of it working with a donut chart.
These are the default fontSize and height why not trying to decrease the first and increase the second ?
legend: {
fontSize: '14px',
height: undefined,
}

Highchart: Break y-axis doest work in react app but is working in js fiddle

using same options in js-fiddle and react app y-axis break is not working in react app but is working fine in js-fiddle.
highchart version i am using is 7.2.1
[enter link description here][1] jsfiddle where break is working
Highcharts.chart('container', {
chart: {
height: 250,
animation: false,
borderColor: '#EFF3F5',
plotBorderColor: '#EFF3F5',
plotBorderWidth: 1,
style: {
},
marginLeft: undefined,
},
legend: {
enabled: false,
},
credits: {
enabled: false,
},
title: {
text: '',
},
subtitle: {
text: '',
},
xAxis: [{
categories: [],
type: 'datetime',
crosshair: {
color: '#96abb6',
width: 1,
snap: false,
},
labels: {
style: {
fontSize: '10px',
color: '#334252',
fontFamily: 'DecimaMono',
textTransform: 'uppercase',
lineHeight: '12px',
whiteSpace: 'nowrap',
},
formatter: function() {
return this.value;
},
},
alternateGridColor: '#F7F9FA',
}, ],
yAxis: [{
tickPositioner: function() {
const positions = [];
let tick = Math.floor(this.dataMin);
const max = Math.min(200, this.dataMax);
const increment = Math.ceil((max - this.dataMin) / 6);
if (this.dataMax !== null && this.dataMin !== null) {
for (tick; tick - increment <= max; tick += increment) {
positions.push(tick);
}
}
if (this.dataMax > 200) {
positions.push(this.dataMax);
}
return positions;
},
title: {
text: null,
},
labels: {
style: {
fontSize: '10px',
textAlign: 'right',
},
},
breaks: [{
from: 200,
to: 1700,
}],
}, ],
series: [{
name: 'Attraction 1',
data: [-0.3543, 5.4184, -31.3792, 95.2435, 135.5852, 104.7914, 84.5844, 8.5129, -38.4724, -54.1816, -13.1134, 677.986, 1763, 1420.0503, 760.9013, 100.8341, 10.4576, 89.8975, 97.4758, 55.4993, 51.4611, 24.1278, 9.9771, 26.9394, 22.042, 32.9894, 145.3526, 88.1315, 135.0617, 119.6472, 29.8568, 43.94, 26.4247, 43.4719, 128.6346, 119.7356, 33.2159, 58.6534, -7.6348, 2.1865, 31.7992],
color: '#e63c45',
lineWidth: 3,
}, ]
});
[enter image description here][2]
[2]: https://i.stack.imgur.com/TIKkO.png screenshot from react app
I reproduce your code in the React environment and everything looks fine, same as in the jsFiddle.
Demo: https://codesandbox.io/s/highcharts-react-demo-83jnr?file=/demo.jsx

Resources