I am trying to reference data from a user input in Javascript. The variable is passed in as JSON and I need to extract one value and reference this inside another JSON that creates a chart using Chart JS. The line labels is what I have tried but it does not seem to work. I am trying to avoid refactoring where possible. Any suggestions?
{
"labels": "['jan', 'Feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec']"
}
var lineChart = document.getElementById('line-chart').getContext('2d');
new Chart(document.getElementById("line-chart"), {
type: 'line',
data: {
labels: JSON.parse(document.getElementById('ctl00_ctl00_cphMain_cphMacTool_DASHBOARD').value).labels,
datasets: [{
data: [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200],
label: "Processed",
borderColor: "#9C2AA0",
fill: false
},
{
data: [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200],
label: "Error",
borderColor: "#123456",
fill: false
},
{
data: [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200],
label: "Not Processed",
borderColor: "#A8B400",
fill: false
}
]
},
options: {
title: {
display: false,
text: '',
fontColor: '#000000',
fontFamily: 'Calibri',
fontSize: 30
},
legend: {
position: 'top',
labels: {
fontColor: '#000000',
fontFamily: 'Calibri',
boxWidth: 20,
fontSize: 20
}
},
scales: {
xAxes: [{
ticks: {
fontColor: '#000000'
}
}],
yAxes: [{
ticks: {
fontColor: '#000000'
}
}]
}
}
});
There are two problems in your code.
As others already commented, the data in your input element is not of valid JSON format
labels itself is a string since it is surrounded by double quotes
To make it work, you can perform the following steps.
parse the value from the input string with JSON.parse and extract labels (that's what you already did).
replace all single quotes by double quotes in the obtained labels string.
parse the labels string to a JSON array using again JSON.parse.
const labelsAsString = JSON.parse(document.getElementById('ctl00_ctl00_cphMain_cphMacTool_DASHBOARD').value).labels;
const labelsAsJSONString = labelsAsString.replace(/'/g,'"');
const labelsArray = JSON.parse(labelsAsJSONString);
Please have a look at your amended code below and see how it works.
const labelsAsString = JSON.parse(document.getElementById('ctl00_ctl00_cphMain_cphMacTool_DASHBOARD').value).labels;
const labelsAsJSONString = labelsAsString.replace(/'/g,'"');
const labelsArray = JSON.parse(labelsAsJSONString);
new Chart('line-chart', {
type: 'line',
data: {
labels: labelsArray,
datasets: [{
data: [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200],
label: "Processed",
borderColor: "#9C2AA0",
fill: false
},
{
data: [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200],
label: "Error",
borderColor: "#123456",
fill: false
},
{
data: [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200],
label: "Not Processed",
borderColor: "#A8B400",
fill: false
}
]
},
options: {
title: {
display: false,
text: '',
fontColor: '#000000',
fontFamily: 'Calibri',
fontSize: 30
},
legend: {
position: 'top',
labels: {
fontColor: '#000000',
fontFamily: 'Calibri',
boxWidth: 20,
fontSize: 20
}
},
scales: {
xAxes: [{
ticks: {
fontColor: '#000000'
}
}],
yAxes: [{
ticks: {
fontColor: '#000000'
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<input id="ctl00_ctl00_cphMain_cphMacTool_DASHBOARD" value="{ "labels": "['jan', 'Feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec']" }">
<canvas id="line-chart" height="80"></canvas>
The JSON I posted was valid but when parsed, returned a string. As uminder mentioned, labels needs to be an array hence replacing single quotes with double quotes and parsing twice returns an object. This worked! Really appreciate the help.
Related
How to display different tooltips on chart columns? It is necessary to output data from:
data: [220, 315, 380, 470, 520] and data: [135, 190, 180, 160, 240]
Now duplicated.
Here is my code (using chart.js):
My fiddle
https://jsfiddle.net/ebgaouv8/
Thanks in advance for any help!
You have to change your tooltip mode from label to point and dont hard code the datasetIndex. To solve deprecation issue, remove the barpercentage from the scale option and specify it in every dataset or you can configure it globally before you make the chart like this: Chart.defaults.global.datasets.bar.barPercentage = 0.5;.
var barChart = {
labels: ["2016", "2017", "2018", "2019", "2020"],
datasets: [{
label: '',
backgroundColor: "rgba(34,42,171, 0.7)",
borderColor: 'rgba(34,42,171, 1)',
borderWidth: 1,
barPercentage: 0.5,
data: [220, 315, 380, 470, 520]
},
{
label: '',
backgroundColor: "#ceb947",
barPercentage: 0.5,
data: [135, 190, 180, 160, 240]
},
]
};
var ctx4 = document.getElementById("chartJSContainer").getContext("2d");
window.newBar = new Chart(ctx4, {
type: 'bar',
data: barChart,
options: {
title: {
display: false,
fontStyle: 'bold',
text: "Figure"
},
legend: {
display: false,
position: "bottom",
padding: 20,
labels: {}
},
tooltips: {
mode: 'point',
bodySpacing: 10,
cornerRadius: 0,
titleFontSize: 16,
bodyFontSize: 14,
titleMarginBottom: 15,
callbacks: {
label: function(tooltipItem, data) {
var value = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
value = value.toString();
value = value.split((/(?=(?:..)?$)/));
value = value.join(',');
return 'Total: ' + value + ' %';
}
}
},
scales: {
xAxes: [{
gridLines: false,
ticks: {
fontColor: 'rgb(37,39,103)',
fontSize: '14',
autoSkip: false,
maxRotation: 45,
minRotation: 45,
padding: 15
}
}],
yAxes: [{
ticks: {
fontColor: 'rgb(37,39,103)',
fontSize: '14',
beginAtZero: true,
stepSize: 100,
userCallback: function(value, index, values) {
value = value.toString();
value = value.split(/(?=(?:..)?$)/);
value = value.join(',');
return value + ' %';
}
}
}]
},
responsive: true,
}
});
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
</body>
im trying to using chartsjs to do a line chart.
new Chart(document.getElementById("myChart"), {
type: 'line',
data: {
labels: ['GEN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'],
datasets: [{
data: [0, 10, 20, 30, 40, 50, 40, 30, 20, 10, 0, 15],
label: "CDL",
borderColor: "#3e95cd",
fill: false
}, {
data: [50, 50, 50, 50, 50, 50, 50, 50, 50, 50],
label: "CLA",
borderColor: "#8e5ea2",
fill: false
}, {
data: [10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
label: "CLB",
borderColor: "#3cba9f",
fill: false
}, {
data: [40, 20, 10, 16, 24, 38, 5, 7, 45, 0],
label: "CLC",
borderColor: "#e8c3b9",
fill: false
}
]
},
options: {
responsive: false,
scales: {
yAxes: [{
stacked: true,
gridLines: {
display: true,
color: "rgba(255,99,132,0.2)"
}
}],
xAxes: [{
gridLines: {
display: true
}
}]
},
legend: {
labels: {
fontColor: 'black'
}
}
}
});
This is my code and it works, but my lines dont starting in "absolute position" and theyr position is like this:
chart_image
I dont understand why, can someone help me?
If I add two Y-Axes to an Apexchart it is pushed beyond the wrapper and does not resize properly.
I would like to have one Y-Axis displayed on the left side of the chart and the other one on the right side of the chart.
I tried to debug it in my dev tools but I am sure that this is a canvas problem itself.
I provided the snippet below which shows how the left Y-Axis and Jan data are out of scope.
var yearMapOptions = {
chart: {
fontFamily: "'Varela Round', sans-serif",
foreColor: '#2e1a6d',
toolbar: {
show: false
},
height: "100%",
stacked: false
},
colors: ['#2e1a6d', '#47bfb6', '#f37b94', '#ebf394'],
dataLabels: {
enabled: false
},
series: [{
name: 'Net Pips',
type: 'line',
data: [-10, 17, 39, -4, 63, -27, 55, 290, -83, 26, -45, 17],
}, {
name: 'Net Profit',
type: 'line',
data: [-35, 45, 190, -70, -50, 36, -80, 59, -29, 62, -65, 70]
}, {
name: 'Total Volume',
type: 'column',
data: [20, 60, 35, 57, 330, 30, 660, 58, 58, 230, 70, 120]
}, {
name: 'Total Trades',
type: 'column',
data: [6, 23, 11, 8, 33, 4, 57, 13, 13, 45, 17, 28]
}],
stroke: {
width: [3, 3, 3, 3],
curve: 'smooth'
},
xaxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'June', 'July', 'August', 'Sep', 'Oct', 'Nov', 'Dec'],
},
yaxis: [{
show: true,
seriesName: 'Net Pips',
opposite: true,
tickAmount: 2,
forceNiceScale: true,
axisTicks: {
show: false,
},
axisBorder: {
show: true,
color: '#00E396'
},
axisTicks: {
show: false,
borderType: 'solid',
color: '#47bfb6',
},
labels: {
style: {
color: '#00E396',
}
},
title: {
text: undefined,
style: {
color: '#00E396',
}
},
}, {
show: true,
seriesName: 'Net Profit',
opposite: false,
tickAmount: 2,
forceNiceScale: true,
axisTicks: {
show: true,
borderType: 'solid',
color: '#2e1a6d',
},
axisBorder: {
show: true,
color: '#FEB019'
},
labels: {
style: {
color: '#FEB019',
},
},
title: {
text: undefined,
style: {
color: '#FEB019',
}
},
}
],
plotOptions: {
bar: {
horizontal: false,
endingShape: 'rounded',
barheight: '100%'
}
},
tooltip: {
fixed: {
enabled: true,
position: 'topLeft', // topRight, topLeft, bottomRight, bottomLeft
offsetY: 30,
offsetX: 60
},
},
grid: {
show: false
},
legend: {
position: 'top',
horizontalAlign: 'left',
offsetY: 10
}
};
var yearMapChart = new ApexCharts(
document.querySelector("#yearMap"),
yearMapOptions
);
yearMapChart.render();
.apexcharts-yaxis, .apexcharts-xaxis-label {
font-weight: bold;
}
.yearMapWrapper {
height: 100%;
width: 80%;
margin-left: 10%;
}
<html>
<body>
<div class="rowFiveCol2 layerStyles">
<div class="yearMapWrapper">
<div id="yearMap"></div>
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<html>
Removing grid: { show: false } makes the y-axis visible.
PS: Changing grid behavior should not affect the y-axis. It seems like a bug in ApexCharts which will be addressed soon.
I am facing dificulties to make realign labels inside and outside the bar if value is < 0.35 of max. The labels simply dont appears to lower values. My Fiddle: http://jsfiddle.net/Yrygy/527/
My Code:
var GlobalRotation = -90;
var GlobalAlign = 'right';
var X;
var Y;
function realignLabels(serie) {
$.each(serie.points, function (j, point) {
if (!point.dataLabel) return true;
var max = serie.yAxis.max,
labely = point.dataLabel.attr('y')
if (point.y / max < 0.35) {
point.dataLabel.attr({
y: labely - 120,
});
}
});
};
$(function() {
Highcharts.Series.prototype.drawDataLabels = (function(func) {
return function() {
func.apply(this, arguments);
if ((this.options.dataLabels.enabled || this._hasPointLabels) && this.chart.options.chart.realignLabels) {
realignLabels(this);
}
};
}(Highcharts.Series.prototype.drawDataLabels));
$('#container').highcharts({
chart: {
type: 'line',
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
plotOptions: {
line: {
dataLabels: {
enabled: true,
style: {
fontWeight: 'bold'
},
formatter: function() {
var max = this.series.yAxis.max,
color = 'black';
return '<span style="color: ' + color + '">' + this.y + ' </span>';
},
verticalAlign: "top",
}
}
},
series: [{
data: [69.9, 71.5, 76.4, 69.2, 74.0, 176.0, 75.6, 48.5, 316.4, 94.1, 95.6, 2.33]
}]
});
$('#container2').highcharts({
chart: {
type: 'column',
realignLabels: true,
animation: false
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
tooltip: {
headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
'<td style="padding:0"><b>{point.y:,.1f}</b></td></tr>',
footerFormat: '</table>',
shared: true,
useHTML: true
},
plotOptions: {
column: {
animation: true,
pointPadding: 0.05, // Defaults to 0.1
groupPadding: 0.05, // Defaults to 0.2
dataLabels: {
enabled: true,
rotation: GlobalRotation,
color: '#FFFFFF',
align: GlobalAlign,
verticalAlign: "top",
y: 10,
inside: false,
style: {
fontSize: '12px',
fontFamily: 'Verdana, sans-serif'
},
formatter: function () {
return Highcharts.numberFormat(this.y, 2);
}
}
},
},
series: [
{
name: 'Serie 2',
data: [120, 125, 130, 140, 120, 120, 130, 125, 130, 125, 120, 130]},
{
name: 'Serie 1',
data: [116, 120, 125, 136, 115, 114, 125, 119, 125, 120, 114, 25]},
{
name: 'Serie 1',
data: [4, 5, 5, 4, 5, 6, 5, 6, 5, 5, 6, 115]}
]
});
});
The data appear inside the column as I desired, but i dont know how to show the lower values.
Your labels are moved out of the view (dataLabel.attr('y') == -9999). This is caused by crop option. Disable that option, and labels will show up:
plotOptions: {
column: {
animation: true,
pointPadding: 0.05, // Defaults to 0.1
groupPadding: 0.05, // Defaults to 0.2
dataLabels: {
enabled: true,
rotation: GlobalRotation,
color: '#FFFFFF',
align: GlobalAlign,
verticalAlign: "top",
y: 10,
inside: false,
crop: false, // disabled crop
style: {
fontSize: '12px',
fontFamily: 'Verdana, sans-serif'
},
formatter: function () {
return Highcharts.numberFormat(this.y, 2);
}
}
},
}
Demo: http://jsfiddle.net/Yrygy/530/
I am using Highcharts to draw a line graph.
When the page loads, the line graph is drawn. Please note, that i got an y-Value for every x-Value starting from 0 till 700 ( 0,1,2,3,...,700). This is how i create the graph:
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
animation: false,
type: 'line',
marginTop: null,
marginRight: 55,
marginBottom: 50,
marginLeft: 80,
backgroundColor: backgroundColor,
spacingTop: 10,
spacingRight: 10,
spacingBottom: 15,
spacingLeft: 10,
},
title: {
text: ' Graph',
style: {color: graphLabelColor},
x: -20 //center
},
xAxis: {
title: {
text: 'xAXIS',
style: {
color: axisLabelColor
},
},
min:0,
max: 600,
gridLineColor: gridLineColor,
minorTickInterval: 50,
minorTickLength: 1,
tickInterval: 100,
minorGridLineWidth: 0,
gridLineWidth: 1,
lineColor: axisColor,
labels: {
style : {
color: axisColor
}
},
plotLines: [{
value: 0,
width: 0,
color: axisColor
}]
},
yAxis: {
title: {
text: 'yAxis',
style: {color:
axisLabelColor
},
},
min:0,
max: 700,
gridLineColor: gridLineColor,
lineColor: axisColor,
minorTickInterval: 50,
minorTickLength: 1,
minorGridLineWidth: 0,
tickInterval: 100,
labels: {
style: {
color: axisColor
}
},
plotLines: [{
value: 0,
width: 0,
color: axisColor
}]
},
exporting: {
enabled: false
},
tooltip: {
enabled: true,
borderColor: crosshairColor,
crosshairs: [{
width: 1,
color: crosshairColor,
},
{
width: 1,
color: crosshairColor,
}],
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+this.y +' & '+ this.x.toFixed(0);
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 100,
borderWidth: 1,
borderColor: plotlineColor,
enabled: false,
floating: true,
shadow: true
},
plotOptions: {
series: {
enableMouseTracking: true
},
line: {
color:plotlineColor,
},
},
series: [{
lineWidth: 2,
name: carname,
data: dataArray,
marker: {
color:crosshairColor,
radius: 1
}
}]
});
In my HTML-Page I got two buttons to increase/decrease (+1/-1) a number in a textfield, starting at 200. The number represents a x-Coordinate in the graph.
I would like to highlight the shown number of my textfield in the graph with another color and a bigger point when the graph is loaded the first time and also when the user changes the number using one of these buttons. How can I do this?
I tried
chart.series[0].options.data[valueOfTextfield].color = 'yellow';
chart.redraw(true);
in the onclick method of the buttons but it doesnt work.
Thanks for your answers!
Using a marker we can do this:
$(function () {
$('#container').highcharts({
chart: {
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
data: [29.9, { marker: {
fillColor: '#FF0000',
lineWidth: 3,
lineColor: "#FF0000" // inherit from series
},y:71.5}, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
});
http://jsfiddle.net/zR4Kn/
use the select method of the point object
https://api.highcharts.com/highcharts/series.line.point.events.select