ApexCharts don't showing toolbar - reactjs

I'm using ApexCharts with React and i'm using a line's chart and it's not showing the toolbar, someone can help me?
My summed up state of options:
const [propriedades, setPropriedades] = useState({
options: {
chart: {
height: 150,
type: 'line',
selection: {
enabled: true
},
toolbar: {
tools: {
zoomin: true,
zoomout: true,
}
}
},
dataLabels: {
enabled: false
},
stroke: {
curve: 'straight'
}
},
});

xaxis: {tickPlacement: "on"},
For Angular it was solved by adding this line

Related

Using chartjs to limit data?

I have a react chartjs project that uses chartjs-chart-matrix to render a heatmap. My code config looks like so:
const getHeatmapConfig = ({
heatmapData,
getBackgroundColor,
xAxisLabels,
tissues: items,
openMenu,
title
}) => ({
type: 'matrix',
data: {
datasets: [
{
data: heatmapData,
backgroundColor: function (ctx) {
const value = ctx.dataset.data[ctx.dataIndex].v;
return getBackgroundColor(colors, value);
},
}
]
},
options: {
scales: {
x: {
type: 'category',
labels: xAxisLabels,
offset: true,
position: 'bottom',
stacked: true,
ticks: {
autoSkip: true,
maxRotation: 90,
minRotation: 90
},
grid: {
display: false,
drawBorder: false
}
},
y: {
type: 'category',
labels: items,
reverse: false,
offset: true,
grid: {
display: false,
drawBorder: false
},
ticks: {
autoSkip: true
}
}
},
plugins: {
legend: false,
title: {
align: 'center',
font: { size: 15 },
display: true,
text: title
},
tooltip: {
callbacks: {
title() {
return '';
},
}
}
}
}
});
My question is - I want to ensure that their are never more than 50 values and labels on the x axis but there doesn't seem to be a straightforward way of limiting the data like this. Is it possible?
You should limit the array of labels that you pass into your component.
For example: xAxisLabels.slice(0, 50)

chartjs-plugin-zoom: get currently visible values when the page first loads

I have a chart component called genStarts whose view depends on the visible data of the following chart (singleChart). I'm using the onZoomComplete and onPanComplete options to insert my getVisibleValues function so that genStarts can be updated on zooms and pans. However, I have no way to get the currently visible values when the page first starts up. My getVisibleValues function does not work outside of the chartStyle object, and I haven't found a chart option that executes on startup.
In other words, my genStarts graph is only populated when SingleChart is zoomed or panned but I want it to be populated immediately.
const SingleChart = React.memo(({ setVisible }) => {
function getVisibleValues({ chart }) {
setVisible(chart.scales.x.ticks);
}
const chartStyle = {
options: {
animation: false,
maintainAspectRatio: false,
responsive: true,
plugins: {
zoom: {
zoom: {
wheel: {
enabled: true,
modifierKey: "shift",
},
pinch: {
enabled: true,
},
enabled: true,
drag: true,
mode: "x",
onZoomComplete: getVisibleValues,
},
pan: {
enabled: true,
mode: "x",
speed: 2,
onPanComplete: getVisibleValues,
},
mode: "xy",
},
legend: {
display: false,
},
},
scales: {
y: {
type: "linear",
display: "true",
position: "left",
grid: {
drawBorder: true,
color: "#000000",
},
ticks: {
beginAtZero: true,
color: "#000000",
},
title: {
display: yAxisLabel != "",
text: yAxisLabel,
},
},
x: {
max: 9,
grid: {
drawBorder: true,
color: "#00000",
},
ticks: {
beginAtZero: false,
color: "#000000",
},
},
},
},
};
// ... some code to get chartData
return (
<div>
<Line
data={chartData}
options={chartStyle.options}
width={20}
height={195}
/>
</div>
);
});
export default SingleChart;
You can make use of the animations, they have a property to check if its the first time they have fired, although since you dont want animations you will need to set the main one to a verry low number and at least the tooltip to false and the transition duration of active elements to 0.
const getVisibleValues = ({
chart
}) => {
console.log(chart.scales.x.ticks.map(el => ({
value: el.value,
label: el.label
}))) // Map because stack console prints whole circular context which takes long time
}
const options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderColor: 'pink'
}]
},
options: {
animation: {
onComplete: (ani) => {
if (ani.initial) {
getVisibleValues(ani)
}
},
duration: 0.0001
},
transitions: {
active: {
animation: {
duration: 0
}
}
},
plugins: {
tooltip: {
animation: false
}
}
}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.js"></script>
</body>

High charts / Stacked Bar - Legends Disable hover

We have implemented high chart - Stacked bar as below -
const options = {
chart: {
….
},
title: {
text: ''
},
xAxis: {
visible: false,
categories: ['']
},
credits: {
enabled: false
},
yAxis: {
visible: false,
…….
},
legend: {
itemStyle: {
cursor: 'default',
fontWeight: 'normal'
},
reversed: true
},
plotOptions: {
series: {
cursor: 'default',
stacking: 'normal',
enableMouseTracking: false,
events: {
legendItemClick: function () {
return false;
}
},
states: {
hover: {
enabled: false
}
}
}
},
tooltip: {
useHTML: true,
enabled: false,
outside: true,
followPointer: true,
crosshairs: false,
},
accessibility: {
…….
},
exporting: {
enabled: false
},
series: props.series
};
It loads fine, also hovering on any of the block does not change opacity for other blocks.
How can we disable hovering on legends below stacked bar?
Example - http://jsfiddle.net/clockworked247/FGmgC/
In above link, basically hover effect on John, Joe, Jane, Janet legends need to be disabled.
Thanks all.
Below answer helped, and worked.
Above link should help. If you are looking for more solutions you can also achieve it using CSS. Make pointer event none for legends like .highcharts-legend-item:{ pointer-events:none; }

Apexcharts tooltip styles don't applied

I'm trying to apply some basic style into my tooltip using ApexCharts in React.
This is my configuration:
const options = {
chart: {
foreColor: "#ffffff12",
toolbar: {
show: false
}
},
colors: ["white"],
stroke: {
width: 3
},
grid: {
borderColor: "#ffffff12",
borderWidth: 1,
clipMarkers: false,
yaxis: {
lines: {
show: false
}
},
xaxis: {
lines: {
show: true,
},
}
},
dataLabels: {
enabled: false
},
fill: {
gradient: {
enabled: true,
opacityFrom: 0.4,
opacityTo: 0
}
},
markers: {
size: 0
},
tooltip: {
enabled: true,
style: {
fontSize: '20px',
fontFamily: 'Roboto'
},
x: {
show: true,
format:'HH:mm'
},
y: {
formatter:(value) => `${value}$`
},
marker: {
show: false,
},
theme:'dark'
},
...
I'm able to see it with the dark default values (like dark background and white font color etc...), but I'm not able to make it work with my own.
Thanks in advance!
Please add id property to parent of chart element like this.
#chartContainer .apexcharts-tooltip {
color: #000000;
}
#chartContainer .apexcharts-tooltip .apexcharts-tooltip-series-group.active {
background: #ffffff !important;
}
The tooltip in ApexCharts can be targetted directly through CSS as it is just an HTML element.
Change the tooltip style by overriding .apexcharts-tooltip class and any inner elements inside it.
.apexcharts-tooltip.light{
background:red;
color:green;
}

Zoom and Pan in react-chartjs-2

I have recently implemented chart display using react-chartjs-2 (https://github.com/jerairrest/react-chartjs-2)
I want to enable zooming and panning feature so that it will be more user-friendly in touch based screens. To implement this features, I installed react-hammerjs and chartjs-plugin-zoom.
import {Chart, Line} from 'react-chartjs-2';
import Hammer from 'react-hammerjs';
import zoom from 'chartjs-plugin-zoom'
And I registered the plugin
componentWillMount(){
Chart.plugins.register(zoom)
}
And the render method goes as follows:
render(){
return <Line data={data} options={options} />
}
Pan and Zoom options:
pan:{
enabled=true,
mode:'x'
},
zoom:{
enabled:true,
drag:true,
mode:'xy'
}
I guess this is the correct method to implement. Unfortunately, the above implementation did not work. I will be really grateful if some of you guys already implemented Zooming and Panning using react-chartjs-2 plugin, please share if how you achieved these functionalities. Or you could point out the problem in my code above.
In order to add Zoom and Pan capabilities to your chart components based on react-chartjs-2, you can follow the steps as shown below:
Step 1: you need to install chartjs-plugin-zoom
$ npm install chartjs-plugin-zoom
Step 2: Import chartjs-plugin-zoom in your chart component
import 'chartjs-plugin-zoom';
Step 3: Enable zoom and pan in the ChartJS component options
zoom: {
enabled: true,
mode: 'x',
},
pan: {
enabled: true,
mode: 'x',
},
That's it. So now your chart component should look like this:
import React from 'react';
import { Line } from 'react-chartjs-2';
import 'chartjs-plugin-zoom';
export default function TimelineChart({ dailyDataSets }) {
const lineChart = dailyDataSets[0] ? (
<Line
data={{
labels: dailyDataSets.map(({ date }) => date),
datasets: [
{
data: dailyDataSets.map((data) => data.attr1),
label: 'First data set',
borderColor: 'red',
fill: true,
},
{
data: dailyDataSets.map((data) => data.attr2),
label: 'Second data set',
borderColor: 'green',
fill: true,
},
],
}}
options={{
title: { display: true, text: 'My Chart' },
zoom: {
enabled: true,
mode: 'x',
},
pan: {
enabled: true,
mode: 'x',
},
}}
/>
) : null;
return <div>{lineChart}</div>;
}
Notes:
You don't have to install hammerjs explicitly, as it will be automatically included by installing chartjs-plugin-zoom as its dependency, see below:
$ npm ls
...
├─┬ chartjs-plugin-zoom#0.7.7
│ └── hammerjs#2.0.8
...
One way to zoom as an example (at least for Mac), you can move your mouse pointer into the chart area, and then scroll your mouse down or up. Once zoomed in, you can keep your mouse clicked while dragging left or right.
There's a syntax error under pan object for enabled attribute.
You've mistakenly put = instead of :
Replace this:
pan:{
enabled=true,
...
},
With:
pan:{
enabled:true,
...
},
And also as #Jun Bin suggested:
Install hammerjs as:
npm install hammerjs --save
And in your component, import it as:
import Hammer from "hammerjs";
you imported the wrong hammer it should be from "hammerjs";
You need to add import 'chartjs-plugin-zoom'; and then add zoom options into options.plugins.zoom, like:
const options = {
plugins: {
zoom: {
pan: {
enabled: true,
mode: 'x',
},
zoom: {
enabled: true,
drag: true,
mode: 'xy'
}
}
}
};
I am trying to do this in a NextJS Project. But to no success so far.
I am using a timeseries plot with date-fns/locale for German and English and keep getting this error:
Cannot convert a Symbol value to a string
TypeError: Cannot convert a Symbol value to a string at TypedRegistry.register (webpack-internal:///./node_modules/chart.js/dist/chart.esm.js:4802:50) at Registry._exec (webpack-internal:///./node_modules/chart.js/dist/chart.esm.js:4927:21) at eval (webpack-internal:///./node_modules/chart.js/dist/chart.esm.js:4919:16) at each (webpack-internal:///./node_modules/chart.js/dist/chunks/helpers.segment.js:233:10) at eval (webpack-internal:///./node_modules/chart.js/dist/chart.esm.js:4917:70) at Array.forEach (<anonymous>) at Registry._each (webpack-internal:///./node_modules/chart.js/dist/chart.esm.js:4912:15) at Registry.add (webpack-internal:///./node_modules/chart.js/dist/chart.esm.js:4870:10) at Function.value [as register] (webpack-internal:///./node_modules/chart.js/dist/chart.esm.js:6192:16) at eval (webpack-internal:///./components/Charts/PortfolioPriceLineDual.jsx:39:45) at Module../components/Charts/PortfolioPriceLineDual.jsx (https://dev.domain.de/_next/static/chunks/components_Charts_PortfolioPriceLineDual_jsx.js:7758:1) at Module.options.factory (https://dev.domain.de/_next/static/chunks/webpack.js?ts=1653499440538:655:31) at __webpack_require__ (https://dev.domain.de/_next/static/chunks/webpack.js?ts=1653499440538:37:33) at Function.fn (https://dev.domain.de/_next/static/chunks/webpack.js?ts=1653499440538:310:21)
My Component:
import { Line } from 'react-chartjs-2'
import 'chartjs-adapter-date-fns'
import { de, enGB, ja } from 'date-fns/locale'
import dynamic from 'next/dynamic'
import 'chart.js/auto'
import { useRouter } from 'next/router'
import { Chart } from 'chart.js'
// import zoomPlugin from 'chartjs-plugin-zoom';
const zoomPlugin = dynamic(() => import('chartjs-plugin-zoom'), {
ssr: false,
})
Chart.register(zoomPlugin);
const PortfolioPriceLineDual = ({
title,
data,
unit,
axesOptions,
showLegend = true,
}) => {
const totalDuration = 5000
const delayBetweenPoints = totalDuration / data.datasets[0].data.length
// const animation =
const { locale } = useRouter()
let format
switch (locale) {
case 'de-DE':
format = de
break
case 'en-US':
format = enGB
break
case 'ja-JP':
format = ja
break
default:
break
}
return (
<Line
data={data}
options={{
responsive: true,
// maintainAspectRatio: true,
// aspectRatio: 16 / 9,
resizeDelay: 5,
animation: {
x: {
type: 'number',
easing: 'linear',
duration: delayBetweenPoints,
from: NaN, // the point is initially skipped
delay: (ctx) => {
if (ctx.type !== 'data' || ctx.xStarted) {
return 0
}
ctx.xStarted = true
return ctx.index * delayBetweenPoints
},
},
y: {
type: 'number',
easing: 'linear',
duration: delayBetweenPoints,
from: (ctx) => {
return ctx.index === 0
? ctx.chart.scales.y.getPixelForValue(100)
: ctx.chart
.getDatasetMeta(ctx.datasetIndex)
.data[ctx.index - 1].getProps(['y'], true).y
},
delay: (ctx) => {
if (ctx.type !== 'data' || ctx.yStarted) {
return 0
}
ctx.yStarted = true
return ctx.index * delayBetweenPoints
},
},
y1: {
type: 'number',
easing: 'linear',
duration: delayBetweenPoints,
from: (ctx) => {
return ctx.index === 0
? ctx.chart.scales.y.getPixelForValue(100)
: ctx.chart
.getDatasetMeta(ctx.datasetIndex)
.data[ctx.index - 1].getProps(['y'], true).y
},
delay: (ctx) => {
if (ctx.type !== 'data' || ctx.yStarted) {
return 0
}
ctx.yStarted = true
return ctx.index * delayBetweenPoints
},
},
},
interaction: {
mode: 'index',
intersect: false,
},
scales: {
x: {
type: 'time',
time: {
unit: 'year',
displayFormats: {
quarter: 'yyyy',
},
tooltipFormat: 'MMMM yyyy',
},
adapters: {
date: {
locale: format,
},
},
ticks: {
align: 'start',
color: '#122a42',
font: {
size: 14,
weight: 'bold',
},
},
grid: {
display: true,
drawBorder: false,
drawOnChartArea: true,
drawTicks: true,
},
},
y: {
type: 'logarithmic',
grid: {
display: true,
drawBorder: false,
drawOnChartArea: true,
drawTicks: true,
},
ticks: {
color: '#122a42',
align: 'end',
font: {
size: 10,
weight: 'normal',
},
// Include a dollar sign in the ticks
// stepSize: 1000,
callback: function (value) {
// callback: function (value, index, ticks) {
return `${new Intl.NumberFormat(locale, axesOptions).format(
value
)}`
},
},
},
y1: {
type: 'linear',
display: true,
position: 'right',
// grid line settings
grid: {
drawOnChartArea: false, // only want the grid lines for one axis to show up
},
ticks: {
color: '#122a42',
align: 'end',
font: {
size: 10,
weight: 'normal',
},
// Include a dollar sign in the ticks
// stepSize: 1000,
callback: function (value) {
// callback: function (value, index, ticks) {
return `${new Intl.NumberFormat(locale, axesOptions).format(
value
)}`
},
},
},
},
zoom: {
enabled: true,
mode: 'x',
},
pan: {
enabled: true,
mode: 'x',
},
plugins: {
zoom: {
enabled: true,
mode: 'x',
},
pan: {
enabled: true,
mode: 'x',
},
// zoom: {
// zoom: {
// wheel: {
// enabled: true,
// },
// pinch: {
// enabled: true,
// },
// mode: 'x',
// },
// },
title: {
display: true,
color: '#151C30',
font: {
size: 26,
weight: 'bold',
style: 'normal',
},
padding: {
bottom: 10,
},
text: `${title}`,
},
tooltip: {
enabled: true,
backgroundColor: '#122a42',
itemSort: function (a, b) {
return b.raw - a.raw
},
callbacks: {
label: function (context) {
let label = context.dataset.label || ''
if (label) {
label += ': '
}
if (context.parsed.y !== null) {
label += `${new Intl.NumberFormat(locale, axesOptions).format(
context.parsed.y
)} ${unit}`
}
return label
},
},
},
legend: {
position: 'bottom',
labels: {
// This more specific font property overrides the global property
color: '#151C30',
font: {
size: 12,
weight: 'light',
},
},
},
},
}}
/>
)
}
export default PortfolioPriceLineDual

Resources