I am very new to java-script and was trying to learn how to add multiple line charts to my web UI. But unfortunately I am stuck with a problem, I am unable to add multiple line charts to my web UI.
I am unable to understand what I am doing wrong. I tried several approaches but couldn't find the solution.
Appreciate the help!
Below is my code for your reference.
var xValues = [50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150];
var yValues = [7, 8, 8, 9, 9, 9, 10, 11, 14, 14, 15];
function displayPanel(i) {
var panel = document.getElementById('panel');
panel.innerHTML += `
<div class="row">
<div class="column">
<form>
<label id="paramname_${i}" for="paramvalue">${i}</label>
<input type="text" id="paramvalue_${i}" name="param" value=${i} readonly>
</form>
</div>
<div id="chart_${i}" class="column">
<canvas id="myChart${i}" style="width:100%;max-width:600px"></canvas>
</div>
</div>`;
new Chart("myChart" + i, {
type: "line",
data: {
labels: xValues,
datasets: [{
fill: false,
lineTension: 0,
backgroundColor: "rgba(0,0,255,1.0)",
borderColor: "rgba(0,0,255,0.1)",
data: yValues
}]
},
options: {
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
min: 6,
max: 16
}
}],
}
}
});
new Chart("myChart" + i, {
type: "line",
data: {
labels: xValues,
datasets: [{
fill: false,
lineTension: 0,
backgroundColor: "rgba(0,0,255,1.0)",
borderColor: "rgba(0,0,255,0.1)",
data: yValues
}]
},
options: {
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
min: 6,
max: 16
}
}],
}
}
});
}
for (i = 0; i < 2; i++) {
displayPanel(i);
}
<style>.column {
float: left;
align-self: right;
width: 50%;
padding: 10px;
}
.row {
content: "";
clear: both;
display: table;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
<!DOCTYPE html>
<html>
<body>
<div id="panel"></
----------
div>
</body>
function addParamsToPanel(parameter, paramValue, isDisplay, i) {
console.log("XXXX" + parameter);
if (isDisplay) {
displayPanel(parameter, paramValue,i);
}
}
function updatePanel(paramList, valueList) {
param = paramList.toString().split(',');
paramValue = valueList.toString().split(',');
for (var i = 0; i < param.length; i++) {
var p = document.createElement("div");
var checkBox = document.createElement("input");
var label = document.createElement("label");
checkBox.type = "checkbox";
checkBox.id = param[i];
p.appendChild(checkBox);
p.appendChild(label);
document.getElementById("cboxes").appendChild(p);
label.appendChild(document.createTextNode(param[i]));
document.getElementById(param[i]).checked = true;
addParamsToPanel(param[i], paramValue[i], document.getElementById(param[i]).checked, i);
}
}
function displayPanel(parameter, paramValue, i) {
var panel = document.getElementById('panel');
var today = new Date();
var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
var newChart = 'paramChart_' + parameter;
panel.innerHTML += `
<div class="row">
<!--div class="col-md-9 col-lg-10 col-sm-11"-->
<div class="column">
<form>
<label id="paramname_${parameter}" for="paramvalue">${parameter}</label>
<input type="text" id="paramvalue_${parameter}" name="param" value=${paramValue} readonly>
</form>
</div>
<div id="chart_${i}" class="column">
<canvas id=${newChart} style="width:100%;max-height:100px;max-width:700px;border: solid;rgb(4, 31, 65);"></canvas>
</div>
`;
console.log(newChart.value);
var chart = new Chart(newChart, {
type: "line",
data: {
labels: xValues,
datasets: [{
//label: 'set of ' + parameter,
fill: false,
//lineTension: 0,
backgroundColor: "rgba(0,0,255,1.0)",
borderColor: "rgba(0,0,255,0.1)",
data: yValues,
showLine: true,
spanGaps: true
}]
},
options: {
legend: { display: false }
}
});
chartMap.set(newChart, chart);
chart.data.datasets[0].data.push(i.value);
chart.data.labels.push(time);
chart.update();
}
updatePanel(paramList, valueList);
It seems like that when you add a new part to the inner html it has some weird behaviour with chart.js, if you first make all the divs with forms and canvasses and then create the charts it works fine:
var xValues = [50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150];
var yValues = [7, 8, 8, 9, 9, 9, 10, 11, 14, 14, 15];
function displayPanel(i) {
var panel = document.getElementById('panel');
panel.innerHTML += `
<div class="row">
<div class="column">
<form>
<label id="paramname_${i}" for="paramvalue">${i}</label>
<input type="text" id="paramvalue_${i}" name="param" value=${i} readonly>
</form>
</div>
<div id="chart_${i}" class="column">
<canvas id="myChart${i}" style="width:100%;max-width:600px"></canvas>
</div>`;
}
function createChart(i) {
new Chart("myChart" + i, {
type: "line",
data: {
labels: xValues,
datasets: [{
fill: false,
lineTension: 0,
backgroundColor: "rgba(0,0,255,1.0)",
borderColor: "rgba(0,0,255,0.1)",
data: yValues
}]
},
options: {
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
min: 6,
max: 16
}
}],
}
}
});
}
function createUI(k) {
for (i = 0; i < k; i++) {
displayPanel(i);
}
for (i = 0; i < k; i++) {
createChart(i);
}
}
createUI(3)
<style>.column {
float: left;
align-self: right;
width: 50%;
padding: 10px;
}
.row {
content: "";
clear: both;
display: table;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
<!DOCTYPE html>
<html>
<body>
<div id="panel"></div>
</body>
Related
I want to make a pie chart like the image below, using chart.js however, cannot seem to get there.
this is what i wanna make
I have seen some d3.js plugins that helps with this however, I cannot learn that in time so whatever i can do with chart.js.
can i get some help please. i am struggling with this, not sure if this should be simple or i am just over complicating thing. as for as i am aware i am taking the logical approach
below is my code.
<script>
const documentType = [];
const documentRevision = [];
const docTypeRev = [];
const docTypeTotal = [];
const percentage = [];
showDoughnutChart();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// START OF DOUGHNUT CHART
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
async function showDoughnutChart() {
await getDataDoughnutGraph();
const doughnutChart = document
.getElementById("myChart")
.getContext("2d");
let chart3a = new Chart(doughnutChart, {
type: "doughnut",
data: {
labels: documentType,
datasets: [
{
label: "Some metric",
backgroundColor: [
"#619E98",
"#4164BE",
"#7D35CA",
"#B2A44D",
"#946B76",
"#6C9D62",
"#C6B139",
"#2688D9",
"#D62963",
"#CCBF33",
"#adff2f",
"#B6495D",
],
borderWidth: 1,
borderRadius: 5,
offset: [0, 0, 0, 0, 0, 0, 0],
cutout: "50%",
data: docTypeRev,
},
{
label: "Some metric",
backgroundColor: [
"#619E98",
"#4164BE",
"#7D35CA",
"#B2A44D",
"#946B76",
"#6C9D62",
"#C6B139",
"#2688D9",
"#D62963",
"#CCBF33",
"#adff2f",
"#B6495D",
],
borderWidth: 1,
borderRadius: 5,
offset: [0, 0, 0, 0, 0, 0, 0],
cutout: "50%",
data: [1, 1, 1],
},
],
},
options: {
plugins: {
legend: {
display: true,
position: "right",
},
title: {
display: true,
text: "Tag Distrubution by Class",
color: "black",
},
},
layout: {
padding: 10,
},
maintainAspectRatio: true,
responsive: true,
},
});
}
async function getDataDoughnutGraph() {
const responseLine = await fetch("stats_doc_type_Rev.csv");
const chart3el = document.getElementById("myChart").getContext("2d");
const data = await responseLine.text();
const table = data.split("\n").slice(1);
table.forEach((row) => {
//split by line
const columns = row.split(",");
// split by column
const documentTypeEX = columns[0];
const documentRevisionEX = columns[1];
const docTypeRevEX = columns[2];
const docTypeTotalEX = columns[3];
const percentage_EX = columns[4];
//pushing into global variables
documentType.push(documentTypeEX);
documentRevision.push(documentRevisionEX);
docTypeRev.push(docTypeRevEX);
docTypeTotal.push(docTypeTotalEX);
percentage.push(percentage_EX);
// console.log(percentage_EX);
});
}
</script>
</body>
</html>
<style>
* {
margin: 0;
padding: 0;
font-family: sans-serif;
}
.chartMenu {
width: 100vw;
height: 40px;
background: #1a1a1a;
color: rgba(255, 26, 104, 1);
}
.chartMenu p {
padding: 10px;
font-size: 20px;
}
.chartCard {
width: 100vw;
height: calc(100vh - 40px);
background: rgba(255, 26, 104, 0.2);
display: flex;
align-items: center;
justify-content: center;
}
.chartBox {
width: 700px;
padding: 20px;
border-radius: 20px;
border: solid 3px rgba(255, 26, 104, 1);
background: white;
}
</style>
<div class="chartMenu">
<p></p>
</div>
<div class="chartCard">
<div class="chartBox">
<canvas id="myChart"></canvas>
</div>
</div>
<script
type="text/javascript"
src="https://cdn.jsdelivr.net/npm/chart.js"
></script>
I think you could add 2 datasets, 1 grouped and 1 with all values.
To show the labels, you can use https://github.com/chartjs/chartjs-plugin-datalabels/.
const multiLeveData = {
firstLevel: {
data: [15, 10]
},
secondLevel: {
data: [20, 30]
},
};
const dataForDataset = function(grouped) {
const result = [];
for (const key of Object.keys(multiLeveData)) {
if (grouped) {
result.push(multiLeveData[key].data.reduce(function(a, b) { return a + b; }, 0));
} else {
multiLeveData[key].data.forEach(function(item){
result.push(item);
})
}
}
return result;
}
const ctx = document.getElementById("myChart");
Chart.register(ChartDataLabels);
const myChart = new Chart(ctx, {
type: "doughnut",
data: {
datasets: [
{
label: "Some metric",
backgroundColor: [
"#619E98",
"#619E98",
"#7D35CA",
"#7D35CA"
],
borderWidth: 1,
borderRadius: 5,
offset: [0, 0, 0, 0, 0, 0, 0],
cutout: "50%",
data: dataForDataset(),
},
{
label: "Some metric",
backgroundColor: "#4164BE",
borderWidth: 1,
borderRadius: 5,
offset: [0, 0, 0, 0, 0, 0, 0],
cutout: "50%",
data: dataForDataset(true),
},
],
},
options: {
plugins: {
legend: {
display: false,
},
tooltip: {
display: false,
},
title: {
display: true,
text: "Tag Distrubution by Class",
color: "black",
},
datalabels: {
color: 'white',
font: {
size: 16
}
}
},
layout: {
padding: 10,
},
maintainAspectRatio: true,
responsive: true,
},
});
.myChartDiv {
max-width: 600px;
max-height: 400px;
}
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.9.1/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#2.1.0/dist/chartjs-plugin-datalabels.min.js"></script>
<html>
<body>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400" tabindex="1"/>
</div>
</body>
</html>
I made a radial progress bar using the nested doughnut chart, the object works fine.
I wanted to show the progress on a label, but the label became visible in the data I used as the background.
q1:How can i hide the label i just use as background?
q2:Do you think it is good to make progress bar using chartjs? (real time) I would be very happy if you could provide information about another alternative library.
My code:
var _gaugeValue = 5;
var _gaugeValue2 = 43;
var _gagueMaxVal = 100;
var _gagueMaxVal2 = 150;
var ctxGauge = document.getElementById("myCanvasGauge");
var myGauge = new Chart(ctxGauge, {
type: "doughnut",
data: {
datasets: [
{
data: [_gaugeValue2, _gagueMaxVal2 - _gaugeValue2],
backgroundColor: ["rgba(255,0,0,1)", "rgba(220,220,220,1)"],
hoverOffset: 4,
cutout: "80%",
},
{
data: [_gaugeValue, _gagueMaxVal - _gaugeValue],
backgroundColor: ["rgba(71,148,218,1)", "rgba(220,220,220,1)"],
hoverOffset: 4,
cutout: "70%",
options: {
plugins: {
datalabels: {
display: false,
},
},
},
},
],
},
options: {
response: true,
maintainAspectRatio: false,
plugins: {
tooltip: {
enabled: false,
},
datalabels: {
backgroundColor: function (context) {
return context.dataset.backgroundColor;
},
borderColor: "white",
borderRadius: 25,
borderWidth: 2,
color: "white",
display: function (context) {
var dataset = context.dataset;
var count = 2;
var value = dataset.data[1];
return value > count * 1.5;
},
font: {
weight: "bold",
},
padding: 6,
formatter: Math.round,
},
},
},
plugins: [ChartDataLabels],
});
function changeData() {
_gaugeValue = Math.floor(Math.random() * 100) - 1;
myGauge.data.datasets[1].data = [
_gaugeValue,
_gagueMaxVal - _gaugeValue,
];
myGauge.update();
}
function changeData2() {
_gaugeValue2 = Math.floor(Math.random() * 100) - 1;
myGauge.data.datasets[0].data = [
_gaugeValue2,
_gagueMaxVal2 - _gaugeValue2,
];
myGauge.update();
}
.gauge-container {
margin: auto;
}
.button-container {
margin: auto;
padding: 10px;
}
<script
src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js"
integrity="sha512-TW5s0IT/IppJtu76UbysrBH9Hy/5X41OTAbQuffZFU6lQ1rdcLHzpU5BzVvr/YFykoiMYZVWlr/PX1mDcfM9Qg=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0/chartjs-plugin-datalabels.min.js"
integrity="sha512-R/QOHLpV1Ggq22vfDAWYOaMd5RopHrJNMxi8/lJu8Oihwi4Ho4BRFeiMiCefn9rasajKjnx9/fTQ/xkWnkDACg=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<div class="gauge-container">
<canvas id="myCanvasGauge"></canvas>
</div>
<div class="button-container">
<button onclick="changeData()">Change Data 1</button>
</div>
<div class="button-container">
<button onclick="changeData2()">Change Data 2</button>
</div>
you can use the display callback to determine which labels are displayed
if I follow correctly, you do not want labels to appear on the gray portion of the chart...?
if so, only display the first value...
display: function (context) {
return context.dataIndex === 0;
},
see following working snippet...
var _gaugeValue = 5;
var _gaugeValue2 = 43;
var _gagueMaxVal = 100;
var _gagueMaxVal2 = 150;
var ctxGauge = document.getElementById("myCanvasGauge");
var myGauge = new Chart(ctxGauge, {
type: "doughnut",
data: {
datasets: [
{
data: [_gaugeValue2, _gagueMaxVal2 - _gaugeValue2],
backgroundColor: ["rgba(255,0,0,1)", "rgba(220,220,220,1)"],
hoverOffset: 4,
cutout: "80%",
},
{
data: [_gaugeValue, _gagueMaxVal - _gaugeValue],
backgroundColor: ["rgba(71,148,218,1)", "rgba(220,220,220,1)"],
hoverOffset: 4,
cutout: "70%",
options: {
plugins: {
datalabels: {
display: false,
},
},
},
},
],
},
options: {
response: true,
maintainAspectRatio: false,
plugins: {
tooltip: {
enabled: false,
},
datalabels: {
backgroundColor: function (context) {
return context.dataset.backgroundColor;
},
borderColor: "white",
borderRadius: 25,
borderWidth: 2,
color: "white",
display: function (context) {
return context.dataIndex === 0;
},
font: {
weight: "bold",
},
padding: 6,
formatter: Math.round,
},
},
},
plugins: [ChartDataLabels],
});
function changeData() {
_gaugeValue = Math.floor(Math.random() * 100) - 1;
myGauge.data.datasets[1].data = [
_gaugeValue,
_gagueMaxVal - _gaugeValue,
];
myGauge.update();
}
function changeData2() {
_gaugeValue2 = Math.floor(Math.random() * 100) - 1;
myGauge.data.datasets[0].data = [
_gaugeValue2,
_gagueMaxVal2 - _gaugeValue2,
];
myGauge.update();
}
.gauge-container {
margin: auto;
}
.button-container {
margin: auto;
padding: 10px;
}
<script
src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js"
integrity="sha512-TW5s0IT/IppJtu76UbysrBH9Hy/5X41OTAbQuffZFU6lQ1rdcLHzpU5BzVvr/YFykoiMYZVWlr/PX1mDcfM9Qg=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0/chartjs-plugin-datalabels.min.js"
integrity="sha512-R/QOHLpV1Ggq22vfDAWYOaMd5RopHrJNMxi8/lJu8Oihwi4Ho4BRFeiMiCefn9rasajKjnx9/fTQ/xkWnkDACg=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<div class="gauge-container">
<canvas id="myCanvasGauge"></canvas>
</div>
<div class="button-container">
<button onclick="changeData()">Change Data 1</button>
</div>
<div class="button-container">
<button onclick="changeData2()">Change Data 2</button>
</div>
I created an application with Django. In this system, there is an approval system. I created an ApprovalProcess model and it has a beginning_date field. I crated a chart for showing how many approval processes are started on which day? But I cannot fill this chart.
But I cannot figure it out how can I get approval process values as my data? the data that I want to display is all_approvals in my views.
models.py
class ApprovalProcess(models.Model):
id = models.AutoField(primary_key=True)
user_id = models.ForeignKey(UserProfile, on_delete=models.CASCADE, null=True, related_name='starter')
doc_id = models.ForeignKey(Pdf, on_delete=models.CASCADE, null=True)
begin_date = models.DateTimeField(auto_now=True)
end_date = models.DateTimeField(auto_now=True)
status = models.IntegerField(default=0)
highest_rank = models.IntegerField(default=0)
last_approved = models.ForeignKey(UserProfile, on_delete=models.CASCADE, null=True, related_name='last_approved')
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, null=True)
views.py
def approval_context_processor(request):
if request.user.is_authenticated:
current_user = request.user
rank_priority = RankPriority.objects.filter(rank=current_user.rank)
priority = rank_priority[0].priority
pend_list = ApprovalProcess.objects.filter(status=priority)
submit_list = ApprovalProcess.objects.filter(user_id=current_user)
userP = UserProfile.objects.get_or_create(username=current_user)
customer_list = Customer.objects.filter(company=userP[0].company)
all_approvals = ApprovalProcess.objects.filter(user_id__company=request.user.company)
approved_reports = 0
waiting_reports = 0
for submit in submit_list:
if submit.status - submit.highest_rank == 1:
approved_reports += 1
else:
waiting_reports += 1
else:
pend_list = 0
submit_list = 0
context = {
'pend_list': pend_list,
'submit_list': submit_list,
'approved_reports': approved_reports,
'waiting_reports': waiting_reports,
'customer_list': customer_list,
'all_approvals': all_approvals
}
return context
chart
<div class="row">
<div class="col-md-8">
<div class="card">
<div class="card-header">
<div class="card-head-row">
<div class="card-title">User Statistics</div>
<div class="card-tools">
</div>
</div>
</div>
<div class="card-body">
<div class="chart-container" style="min-height: 375px">
<canvas id="statisticsChart"></canvas>
</div>
<div id="myChartLegend"></div>
</div>
</div>
</div>
...
...
var ctx = document.getElementById('statisticsChart').getContext('2d');
var statisticsChart = new Chart(ctx, {
type: 'line',
data: {
labels: [
],
datasets: [ {
label: "Approval Processes",
borderColor: '#f3545d',
pointBackgroundColor: 'rgba(243, 84, 93, 0.6)',
pointRadius: 0,
backgroundColor: 'rgba(243, 84, 93, 0.4)',
legendColor: '#f3545d',
fill: true,
borderWidth: 2,
data: [100, 184, 250, 203, 210, 231, 240, 278, 252, 312, 320, 374]
}, ]
},
options : {
responsive: true,
maintainAspectRatio: false,
legend: {
display: false
},
tooltips: {
bodySpacing: 4,
mode:"nearest",
intersect: 0,
position:"nearest",
xPadding:10,
yPadding:10,
caretPadding:10
},
layout:{
padding:{left:5,right:5,top:15,bottom:15}
},
scales: {
yAxes: [{
ticks: {
fontStyle: "500",
beginAtZero: false,
maxTicksLimit: 5,
padding: 10
},
gridLines: {
drawTicks: false,
display: false
}
}],
xAxes: [{
gridLines: {
zeroLineColor: "transparent"
},
ticks: {
padding: 10,
fontStyle: "500"
}
}]
},
legendCallback: function(chart) {
var text = [];
text.push('<ul class="' + chart.id + '-legend html-legend">');
for (var i = 0; i < chart.data.datasets.length; i++) {
text.push('<li><span style="background-color:' + chart.data.datasets[i].legendColor + '"></span>');
if (chart.data.datasets[i].label) {
text.push(chart.data.datasets[i].label);
}
text.push('</li>');
}
text.push('</ul>');
return text.join('');
}
}
});
i don't know which data you want to get from ApprovalProcess model but suppose you want to get highest_rank field to pass it to data chart
you code will be like this :
import json
def approval_context_processor(request):
if request.user.is_authenticated:
current_user = request.user
rank_priority = RankPriority.objects.filter(rank=current_user.rank)
priority = rank_priority[0].priority
pend_list = ApprovalProcess.objects.filter(status=priority)
submit_list = ApprovalProcess.objects.filter(user_id=current_user)
userP = UserProfile.objects.get_or_create(username=current_user)
customer_list = Customer.objects.filter(company=userP[0].company)
all_approvals = ApprovalProcess.objects.filter(user_id__company=request.user.company)
approved_reports = 0
waiting_reports = 0
for submit in submit_list:
if submit.status - submit.highest_rank == 1:
approved_reports += 1
else:
waiting_reports += 1
else:
pend_list = 0
submit_list = 0
context = {
'pend_list': pend_list,
'submit_list': submit_list,
'approved_reports': approved_reports,
'waiting_reports': waiting_reports,
'customer_list': customer_list,
'all_approvals': json.dumps([e.highest_rank for e in all_approvals])
}
return context
then you get your data in template like this :
var ctx = document.getElementById('statisticsChart').getContext('2d');
var statisticsChart = new Chart(ctx, {
type: 'line',
data: {
labels: [
],
datasets: [ {
label: "Approval Processes",
borderColor: '#f3545d',
pointBackgroundColor: 'rgba(243, 84, 93, 0.6)',
pointRadius: 0,
backgroundColor: 'rgba(243, 84, 93, 0.4)',
legendColor: '#f3545d',
fill: true,
borderWidth: 2,
data: {{ all_approvals|safe }}
}, ]
},
options : {
responsive: true,
maintainAspectRatio: false,
legend: {
display: false
},
tooltips: {
bodySpacing: 4,
mode:"nearest",
intersect: 0,
position:"nearest",
xPadding:10,
yPadding:10,
caretPadding:10
},
layout:{
padding:{left:5,right:5,top:15,bottom:15}
},
scales: {
yAxes: [{
ticks: {
fontStyle: "500",
beginAtZero: false,
maxTicksLimit: 5,
padding: 10
},
gridLines: {
drawTicks: false,
display: false
}
}],
xAxes: [{
gridLines: {
zeroLineColor: "transparent"
},
ticks: {
padding: 10,
fontStyle: "500"
}
}]
},
legendCallback: function(chart) {
var text = [];
text.push('<ul class="' + chart.id + '-legend html-legend">');
for (var i = 0; i < chart.data.datasets.length; i++) {
text.push('<li><span style="background-color:' + chart.data.datasets[i].legendColor + '"></span>');
if (chart.data.datasets[i].label) {
text.push(chart.data.datasets[i].label);
}
text.push('</li>');
}
text.push('</ul>');
return text.join('');
}
}
});
I am reading a text file and put the data from the text file into arrays and I pass the arrays as data in the Chart.js dataset field but the data is not plotted. I have tried to use the update function but I am not winning. The arrays are populated when I log them to the console.
Here's my JS and HTML:
/// <reference path="../scripts/angular.js" />
/// <reference path="angular-chart.min.js" />
/// <reference path="Chart.min.js" />
var app;
//Start of File Reader
var currentArray = new Array();
var voltageArray = new Array();
document.getElementById('inputFile').onchange = function () {
var file = this.files[0];
var reader = new FileReader();
reader.onload = function (progressEvent) {
var lines = this.result.split('\n');
for (var line = 4; line < lines.length - 2; line++) {
var pair = lines[line].split('\t');
if (!pair[0].includes(".") || !pair[1].includes(".")) {
voltageArray.push(parseFloat(pair[0].replace(' ', '.')));
currentArray.push(parseFloat(pair[1].replace(' ', '.')));
}
else {
voltageArray.push(parseFloat(pair[0]));
currentArray.push(parseFloat(pair[1]));
}
}
};
reader.readAsText(file);
};
//End of File Reader
console.log(voltageArray);
console.log(currentArray);
//Module
(function () {
app = angular.module("app", ['chart.js']);
})();
app.controller("lineCtrl_Voltage", function ($scope) {
let lineV = new Chart(document.getElementById("voltage"), {
type: 'line',
data: {
labels: [0.00018,
0.00036,
0.00054,
0.00072,
0.0009,
0.00108,
0.00126,
0.00144,
0.00162,
0.0018,
0.00198,
0.00216,
0.00234,
0.00252,
0.0027,
0.00288,
0.00306,
0.00324,
0.00342,
0.0036,
0.00378,
0.00396,
0.00414,
0.00432,
0.0045,
0.00468,
0.00486,
0.00504,
0.00522,
0.0054,
0.00558,
0.00576,
0.00594,
0.00612,
0.0063,
0.00648,
0.00666,
0.00684,
0.00702,
0.0072,
0.00738,
0.00756,
0.00774,
0.00792,
0.0081,
0.00828,
0.00846,
0.00864,
0.00882,
0.009,
0.00918,
0.00936],
datasets: [{
data: [0, 0, 0, 0],
label: "Voltage",
borderColor: "#8e5ea2",
fill: false
}]
},
options: {
title: {
display: true,
text: ''
},
scales: {
yAxes: [{
display: true,
ticks: {
suggestedMin: 0, // minimum will be 0, unless there is a lower value.
},
scaleLabel: {
display: true,
labelString: 'Voltage (V)'
}
}],
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Time (ms)'
}
}],
}
}
});
lineV.update();
});
app.controller("lineCtrl_Current", function ($scope) {
new Chart(document.getElementById("current"), {
type: 'line',
data: {
labels:
[0.00018,
0.00036,
0.00054,
0.00072,
0.0009,
0.00108,
0.00126,
0.00144,
0.00162,
0.0018,
0.00198,
0.00216,
0.00234,
0.00252,
0.0027,
0.00288,
0.00306,
0.00324,
0.00342,
0.0036,
0.00378,
0.00396,
0.00414,
0.00432,
0.0045,
0.00468,
0.00486,
0.00504,
0.00522,
0.0054,
0.00558,
0.00576,
0.00594,
0.00612,
0.0063,
0.00648,
0.00666,
0.00684,
0.00702,
0.0072,
0.00738,
0.00756,
0.00774,
0.00792,
0.0081,
0.00828,
0.00846,
0.00864,
0.00882,
0.009,
0.00918,
0.00936],
datasets: [{
data: [0, 0, 0, 0, 0, 0, 0, 0, 0],
label: "Current",
borderColor: "#3e95cd",
fill: false
}]
},
options: {
title: {
display: true,
text: ''
},
scales: {
yAxes: [{
display: true,
ticks: {
suggestedMin: 0, // minimum will be 0, unless there is a lower value.
},
scaleLabel: {
display: true,
labelString: 'Current (A)',
}
}],
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Time (ms)'
}
}],
}
}
});
});
function addData(chart, data) {
chart.data.datasets.forEach((dataset) => {
dataset.data.push(data);
});
chart.update();
}
<div class="row" ng-app="app">
<div class="col-md-1"></div>
<div class="col-md-5">
<div class="x_panel">
<div class="x_title">
<h2 style="text-align: -webkit-center;">Voltage vs Time </h2>
<div class="clearfix"></div>
</div>
<div class="x_content">
<div ng-controller="lineCtrl_Voltage">
<canvas id="voltage"></canvas>
</div>
</div>
</div>
</div>
<div class="col-md-5">
<div class="x_panel">
<div class="x_title">
<h2 style="text-align: -webkit-center;">Current vs Time</h2>
<div class="clearfix"></div>
</div>
<div class="x_content">
<div ng-controller="lineCtrl_Current">
<canvas id="current"></canvas>
</div>
</div>
</div>
</div>
<div class="col-md-1"></div>
</div>
The low and high points on this chart are getting cut off, is there any way to fix this without knowing what numbers will be in the data?
I've seen other people create some padding with the chart's minimum and maximum values, but I don't know what the values will be beforehand.
Chart:
A similar example suffering from the same problem is shown here: http://codepen.io/erose/pen/LNwdQO/
Here's the HTML:
<div class="chart-container">
<canvas id="chart"></canvas>
</div>
Here's the CSS:
.chart-container {
width: 493px;
height: 83px;
}
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
and here the JS used to create the above chart:
var ctx = $("#chart");
Chart.defaults.global.responsive = true;
Chart.defaults.global.maintainAspectRatio = false;
Chart.defaults.global.legend.display = false;
Chart.defaults.global.tooltips.backgroundColor = "lightblue";
Chart.defaults.global.tooltips.bodyFontFamily = "sans-serif";
Chart.defaults.global.tooltips.bodyFontSize = 20;
Chart.defaults.global.tooltips.bodyColor = "#95989a";
Chart.defaults.global.tooltips.bodyAlign = "left";
Chart.defaults.global.tooltips.titleFontSize = 0;
Chart.defaults.global.tooltips.titleMarginBottom = 0;
Chart.defaults.global.tooltips.footerMarginTop = 0;
Chart.defaults.global.tooltips.cornerRadius = 12;
Chart.defaults.global.tooltips.caretSize = 10;
Chart.defaults.global.tooltips.xPadding = 20;
Chart.defaults.global.tooltips.yPadding = 10;
Chart.defaults.scale.gridLines.color = 'white';
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [" ", "", "", "", "", "", "", "", "", " "],
datasets: [{
label: '$',
data: [100,100,100,100,0,100,100,100,100,100],
fill: false,
borderWidth: 1,
borderColor: "#2f75c1",
borderCapSytle: "round",
pointBorderColor: "#2f75c1",
pointBackgroundColor: "#2f75c1",
pointBorderWidth: 5,
pointHoverRadius: 10,
}]
},
options: {
scales: {
yAxes: [{
gridLines: {
display: false
},
scaleLabel: {
display: false
},
scaleLkneColor: 'white',
ticks: {
display: false
}
}],
xAxes: [{
gridLines: {
display: false
},
scaleLabel: {
display: false
},
// ticks: {
// display: false
// }
}]
}
}
});
From reading your question I believe you not only want the for the circle to not be cut off but you would like some extra padding inside the chart.
For that I would structure this a little different:
var ctx = $("#chart");
Chart.defaults.global.responsive = true;
Chart.defaults.global.maintainAspectRatio = false;
Chart.defaults.global.legend.display = false;
Chart.defaults.global.tooltips.backgroundColor = "lightblue";
Chart.defaults.global.tooltips.bodyFontFamily = "sans-serif";
Chart.defaults.global.tooltips.bodyFontSize = 20;
Chart.defaults.global.tooltips.bodyColor = "#95989a";
Chart.defaults.global.tooltips.bodyAlign = "left";
Chart.defaults.global.tooltips.titleFontSize = 0;
Chart.defaults.global.tooltips.titleMarginBottom = 0;
Chart.defaults.global.tooltips.footerMarginTop = 0;
Chart.defaults.global.tooltips.cornerRadius = 12;
Chart.defaults.global.tooltips.caretSize = 10;
Chart.defaults.global.tooltips.xPadding = 20;
Chart.defaults.global.tooltips.yPadding = 10;
Chart.defaults.scale.gridLines.color = 'white';
var getData = [100,100,100,100,0,100,100,100,100,100];
var getLabels = ["", "", "", "", "", "", "", "", "", ""];
var minNum = function(array){
return Math.min.apply( Math, array )-10;
}
var maxNum = function(array){
return Math.max.apply( Math, array )+10;
}
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: getLabels,
datasets: [{
label: '$',
data: getData,
fill: false,
borderWidth: 1,
borderColor: "#2f75c1",
borderCapSytle: "round",
pointBorderColor: "#2f75c1",
pointBackgroundColor: "#2f75c1",
pointBorderWidth: 5,
pointHoverRadius: 10,
}]
},
options: {
scales: {
yAxes: [{
gridLines: {
display: false
},
scaleLabel: {
display: false
},
scaleLkneColor: 'white',
ticks: {
suggestedMin: minNum(getData),
suggestedMax: maxNum(getData),
}
}],
xAxes: [{
gridLines: {
display: false
},
scaleLabel: {
display: false
},
// ticks: {
// display: false
// }
}]
}
}
});
.chart-container {
width: 493px;
height: 83px;
}
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.3/Chart.bundle.min.js"></script>
<div class="chart-container">
<canvas id="chart"></canvas>
</div>
2 Important changes
I create a getData var to hold the array this way the array can be formatted however you like the function does not care it just looks for getData and expects an array.
I created a minNum and maxNum function to go through the array and select either the lowest or highest number then call that inside the ticker you can find more on this at ChartJS Scales