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>
Related
This is my code in Particle.js
import React from "react";
import Particles from "react-tsparticles";
function Particle() {
return (
<Particles
id="tsparticles"
params={{
particles: {
number: {
value: 160,
density: {
enable: true,
value_area: 1500,
},
},
line_linked: {
enable: false,
opacity: 0.03,
},
move: {
direction: "right",
speed: 0.05,
},
size: {
value: 1,
},
opacity: {
anim: {
enable: true,
speed: 1,
opacity_min: 0.05,
},
},
},
interactivity: {
events: {
onclick: {
enable: true,
mode: "push",
},
},
modes: {
push: {
particles_nb: 1,
},
},
},
retina_detect: true,
}}
/>
);
}
export default Particle;
and I call particle in Home.js
import Particle from "../Particle";
import Button from 'react-bootstrap/Button';
function Home() {
return (
<div className="mt-5">
<Particle/>
<Button href="" target="_blank" className="register-btn-inner" size="lg">
Register
</Button>
</div>
);
}
export default Home;
I checked a lot of same questions like particles.js not showing up in reactjs project and Particle.js not showing particles on ReactJS website
but solutions don't help me at all. I searched a lot but I don't understand my mistake. why Particle doesn't work?
I installed tsparticles and react-tsparticles libraries too.
You are missing the init attribute on the Particles component. It's visible in the documentation as well here
This is the documentation example:
import { useCallback } from "react";
import Particles from "react-particles";
import { loadFull } from "tsparticles";
const App = () => {
const particlesInit = useCallback(async engine => {
console.log(engine);
// you can initiate the tsParticles instance (engine) here, adding custom shapes or presets
// this loads the tsparticles package bundle, it's the easiest method for getting everything ready
// starting from v2 you can add only the features you need reducing the bundle size
await loadFull(engine);
}, []);
const particlesLoaded = useCallback(async container => {
await console.log(container);
}, []);
return (
<Particles
id="tsparticles"
init={particlesInit}
loaded={particlesLoaded}
options={{
background: {
color: {
value: "#0d47a1",
},
},
fpsLimit: 120,
interactivity: {
events: {
onClick: {
enable: true,
mode: "push",
},
onHover: {
enable: true,
mode: "repulse",
},
resize: true,
},
modes: {
push: {
quantity: 4,
},
repulse: {
distance: 200,
duration: 0.4,
},
},
},
particles: {
color: {
value: "#ffffff",
},
links: {
color: "#ffffff",
distance: 150,
enable: true,
opacity: 0.5,
width: 1,
},
collisions: {
enable: true,
},
move: {
directions: "none",
enable: true,
outModes: {
default: "bounce",
},
random: false,
speed: 6,
straight: false,
},
number: {
density: {
enable: true,
area: 800,
},
value: 80,
},
opacity: {
value: 0.5,
},
shape: {
type: "circle",
},
size: {
value: { min: 1, max: 5 },
},
},
detectRetina: true,
}}
/>
);
};
When I try to draw a graph, I get an error:echarts.min.js:45 Uncaught TypeError: Bind must be called on a function at bind (<anonymous>) at Bd (echarts.min.js:45:130031)
My echarts-init.js:
let domTemp = document.getElementById("main");
let mytempChart = echarts.init(domTemp, null, {
renderer: 'canvas',
useDirtyRect: false
});
var app = {};
var option;
runDaysDatas(sens_data_result, sens_name_list);
function runDaysDatas(sens_data_result, sens_name_list) {
const sens_names = sens_name_list;
const datasetWithFilters = [];
const seriesList = [];
echarts.util.each(sens_names, function (sens) {
var datasetId = 'dataset_' + sens;
datasetWithFilters.push({
id: datasetId,
fromDatasetId: sens_data_result,
transform: {
type: 'filter',
config: {
and: [
{ dimension: 'Uid', '=': sens }
]
}
}
});
seriesList.push({
type: 'line',
datasetId: datasetId,
showSymbol: false,
name: sens,
endLabel: {
show: true,
formatter: function (params) {
return params.value[3] + ': ' + params.value[0];
}
},
labelLayout: {
moveOverlap: 'shiftY'
},
emphasis: {
focus: 'series'
},
encode: {
x: 'Date',
y: 'Temperature',
label: ['Name', 'Temperature'],
itemName: 'Date',
tooltip: ['Temperature']
}
});
});
option = {
animationDuration: 10000,
dataset: [
{
id: 'dataset_sens_names',
source: sens_data_result
},
...datasetWithFilters
],
title: {
text: 'Temperature for Day'
},
tooltip: {
order: 'valueDesc',
trigger: 'axis'
},
xAxis: {
type: 'category',
nameLocation: 'middle'
},
yAxis: {
name: 'Temperature'
},
grid: {
right: 140
},
series: seriesList
};
mytempChart.setOption(option);
}
In sens_data_result i pass data from api.
In sens_name_list i pass names of the sensors.
The console does not send errors to my script, it swears at the library. I took an example from the official site and remade it for my task, displaying the temperature by time of day with the name of the sensor. There can be N number of graphs on one chart.
Thnx for help!
Okey, i'm a solved the problem, this is decision:
let url = '/api/sensdata';
let domTemp = document.getElementById("main");
let mytempChart = echarts.init(domTemp, null, {
renderer: 'canvas',
useDirtyRect: false
});
var app = {};
var option;
$.get(
url,
sensors_uid,
(_rawData) => {
runDaysDatas(_rawData, sens_name_list);
}
);
function runDaysDatas(_rawData, sens_names) {
const datasetWithFilters = [];
const seriesList = [];
_rawData.unshift(['Name', 'Date', 'Humidity', 'Temperature']);
echarts.util.each(sens_names, function (sens) {
var datasetId = 'dataset_' + sens;
datasetWithFilters.push({
id: datasetId,
fromDatasetId: 'dataset_raw',
transform: {
type: 'filter',
config: {
and: [
{ dimension: 'Name', '=': sens }
]
}
}
});
seriesList.push({
type: 'line',
datasetId: datasetId,
showSymbol: false,
name: sens,
endLabel: {
show: true,
formatter: function (params) {
return 'Uid ' + params.value[0] + ': ' + params.value[3] + '°C';
}
},
labelLayout: {
moveOverlap: 'shiftY'
},
emphasis: {
focus: 'series'
},
encode: {
x: 'Date',
y: 'Temperature',
label: ['Name', 'Temperature'],
itemName: 'Temperature',
tooltip: ['Temperature']
},
});
});
console.log(seriesList);
option = {
toolbox: {
show : true,
feature : {
magicType : {show: true, type: ['line', 'bar']},
restore : {show: true},
saveAsImage : {show: true}
}
},
legend: {},
dataset: [
{
id: 'dataset_raw',
source: _rawData
},
...datasetWithFilters
],
tooltip: {
order: 'valueDesc',
trigger: 'axis'
},
xAxis: {
type: 'time',
nameLocation: 'middle',
axisLabel: {
formatter: (function(value){
moment.locales('RU_ru');
return moment(value).format('MM/DD HH:mm');
})
}
},
yAxis: [
{
type : 'value',
axisLabel : {
formatter: '{value} °C'
}
}
],
grid: {
right: 140
},
series: seriesList
};
mytempChart.clear();
mytempChart.setOption(option);
}
window.addEventListener('resize', mytempChart.resize);
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
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);
});
}
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,
},