Highchart with dual y-axis with date - javascript

I'm trying to display details of projects.
I want show completion percentage on a bar chart with the start date for each of those project as line chart.
Now, for achieving this I have created a chart with dual y-axis.
1 - axis-1 shows progress with bar-chart
2 - axis-2 supposed to show start dates with a line chart
Bar chart works fine. Even the line chart works fine without the dual axis. But, when I add them together the line-chart disappears. I tried changing the dates on the line chart for random numbers - that works as well.
Anyone knows how to make dates work on a dual-axis chart.
jsfiddle
var projectDetails =
[{
"name": "+PS8039",
"startDate": "2016-02-01",
"finishDate": "2016-04-01"
}, {
"name": "+PS8039",
"startDate": "2016-01-02",
"finishDate": "2016-08-02"
}, {
"name": "+PS8039",
"startDate": "2016-03-08",
"finishDate": "2016-08-08"
}, {
"name": "+PS8039",
"startDate": "2016-04-11",
"finishDate": "2016-09-11"
}, {
"name": "+PS8039",
"startDate": "2016-05-13",
"finishDate": "2016-12-13"
}, {
"name": "+PS8039",
"startDate": "2016-01-15",
"finishDate": "2016-04-15"
}, {
"name": "+PS8039",
"startDate": "2016-02-25",
"finishDate": "2016-08-25"
}, {
"name": "+PS8039",
"startDate": "2016-03-03",
"finishDate": "2016-07-03"
}, {
"name": "+PC2E",
"startDate": "2016-04-07",
"finishDate": "2016-05-31"
}, {
"name": "+PC2E",
"startDate": "2016-05-16",
"finishDate": "2016-09-01"
}];
$(function () {
var xCategories = new Array();
var completionpercent = new Array();
var startdates = new Array();
var finishdates = new Array();
for(var i = 0; i< projectDetails.length; i++){
xCategories[i] = projectDetails[i].name;
startdates[i] = moment(projectDetails[i].startDate).format('x');
finishdates[i] = projectDetails[i].finishDate;
completionpercent[i] = ((Date.now() - Date.parse(projectDetails[i].startDate))
/(Date.parse(projectDetails[i].finishDate) - Date.parse(projectDetails[i].startDate)))
*100 ;
}
$('#Chart').highcharts({
colors: ['#2C5898'],
title: {
text: 'Project Completion'
},
legend: {
enabled: false
},
xAxis: [{
categories: xCategories,
crosshair: true
}],
yAxis:[{
title: {
text: '% Completion'
},
max: 110
},
{
"title": {
"text": "Start Dates"
},
opposite: true
}
],
plotOptions: {
bar: {
groupPadding: 0,
zones: [{
value: 100
},{
color: {
linearGradient: { x1: 0, x2: 0, y1: 0, y2: 1 },
stops: [
[0, '#cc0000'],
[1, '#ff8080']
]
}
}]
}
},
credits: {
enabled: false
},
series: [{
name: 'Start Dates',
type: 'line',
data: startdates
},{
name: 'Completion %',
type: 'bar',
data: completionpercent
}]
});
});

You need to specify that the line series relates to the second axis:
yAxis: 1,
Updated fiddle:
https://jsfiddle.net/jlbriggs/4e6edy7t/2/

Related

SAPUI5 line chart returning weird output

I am using northwind oData model and using the "SummaryByYear" model to create a line chart. The data looks as follows (for easier representation, only 4 entries are shown):
{
"results": [
{
"__metadata": {
"uri": "https://services.odata.org/V2/Northwind/Northwind.svc/Summary_of_Sales_by_Years(10248)",
"type": "NorthwindModel.Summary_of_Sales_by_Year"
},
"ShippedDate": "1996-07-16T00:00:00.000Z",
"OrderID": 10248,
"Subtotal": "440.00"
},
{
"__metadata": {
"uri": "https://services.odata.org/V2/Northwind/Northwind.svc/Summary_of_Sales_by_Years(10249)",
"type": "NorthwindModel.Summary_of_Sales_by_Year"
},
"ShippedDate": "1996-07-10T00:00:00.000Z",
"OrderID": 10249,
"Subtotal": "1863.40"
},
{
"__metadata": {
"uri": "https://services.odata.org/V2/Northwind/Northwind.svc/Summary_of_Sales_by_Years(10250)",
"type": "NorthwindModel.Summary_of_Sales_by_Year"
},
"ShippedDate": "1996-07-12T00:00:00.000Z",
"OrderID": 10250,
"Subtotal": "1552.60"
},
{
"__metadata": {
"uri": "https://services.odata.org/V2/Northwind/Northwind.svc/Summary_of_Sales_by_Years(10251)",
"type": "NorthwindModel.Summary_of_Sales_by_Year"
},
"ShippedDate": "1996-07-15T00:00:00.000Z",
"OrderID": 10251,
"Subtotal": "654.06"
}
]
}
following is the XML view for Chart:
<chart:ChartContainer id="chartContainer" showFullScreen="true" showZoom="false" title="Sales Summary (by Year)">
<chart:ChartContainerContent>
<chart:content>
<viz:VizFrame id="lineChart" width="auto" uiConfig="{applicationSet:'fiori'}">
</viz:VizFrame>
</chart:content>
</chart:ChartContainerContent>
</chart:ChartContainer>
and this is the controlles onInit function:
onInit: function () {
var northwind = this.getOwnerComponent().getModel("northwind");
var that = this;
northwind.read("/Summary_of_Sales_by_Years", {
method: "GET",
success: function (resp) {
resp["results"].forEach(item => {
item.Subtotal = item.Subtotal.toString().slice(0, -2)
});
var summaryByYear = new JSONModel({
"results": resp["results"]
})
var lineChart = that.getView().byId("lineChart");
lineChart.setVizType('line');
lineChart.setUiConfig({
applicationSet: 'fiori',
});
var oDataset = new FlattenedDataset({
dimensions: [{
axis: 1,
name: 'Year',
value: '{ShippedDate}',
datatype: "date"
}, ],
measures: [{
name: 'Subtotal',
value: '{Subtotal}',
}],
data: {
path: '/results',
},
});
lineChart.setDataset(oDataset);
lineChart.setModel(summaryByYear);
var feedValueAxis = new FeedItem({
uid: 'valueAxis',
type: 'Measure',
values: ['Subtotal'],
}),
feedCategoryAxis = new FeedItem({
uid: 'categoryAxis',
type: 'Dimension',
values: ['Year'],
});
lineChart.addFeed(feedValueAxis);
lineChart.addFeed(feedCategoryAxis);
lineChart.setVizProperties({
general: {
layout: {
padding: 0.04,
},
},
plotArea: {
window: {
start: 'firstDataPoint',
end: 'lastDataPoint'
}
},
valueAxis: {
label: {
formatString: 'axisFormat',
},
title: {
visible: false,
},
},
categoryAxis: {
title: {
visible: false,
},
},
plotArea: {
dataLabel: {
visible: true,
formatString: 'datalabelFormat',
style: {
color: null,
},
},
},
legend: {
title: {
visible: false,
},
},
title: {
visible: false,
text: 'Summary of Sales (by year)',
},
levels: ['month', 'day', 'year'],
interval: {
unit: ''
}
});
}
});
}
following is the result:
I am getting the date in raw timestamp format instead of year and month and also there are weird texts such as "5atalabelfor9at". What am I doing wrong here and please point me to the correct docs if I am missing some kind of config, thanks.

Loop through array and pass array data to properties in javascript object

So I have this problem. I'm working with highchairs and I'm trying to make some dynamic charts.
But I'm having some problem with passing array data to a property javascript object. Let me explain better by adding some code :
So this is the JSON
{
"businessId": 1,
"surveyName": "test",
"year": "2019",
"period": "november",
"kp": [{
"id": 7,
"title": "Standard Test",
"widgetType": "Bar",
"goal": null,
"trend": null,
"data": {
"questions": ["Test 1", "Test 2", "Test 3"],
"seriesValue": [{
"test values"
}]
}
}, {
"id": 8,
"title": "% of usual sample",
"widgetType": "Pie",
"goal": null,
"trend": null,
"data": {
"slice": [20, 30, 50],
"discardReasons": ["Reason1", "Reason2", "Reason3"]
}
}]
}
And this is the code to create the piechart:
var piechart = Highcharts.chart('container-pie-1', {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: 'Septembre, 2019'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: false
},
showInLegend: true
}
},
exporting: {
enabled: true
},
navigation: {
buttonOptions: {
enabled: true
}
},
series: [{
name: 'Discrad Reasons',
colorByPoint: true,
data: [{
name: dynamic names,
y: dynamic data
}]
}]
});
inside the series property there are supposed to be multiple names and multiple ~y~ data. I would like to fill it looping through the JSON array.
For example :
//now it's like this
series: [{
name: 'Discrad Reasons',
colorByPoint: true,
data: [{
name: 'Wrong Email',
y: 61.41,
sliced: true,
selected: true
}, {
name: 'Business not found',
y: 11.84
}, {
name: 'Etc',
y: 10.85
}, {
name: 'Etc',
y: 4.67
}, {
name: 'Etc',
y: 4.18
}, {
name: 'Other',
y: 7.05
}]
}]
//and I want something dynamic like this
series: [{
name: 'Discrad Reasons',
colorByPoint: true,
data: [{
name: loop through json array,
y: loop through json array
}]
}]
Can anyone give any idea?

How to add HTML to the panel title in amchart

How to add HTML to the panel title in amchart. I tried adding HTML for title but its rendering as HTML code only.
Here is the DEMO.
Here is the JavaScript code:
var chartData1 = [];
var chartData2 = [];
generateChartData();
function generateChartData() {
var firstDate = new Date();
firstDate.setDate(firstDate.getDate() - 500);
firstDate.setHours(0, 0, 0, 0);
for (var i = 0; i < 500; i++) {
var newDate = new Date(firstDate);
newDate.setDate(newDate.getDate() + i);
var a1 = Math.round(Math.random() * (40 + i)) + 100 + i;
var a2 = -1 * Math.round(Math.random() * (100 + i)) + 200 + i;
chartData1.push({
date: newDate,
value: a1
});
chartData2.push({
date: newDate,
value: a2
});
}
}
AmCharts.makeChart("chartdiv", {
type: "stock",
dataSets: [{
title: "first data set",
fieldMappings: [{
fromField: "value",
toField: "value"
}],
dataProvider: chartData1,
categoryField: "date"
},
{
title: "second data set",
fieldMappings: [{
fromField: "value",
toField: "value2"
}],
dataProvider: chartData2,
categoryField: "date",
compared: true
}
],
panels: [{
showCategoryAxis: false,
title: "<span>Hello</span>",
recalculateToPercents: "never",
stockGraphs: [{
id: "g1",
valueField: "value",
comparable: true
}],
stockLegend: {
}
}, {
showCategoryAxis: true,
title: "Data set #2",
recalculateToPercents: "never",
stockGraphs: [{
id: "g2",
valueField: "value2",
compareField: "value2",
comparable: true,
visibleInLegend: false
}],
stockLegend: {
}
}
],
chartScrollbarSettings: {
graph: "g1"
},
chartCursorSettings: {
valueBalloonsEnabled: true,
cursorColor: '#000000',
cursorAlpha:0.1
},
periodSelector: {
periods: [{
period: "MM",
selected: true,
count: 1,
label: "1 month"
}, {
period: "YYYY",
count: 1,
label: "1 year"
}, {
period: "YTD",
label: "YTD"
}, {
period: "MAX",
label: "MAX"
}]
}
});
It only supports text. Depending on what you need, you can try styling it directly using css by setting addClassNames to true in your chart using the generated CSS classes. For example, to change the color of the first panel's legend title:
.amcharts-stock-panel-div-stockPanel0 .amcharts-legend-title {
fill: #ee0000;
}
Demo

Struggling to get this JSON data into highcharts

I have the following snippet of code which takes data from a JSON URL and inputs it into MariaDB.
Now I want to take that data back out the database (as the database records the JSON over time), and then put this into a graph, but I am having difficulty in getting the data out the JSON URL into highcharts... My data looks like this:
[{"time":"1509488314","hashrate":"34096322642","minersTotal":"99"},
{"time":"1509490093","hashrate":"34096645609","minersTotal":"101"},
{"time":"1509490201","hashrate":"34096374421","minersTotal":"101"},
{"time":"1509490321","hashrate":"34138925733","minersTotal":"101"},
{"time":"1509490441","hashrate":"34062086317","minersTotal":"101"},
{"time":"1509490561","hashrate":"34116887228","minersTotal":"101"},
{"time":"1509490681","hashrate":"34053449517","minersTotal":"103"},
{"time":"1509490801","hashrate":"34060600882","minersTotal":"103"},
{"time":"1509490921","hashrate":"34065888457","minersTotal":"103"},
{"time":"1509491041","hashrate":"34093378965","minersTotal":"105"}]
I wish to basically plot the time across the X axis, and hashrate as a line and minersTotal as a bar.
I have done the PHP / MariaDB bit, but doing this part is proving to be a struggle for me.
My php code:
$mysqli = new mysqli($servername, $username, $password, $dbname);
$myArray = array();
if ($result = $mysqli->query("SELECT * FROM hashrates LIMIT 100")) {
while($row = $result->fetch_object()) {
$myArray[] = $row;
}
echo json_encode($myArray);
}
$result->close();
$mysqli->close();
According this demo (Highcharts Demos › Dual axes, line and column). The data must be an array of values e.g: ["Item1", "Item2", "Item3"].
With your data, you can use Array#map().
var times = data.map(function(x) {
return new Date(x.time * 1000);
});
var hashrates = data.map(function(x) {
return x.hashrate * 1;
});
var minersTotals = data.map(function(x) {
return x.minersTotal * 1;
});
You can do something like this:
(function() {
var data = [{
"time": "1509488314",
"hashrate": "34096322642",
"minersTotal": "99"
},
{
"time": "1509490093",
"hashrate": "34096645609",
"minersTotal": "101"
},
{
"time": "1509490201",
"hashrate": "34096374421",
"minersTotal": "101"
},
{
"time": "1509490321",
"hashrate": "34138925733",
"minersTotal": "101"
},
{
"time": "1509490441",
"hashrate": "34062086317",
"minersTotal": "101"
},
{
"time": "1509490561",
"hashrate": "34116887228",
"minersTotal": "101"
},
{
"time": "1509490681",
"hashrate": "34053449517",
"minersTotal": "103"
},
{
"time": "1509490801",
"hashrate": "34060600882",
"minersTotal": "103"
},
{
"time": "1509490921",
"hashrate": "34065888457",
"minersTotal": "103"
},
{
"time": "1509491041",
"hashrate": "34093378965",
"minersTotal": "105"
}
];
var times = data.map(function(x) {
return new Date(x.time * 1000);
});
var hashrates = data.map(function(x) {
return x.hashrate * 1;
});
var minersTotals = data.map(function(x) {
return x.minersTotal * 1;
});
Highcharts.chart("container", {
chart: {
zoomType: "xy"
},
title: {
text: "Data"
},
subtitle: {
text: "Subtitle"
},
xAxis: [{
categories: times,
crosshair: true
}],
yAxis: [{ // Primary yAxis.
labels: {
format: "{value}",
style: {
color: Highcharts.getOptions().colors[1]
}
},
title: {
text: "Hashrate",
style: {
color: Highcharts.getOptions().colors[1]
}
}
}, { // Secondary yAxis.
title: {
text: "MinersTotal",
style: {
color: Highcharts.getOptions().colors[0]
}
},
labels: {
format: "{value}",
style: {
color: Highcharts.getOptions().colors[0]
}
},
opposite: true
}],
tooltip: {
shared: true
},
legend: {
layout: "vertical",
align: "left",
x: 120,
verticalAlign: "top",
y: 100,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || "#FFFFFF"
},
series: [{
name: "MinersTotal",
type: "column",
yAxis: 1,
data: minersTotals,
tooltip: {
valueSuffix: ""
}
}, {
name: "Hashrate",
type: "line",
data: hashrates,
tooltip: {
valueSuffix: ""
}
}]
});
})();
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="height: 400px; margin: 0 auto; min-width: 310px;"></div>
Let me know if this works for you.
I ended up going with this
$(function () {
var hashrates = new Array();
var minersTotal = new Array();
function refreshdata() {
$.getJSON("data.json", function(data) {
var hashrates = new Array();
var minersTotal = new Array();
for (i = 0; i < data.length; i++) {
var object = data[i];
var time = object.time * 1000;
hashrates.push([time, parseFloat(object.hashrate) / 1000000000]);
minersTotal.push([time, parseFloat(object.minersTotal)]);
}
$('#container').highcharts().series[0].setData(minersTotal, true);
$('#container').highcharts().series[1].setData(hashrates, true);
$('#container').highcharts().redraw();
});
}
$('#container').highcharts({
chart: {
backgroundColor: "rgba(0,0,0,0)",
color: "#FF0000",
alignTicks: false,
events: {
load: function () {
setInterval(function () {refreshdata();}, 60000);
}
}
},
title: {
text: "Pool performance"
},
subtitle: {
text: "3 days (15 min intervals)"
},
tooltip: {
shared: true,
valueDecimals: 2
},
legend: {
layout: "horizontal"
},
xAxis: {
title: {
text: "Time (UTC)"
},
type: "datetime",
showFirstLabel: true
},
yAxis: [{
title: {
text: "Hashrate (GH/s)"
},
labels: {
style: {
color: "#434348"
},
formatter: function() {
return this.axis.defaultLabelFormatter.call(this).toString().substr(0,4);
}
},
gridLineColor: "#434348",
tickInterval: 10,
min: 0
},{
title: {
text: "Miners",
style: {
color: "#95CEFF"
},
},
labels: {
style: {
color: "#95CEFF"
}
},
opposite: true,
tickInterval: 40,
gridLineColor: "#95CEFF"
}],
series: [{
name: "Miners",
type: "spline",
data: minersTotal,
yAxis: 1
},{
name: "Hashrate",
data: hashrates,
type: "spline"
}]
});
refreshdata();
});
It can be seen in action here: https://metaverse.farm/

Highcharts - Add Series Name As X-Axis Label

Is it possible to have the "name" key of each object in the series be the x-axis label?
series: [{
"data": [3570.5],
"name": "R",
"id": 0
}, {
"data": [3000],
"name": "S",
"id": 1
}, {
"data": [2500],
"name": "T",
"id": 2
}]
For example, I would like column 1 to have an x-axis label of "R", column 2 to have an x-axis label of "S", etc. I have tried assigning the x-axis categories
xAxis: {categories: ['R', 'S', 'T']}
But only the "R" label shows up on the x-axis. I have also tried to format the series differently:
series: [{
"data": [3570.5, null, null],
"name": "R",
"id": 0
}, {
"data": [null, 3000, null],
"name": "S",
"id": 1
}, {
"data": [null, null, 2500],
"name": "T",
"id": 2
}]
But that complicates the ease with which I can change the series visibility, i.e. auto-resizing both axes, hiding the full column and then putting the hidden column back in its original spot when trying to show again.
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function () {
var id = this.series.options.id;
var chart = $('#container').highcharts();
var isVisible = chart.get(id).visible;
chart.get(id).setVisible(!isVisible);
}
}
}
}
}
http://jsfiddle.net/calanoue/suw6xweh/
You were properly setting your xAxis categories. However, you were only ever setting one point. Highcharts is defaulting to that point going to index 0 (the "R"). Try setting the xAxis category index and use the {x, y} point format:
series: [{
data: [{x:0, y:3570.5}],
name: "R",
id: 0
}, {
data: [{x:1, y:3000}],
name: "S",
id: 1
}, {
data: [{x:2, y:2500}],
name: "T",
id: 2
}]
The x: values are the category index you want populated.
You can try by adding name to each data point as in this
DEMO.
$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'column',
},
xAxis: {
categories: ['R', 'S', 'T'],
},
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function () {
changeSeriesVisibility(this.series.options.id);
}
}
}
}
},
series: [{
data : [{ x : 0,
y : 3750,
name : "R"},
{
x : 1,
y: 3000,
name: "S"
},
{
x : 2,
y : 2500,
name : "T"
}
]
},
]
});
function changeSeriesVisibility(id) {
// Hide/Show the series on click
var chart = $('#container').highcharts();
var isVisible = chart.get(id).visible;
chart.get(id).setVisible(!isVisible);
}
});

Categories