React Highcharts v9.2 Solid Gauge Rounded Ends - reactjs

I am working with solid gauge. We are upgrading from version 7.2.2 to the latest 9.2. We use to be able to pass in the y-axis plotbands a rounded: true which would round the tips of the bands. Since upgrading this no longer works. Instead the tips are squared off. I am looking for any assistance in how I might handle this.
Here is a fiddle of what it looks like squared off:
fiddle
Highcharts.chart('container', {
chart: {
type: 'solidgauge',
height: '110%',
},
tooltip: {
borderWidth: 0,
backgroundColor: 'none',
shadow: false,
style: {
fontSize: '16px'
},
valueSuffix: '%',
pointFormat: '{series.name}<br><span style="font-size:2em; color: {point.color}; font-weight: bold">{point.y}</span>',
positioner: function (labelWidth) {
return {
x: (this.chart.chartWidth - labelWidth) / 2,
y: (this.chart.plotHeight / 2) + 15
};
}
},
pane: [
{
"startAngle": -140,
"endAngle": 140,
"background": {
"shape": "arc",
"borderWidth": 0,
"backgroundColor": "#FFF0"
}
}
],
yAxis: [
{
"gridLineWidth": 0,
"opposite": false,
"title": {
"text": "",
"useHTML": true
},
"labels": {
"useHTML": true,
"format": "{value}",
"enabled": false
},
"min": 0,
"max": 100,
"lineWidth": 0,
"tickWidth": 0,
"minorTickWidth": 0,
"plotBands": [
{
"thickness": "10%",
rounded: true,
"from": 0,
"to": 73,
"color": "#1792E555",
},
{
"thickness": "10%",
"from": 76,
"to": 88,
"color": "#FFE393"
},
{
"thickness": "10%",
"from": 91,
"to": 100,
"color": "#F9B890"
}
],
"plotLines": [],
"index": 0
}
],
plotOptions: {
solidgauge: {
dataLabels: {
enabled: false
},
linecap: 'round',
stickyTracking: false,
rounded: true
}
},
series: [
{
"data": [
{
"y": 10,
"color": "#1792E5"
}
],
"radius": "100%",
"innerRadius": "90%",
linecap: 'rounded',
"rounded": true,
"useDial": false,
"type": "solidgauge",
"tooltip": {
"enabled": true,
"useHTML": true,
"borderRadius": 0,
"borderWidth": 0,
"shadow": false,
"valueDecimals": 2,
"style": {
"fontFamily": "inherit"
},
"padding": 6,
"shape": "square"
},
"dataLabels": {
"style": {
"textOutline": "none"
}
},
"events": {}
}
]
});

Unfortunately, it's not so easy to do. Since the plotBand is an SVG element you can try to edit its path and round the corners but it might be hard. You can check how the rounded path is created here: https://code.highcharts.com/modules/solid-gauge.src.js?_ga=2.104350400.154582566.1629699669-527407293.1629434064
And you can also check out this plugin: https://github.com/highcharts/rounded-corners
But the easiest solution would be to use another solidGauge series instead of plotBand. Something like that: https://jsfiddle.net/BlackLabel/k35vcsnx/
series[{...}, {
type: "solidgauge",
rounded: true,
data: [{
color: "#1792E555",
radius: '100%%',
innerRadius: '90%',
y: 73
}]
}

Related

How to align horizontal bars to the right

I'm using react-chartjs-2.
<HorizontalBar
options={{
legend: {
display: false,
},
tooltips: {
enabled: false,
},
hover: {
mode: null,
},
scales: {
xAxes: [
{
display: false,
gridLines: {
color: "rgba(0, 0, 0, 0)",
},
position: 'right'
},
],
yAxes: [
{
position: "right",
ticks: {
reverse: true,
},
gridLines: {
color: "rgba(0, 0, 0, 0)",
},
},
],
},
plugins: {
tooltip: {
enabled: false,
},
},
}}
data={{
datasets: [
{
label: "My First dataset 2",
borderWidth: 0,
backgroundColor: [
"#68B68A",
"#5B9FC9",
"#83C39F",
"#85B7D6",
"#9FD1B4",
"#C2DAEB",
],
data: ...,
barPercentage: 0.5,
},
],
}}
/>
I need to align horizontal bars to the right side like this
but actual result from my code is this
You could use floating bars for this:
const options = {
type: 'horizontalBar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [
[
20,
12
],
[
20,
19
],
[
20,
3
],
[
20,
5
],
[
20,
2
],
[
20,
14
]
],
backgroundColor: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"]
}]
},
options: {
scales: {
yAxes: [{
ticks: {
reverse: false
}
}]
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
</body>
You put the maximum value of your axis as the first or last (chart.js will render it the same) in your array. Then for the other value you enter the start point. So that would be max value - the percentage

react-chart-js2 Showing Negative Axis when dataset contains all 0's

I am using react-chart-js2#3.3.0 with chart.js#3.6.2
When my dataset contains all 0s, the y-axis scales from -1 to 1 as such:
See Image
How do I make it start at 0 regardless? There seems to be a workaround for this: here and here but these solutions did not work for me. Basically, the workaround is to include a max in the ticks but it appears to just ignore it. I also tried upgrading to react-chart-js2#4 but for some reason it breaks so I reverted it back to 3.3.0.
Here is my options object:
const options = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false,
},
},
layout: {
padding: 0,
},
scales: {
xAxes: [
{
gridLines: {
display: false,
drawBorder: false,
},
ticks: {
padding: 18,
fontColor: theme.palette.text.secondary,
},
},
],
yAxes: [
{
gridLines: {
borderDash: [6],
borderDashOffset: [0],
display: false,
color: theme.palette.divider,
drawBorder: false,
zeroLineBorderDash: [6],
zeroLineBorderDashOffset: [0],
zeroLineColor: theme.palette.divider,
},
ticks: {
padding: 12,
fontColor: theme.palette.text.secondary,
beginAtZero: true,
min: 0,
max: 100,
},
},
],
},
tooltips: {
enabled: true,
mode: "nearest",
intersect: false,
caretSize: 6,
displayColors: false,
yPadding: 8,
xPadding: 16,
borderWidth: 4,
borderColor: theme.palette.common.black,
backgroundColor: theme.palette.common.black,
titleFontColor: theme.palette.common.white,
bodyFontColor: theme.palette.common.white,
footerFontColor: theme.palette.common.white,
callbacks: {
title: () => {},
label: (tooltipItem) => {
return `New Users: ${tooltipItem.yLabel}`;
},
},
},
};
the min and max have to be outside of the ticks:
y: { ticks: { }, min: 0, max: 100 }

Chart is not rendering properly time axis

I have a lists of utc timestamps, ready to parse into ChartJS 2.9.3, the graph couldn't show the x-axis time and data is not showing.
Config
let chartConfig = {
type: "line",
data: {
labels: [],
datasets: [
{
pointRadius: 0,
data: [],
backgroundColor: ['rgba(255, 99, 132, 0.2)'],
borderColor: ['rgba(255,99,132,1)'],
borderWidth: 1
}
]
},
options: {
responsive: true,
animation: {
duration: 0
},
hover: {
animationDuration: 0
},
responsiveAnimationDuration: 0,
legend: {
display: false
},
scales: {
xAxes: [{
type: 'time',
ticks: {
source: "data",
autoSkip: true,
maxTicksLimit: 20
},
time: {
parser: 'HH:mm:ss',
tooltipFormat: 'HH:mm:ss',
unit: 'minute',
unitStepSize: 5,
displayFormats: {
'second': 'ss A',
'minute': 'hh:mm A',
'hour': 'HH:mm A'
}
}
}],
yAxes: [{
ticks: {min: 0, max: 150, stepSize: 10 }
}]
}
}
}
Labels (x-axis)
Generates through moment(timestamp).format("HH:mm:ss")
["22:02:30","22:03:00","22:03:30","22:4:00","22:05:00".,"22:07:00","22:10:00"]
Data (y-axis)
[60,78,89,100,120,45,55]
Problem
I took your code and everything works as expected as you can see below. The only thing I had to correct was removing a superfluous dot in the labels array.
new Chart('myChart', {
type: "line",
data: {
labels: ["22:02:30", "22:03:00", "22:03:30", "22:4:00", "22:05:00", "22:07:00", "22:10:00"],
datasets: [{
pointRadius: 0,
data: [60, 78, 89, 100, 120, 45, 55],
backgroundColor: ['rgba(255, 99, 132, 0.2)'],
borderColor: ['rgba(255,99,132,1)'],
borderWidth: 1
}]
},
options: {
responsive: true,
animation: {
duration: 0
},
hover: {
animationDuration: 0
},
responsiveAnimationDuration: 0,
legend: {
display: false
},
scales: {
xAxes: [{
type: 'time',
ticks: {
source: "data",
autoSkip: true,
maxTicksLimit: 20,
minRotation: 30
},
time: {
parser: 'HH:mm:ss',
tooltipFormat: 'HH:mm:ss',
unit: 'minute',
unitStepSize: 5,
displayFormats: {
'minute': 'hh:mm:ss A'
}
}
}],
yAxes: [{
ticks: {
min: 0,
max: 150,
stepSize: 10
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<canvas id="myChart"></canvas>

Annotations not showing on ChartJS - React

The datasets plot fine on my line chart but I am trying to get vertical lines to display on the chart using chartjs-plugin-annotation. From looking at these questions & answers:
SOLVED : ChartJS annotation not displaying
https://github.com/chartjs/chartjs-plugin-annotation/issues/209
react-chartjs-2 vertical line when hovering over chart
Chart.js — drawing an arbitrary vertical line
I thought I had the correct configuration but the lines are not appearing.
LineChart.js
import 'chartjs-plugin-annotation'
import React, { useContext } from 'react'
import { Card, CardBody } from 'reactstrap'
import { Line } from 'react-chartjs-2'
import flatten from 'lodash/flatten'
import { rgbaColor, exchangeChartColors, capitalize, exchanges } from '../../helpers/utils'
import AppContext from '../../context/Context'
import dayjs from 'dayjs'
function getDepositsAndWithdrawals(activity) {
return ['DEPOSIT', 'WITHDRAWAL'].reduce((acc, type) => {
if (activity) {
if (activity.betfair) {
acc[type].betfair = activity.betfair.filter(s => {
return s.legacyData.marketName === type
}).map(s => {
return {
exchange: 'BETFAIR',
type: type,
amount: s.amount,
date: getFormattedDate(s.itemDate)
}
})
}
if (activity.betdaq) {
acc[type].betdaq = activity.betdaq.filter(s => {
return s.PostingCategory === 3 && s.Description.toUpperCase().includes(`${type}:`)
}).map(s => {
return {
exchange: 'BETDAQ',
type: type,
amount: s.Amount,
date: getFormattedDate(s.PostedAt)
}
})
}
if (activity.smarkets) {
const typeToGet = (type === 'DEPOSIT') ? 'deposit' : 'withdraw'
acc[type].smarkets = activity.smarkets.filter(s => {
return s.source === typeToGet
}).map(s => {
return {
exchange: 'SMARKETS',
type: type,
amount: parseFloat(s.money_change),
date: getFormattedDate(s.timestamp)
}
})
}
}
return acc
}, {
DEPOSIT: {},
WITHDRAWAL: {}
})
}
function getFormattedDate(date) {
const parsed = dayjs(date)
const day = parsed
.date()
.toString()
.padStart(2, '0')
// Unsure why have to add 1 but don't care really
const mnth = (parsed
.month() + 1)
.toString()
.padStart(2, '0')
const yr = parsed
.year()
.toString()
.padStart(2, '0')
const hr = parsed
.hour()
.toString()
.padStart(2, '0')
const min = parsed
.minute()
.toString()
.padStart(2, '0')
return `${day}/${mnth}/${yr} # ${hr}:${min}`
}
function getXAxis(balances, annotations) {
const balanceDates = balances.map(entry => {
return getFormattedDate(entry.date)
})
const annotationDates = annotations.map(ann => {
return ann.value
})
return [
...balanceDates,
...annotationDates
]
}
const ProfitsLineChart = props => {
const { isDark } = useContext(AppContext)
const depositsAndWithdrawals = getDepositsAndWithdrawals(props.activity)
const annotations = Object.values(depositsAndWithdrawals).reduce((acc, exs) => {
const newEntries = Object.values(exs).map(entries => {
return entries.map(entry => {
return {
type: 'line',
mode: 'vertical',
drawTime: 'afterDatasetDraw',
scaleID: 'x-axis-0',
value: entry.date,
borderColor: isDark
? exchangeChartColors.dark[entry.exchange.toLowerCase()]
: exchangeChartColors.light[entry.exchange.toLowerCase()],
borderWidth: 2,
label: {
content: `${entry.exchange} ~ ${entry.type} ~ ${entry.amount}`,
enabled: true,
position: 'top'
}
}
})
})
return [
...acc,
...flatten(newEntries)
]
}, [])
const config = {
data(canvas) {
let datasets = exchanges.map(exchange => {
return {
exchange,
data: props.balances.reduce((acc, entry) => {
const entryForExchange = entry.balances.find(balance => {
return balance.exchange.toUpperCase() === exchange.toUpperCase()
})
if (entryForExchange) {
acc.push({
date: entry.date,
balance: entryForExchange.balance
})
}
return acc
}, [])
}
})
let labels = getXAxis(props.balances, annotations)
// If not specified time period, only show most recent (30) entries
if (!props.start && !props.end) {
datasets = datasets.map(ds => {
return {
...ds,
data: ds.data.slice(ds.data.length - 50, ds.data.length)
}
})
labels = labels.slice(labels.length - 50, labels.length)
}
return {
labels,
datasets: datasets.map(set => {
return {
label: capitalize(set.exchange),
borderWidth: 2,
fill: false,
data: set.data.map(s => s.balance.toFixed(2)),
borderColor: isDark ? exchangeChartColors.dark[set.exchange.toLowerCase()] : exchangeChartColors.light[set.exchange.toLowerCase()],
backgroundColor: isDark ? exchangeChartColors.dark[set.exchange.toLowerCase()] : exchangeChartColors.light[set.exchange.toLowerCase()]
}
})
}
},
options: {
annotation: {
annotations
},
responsive: true,
title: {
display: true,
text: 'Balances',
fontSize: 20,
fontStyle: 'bold',
lineHeight: 2.5,
fontColor: rgbaColor('#cccccc', 0.7)
},
legend: {
labels: {
fontSize: 16,
fontStyle: 'italic',
fontColor: rgbaColor('#cccccc', 0.7)
},
display: true,
position: 'bottom'
},
tooltips: {
mode: 'index',
displayColors: true
},
hover: {
mode: 'label'
},
scales: {
xAxes: [
{
display: true,
id: 'x-axis-0',
scaleLabel: {
display: true,
labelString: 'Time',
fontSize: 12,
fontColor: rgbaColor('#cccccc', 0.7)
},
ticks: {
callback: () => '',
fontColor: rgbaColor('#cccccc', 0.7),
fontStyle: 600
}
}
],
yAxes: [
{
display: true,
id: 'y-axis-0',
scaleLabel: {
display: true,
labelString: 'Balance (£)',
fontSize: 14,
fontColor: rgbaColor('#cccccc', 0.7)
},
ticks: {
min: 0,
fontColor: rgbaColor('#cccccc', 0.7),
fontStyle: 600
}
}
]
}
}
}
return !props.balances.length ? (
<Card className="text-center mb-3">
<CardBody className="p-5">
<div className="display-2 text-200">No Data</div>
<p className="lead mt-4 text-800 text-sans-serif font-weight-semi-bold">There are no balances to display.</p>
<hr />
<p>Please edit your time period search (or remove it altogether) to see data</p>
</CardBody>
</Card>
) : (
<Card className="mb-3">
<CardBody className="rounded-soft bg-gradient">
<Line data={config.data} options={config.options} />
</CardBody>
</Card>
)
}
export default ProfitsLineChart
This is the config that is spit out that the chart is using:
{
"options": {
"annotation": {
"annotations": [
{
"type": "line",
"mode": "vertical",
"drawTime": "afterDatasetDraw",
"scaleID": "x-axis-0",
"value": "08/03/2020 # 14:47",
"borderColor": "rgba(239, 131, 0, 0.8)",
"borderWidth": 2,
"label": {
"content": "BETFAIR ~ DEPOSIT ~ 22",
"enabled": true,
"position": "top"
}
},
{
"type": "line",
"mode": "vertical",
"drawTime": "afterDatasetDraw",
"scaleID": "x-axis-0",
"value": "03/03/2020 # 23:04",
"borderColor": "rgba(119, 0, 255, 0.8)",
"borderWidth": 2,
"label": {
"content": "BETDAQ ~ DEPOSIT ~ 26.57",
"enabled": true,
"position": "top"
}
},
{
"type": "line",
"mode": "vertical",
"drawTime": "afterDatasetDraw",
"scaleID": "x-axis-0",
"value": "19/03/2020 # 17:57",
"borderColor": "rgba(68, 254, 59, 0.8)",
"borderWidth": 2,
"label": {
"content": "SMARKETS ~ DEPOSIT ~ 21",
"enabled": true,
"position": "top"
}
},
{
"type": "line",
"mode": "vertical",
"drawTime": "afterDatasetDraw",
"scaleID": "x-axis-0",
"value": "27/03/2020 # 12:55",
"borderColor": "rgba(239, 131, 0, 0.8)",
"borderWidth": 2,
"label": {
"content": "BETFAIR ~ WITHDRAWAL ~ -10",
"enabled": true,
"position": "top"
}
},
{
"type": "line",
"mode": "vertical",
"drawTime": "afterDatasetDraw",
"scaleID": "x-axis-0",
"value": "27/03/2020 # 13:02",
"borderColor": "rgba(119, 0, 255, 0.8)",
"borderWidth": 2,
"label": {
"content": "BETDAQ ~ WITHDRAWAL ~ -10",
"enabled": true,
"position": "top"
}
},
{
"type": "line",
"mode": "vertical",
"drawTime": "afterDatasetDraw",
"scaleID": "x-axis-0",
"value": "01/03/2020 # 09:45",
"borderColor": "rgba(68, 254, 59, 0.8)",
"borderWidth": 2,
"label": {
"content": "SMARKETS ~ WITHDRAWAL ~ -26.57",
"enabled": true,
"position": "top"
}
}
]
}
},
"responsive": true,
"title": {
"display": true,
"text": "Balances",
"fontSize": 20,
"fontStyle": "bold",
"lineHeight": 2.5,
"fontColor": "rgba(204,204,204,0.7)"
},
"legend": {
"labels": {
"fontSize": 16,
"fontStyle": "italic",
"fontColor": "rgba(204,204,204,0.7)"
},
"display": true,
"position": "bottom"
},
"tooltips": {
"mode": "index",
"displayColors": true
},
"hover": {
"mode": "label"
},
"scales": {
"xAxes": [
{
"display": true,
"id": "x-axis-0",
"scaleLabel": {
"display": true,
"labelString": "Time",
"fontSize": 12,
"fontColor": "rgba(204,204,204,0.7)"
},
"ticks": {
"fontColor": "rgba(204,204,204,0.7)",
"fontStyle": 600
}
}
],
"yAxes": [
{
"display": true,
"id": "y-axis-0",
"scaleLabel": {
"display": true,
"labelString": "Balance (£)",
"fontSize": 14,
"fontColor": "rgba(204,204,204,0.7)"
},
"ticks": {
"min": 0,
"fontColor": "rgba(204,204,204,0.7)",
"fontStyle": 600
}
}
]
}
}
I can't think as to why this is not working as intended. getXAxis ensures that the string timestamps of the annotations are added to the X-Axis as well. I'm lost for ideas
Look at this:
https://github.com/reactchartjs/react-chartjs-2/issues/201#issuecomment-579630734
and here, for vertical line instead of horizontal, write
mode: 'vertical',

react-particle-js not updating the number of particles

I have:
return (
<Particles
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
zIndex: -1
}}
params={{
number: {
value: 400,
density: {
enable: true,
value_area: 800
}
},
line_linked: {
enable: true,
distance: 150,
color: "#ffffff",
opacity: 0.4,
width: 1
},
"shape": {
"type": "circle",
"stroke": {
"width": 0,
"color": "#000000"
},
polygon: {
nb_sides: 7
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": true,
"mode": "grab"
},
"onclick": {
"enable": true,
"mode": "push"
},
"resize": true
},
"modes": {
"grab": {
"distance": 400,
"line_linked": {
"opacity": 1
}
},
"repulse": {
"distance": 200,
"duration": 0.4
}
}
},
"retina_detect": true
}} />
No matter how high I make number.value, the number of particles on the screen just doesn't increase. Any thoughts on what I'm doing wrong?
You've missed to enclose this properties inside particles. Also remove the z-index property from styles or set it to 0 that will display the particles
particles: {
number: {
value: 400,
density: {
enable: true,
value_area: 800
}
},
line_linked: {
enable: true,
distance: 150,
color: "#ffffff",
opacity: 0.4,
width: 1
},
"shape": {
"type": "circle",
"stroke": {
"width": 0,
"color": "#000000"
},
polygon: {
nb_sides: 7
}
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": true,
"mode": "grab"
},
"onclick": {
"enable": true,
"mode": "push"
},
"resize": true
},
"modes": {
"grab": {
"distance": 400,
"line_linked": {
"opacity": 1
}
},
"repulse": {
"distance": 200,
"duration": 0.4
}
}
},
"retina_detect": true

Resources