Related
I need an array with chart values, I obtained one but after exiting from the function it became blank, here's what happens: Example
function AddvotoTec(votor) {
class Avg {
constructor() {}
static average(votor) {
var total = 0;
var count = 0;
jQuery.each(votor, function(index, value) {
total += value;
count++;
});
return total / count;
}
}
var mvoti = Avg.average(votor);
var mvoti = Math.round((mvoti + Number.EPSILON) * 10) / 10;
const myJSON = JSON.stringify(mvoti);
voti(myJSON);
}
var allvoti = [];
function voti(Voti) {
allvoti.push(Voti);
}
const data = {
labels: labels,
datasets: [{
label: 'My First dataset',
backgroundColor: [
'rgb(255, 132, 0)'
],
borderColor: 'rgb(255, 99, 132)',
data: allvoti,
}]
};
The chart that I used is Chart.js.
I need to make a chart at the level with a row in the table, are there any tips on how to implement this enter image description here
I need the chart lines to match the row level in the table
and this code draws a separate chart
const diag = () => {
document.getElementById("canvasic").innerHTML = ' ';
document.getElementById("canvasic").innerHTML = '<canvas id="densityChart" className="canav"></canvas>';
densityCanvas = document.getElementById("densityChart");
//remove canvas from container
Chart.defaults.global.defaultFontFamily = "Arial";
Chart.defaults.global.defaultFontSize = 16;
var densityData = {
label: 'CallVol',
data:calloiList1,
backgroundColor: 'rgba(0,128,0, 0.6)',
borderColor: 'rgba(0,128,0, 1)',
borderWidth: 2,
hoverBorderWidth: 0
};
var densityData1 = {
label: 'PutVol',
data:calloiList3 ,
backgroundColor: 'rgba(255,0,0, 0.6)',
borderColor: 'rgba(255,0,0, 1)',
borderWidth: 2,
hoverBorderWidth: 0
};
var chartOptions = {
scales: {
yAxes: [{
barPercentage: 0.5
}]
},
elements: {
rectangle: {
borderSkipped: 'left',
}
}
};
var barChart = new Chart(densityCanvas, {
type: 'horizontalBar',
data: {
labels: calloiList4,
datasets: [densityData,densityData1],
},
options: chartOptions
}
);
}
enter image description here
EDIT: I have narrowed it down to something like this:
for (i = 0; i < data.length; i++) {
const newCanvas = document.createElement("canvas");
newCanvas.id = data[i].design_name;
const currentDiv = document.getElementById("chartSpace");
var parentDiv = document.getElementById("gridHere");
parentDiv.insertBefore(newCanvas, currentDiv);
createChart([data[i].design_name], [data[i].design_start, data[i].design_end]);
}
With the create chart making the chart id = to the array 'labels':
const myChart = new Chart(
document.getElementById(labels),
config
);
I am attempting to create a tool that creates an 'n' number of charts in ChartJS and save each of them as images. Currently, designButtonClick() sends the 'event_fky' value to
getDesigns(event_fky) in my controller. This method returns all designs with that foreign key. In turn, the chart plots each design on the chart. I need to evolve this into
something that can make a group individual charts for each design based on how many designs there are. My current solution, still conceptual, is to have methods in my controller
create chart variables 'chartData [data here]' and 'labels[datahere]' while looping through the designs returned from getDesigns, and sending those back to the JS script createChart
'n' number of times for each design. It would also send html chart/html element ids based on the design_name attribute to send back to createChart. This way, it is create a unique
chart 'n' number of times.
To save the charts as images, I would use the same set of element ids generated by getDesigns to send the charts to images using JS' toBase64Image() function and saving them to the
user's system.
Is this the best way of solving this problem? Or is this spaghetti, and is there a better method for this? My attempts to find better online answers have only resulted in docs on
updating one chart dynamically, not creating a dynamic number of charts. Much help is appreciated, code is below as well as a screenshot of the current chart output.
JavaScript:
var labels = [];
var cData = [];
function designButtonClick() {
var event_fky = 3;
$.ajax({
url: 'Tree/getDesigns',
type: 'POST',
data: { event_fky }
}).done(function (data) {
for (i = 0; i < data.length; i++) {
labels.push(data[i].design_name);
cData.push([data[i].design_start, data[i].design_end])
}
createChart(labels, cData);
});
}
function createChart(labels, cData) {
const data = {
labels: labels,
datasets: [{
barThickness: 2,
categoryPercentage: .5,
label: 'Design Time',
data: cData,
backgroundColor: [
'rgba(255, 26, 104, 0.2)'
],
borderColor: [
'rgba(255, 26, 104, 1)'
],
borderWidth: 1,
borderSkipped: false,
borderRadius: 20
}]
};
const config = {
type: 'bar',
data,
options: {
indexAxis: 'y',
scales: {
y: {
beginAtZero: true
},
x: {
min: 0,
max: 6000,
ticks: {
stepSize: 1000
}
}
}
}
};
const myChart = new Chart(
document.getElementById('myChart'),
config
);
}
C# Controller:
public ActionResult getDesigns(int? event_fky)
{
var designs = from e in _context.designs
where (event_fky.HasValue ? e.event_fky == event_fky : e.event_fky == null)
select new
{
design_pky = e.design_pky,
design_name = e.design_name,
design_start = e.design_start,
design_end = e.design_end
};
return this.Json(designs, JsonRequestBehavior.AllowGet);
}
Designs Table:
--------Design--------
design_pky |int
event_fky |int
design_name |varchar
design_start |number
design_end |number
Screenshot of Chart
This is a working answer for the javascript:
var eventList = function () {
var tmp = null;
$.ajax({
'async': false,
url: 'Tree/getEventIDs',
type: 'POST',
data: {},
'success': function (data) {
tmp = data;
}
});
return tmp;
}();
for (var i = 0; i < eventList.length; i++) {
event_fky = eventList[i].event_pky;
event_name = eventList[i].event_name;
event_length = eventList[i].event_end;
var designList = function () {
var tmpi = null;
$.ajax({
'async': false,
url: 'Tree/getDesigns',
type: 'POST',
data: {event_fky},
'success': function (data1) {
tmpi = data1;
}
});
console.log(event_fky);
console.log(tmpi);
return tmpi;
}();
var dLabels = [];
var dLengths = [];
for (var j = 0; j < designList.length; j++) {
dLabels.push(designList[j].design_name);
dLengths.push([designList[j].design_start, designList[j].design_end]);
}
const newCanvas = document.createElement("canvas");
newCanvas.id = event_name;
const currentDiv = document.getElementById("chartSpace");
var parentDiv = document.getElementById("gridHere");
parentDiv.insertBefore(newCanvas, currentDiv);
if (dLabels.length != 0) {
createChart(dLabels, dLengths, event_name, event_length);
}
}
}
function createChart(labels, cData, evName, evLen) {
// setup
const data = {
labels: labels,
datasets: [{
barThickness: 4,
categoryPercentage: .5,
label: evName,
data: cData,
backgroundColor: [
'rgba(' + Math.random() * 85 + ', ' + Math.random() * 170 + ', ' + Math.random() * 255 + ', 1)'
],
borderColor: [
'rgba(255, 26, 104, 1)'
],
borderWidth: 0,
borderSkipped: false,
borderRadius: 20
}]
};
// config
const config = {
type: 'bar',
data,
options: {
indexAxis: 'y',
scales: {
y: {
beginAtZero: true
},
x: {
min: 0,
max: evLen,
ticks: {
stepSize: 100
}
}
}
}
};
// render init block
const myChart = new Chart(
document.getElementById(evName),
config
);
return myChart;
}
Created a Sandbox where you could see full code:
codesandbox.io/s/elastic-cray-mdpfx?file=/src/visualizations.js
So I first created three React hooks as follows and have already set their state in another function.
var [questionsAndAnswersGuide, setQuestionsAndAnswersGuide] = useState({});
var [dataForChart, setDataForChart] = useState({});
var [currentQuestionID, setCurrentQuestionID] = useState('Q1');
And then I created a function called generateChartData with this function signature
const generateChartData = (questionID, data, questionsAndAnswers) => {
var answersToFrequency = {};
var chartLabels = [];
var graphData = [];
var graphLabel = "Answers";
var graphBackgroundColors = [
'rgba(7,221,100,0.6)',
'rgba(63,130,7, 0.6)',
'rgba(255, 99, 132, 0.6)',
'rgba(54, 162 ,235, 0.6)',
'rgba(200,7,100)',
'rgba(255,206,86,0.6)',
'rgba(75,192,192,0.6)',
'rgba(153,102,255,0.6)',
'rgba(255,159,64,0.6)',
'rgba(255,99,132,0.6)'
];
for(var i = 0; i < questionsAndAnswers[questionID].length; i++) {
answersToFrequency[questionsAndAnswers[questionID][i]] = 0;
}
for(const post of data) {
if(post[questionID] != "") {
answersToFrequency[post[questionID]] += 1;
}
}
for(var key in answersToFrequency) {
if(!isNaN(answersToFrequency[key])) {
chartLabels.push(key);
graphData.push(answersToFrequency[key]);
}
}
return {labels: chartLabels, datasets: [{label: graphLabel, data:
graphData, backgroundColor: graphBackgroundColors}]};
}
And this function returns a dictionary that contains data
Now I created a Chart class that would just display a bar graph.
class Chart extends Component {
constructor(props) {
super(props);
this.state = {
chartData: props.chartData
}
}
static defaultProps = {
displayTitle:true,
displayLegend:true,
legendPosition:'right',
questionNumber: 'Question 1'
}
render() {
return (
<div className='chart'>
<Bar
data={this.state.chartData}
options={{
title: {
display: this.props.displayTitle,
text: 'Bar Chart for ' + this.props.questionNumber,
fontSize:50
},
legend: {
display: this.props.displayLegend,
position: this.props.legendPosition
}
}}
/>
</div>
)
}
}
export default Chart;
However, when I say that the chartData should be the result of the function generateChartData, it fails to actually hold the value of the result of generateChartData and in the Chart class, it says that the value of chartData is undefined. How do I properly make chartData equal to the result of function generateChartData?
useEffect(() => { <br>
chart(); <br>
}, []); <br>
return ( <br>
<div className='Visualization'> <br>
<Chart chartData={generateChartData(currentQuestionID, dataForChart, questionsAndAnswersGuide)}
legendPosition='bottom'/>
However when I do something like this:
useEffect(() => { <br>
chart(); <br>
}, []); <br>
return ( <br>
<div className='Visualization'> <br>
<Chart chartData={{labels: ['Miami', 'San Francisco', 'Chicago', 'New York', 'Los Angeles', 'Houston'],
datasets: [
{
label: 'Population',
data: [
104343,
423424,
902114,
1000533,
156789,
78939
],
backgroundColor: [
'rgba(7,221,100,0.6)',
'rgba(63,130,7, 0.6)',
'rgba(255, 99, 132, 0.6)',
'rgba(54, 162 ,235, 0.6)',
'rgba(200,7,100)',
'rgba(255,206,86,0.6)',
'rgba(75,192,192,0.6)',
'rgba(153,102,255,0.6)',
'rgba(255,159,64,0.6)',
'rgba(255,99,132,0.6)'
]
}
]
}
} legendPosition='bottom'/>
It generates the chart for me ad Im not sure where I am going wrong here. Moreover, if I now try this:
const generateChartData = (questionID, data, questionsAndAnswers) => {
var answersToFrequency = {};
var chartLabels = [];
var graphData = [];
var graphLabel = "Answers";
var graphBackgroundColors = [
'rgba(7,221,100,0.6)',
'rgba(63,130,7, 0.6)',
'rgba(255, 99, 132, 0.6)',
'rgba(54, 162 ,235, 0.6)',
'rgba(200,7,100)',
'rgba(255,206,86,0.6)',
'rgba(75,192,192,0.6)',
'rgba(153,102,255,0.6)',
'rgba(255,159,64,0.6)',
'rgba(255,99,132,0.6)'
];
for(var i = 0; i < questionsAndAnswers[questionID].length; i++) {
answersToFrequency[questionsAndAnswers[questionID][i]] = 0;
}
for(const post of data) {
if(post[questionID] != "") {
answersToFrequency[post[questionID]] += 1;
}
}
for(var key in answersToFrequency) {
if(!isNaN(answersToFrequency[key])) {
chartLabels.push(key);
graphData.push(answersToFrequency[key]);
}
}
return {labels: ['Miami', 'San Francisco', 'Chicago', 'New York', 'Los Angeles', 'Houston'],
datasets: [
{
label: 'Population',
data: [
104343,
423424,
902114,
1000533,
156789,
78939
],
backgroundColor: [
'rgba(7,221,100,0.6)',
'rgba(63,130,7, 0.6)',
'rgba(255, 99, 132, 0.6)',
'rgba(54, 162 ,235, 0.6)',
'rgba(200,7,100)',
'rgba(255,206,86,0.6)',
'rgba(75,192,192,0.6)',
'rgba(153,102,255,0.6)',
'rgba(255,159,64,0.6)',
'rgba(255,99,132,0.6)'
]
}
]
}
`` }
It fails to actually hold the value of the result of generateChartData and in the Chart class, it says that the value of chartData is undefined.
// here I am taking another json encoded data from phpfile
$(document).ready(function () {
showGraph();
});
function showGraph()
{
{
$.post("phpfile.php",
function (data)
{
console.log(data);
var name = [];
var marks = [];
var height=[];
//and here as I couldn't encode two json array's separetly I'm declaring it to a variable and then using it
var jsonfile =[{"height":"85","st_name":"Name1"},{"height":"100","st_name":"Name3"},{"height":"92","st_name":"Name4"},{"height":"104","st_name":"Name5"},{"height":"91","st_name":"Name2"},{"height":"99","st_name":"Name6"},{"height":"140","st_name":"AI346"},{"height":"139","st_name":"abc"},{"height":"141","st_name":"def"},{"height":"140","st_name":"ghi"},{"height":"144","st_name":"jkl"},{"height":"130","st_name":"lmn"},{"height":"142","st_name":"opq"},{"height":"132","st_name":"rst"},{"height":"135","st_name":"xyz"},{"height":"135","st_name":"asdfsf"}];
//here I am reading the data from phpfile(1st Json array)
for (var i in data) {
name.push(data[i].st_name);
marks.push(data[i].height);
}
//here i am trying to access data from second json
for (var i=0;i<jsonfile.length;i++){
if(jsonfile[i].height==100)
{ height.push(jsonfile[i].height)}
}
//my graph function ,when I do this I am getting a single point with second json(height variable) but I need to highlight the particular point under a condition... I am not understanding how to do it.
var chartdata = {
labels: name,
datasets: [
{
label: 'height',
fill:false,
lineTension:0.5,
backgroundColor: '#5B2C6F',
borderColor: '#5B2C6F',
pointHoverBackgroundColor: '#5B2C6F',
pointHoverBorderColor: '#5B2C6F',
data: marks
//data:height
},
{
label: 'weight',
fill:false,
lineTension:0.1,
backgroundColor: '#C0392B',
borderColor: '#C0392B',
pointHoverBackgroundColor: '#C0392B',
pointHoverBorderColor: '#C0392B',
data:height,
//data:height
}
]
};
var graphTarget = $("#graphCanvas");
var lineGraph = new Chart(graphTarget, {
type: 'line',
data: chartdata,
options :{
scales:{
xAxes: [{
display: false //this will remove all the x-axis grid lines
}]
}
}
});
});
}
}
</script>
i will try to improve this.
var data =[{"height":"85","st_name":"Name1","color":"rgba(85, 85, 255, 255)"},{"height":"100","st_name":"Name3","color":"rgba(255, 0, 0, 2)"},{"height":"92","st_name":"Name4","color":"rgba(85, 85, 255, 255)"},{"height":"104","st_name":"Name5","color":"rgba(85, 85, 255, 255)"}];
var height = [];
var label = [];
var color = [];
for(i = 0; i<data.length; i++){
height.push(data[i]['height']);
label.push(data[i]['st_name']);
color.push(data[i]['color']);
}
var ctx = document.getElementById('myLine').getContext('2d');
var myLineChart = new Chart(ctx, {
type: 'line',
data: {
labels: label,
datasets: [{
data: height,
pointBorderColor: color,
}]
}
});