How to create Google Analytics like Users chart in Highchart React - reactjs

I am trying to create a comparison graph like the one below which will show the data of the current day vs the present day minus 7 days (or 20 days or 90 days, ...).
I am using highcharts and highchart's react wrapper for this and I've created a multi line graph using the following data:
series: [
{
name: "Weekly",
data: [
24916, 37941, 29742, 29851, 32490, 30282, 38121, 36885, 33726, 34243,
31050,
],
},
{
name: "Weekly Last Week",
data: [
11744, 30000, 16005, 19771, 20185, 24377, 32147, 30912, 29243, 29213,
25663,
],
dashStyle: "ShortDash",
},
]
I am able to create the same solid and dashed line effect. The only issue I am facing is how to show the tooltip (as shown in the image below) with the current date vs last date data and their comparison. I used this tooltip option:
tooltip: {
enabled: true,
shared: true,
formatter: function () {
return this.points.reduce(function (s, point) {
return s + "<br/>" + point.series.name + ": " + point.y + "m";
}, "<b>" + this.x + "</b>");
},
},

I was able to recreate it based on the design requirement we had. Here is the link to the codesandbox (minus the proper design for tooltips and legends) for anyone looking for it in the future.
The tooltip's functionality was achieved by adding the formatter function in the tooltip option (found in the chartOptions.js file in the sandbox). It's a hacky code but it is needed to calculate the percentage change between the current day's data vs last week's (present-day minus 7 days) data. In my current case, all data is restricted to 7 days for the time being.
For creating the legend which shows the same percent change data I need to add an empty series in the series data (found in the chartOptions.js file) which will store the calculated value of the percent change of the last day (basically the last value in the array).
If anyone has a better solution for consuming data inside the formatter function of the tooltip or legends then please add it to the answer to this question.

Related

How to update autoGroupColumnDef property of ag-Grid after table is initialized

I have an ag-grid table (Enterprise version: 22.1.0) which is grouped using autoGroupColumnDef property. The grouping is dependent on the table's data and the data loads on a button click. I need to update the autoGroupColumnDef property's field name (_this.colName in the below code) after the page is loaded, right before loading the data.
Table's grid options:
_this.gridOptions = {
defaultColDef: {
sortable: true,
resizable: true,
filter: true
},
columnDefs: _this.columnDefs,
rowData: [],
enableRangeSelection: true,
autoGroupColumnDef: {
headerName: "Sector",
field: _this.colName,
cellRendererParams: {
suppressCount: true
},
tooltipValueGetter: function(params) {
return _this.tooltipVal
}
},
suppressAggFuncInHeader: true,
enableBrowserTooltips: true
};
I update the variable _this.colName before setting data to the grid. I have tried the following options and none of them worked for me:
_this.gridOptions.api.refreshClientSideRowModel('group');
_this.gridOptions.api.refreshCells();
_this.gridOptions.autoGroupColumnDef.field = 'Column's Name'
Any help would be appreciated!
There is a good workaround for this. You can set autoGroupColumnDef, then remove and readd all row groupings. It will redraw the group column with the new name.
gridOptions.autoGroupColumnDef.headerName = 'new_name';
// Get current groupings
var colstate = gridOptions.columnApi.getColumnState();
var colstateclear = gridOptions.columnApi.getColumnState();
// Clear groupings
var x = 0, xcount = colstateclear.length;
while ( x < xcount ) {
colstateclear[x].rowGroupIndex = null;
x += 1;
}
gridOptions.columnApi.setColumnState(colstateclear);
// Reset groupings
gridOptions.columnApi.setColumnState(colstate);
I contacted ag-grid support and apparently this is a bug and they have it in their backlog with no ETA available for now. A workaround they provided was to use: https://www.ag-grid.com/javascript-grid-grouping/#showRowGroup.
This is not really a good workaround because the grouped columns are separated and makes the page feel cramped. Also there are some look and feel issues that keep popping up (Eg: empty space added before each column that increases with each grouped column. ie second column has 1 cm added before it, third column has 2 cm added before it and so on. I guess this was added to bring the grouped look in the group column but you wouldn't expect this behavior when the columns are separated.)
ag-grid's backlog ID for the ticket: AG-3359 - Allow the autoGroupColumn to be used in the API calls for columns, at the moment there is no way to dynamically change it after creation. (ie, setColumnDefs …)
Link to track the progress: https://www.ag-grid.com/ag-grid-pipeline/
there is a straight forward method to update the autoGroupColumnDef object and its properties with setAutoGroupColumnDef
this.gridOptions.api.setAutoGroupColumnDef(<ColDef>{
...this.gridOptions.autoGroupColumnDef, // preserve the other settings except the ones you need to change
minWidth: 500
})
if any problems with the spread operator,
do it manually:
this.gridOptions.api.setAutoGroupColumnDef(<ColDef>{
// ...this.gridOptions.autoGroupColumnDef, // preserve the other settings except the ones you need to change
headerName: this.gridOptions.autoGroupColumnDef.headerName,
minWidth: 500
})
and one more thing, add this if you have any visual bugs, like: header row gets resized but bellow rows stays the same as previus state, so the refresh of model is required:
this.gridOptions.api.refreshClientSideRowModel();
this refresh is not ideal solution, because it refreshes everything, so you will loose expanded levels for example, still no clue how to preserve all settings.
https://angulargrid.com/angular-grid/client-side-model/#refreshing-the-client-side-model
and best solution for now is tu use:
this.gridOptions.api.redrawRows();
it keeps the rows expanded if are, checkbox selected if is.

Change order in react-apexcharts

I am using react-apexcharts to display data on chart. Chart display data from ascending order like from January to December but I need to display in descending order like from December to January.
Is there any option to change the order.
The order of the data is depending on how you construct the x axis categories (Jan ... Dec or Dec ... Jan) and array of data before passing it up to the series options. Since you are using react version, i assume that you get the data from ajax calls. Let's say you have initial state like these:
this.state = {
options: {
...
xaxis: {
categories: [],
},
noData: {
text: "Loading...",
},
},
series: [],
};
what you have to do is you can either configure the backend to return prepared data for both x-axis categories and series, or received as it is and sort it in the frontend and then set the state accordingly.

amCharts convert unixtime to readable date

I want to show stacked area chart using amCharts, anything else worked as well but date on it was parsed incorrectly.
"dataProvider": [{
"date": 1482192000,
"cars": 1587,
"motorcycles": 650,
"bicycles": 121
}
Property named as date on above data package cannot be converted to readable date like "DD/MM/YYYY"
Finally, the chart must show 30 days of chosen month.
Here is my CodePen: CodePen Stacked Area Chart
Your data and setup are both incorrect. Here's a list of what's wrong and how to fix them
1) dataDateFormat is used for parsing string dates, not formatting them. Since you're using unix timestamps, you don't need this property at all, so you can remove it.
2) Your unix timestamps must also be in milliseconds in order for this to work. Seconds will give you invalid times.
3) Your data must be sorted in ascending date order for it to render correctly. Your data is currently in mixed order.
As for your other questions:
To format your dates, you have to set the dateFormats array in your categoryAxis to the desired format strings as described here. For DD/MM/YYYY:
"categoryAxis": {
// other properties omitted:
"dateFormats": [{period:'fff',format:'JJ:NN:SS'},
{period:'ss',format:'JJ:NN:SS'},
{period:'mm',format:'JJ:NN'},
{period:'hh',format:'JJ:NN'},
{period:'DD',format:'DD/MM/YYYY'}, //you may need to change the entries for 'WW' and 'MM' as well, depending on the amount of visible data
{period:'WW',format:'MMM DD'},
{period:'MM',format:'MMM'},
{period:'YYYY',format:'YYYY'}]
// ...
}
To automatically zoom on chart load, you can add a rendered event similar to how the demos on the AmCharts website does it and call any of the zoom methods, for example:
"listeners": [{
"event": "rendered",
"method": function(e) {
// different zoom methods can be used - zoomToIndexes, zoomToDates, zoomToCategoryValues
e.chart.zoomToDates(new Date(2017, 1, 1), new Date(2017, 1, 15));
}
}]
Here's an updated codepen with all of the aforementioned fixes here.

AmCharts Multipledatasets

I am stuck with http://www.amcharts.com/demos/multiple-data-sets/#theme-none, the creators of the graphic just put a random numbers to fill it, but I would like to load a CSV file which they have a plugin http://www.amcharts.com/demos/stock-
However, the second graphic is only for
"Stock" and financial purposses I would like to have the first one populated with a cvs file so I can compare more than 2 datasets.
Can someone help me? I will really appreciate it.
I need to read a little bit more, but I figured it out and Amcharts provides a lot of guide they are really nice and patience.
Below it's a pastie where you can find the whole solution.
this is a brief explanation:
{
title: 'Title',
fieldMappings: [ { // here you set the fields your chart will display
fromField: 'col1', // col1 because my csv has only 3 columns the first one contains the data
toField: 'value' // shows the value
}, {
fromField: 'col2', // this is the volume to display under the main graphic and that data is on column2
toField: 'volume' //
} ],
categoryField: "col0", // this is the category which it's display in this case i am using dates so it will display dates and my dates are in column 0 or column "A" in my csv file.
dataLoader: { / this is the plugin
url: "data/data2.csv", // the address
showCurtain: true, // widgets of the pluging
showErrors: true, // if there is an error loading amcharts will tell you
delimeter:"\t", // my csv is not delimited by "," but tabs.
format: "csv",
reverse:true // this is what sort of order you have your data, in my case from Z to A or major to minor.
}
here it't the code:
http://pastie.org/private/bwhvpnb6j8o1jv86cfsg

In Line graph, Why x-axis date format is not coming proper?

I have done application using Extjs 4.1. I have plotted line graph, in this x-axis date format is not coming proper. I have defined fromdate, todate and date format, but duplicating December month, Feb month is not coming. line is plotting proper. for more reference have attached images. Can any body tell me how to resolve this issue?. Great appropriated. Thank you.
Code is here:
{
type:'Time',
step: [Ext.Date.MONTH,1] ,
position:'bottom',
fields:['Month'],
fromDate: new Date('12/1/12'),
toDate: new Date('6/1/13'),
grid: true,
dateFormat: 'M Y',
constrain: true,
}
You can try to change the label orientation to have it displayed verticaly, thus giving more space to display intermediate labels.
You can add a section 'label' do this:
label: {
rotate: {degrees: 270}
},

Resources