reactjs apex charts not loading array into series for chart - javascript

I'm using apex charts for react in my reactJS progressive web app, and have had no issues with it for static data, but I"m now trying to take a returned array from my database and use the array for the graph and it's not working.
I'm logging the array returned from the database, which is in this structure:
And in my code, I'm setting this to the third series option of my chart named "Trends" but when the graph loads the line for that data is 'Nan'
What am I doing wrong here?
class TrendsComponent extends Component {
constructor(props) {
super(props);
this.state = {
maxCalories: '',
calorieRecord: {
caloriesConsumed: '',
caloriesBurned: '',
createdAt: undefined,
updatedAt: undefined
},
options: {
fill: {
colors: ['#FF756D', '#85DE77', '#FFF49C']
},
dataLabels: {
enabled: true,
textAnchor: 'middle',
distributed: false,
offsetX: 0,
offsetY: 0,
style: {
fontSize: '14px',
fontFamily: 'Helvetica, Arial, sans-serif',
fontWeight: 'bold',
colors: ["#FF756D", "#85DE77", "#FFF49C"]
},
background: {
enabled: true,
foreColor: '#fff',
padding: 4,
borderRadius: 2,
borderWidth: 1,
borderColor: '#fff',
opacity: 0.9,
},
dropShadow: {
enabled: true,
top: 1,
left: 1,
blur: 1,
color: '#000',
opacity: 0.8
}
},
colors: ["#FF756D", "#85DE77", "#FFF49C"],
chart: {
toolbar: {
show:false
},
id: "basic-bar"
},
xaxis: {
categories: ['3/20', '3/21', '3/22', '3/23', '3/24', '3/25','3/26']
}
},
series: [
{
name: "Baseline",
data: [250,500,234,389,644,245,590]
},
{
name: "Optimal",
data: [2250,2250,2250,2250,2250,2250,2250]
},
{
//this is the line where I'm getting NaN
name: "Trend (tracked)",
data: [this.maxCalories]
}
]
};
}
...
UPDATE:
Upon component mounting, I use these functions to set MaxCalories which is the data array I'm using for the chart
getMax = () => {
this.state.caloriesDB.db.createIndex({
index: {
fields: ['_id','caloriesBurned']
}
}).then(result => {
console.log(result);
this.setMax();
}).catch((err) =>{
console.log(err);
});
}
setMax = () => {
this.state.caloriesDB.db.find({
selector: {
$and: [
{_id: {"$gte": null}},
{caloriesBurned: {$exists: true}},
]
},
fields: ['caloriesBurned'],
sort: [{'_id':'desc'}],
limit: 7
}).then(result => {
console.log('max');
console.log(result);
const newDocs = result.docs;
this.setState({
maxCalories: newDocs.map(docs => docs)
});
console.log('maxCalories');
console.log(this.state.maxCalories);
}).catch((err) =>{
console.log(err);
});
}

Related

Broken apexcharts legend (vue-apexcharts)

i just create simple piechart with vue-apexchart. expected process what I want is,
set default config chart
mutate the component then re-config the chart based on props
render it
i was success this scenario works, but idk what happens with my pie chart. this is my pie chart
the legend successfully showed, but the legend position is bedhind of pie. i am trying to add offsetY in chart options and legend options. it's still not working.
am i miss something ?
this is my code
<script>
import VueApexCharts from 'vue-apexcharts'
export default {
components: {
'apexchart': VueApexCharts,
},
props: {
name: {default: "Durasi Parkir"},
value: {default: () => ({})},
height: {default: "320"},
dir: {default: "ltr"},
is_showed_legend: {default: true},
is_floating_legend: {default: true},
legend_position: {default: "top"},
legend_vertical_align: {default: "center"},
legend_horizontal_align: {default: "center"},
legend_font_size: {default: "14px"},
legend_x_offset: {default: 0},
legend_y_offset: {default: 0},
responsive_breakpoints: {default: 600},
responsive_chart_height: {default: 240},
is_responsive_show_legend: {default: false},
additional_class: {default: ""}
},
data: () => ({
series: [],
options: {
labels: [],
colors: [],
chart: {
offsetY: 0, // iam trying to add offset but its still not works
},
legend: {
show: true,
position: "bottom",
horizontalAlign: 'center',
verticalAlign: 'middle',
floating: false,
fontSize: "14px",
offsetX: 0,
offsetY: 10,
},
responsive: [{
breakpoint: 0,
options: {
chart: {
height: 0
},
legend: {
show: false
},
}
}]
}
}),
created() {
this.processThemingChart()
},
methods: {
formatChartColor(index = 0) {
let array_colors = [this.$utility.getPrimaryColor(), "#b6b6b6", "#5fa2f4", "#5abf78",
"#6983aa", "#e97171", "#ede682", "#ba7967", "#f1c5c5", "#f69e7b"]
if (index) return array_colors[index]
else return array_colors
},
processFillChartColor() {
this.options.colors = this.formatChartColor()
},
processFillChartOption() {
this.options.legend.position = this.legend_position
this.options.legend.fontSize = this.legend_font_size
this.options.legend.show = this.is_showed_legend
this.options.legend.floating = this.is_floating_legend
this.options.responsive[0].breakpoint = this.responsive_breakpoints
this.options.responsive[0].options.chart.height = this.responsive_chart_height
this.options.responsive[0].options.legend.show = this.is_responsive_show_legend
this.options.legend.horizontalAlign = this.legend_horizontal_align
this.options.legend.verticalAlign = this.legend_vertical_align
this.options.legend.offsetY = this.legend_y_offset
this.options.legend.offsetX = this.legend_x_offset
},
processThemingChart() {
this.processFillChartColor()
this.processFillChartOption()
this.processDataChart()
},
processDataChart() {
this.series = []
this.options.labels = []
this.value.forEach(item => {
this.series.push(item.value)
this.options.labels.push(item.text)
})
},
processFillChart() {
try {
(this.value !== '') ? this.processDataChart() : ''
} catch (e) {
this.$sentry.captureException(e, `user gagal merender grafik ${this.name}`)
}
},
}
}
</script>
<template>
<apexchart :class="`apex-charts ${additional_class}`" :height="height" type="pie" :dir="dir"
:series="series" :options="options"
></apexchart>
</template>

Apex charts, setting series data from array in state

In my react app, I'm getting results from pouchDB that I want to use as the data points in my series for apexCharts.
I'm getting the results and putting them in state, called maxCalories, and when logging in the console they are in this format:
So I want those 7 numbers (all with the index name of caloriesBurned to be my data in the series for the chart but I'm currently getting NaN on the graph.
Here's the full code, how can I set these to the correct format to use them in the chart data?
import React, { Component } from "react";
import Chart from "react-apexcharts";
import DB from '../../db';
import * as moment from 'moment';
class TrendsComponent extends Component {
constructor(props) {
super(props);
this.state = {
maxCalories: '',
calorieRecord: {
caloriesConsumed: '',
caloriesBurned: '',
createdAt: this.newestDate,
updatedAt: undefined
},
caloriesDB: new DB('calorie-records'),
calories: {},
calorieElements: null,
options: {
},
chart: {
toolbar: {
show:false
},
id: "basic-bar"
},
xaxis: {
categories: ['3/20', '3/21', '3/22', '3/23', '3/24', '3/25','3/26']
}
},
series: [
{
name: "Trend (tracked)",
data: {this.maxCalories}
}
]
};
}
componentDidMount(){
this.setMax();
}
setMax = () => {
this.state.caloriesDB.db.find({
selector: {
$and: [
{_id: {"$gte": null}},
{caloriesBurned: {$exists: true}},
{createdAt: {$exists: true}}
]
},
fields: ['caloriesBurned', 'createdAt'],
sort: [{'_id':'desc'}],
limit: 7
}).then(result => {
console.log('max');
console.log(result);
const newDocs = result.docs;
this.setState({
maxCalories: newDocs.map(docs => docs)
});
console.log('maxCalories');
console.log(this.state.maxCalories);
}).catch((err) =>{
console.log(err);
});
}
render() {
return (
<div className="mixed-chart">
<Chart
options={this.state.options}
series={this.state.series}
type="area"
stacked="true"
width="700"
/>
</div>
);
}
}
export default TrendsComponent;
I had the same problem in my project. And I spent a lot of time in looking for solution. So here what I get:
const FinacialResultChart = (props) => {
const options = {
chart: {
toolbar: {
show: false
},
animations: {
enabled: false
}
},
stroke: {
curve: "smooth",
dashArray: [0, 8],
width: [4, 2]
},
grid: {
borderColor: props.labelColor
},
legend: {
show: false
},
colors: [props.dangerLight, props.strokeColor],
fill: {
type: "gradient",
gradient: {
shade: "dark",
inverseColors: false,
gradientToColors: [props.primary, props.strokeColor],
shadeIntensity: 1,
type: "horizontal",
opacityFrom: 1,
opacityTo: 1,
stops: [0, 100, 100, 100]
}
},
markers: {
size: 0,
hover: {
size: 5
}
},
xaxis: {
labels: {
style: {
colors: props.strokeColor
}
},
axisTicks: {
show: false
},
categories: [
"Январь",
"Февраль",
"Март",
"Апрель",
"Май",
"Июнь",
"Июль",
"Август",
"Сентябрь",
"Октябрь",
"Ноябрь",
"Декабрь"
],
axisBorder: {
show: false
},
tickPlacement: "on"
},
yaxis: {
tickAmount: 5,
labels: {
style: {
color: props.strokeColor
}
}
},
tooltip: {
x: { show: false }
}
}
const data = [
{
name: "Итоговый результат",
data: props.userData.traidingMonth
}
]
return (
<Chart
options={options}
series={data}
type="line"
height={280}
/>
)
}
export default FinacialResultChart
So you need to change your class to const, and push all your props (api data for example) into your children chart component. In chart options you can get the chart data with props.data

How to get a prop from another parent-prop?

I want to set a value of prop named "dates:" which is situated in another prop-parent named "attributes:". I cant find dates: because its in array of prop attributes: and I cant set date's value in method created() because of that. How can I get access to prop "dates:" and change its value?
export default {
name: "Vacations",
data() {
return {
vacantDays: '5',
isActive: false,
vacDates: null,
occupiedDays: [new Date("03 January 2019")],
attr:
[
{
highlight: {
backgroundColor: '#ff8080', // Red background
borderColor: '#ff6666',
borderWidth: '2px',
borderStyle: 'solid',
},
contentStyle: {
color: 'white', // White text
},
dates: [5],
},
]
}
},
created() {
this.$acl.change(localStorage.getItem('user'));
let name = localStorage.getItem('username');
instance.get("/calendar/occupied",{
params: {
name: name
}
}).then(res => {
console.log(res.data);
let datesArray = res.data.map(dateString => new Date(dateString));
console.log(datesArray);
//this.attr.dates=datesArray;
console.log(this.attr.get(dates));
}).catch(err=> {
console.log(err);
});
},
}

highstock shows wrong dates in selectorRange buttons

enter image description herei get dates from server and convert all date to timestamp as required highcharts. But, rangeSelector buttons show wrong date. For, example if i have dateBegin = 02/07/2017, and dateEnd 09/07/2017, highstock dateRange shows wrong date like as 01/07/2017 - 08/07/2017. It seems that highstock show always date - 1 day. How can i fix it?
this is my init of config
onInitConfig = ({ series, periodId, height }) => {
const { onSelectRange } = this.props
moment.locale('ru', localization)
const heightChart = `${ height }px`
const config = {
chart: {
height: heightChart,
events: {
redraw: function(event) {
const currentDateBegin = Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.rangeSelector.minInput.HCTime)
const currentDateEnd = Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.rangeSelector.maxInput.HCTime)
onSelectRange && onSelectRange({ currentDateBegin, currentDateEnd })
}
}
},
rangeSelector: {
buttons: [{
type: 'week',
count: '1',
text: 'н'
},{
type: 'month',
count: 1,
text: 'м',
},{
type: 'month',
count: 3,
text: 'кв'
}, {
type: 'month',
count: '6',
text: 'пг'
},{
type: 'year',
count: 1,
text: 'г'
}],
buttonSpacing: 2,
selected: periodId - 1,
inputDateFormat: '%d/%m/%Y',
labelStyle: {
fontFamily: 'HelveticaLight',
fontSize: '14px',
}
},
title: {
align: 'left',
text: '',
},
navigation: {
buttonOptions: {
enabled: false,
}
},
navigator: {
xAxis: {
labels: {
formatter: function () {
return moment(this.value).format('DD MMMM')
},
style: {
fontFamily: 'HelveticaLight',
fontSize: '14px',
}
}
},
},
xAxis: {
labels: {
formatter: function () {
return moment(this.value).format('DD MMMM')
},
style: {
fontFamily: 'HelveticaLight',
fontSize: '14px',
}
}
},
plotOptions: {
series: {
compare: 'percent',
showInNavigator: true
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b><br/>',
valueDecimals: 2,
split: true
},
series: series
}
return config
}
this is my input
order.map((id) => {
const { dateBegin, dateEnd, valueAmount, valueCount, valueQuantity, valueCountCheck, valueCountCustomers } = data[id] || {}
const dateTimeBegin = moment(dateBegin, 'DD.MM.YYYY').toDate().getTime()
const dateTimeEnd = moment(dateBegin, 'DD.MM.YYYY').toDate().getTime()
_.merge( dataCheckCount, { [id]: { id, x: dateTimeBegin, y: valueCount } })
_.merge( dataCheckCount, { [id + 1]: { id: id + 1, x: dateTimeEnd, y: valueCount } })
}
The problem was in timezoneOffset. I add next code to global setOptions and the problem is fixed.
global: {
useUTC: false,
},

Put Rally.ui.chart.Chart charts inside a container

I'm trying to put two Rally charts inside a container to have a control over their layout. Unfortunately, for some reason, it doesn't work.
Plase see the code (the full HTML provided for convinience):
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://rally1.rallydev.com/apps/2.0rc3/sdk.js"></script>
<script type="text/javascript">
Rally.onReady(function () {
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
_atTheStartAddedChart: null,
_stateChart: null,
launch: function () {
//Write app code here
var me = this;
me._createAtTheStartAddedChart();
me._createStateChart();
console.log('chart 1', me._atTheStartAddedChart);
console.log('chart 2', me._stateChart);
me._chartContainer = Ext.create('Ext.Container', {
itemId: 'cont',
renderTo: Ext.getBody(),
layout: {
type: 'hbox',
align: 'middle'
}
,
items: [
me._atTheStartAddedChart,
me._stateChart
]
});
me.add(me._chartContainer);
},
_createAtTheStartAddedChart: function () {
var me = this;
var series = [
{
type: 'pie',
name: 'Features',
data: [
{
name: 'At the Start',
y: 20,
color: '#0CDBE8'
},
{
name: 'Added During Release',
y: 30,
color: '#FFE11A'
}
]
}
];
var chart = me._createChart(series);
me._atTheStartAddedChart = chart;
},
_createStateChart: function () {
var me = this;
var series = [
{
type: 'pie',
name: 'Features',
data: [
{
name: 'Not Completed in Time',
y: 10,
color: '#FFE11A'
},
{
name: 'Completed in Time',
y: 15,
color: '#98C000'
},
{
name: 'Removed from Release',
y: 20,
color: '#EA2E49'
},
{
name: 'Completely Removed',
y: 5,
color: '#3D4C53'
}
]
}
];
var chart = me._createChart(series);
me._stateChart = chart;
},
_createChart: function (series) {
var chart = Ext.create('Rally.ui.chart.Chart', {
chartConfig: {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false
},
title: {
text: 'Release Features'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.y}</b>'
},
plotOptions: {
pie: {
allowPointSelect: false,
cursor: 'pointer',
dataLabels: {
enabled: false
},
showInLegend: true
}
}
},
chartData: {
series: series
}
});
return chart;
}
});
Rally.launchApp('CustomApp', {
name:"Random App Name42726",
parentRepos:""
});
});
</script>
</head>
<body>
</body>
</html>
The charts are created successfully, but they are not displayed at all. There is no error related to their display, so I don't even know where to look for the issue.
Maybe someone knows how to put the charts horizontally (I don't really need Ext.Container here, any other container will be fine as well)?
There is also an error Uncaught Highcharts error #16: www.highcharts.com/errors/16 (Highcharts already defined in the page), not sure what's the reason for it as well.
I made those charts display - you may see full app and the screenshot showing both pie charts in this repo.
Here is the js file. The main change was where in the code the chart was added to container. I moved that to _createChart function. Highchart error 16 does not prevent the charts from loading. You may eventually create two containers and add the charts to separate containers, but this works in its simplest form:
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
_atTheStartAddedChart: null,
_stateChart: null,
items: [
{
xtype: 'container',
itemId: 'mychart',
columnWidth: 1
}
],
launch: function() {
this._createAtTheStartAddedChart();
this._createStateChart();
},
_createAtTheStartAddedChart: function () {
var series = [
{
type: 'pie',
name: 'Features',
data: [
{
name: 'At the Start',
y: 20,
color: '#0CDBE8'
},
{
name: 'Added During Release',
y: 30,
color: '#FFE11A'
}
]
}
];
this._createChart(series);
},
_createStateChart: function () {
var me = this;
var series = [
{
type: 'pie',
name: 'Features',
data: [
{
name: 'Not Completed in Time',
y: 10,
color: '#FFE11A'
},
{
name: 'Completed in Time',
y: 15,
color: '#98C000'
},
{
name: 'Removed from Release',
y: 20,
color: '#EA2E49'
},
{
name: 'Completely Removed',
y: 5,
color: '#3D4C53'
}
]
}
];
this._createChart(series);
},
_createChart: function (series) {
var chartDiv = this.down("#mychart");
chartDiv.add({
xtype: 'rallychart',
chartConfig: {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false
},
title: {
text: 'Release Features'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.y}</b>'
},
plotOptions: {
pie: {
allowPointSelect: false,
cursor: 'pointer',
dataLabels: {
enabled: false
},
showInLegend: true
}
}
},
chartData: {
series: series
}
});
}
});

Categories

Resources