How to aligment nodes with highcharts - reactjs

I am trying to alignment nodes, But I cant see any options how to do it,
Currently my code is
Highcharts.chart('container', {
chart: {
type: 'networkgraph',
plotBorderWidth: 1
},
title: {
text: 'Trans-Siberian Railway'
},
subtitle: {
text: 'Barnes-Hut approximation'
},
plotOptions: {
networkgraph: {
layoutAlgorithm: {
enableSimulation: false,
linkLength: 100,
integration: 'verlet',
approximation: 'barnes-hut',
gravitationalConstant: 4,
// Elastic like forces:
attractiveForce: function (d, k) {
return (k - d) / d;
},
/* repulsiveForce: function (d, k) {
return Math.min((k * k) / (d), 100);
} */
}
}
},
series: [{
marker: {
radius: 3,
lineWidth: 1
},
dataLabels: {
enabled: true,
linkFormatter: function () {
return '';
}
},
nodes: [
{
id: 'test',
marker: {
radius: 10
}
},
{
id: 'Moscow',
marker: {
radius: 10
}
}, {
id: 'Beijing',
marker: {
radius: 10
}
},
{
id: 'Brussels',
marker: {
radius: 10
}
},
{
id: 'Bangkok',
marker: {
radius: 10
}
}],
data: [
{ from: 'Bangkok', to: 'Beijing', color: 'blue' },
{ from: 'Moscow', to: 'Beijing', color: 'blue' },
{ from: 'test', to: 'Moscow', color: 'blue' },
{ from: 'Beijing', to: 'Brussels', color: 'blue' },
]
}]
});
the result of code is:
and its still not alignment the wanted results is

You should be able to set fixed positions in the networkgraph chart by using the initialPositions callback. To work it well you need also to set maxIterations to some small value, like 1.
See demo
initialPositions: function() {
var chart = this.series[0].chart,
width = chart.plotWidth,
height = chart.plotHeight;
this.nodes.forEach(function(node, i) {
if(i === 0){
node.plotX = 600;
node.plotY = 100;
}
if(i === 1) {
node.plotX = 350;
node.plotY = 100;
}
if(i === 2){
node.plotX = 200;
node.plotY = 0;
}
if(i === 3) {
node.plotX = 0;
node.plotY = 0;
}
if(i === 4) {
node.plotX = 200;
node.plotY = 200;
}
});
}
API: https://api.highcharts.com/highcharts/series.networkgraph.layoutAlgorithm.maxIterations
API: https://api.highcharts.com/highcharts/series.networkgraph.layoutAlgorithm.initialPositions
If you want to have those points not draggable, maybe an easier solution will be to render regular line chart?
Demo: https://jsfiddle.net/BlackLabel/06Lkgwbz/

Related

Set Tooltip over line Chartjs

I wanna show tooltips over the line not only on data points.
I also tried the chartjs-plugin-crosshair but it doesn't work in V3 of chartjs.
You can write a custom implementation for V3 for it:
// Options for the indicators
const indicatorOptions = {
radius: 4,
borderWidth: 1,
borderColor: 'red',
backgroundColor: 'transparent'
};
// Override getLabelAndValue to return the interpolated value
const getLabelAndValue = Chart.controllers.line.prototype.getLabelAndValue;
Chart.controllers.line.prototype.getLabelAndValue = function(index) {
if (index === -1) {
const meta = this.getMeta();
const pt = meta._pt;
const vScale = meta.vScale;
return {
label: 'interpolated',
value: vScale.getValueForPixel(pt.y)
};
}
return getLabelAndValue.call(this, index);
}
// The interaction mode
Chart.Interaction.modes.interpolate = function(chart, e, option) {
const x = e.x;
const items = [];
const metas = chart.getSortedVisibleDatasetMetas();
for (let i = 0; i < metas.length; i++) {
const meta = metas[i];
const pt = meta.dataset.interpolate({
x
}, "x");
if (pt) {
const element = new Chart.elements.PointElement({ ...pt,
options: { ...indicatorOptions
}
});
meta._pt = element;
items.push({
element,
index: -1,
datasetIndex: meta.index
});
} else {
meta._pt = null;
}
}
return items;
};
// Plugin to draw the indicators
Chart.register({
id: 'indicators',
afterDraw(chart) {
const metas = chart.getSortedVisibleDatasetMetas();
for (let i = 0; i < metas.length; i++) {
const meta = metas[i];
if (meta._pt) {
meta._pt.draw(chart.ctx);
}
}
},
afterEvent(chart, args) {
if (args.event.type === 'mouseout') {
const metas = chart.getSortedVisibleDatasetMetas();
for (let i = 0; i < metas.length; i++) {
metas[i]._pt = null;
}
args.changed = true;
}
}
})
var ctx = document.getElementById("myChart").getContext("2d");
var chart = new Chart(ctx, {
type: "line",
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
fill: true,
label: "My First dataset",
backgroundColor: "rgba(132, 0, 0, 1)",
borderColor: "rgb(255, 99, 132)",
data: [0, 10, 5, 2, 20, 30, 45]
},
{
data: [30, 40, 50],
label: 'My Second Dataset',
fill: true,
backgroundColor: "lightgreen",
borderColor: "green"
}
]
},
options: {
interaction: {
mode: "interpolate",
intersect: false,
axis: "x"
},
plugins: {
tooltip: {
displayColors: false,
}
}
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.js"></script>
<h1>Interpolating line values</h1>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"></canvas>
</div>
The following combination of chartjs-plugin-crosshair and chart.js seems to be working fine for me.
"chart.js": "^3.4.0",
"chartjs-plugin-crosshair": "^1.2.0"
I am initiating the Chart object like below:
Chart.register(CrosshairPlugin);
Which can be used properly in an useEffect block:
useEffect(() =>
Chart.register(CrosshairPlugin);
return () => {
Chart.unregister(CrosshairPlugin);
};
}, []);
And then you can pass the options of the chart like below:
{
...,
options: {
plugins: {
crosshair: {
line: {
color: "#d1d1d1",
width: 1,
},
sync: {
enabled: true,
group: 1,
suppressTooltips: false,
},
zoom: {
enabled: false,
},
}
}
}
}
Note that the configurations above, will keep the crosshair pointer synced over all your charts rendered on the same component. You may need to change the behavior here.
you can use chartjs-plugin-crosshair
function generateDataset(shift, label, color) {
var data = [];
var x = 0;
while (x < 30) {
data.push({
x: x,
y: Math.sin(shift + x / 3)
});
x += Math.random();
}
var dataset = {
backgroundColor: color,
borderColor: color,
showLine: true,
fill: false,
pointRadius: 2,
label: label,
data: data,
lineTension: 0,
interpolate: true
};
return dataset;
}
var chart1 = new Chart(document.getElementById("chart").getContext("2d"), {
type: "scatter",
options: {
plugins: {
crosshair: {
sync: {
enabled: false
},
},
tooltip: {
animation: false,
mode: "interpolate",
intersect: false,
callbacks: {
title: function(a, d) {
return a[0].element.x.toFixed(2);
},
label: function(d) {
return (
d.chart.data.datasets[d.datasetIndex].label + ": " + d.element.y.toFixed(2)
);
}
}
}
},
scales: {
x: {
min: 2,
max: 28
}
}
},
data: {
datasets: [
generateDataset(0, "A", "red")
]
}
});
<script src="https://cdn.jsdelivr.net/npm/moment#2.27.0/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.4.0/dist/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment#0.1.1"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-crosshair#1.2.0/dist/chartjs-plugin-crosshair.min.js"></script>
<canvas id="chart" height="100"></canvas>
https://jsfiddle.net/Lb0k2sqx/1/

How to create dynamic update spline Highcharts chart?

I'm scratching my head for few days with no luck.
I would like to create Highcharts chart that shows data from my database.
I did some charts without problem, but I'm stuck on chart that shows some points (20 or more) and scrolls spline chart to the left showing new data.
I have created two arrays jfDatumi (containing times in format hh:mm from database) (12:10) and jfTempOuts containing temperature values (-2.3…).
Now I want to show those data on chart that moves every second adding new point (time, temperature) but showing only 20 points at the time.
When it comes to the end of an array I would like chart to start over from first point.
It's like this chart https://www.highcharts.com/demo/dynamic-update but I want X axis to show my times from my array (jfDatumi) not current time (without var x = (new Date()).getTime())
Can anyone please help me? I'm pulling my hair out because of this.
Below is my current code.
$(function ()
{
$(document).ready(function ()
{
Highcharts.setOptions(
{
global:
{
useUTC: false,
}
});
$('#test').highcharts(
{
credits:
{
text: 'By: http://amicus.ba',
href: 'http://amicus.ba'
},
chart:
{
type: 'spline',
animation: Highcharts.svg, // Ne animiraj u starom IE
marginRight: 1,
events:
{
load: function ()
{
// Postaviti update grafikona svake sekunde
var series = this.series[0];
setInterval(function ()
{
var x = jfDatumi, // Trenutno vrijeme
//var x = new Date(), // current time
//x=jfDatumi,
//var x = (new Date()).getTime(),
y = jfTempOuts;
series.addPoint([x, y], true, true);
}, 1500);
}
}
},
title:
{
text: 'Test Vanjska temperatura [°C]'
},
xAxis:
{
type: 'datetime',
categories: jfDatumi,
minRange: 1,
title:
{
text: 'Vrijeme'
},
tickPixelInterval: 1,
},
yAxis:
{
minRange: 0,
title:
{
text: '[°C]'
},
plotLines: [
{
value: 0,
width: 2,
color: '#808080'
}]
},
tooltip:
{
formatter: function ()
{
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.numberFormat(this.y, 2) + ' [°C]';
}
},
legend:
{
enabled: false
},
exporting:
{
enabled: false
},
series: [
{
name: 'Vanjska temperatura',
//data: (jfTempOuts)
data: (function () {
// generate an array of random data
var data = [],
time = jfDatumi,
i;
for (i = 0; i <= 20; i += 1) {
data.push([
time,
jfTempOuts
]);
}
return data;
}())
}]
});
});
});
At this time, i have my times from jfDatumi, but NO temperature values from jfTempOuts.
I have found solution by myself.
Here is code that works for me:
// Animirani grafikon vanjske temperature
$(function ()
{
$(document).ready(function ()
{
Highcharts.setOptions(
{
global:
{
useUTC: false,
}
});
$('#vanjskaTemp').highcharts(
{
credits:
{
text: 'By: http://amicus.ba',
href: 'http://amicus.ba'
},
chart:
{
type: 'spline',
animation: Highcharts.svg, // Ne animiraj u starom IE
marginRight: 1,
events:
{
load: function ()
{
// Postaviti update grafikona po podešenom intervalu
var series = this.series[0];
var br=20; // Start brojača za indeksiranje niza temperatura (podešeno u: for (i = 0; i <= 20; i += 1))
setInterval(function ()
{
br=br+1; // Brojač za indeksiranje niza temperatura
// Zaustavljanje skrolovanja ako je dostignut kraj niza jfTempOuts
if (br<=jfTempOuts.length-1)
{
var x = jfSamoVrijeme; // Vrijeme za X osu (zaustavi se osa ako se ne očitava)
y = jfTempOuts[br]; // Vrijednosti za Y osu (Vanjske temperature)
series.addPoint([x, y], true, true);
}
else
{
//document.write("BR:<li>"+br+"</li>");
}
}, 1500);
}
}
},
title:
{
text: 'Vanjska temperatura [°C]'
},
xAxis:
{
type: 'datetime',
categories: jfSamoVrijeme,
minRange: 1,
title:
{
text: 'Vrijeme'
},
tickPixelInterval: 1,
},
yAxis:
{
minRange: 0,
title:
{
text: 'Vanjska temperatura [°C]'
},
plotLines: [
{
value: 0,
width: 0.5,
color: '#808080'
}]
},
tooltip:
{
formatter: function ()
{
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.numberFormat(this.y, 2) + ' [°C]';
}
},
legend:
{
enabled: false
},
exporting:
{
enabled: false
},
series: [
{
name: 'Vanjska temperatura',
data: (function () {
var data = [],
time = jfSamoVrijeme,
i;
for (i = 0; i <= 20; i += 1) {
data.push([
time,
jfTempOuts
]);
}
return data;
}())
}]
});
});
});
// Kraj animiranog grafikona vanjske temperature
Only problem I have now is that I CAN'T show first 20 points, but not so important.
I will find solution for that problem too.
My chart

How to drilldown to third level when its data is determined by second's click event?

So, I have been trying to use drill down to multiple levels, problem I am facing is that I couldn't drill down to the third level because the data will be fetched by ajax upon second drilldown's selection.
for example, refer to this link:
https://codepen.io/ajaymalhotra15/pen/aZpxXq
drilldown example
Here, the third level is possible because he has the data already, but mine will be depended on seconds selection.
So, how to make this happen, where am I supposed to call the ajax request and set the drill down series data dynamically?
EDIT:
Highcharts.chart("energy_chart", {
chart: {
type: "column",
spacingBottom: 15,
spacingTop: 10,
spacingLeft: 10,
spacingRight: 10,
backgroundColor: "#f2f2f2",
events: {
load: function() {
var fin = new Date();
var finDate = fin.getDate();
var finMonth = fin.getMonth();
var finYear = fin.getFullYear();
var ini = new Date();
ini.setFullYear(ini.getFullYear() - 1);
var iniDate = ini.getDate();
var iniMonth = ini.getMonth();
var iniYear = ini.getFullYear();
if (this.yAxis[0].dataMax == 0) {
this.yAxis[0].setExtremes(null, 1);
}
//this.yAxis.set
this.xAxis[0].setExtremes(
Date.UTC(iniYear, iniMonth, iniDate),
Date.UTC(finYear, finMonth, finDate)
);
},
drilldown: function(e) {
var charts_this = this;
var inidrillDate = new Date(e.point.x);
setTimeout(function() {
inidrillDate.setDate(0);
inidrillDate.setMonth(inidrillDate.getMonth());
var DateinidrillDate = inidrillDate.getDate();
var MonthinidrillDate = inidrillDate.getMonth();
var YearinidrillDate = inidrillDate.getFullYear();
var findrillDate = inidrillDate;
findrillDate.setMonth(findrillDate.getMonth() + 1);
findrillDate.setDate(findrillDate.getDate() - 1);
var DatefindrillDate = findrillDate.getDate();
var MonthfindrillDate = findrillDate.getMonth();
var YearfindrillDate = findrillDate.getFullYear();
charts_this.xAxis[0].setExtremes(
Date.UTC(
YearinidrillDate,
MonthinidrillDate,
DateinidrillDate
),
Date.UTC(
YearfindrillDate,
MonthfindrillDate,
DatefindrillDate
)
);
if (charts_this.yAxis[0].dataMax === 0) {
charts_this.yAxis[0].setExtremes(null, 1);
}
}, 0);
}
}
},
title: {
text: '<p className="energy_gen">Energy Generated</p>'
},
exporting: { enabled: false },
xAxis: {
type: "datetime",
labels: {
step: 1
},
dateTimeLabelFormats: {
day: "%e"
}
},
yAxis: {
title: {
text: "kWh"
}
},
credits: {
enabled: false
},
plotOptions: {
series: {
cursor: "pointer",
dataLabels: {
enabled: true,
format: "{point.y}"
},
color: "#fcd562",
point:{
events:{
click:function(event){
if(this.options!=null){
var dayOfYear=new Date(this.x).getFullYear() +"-"+(new Date(this.x).getMonth()+1)+"-"+new Date(this.x).getDate();
var formatted_date = new Date(this.x).getDate() + " " + months[(new Date(this.x).getMonth())] +" "+ new Date(this.x).getFullYear();
// document.getElementById('chart_date_id').innerHTML = formatted_date; //setting modal title with current date
$('#container').bind('mousemove touchmove touchstart', function (e) {
var chart,
point,
i,
event;
var sync_charts = $('.chart');
for (i = 0; i < sync_charts.length; i = i + 1) {
var chart_1 = sync_charts[i];
var chart_2 = chart_1.getAttribute('data-highcharts-chart');
chart=Highcharts.charts[chart_2];
event = chart.pointer.normalize(e.originalEvent);
point = chart.series[0].searchPoint(event, true);
if (point) {
point.highlight(e);
}
}
});
Highcharts.Pointer.prototype.reset = function () {
return undefined;
};
Highcharts.Point.prototype.highlight = function (event) {
event = this.series.chart.pointer.normalize(event);
this.onMouseOver(); // Show the hover marker
this.series.chart.tooltip.refresh(this); // Show the tooltip
this.series.chart.xAxis[0].drawCrosshair(event, this); // Show the crosshair
};
function syncExtremes(e) {
var thisChart = this.chart;
if (e.trigger !== 'syncExtremes') { // Prevent feedback loop
Highcharts.each(Highcharts.charts, function (chart) {
if (chart !== thisChart) {
if (chart.xAxis[0].setExtremes) { // It is null while updating
chart.xAxis[0].setExtremes(
e.min,
e.max,
undefined,
false,
{ trigger: 'syncExtremes' }
);
}
}
});
}
}
axios({
url: config.fvcstat,
method: "POST",
data: {
"customerId":self.props.location.state.detail.customerId,"rmsVendorId":self.props.location.state.detail.rmsVendorId,
"date":dayOfYear,
"powerType":self.props.location.state.detail.powerType
},
headers: {
"Content-Type": "application/json"
}
}).then((res)=>{
let activity = fvc.data;
if($('.chart')){
$('.chart').remove();
}
$.each(activity.datasets, function (i, dataset) {
console.log(1)
var chartDiv = document.createElement('div');
chartDiv.className = 'chart';
document.getElementById('container').appendChild(chartDiv);
Highcharts.chart(chartDiv,{
chart: {
},
plotOptions: {
series: {
marker:{
enabled:false
}
}
},
exporting: { enabled: false },
title: {
text: dataset.name,
align: 'left',
margin: 0,
x: 30
},
credits: {
enabled: false
},
legend: {
enabled: false
},
xAxis: {
crosshair:{ width: 3},
events: {
setExtremes: syncExtremes
},
labels: {
format: '{value}'
},categories: activity.xData
},
yAxis: {
title: {
text: null
}
},
series: [{
data: dataset
}],
tooltip: {
positioner: function () {
return {
x: this.chart.chartWidth - this.label.width,
y: 10 // align to title
};
},
borderWidth: 0,
backgroundColor: 'none',
pointFormat: '{point.y}',
headerFormat: '',
shadow: false,
style: {
fontSize: '18px'
},
valueDecimals: dataset.valueDecimals
},
series: [{
data: dataset.data,
name: dataset.name,
type: dataset.type,
color: Highcharts.getOptions().colors[i],
fillOpacity: 0.3,
tooltip: {
valueSuffix: ' ' + dataset.unit
}
}]
});
});
})
}
}
}
}
}
},
tooltip: {
formatter: function() {
if (this.point.options.drilldown) {
return (
"Energy generated: <b> " +
this.y +
"</b> kWh " +
"<br>" +
Highcharts.dateFormat("%b %Y", new Date(this.x))
);
} else {
return (
"Energy generated: <b> " +
this.y +
"</b> kWh " +
"<br>" +
Highcharts.dateFormat("%e %b %Y", new Date(this.x))
);
}
}
},
series: [{'data':obj.data,'name':obj.name,"color":"#4848d3"}],
drilldown: {
series: obj.data
}
});
So, here if you notice in plotoptions i am trying to create a whole new chart which is a synced line charts showing frquency, voltage and current.
But, i am guessing my approach is not correct as i am plotting a new highchart.
So, how do i make this synced line chart part of my drilldown.
let me know if you require any help in understanding.
I will suggest first minimize the plotoption. Then expand for further fuck up :P
Thanks.
You can put all your logic to get the third level data and to create a drilldown series in drilldown event:
chart: {
type: 'column',
events: {
drilldown: function(e) {
if (!thirdLevel.length) {
// get data
}
if (!e.seriesOptions) {
var chart = this,
drilldowns = {
'Animals': {
name: 'Animals',
data: [
['Cows', 2],
['Sheep', 3]
]
},
'Fruits': {
name: 'Fruits',
data: [
['Apples', 5],
['Oranges', 7],
['Bananas', 2]
]
},
'Cars': {
name: 'Cars',
data: [
['Toyota', 1],
['Volkswagen', 2],
['Opel', 5]
]
}
},
series = drilldowns[e.point.name];
chart.addSingleSeriesAsDrilldown(e.point, series);
chart.applyDrilldown();
}
}
}
}
Live demo : http://jsfiddle.net/BlackLabel/86v3L4ft/
API Reference: https://api.highcharts.com/highcharts/chart.events.drilldown

Highcharts/Highstock with React and Boost not working (very high cpu usage)

I'm implementing this example http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/samples/highcharts/boost/line-series-heavy-dynamic/ but with React.
import React from 'react'
import Highcharts from 'highcharts'
import HighchartsBoost from 'highcharts/modules/boost'
HighchartsBoost(Highcharts)
Highcharts.setOptions({
global: {
useUTC: false
}
});
class Plot extends React.Component {
constructor(props) {
super(props)
this.n = 20
this.s = 600
this.addPoint = this.addPoint.bind(this)
}
componentDidMount() {
var series = getSeries(this.n, this.s)
console.time('line');
this.chart = Highcharts.chart('hc-container', {
boost: {
enabled: true,
seriesThreshold: 1
},
chart: {
animation: false,
zoomType: 'x'
},
title: {
text: 'Highcharts drawing ' + (this.n * this.s) + ' points across ' + this.s + ' series'
},
navigator: {
xAxis: {
ordinal: false//,
},
yAxis: {
},
series: {
color: null
}
},
legend: {
enabled: false
},
xAxis: {
ordinal: false
},
yAxis: {
},
subtitle: {
text: 'Using the Boost module'
},
tooltip: {
valueDecimals: 2,
shared: false
},
series: series
});
console.timeEnd('line');
setInterval(this.addPoint, 1000);
}
addPoint() {
++this.n;
if (!this.chart.series) return
this.chart.series.forEach(se => {
var x = this.n
var y = 2 * Math.sin(x / 100) + Math.random()
//Yeah...
if (se.options.className === "highcharts-navigator-series") {
return;
}
se.addPoint([x, y], false, true, false);
// se.options.data.push([x, y]);
// se.options.data.shift();
// se.isDirty = true;
// se.isDirtyData = true;
});
this.chart.redraw();
}
render() {
return <div id='hc-container' />
}
}
export default Plot
function getData(n) {
var arr = [],
i;
for (i = 0; i < n; i = i + 1) {
arr.push([
i,
2 * Math.sin(i / 100) + Math.random()
]);
}
return arr;
}
function getSeries(n, s) {
var i = 0,
r = [];
for (; i < s; i++) {
r.push({
data: getData(n),
animation: false,
lineWidth: 2,
boostThreshold: 1,
turboThreshold: 1,
showInNavigator: true,
requireSorting: false
});
}
return r;
}
I don't think boost module is working this way because CPU goes very very high.
I their example (running in chrome) CPU is around 0.x
But in my implementation it goes to 120 most of the time.

how to set zoom in react-native-charts-wrapper?

i'm doing my first React Native app,
i'm using react-native-charts-wrapper to show graphs.
i have a listener for buttons (see code below comment // CHANGE ZOOM HERE) in my screen to set a predefined zoom in the graph that i'm showing.
How would i do that ?
Does anyone has any experience using that library ?
here is my screen:
import React, {Component} from 'react';
import {View, Text, StyleSheet, processColor} from 'react-native';
import { Button} from "native-base";
import {CombinedChart} from 'react-native-charts-wrapper';
import moment from 'moment';
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'stretch',
backgroundColor: 'transparent',
paddingTop:20
}
});
var InsulinShort = [];
var InsulinLong = [];
var glocuseTests = [];
const injectionsCount = 1000;
for (var i = 1; i < injectionsCount; i++) {
var random = Math.random();
if (random <= 0.7) {
var gloguseValue = Math.floor(Math.random() * 40) + 75;
var gloguseposition =Math.random();
glocuseTests.push({x:i+gloguseposition,y: gloguseValue, marker: "level: "+gloguseValue});
}
}
for (var i = 1; i < injectionsCount; i++) {
var random = Math.random();
if (random <= 0.15) {
var shortvalue = Math.floor(Math.random() * 16) + 1 ;
var shortPosition = Math.round(Math.random() * 100) / 100;
InsulinShort.push({x:i+shortPosition,y: shortvalue*20, marker: shortvalue+ " units of short insulin"});
}else if (random <= 0.3) {
var longePosition = Math.round(Math.random() * 10) / 10;
var longvalue = Math.floor(Math.random() * 16) + 1;
InsulinLong.push({x:i+longePosition,y: longvalue*20, marker: longvalue+ " units of long insulin"});
}else{
}
}
export default class LogGraph extends Component {
constructor() {
super();
// var valueFormatter = new Array(3515599953920);
this.state = {
loading: true,
days:1000,
legend: {
enabled: true,
textSize: 18,
form: 'SQUARE',
formSize: 18,
xEntrySpace: 10,
yEntrySpace: 5,
formToTextSpace: 5,
wordWrapEnabled: true,
maxSizePercent: 0.5
},
xAxis: {
valueFormatter: [
'01/04/18',
'02/04/18',
'03/04/18',
'04/04/18',
'05/04/18',
'06/04/18',
'07/04/18',
'08/04/18',
'09/04/18',
'10/04/18',
'11/04/18',
'12/04/18',
'13/04/18',
'14/04/18',
'15/04/18',
'16/04/18',
'17/04/18',
'18/04/18',
'19/04/18',
'20/04/18',
],
// valueFormatterPattern:'ssss',
// limitLines:100,
// drawLimitLinesBehindData:false,
// avoidFirstLastClipping: false,
textColor: processColor('#000'),
gridColor: processColor('#000'),
axisLineColor: processColor('#000'),
drawGridLines:true,
drawAxisLine:false,
drawLabels:true,
granularityEnabled: true,
// granularity:1515599953920,
granularity: 1,
// granularity: 131096 ,
position:'TOP',
textSize: 10,
labelRotationAngle:45,
gridLineWidth: 1,
axisLineWidth: 2,
gridDashedLine: {
lineLength: 10,
spaceLength: 10
},
centerAxisLabels:false,
},
yAxis: {
left: {
axisMinimum: 0,
axisMaximum: 400,
labelCount: 6,
labelCountForce: true,
granularityEnabled: true,
granularity: 5,
},
right: {
axisMinimum: 0,
axisMaximum: 20,
labelCount: 6, // 0 5 10 15 20 25 30
labelCountForce: true,
granularityEnabled: true,
granularity: 5,
}
},
marker: {
enabled: true,
markerColor: processColor('#F0C0FF8C'),
textColor: processColor('white'),
markerFontSize: 18,
},
data: {
barData: {
config: {
barWidth: 1 / 24 ,
},
dataSets: [{
values:InsulinLong,
label: 'Long Insulin',
config: {
drawValues: false,
colors: [processColor('#a2a4b2')],
}
},{
values:InsulinShort,
label: 'Short Insulin',
config: {
barShadowColor: processColor('red'),
highlightAlpha: 200,
drawValues: false,
colors: [processColor('#d0d5de')],
}
}]
},
lineData: {
dataSets: [{
values: glocuseTests,
label: 'Glucose Level',
config: {
drawValues: false,
colors: [processColor('#81d0fa')],
// mode: "CUBIC_BEZIER",
drawCircles: true,
lineWidth: 3,
}
}],
},
}
};
}
creatList(logs){
// var startTime = moment().millisecond();
var list = [];
var time = false;
if (logs) {
// console.log('firstLogDay',moment(firstLogDay).format('L'));
let gloguseItems = [];
let shortItems = [];
let longItems = [];
let firstValidFlag = false;
let firstLogTime;
let lastLogTime;
let days;
let firstLogDate;
let firstLogDayTime;
lastLogTime = logs[0].time;
for (var i = logs.length-1; i >= 0; i--) {
let item = logs[i];
if ( !firstValidFlag && ['glucose', 'long', 'short'].indexOf(item.type) >= 0 ) {
// debugger;
firstValidFlag = true;
firstLogTime = logs[i].time;
days = Math.round((lastLogTime-firstLogTime)/(1000*60*60*24));
firstLogDate = moment(firstLogTime).format('YYYY-MM-DD');
// console.log('firstLogDate',firstLogDate);
firstLogDayTime = new Date(firstLogDate);
firstLogDayTime = firstLogDayTime.getTime() - (2*60*60*1000);
// console.log('firstLogDayTime',firstLogDayTime);
}
if (firstValidFlag) {
let logX = ( item.time - firstLogDayTime ) / 1000 / 60 / 60 /24;
// logX = Math.round(logX * 10) / 10
if (logX) {
// logX = item.time;
// console.log(logX);
let logY = item.amount;
if (item.type !== 'glucose') {
if (item.type === 'short') {
shortItems.push({
x: logX,
y: logY*20,
marker: logY+ " units of short insulin" + moment(item.time).format('LLL')
})
}
if (item.type === 'long') {
longItems.push({
x: logX,
y: logY*20,
marker: logY+ " units of long insulin" + moment(item.time).format('LLL')
})
}
}else{
if(item.type === 'glucose'){
gloguseItems.push({
x: logX,
y: parseInt(logY),
marker: "level: "+ logY + moment(item.time).format('LLL')
})
}
}
}
}
}
let oldData = this.state.data;
oldData.lineData.dataSets[0].values = gloguseItems;
oldData.barData.dataSets[1].values = shortItems;
oldData.barData.dataSets[0].values = longItems;
let DayFlag = firstLogDate;
let valueFormatter = [];
valueFormatter.push(moment(DayFlag).format('DD/MM/YYYY'));
for (let i = 0; i < days; i++) {
DayFlag = moment(DayFlag).add(1, 'days');
valueFormatter.push(DayFlag.format('DD/MM/YYYY'));
}
let xAxis = this.state.xAxis;
xAxis.valueFormatter = valueFormatter;
this.setState({
data:oldData,
days:days,
xAxis:xAxis,
loading:false
});
}else{
this.setState({loading:false});
}
}
componentDidMount() {
this.creatList(this.props.logs);
}
zoomTwentyPressed() {
console.log ("pressed 25");
}
zoomFiftyPressed() {
console.log ("pressed 50");
}
zoomHundredPressed() {
console.log ("pressed 100");
// CHANGE ZOOM HERE
}
static displayName = 'Combined';
handleSelect(event) {
let entry = event.nativeEvent
if (entry == null) {
this.setState({...this.state, selectedEntry: null})
} else {
this.setState({...this.state, selectedEntry: JSON.stringify(entry)})
}
// console.log(event.nativeEvent)
}
render() {
return (
<View style={styles.container}>
{
(this.state.loading) ? <Text>Loading</Text>:
<CombinedChart
data={this.state.data}
xAxis={this.state.xAxis}
yAxis={this.state.yAxis}
legend={this.state.legend}
onSelect={this.handleSelect.bind(this)}
onChange={(event) => console.log(event.nativeEvent)}
marker={this.state.marker}
animation={{durationY: 1000,durationX: 1000}}
maxVisibleValueCount={16}
autoScaleMinMaxEnabled={true}
zoom={{scaleX: Math.floor(this.state.days/12), scaleY: 1, xValue: 4, yValue: 4, axisDependency: 'LEFT'}}
style={styles.container}/>
}
<View style={styles.buttonWrap}>
<Button block light onPress={this.zoomTwentyPressed()} style={(this.state.view === 'graph')?styles.buttonStyleCurrent:styles.buttonStyle}>
<Text>x100</Text>
</Button>
<Button block light onPress={this.zoomFiftyPressed()} style={(this.state.view === 'graph')?styles.buttonStyleCurrent:styles.buttonStyle}>
<Text>x50</Text>
</Button>
<Button block light onPress={this.zoomHundredPressed()} style={(this.state.view === 'graph')?styles.buttonStyleCurrent:styles.buttonStyle}>
<Text>x25</Text>
</Button>
</View>
</View>
);
}
}
I just put in the json format of options the prop dataZoom look this is my example
{
grafica: true,
option: {
title: {
text: ''
},
width: WIDTH - 100,
tooltip: {
trigger: 'axis'
},
xAxis: {
data: energiaV2.map(function (item) {
console.log(item.date, moment(item.date).format('hh:mm:ss'))
return moment(item.date).utc().calendar()//moment(item.date).utc().format('LL');//moment(item.date).utc().format('hh:mm:ss a');
}),
name: "dias",
nameLocation: 'middle',
nameGap: 30,
splitLine: {
show: false
}
},
yAxis: {
splitLine: {
show: false
},
name: "kWh",
nameLocation: 'middle',
},
/* toolbox: {
left: 'center',
feature: {
dataZoom: {
yAxisIndex: 'none'
},
restore: {},
}
}, */
dataZoom: [{
type: 'inside',
}, {
start: 5,
end: 10,
handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
handleSize: '80%',
handleWidth:30,
handleStyle: {
color: '#fff',
shadowBlur: 3,
shadowColor: 'rgba(0, 0, 0, 0.6)',
shadowOffsetX: 2,
shadowOffsetY: 2,
}
}],
series: [{
name: 'Activa kWh',
type: 'line',
data: energiaV2.map(function (item) {
return Math.floor(item.value * 100) / 100;
}),
},
{
name: 'Inductiva kVAr',
type: 'line',
data: energiaV2reactive.map(function (item) {
return Math.floor(item.value * 100) / 100;
}),
},
{
name: 'Capacitiva kVArhR',
type: 'line',
data: energiaV2inductive.map(function (item) {
return Math.floor(item.value * 100) / 100;
}),
},
],
color: ['rgb(253, 180, 59)', 'rgb(240, 94, 54)', 'rgb(0, 128, 35)']
},
grafica: true,
})

Resources