I am using a canvasjs to make a pie chart. I am using it in my custom code where I am getting the response from the server in an xml file and then I am using it to fill the chart values. My problem is that I am not able to change the colour of the chart meaning even for different labels the colour remains the same for the whole pie chart.
I used debugger also where it the value for colour is changing but still I am not able to resolve it.
color: scopes.chart_color_value[i]
I am using an another configuration file where I am storing colour values.
Here is my custom code
$scope.loadChartValue = function (data, scopes) {
scopes.data_id = [];
scopes.legend_text = "";
scopes.inner_chart_data = [];
for (var i = 0; i <= data.length; i++) {
var arrayvalue = data[0].data[i]._attr
if (existsInArray(scopes.data_id, arrayvalue.label._value) == false) {
scopes.data_id.push(arrayvalue.label._value);
}
}
scopes.inner_chart_data = [];
var i=1;
for (var j = 0; j < data[0].data.length; j++) {
scopes.inner_chart_data.push({ label: data[0].data[j]._attr.label._value, y: data[0].data[j]._attr.value._value });
scopes.dataset.push(
{
type: "pie",
markerType: "circle",
markerSize: scopes.markersize,
color: scopes.chart_color_value[i],
showInLegend: false,
name: scopes.legend_text,
dataPoints: scopes.inner_chart_data
}
);
i++;
}
}
It seems you are creating 2 data-series instead of 1 data-series with 2 dataPoints. When color is set at data-series level, whole pie becomes single color, so try changing it at data-point level.
The following code should work fine.
for (var j = 0; j < data[0].data.length; j++) {
scopes.inner_chart_data.push({ label: data[0].data[j]._attr.label._value, y: data[0].data[j]._attr.value._value, color: scopes.chart_color_value[i], });
i++;
}
scopes.dataset.push(
{
type: "pie",
markerType: "circle",
markerSize: scopes.markersize,
showInLegend: false,
name: scopes.legend_text,
dataPoints: scopes.inner_chart_data
}
);
Related
I am using a chart.js 3.x JavaScript library for displaying charts.
I need to update the chart for which rendering is in progress.
I am using JavaScript Worker for updating the chart data.
for (var index=0;index < myjson.length;index++) {
chart.data.datasets[index].data.push(myjson[index]);
}
chart.update();
I am doing something like below to clean the chart dataset.
// Set the empty data and render the chart to clear the data
for (var index=0;index < chart.data.datasets.length;index++) {
chart.data.datasets[index].data = [];
}
chart.update();
But I see a few of the lines are still on the chart and not cleared properly.
May be continuous drawing is causing this issue.
I have also tried to clear() and reset() the chart but no effect.
So how to clear the chart data properly and redraw new dataset.
use stop() to end the current animation loop,
then clear the data, and update the chart without animation.
see following working snippet,
once the animation progress reaches 50%,
the animation is stopped, the data is cleared, and the chart is updated without animation...
$(document).ready(function() {
var offset = [100, 100, 100, 100];
var data = [7900, 5400, 4300, 4300];
var ctx = document.getElementById('bar-chart');
var data = {
labels: ['June 9', 'June 11', 'June 13', 'June 15'],
datasets: [{
data: offset,
backgroundColor: 'transparent'
}, {
data: data.map(function (value, index) {
return value - offset[index];
}),
backgroundColor: 'orange'
}]
}
var chart = new Chart(ctx, {
type: 'bar',
data: data,
options: {
animation: {
onProgress: function(animation) {
var progress = animation.currentStep / animation.numSteps;
// determine if progress is above 50%
if (progress >= 0.5) {
// stop current animation loop
animation.chart.stop();
// remove labels and data
for (var i = chart.data.labels.length - 1; i >= 0; i--) {
animation.chart.data.labels.pop();
}
for (var i = chart.data.datasets.length - 1; i >= 0; i--) {
animation.chart.data.datasets.pop();
}
// update without animation
animation.chart.update(0);
}
}
},
legend: {
display: false
},
tooltips: {
enabled: false
},
scales: {
yAxes: [{
stacked: true
}]
}
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.0.0-beta/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="bar-chart"></canvas>
I want to generate graphs dynamically when I click on a button. My problem is when I click the button second time, the first graphs blocks displaying data.
The problem is with setInterval used within addChart function but I can't figure out how to rectify the issue. Is there some sanity in my logic or not?
<script>
function addChart() {
chartCount++;
var name = document.getElementById("chartName").value;
chartDict[name] = chartCount;
chart[chartCount] = new CanvasJS.Chart("chartContainer" + chartCount, {
title: {
text: name
},
axisY: {
includeZero: false,
maximum: 70
},
axisX: {
valueFormatString: "hh:mm tt"
},
data: [{
type: "line",
dataPoints: dps[chartCount]
}]
});
updateChart[chartCount] = function(count) {
count = count || 1;
for (var j = 0; j < count; j++) {
dps[chartCount].push({
x: xVal[chartCount],
y: yVal[chartCount]
});
xVal[chartCount] = new Date()
//console.log(xVal)
//xVal++;
}
if (dps[chartCount].length > dataLength) {
dps[chartCount].shift();
}
chart[chartCount].render();
};
intervals[chartCount] = setInterval(updateChart[chartCount], 1000)
}
</script>
You can try below workaround :
Remove the chart's inner content from DOM before reassigning the new values to chart element
Below is link to use remove() method of jquery:
https://api.jquery.com/remove/
I am trying to get user inputs and then draw a bubble chart with 100 bubbles. How can I change the background color of bubbles to different colors(up to 10 colors)?
Below is my javascript code,
<script>
function generateChart() {
var my_arr = [];
var Stakeholders = [];
$('td').each(function () {
my_arr.push($(this).children().val());
});
var length = my_arr.length;
for (var i = 0; i < length - 2; i++) {
var Stakeholder = new Object();
Stakeholder.name = my_arr[i] || 'Unknown';
Stakeholder.x = parseFloat(my_arr[i + 1] || 5);
Stakeholder.y = parseFloat(my_arr[i + 2] || 5);
Stakeholders.push(Stakeholder);
i += 2;
}
drawChart(Stakeholders);
};
function drawChart(Stakeholders) {
Highcharts.chart('container', {
chart: {
type: 'bubble',
plotBorderWidth: 1,
zoomType: 'xy',
spacingTop: 40,
spacingRight: 40,
spacingBottom: 40,
spacingLeft: 40,
borderWidth: 1
},
plotOptions: {
column: {
colorByPoint: true
}
},
series: [{
data: Stakeholders
}]
});
};
</script>
I should have added a property to Stakeholder:
var colors = ['#98d9c2', '#ffd9ce', '#db5461', '#f5853f', '#b497d6', '#dc965a', '#FF9655', '#FFF263', '#6AF9C4', "000"];
for (var i = 0; i < length - 2 ; i++) {
var Stakeholder = new Object();
var color = parseInt(Math.random() * 10);
Stakeholder.name = my_arr[i] || 'Unknown';
Stakeholder.x = parseFloat(my_arr[i + 1]);
Stakeholder.y = parseFloat(my_arr[i + 2]);
Stakeholder.z = 5;
Stakeholder.color = colors[color];
Stakeholders.push(Stakeholder);
i += 2;
}
I'm not sure if you want to assign specific colors to specific bubbles or just randomly assign colors, but you can add a color: 'somecolor' property to each bubble object in the series.
Fiddle here (see lines 96-110).
Or, you could create an array of colors, loop through your bubble series, and randomly assign a color to each bubble object.
Hope this helps.
I'm currently trying to get a chart I have as drilldown remove all series data previously and redraw with new data. Below I've added the ajax calls and the html/javascript for the chart. The problem was that everytime I called the chart, it would rebuild the chart and double call. So I've been trying to get it to simply remove the data and redraw with new data from the ajax call.
AJAX & SetData call:
self.drilldownLoad = (year: number) => {
self.isDrilldownLoading(true);
self.isDrilldownLoaded(false);
$.ajax({
xhrFields: { withCredentials: true },
url: areaUrl + "api/Incident/IncidentDrilldown?year=" + year,
success: data => {
self.isDrilldownLoading(false);
self.data(data);
self.setDrilldownPlotData(data);
self.isDrilldownLoaded(true);
},
error: data => {
self.loadingError(true)
}
});
}
self.setDrilldownPlotData = (data: any) => {
while (self.drilldownPlotData().length) {
self.drilldownPlotData().pop();
}
while (self.drilldownPlotDataLabels().length) {
self.drilldownPlotDataLabels().pop();
}
var len = data.List.length,
i;
var criticalData = [];
for (i = 0; i < len; i++) {
criticalData.push(
data.List[i].Critical
)
}
var highData = [];
for (i = 0; i < len; i++) {
highData.push(
data.List[i].High
)
}
var mediumData = [];
for (i = 0; i < len; i++) {
mediumData.push(
data.List[i].Medium
)
}
var lowData = [];
for (i = 0; i < len; i++) {
lowData.push(
data.List[i].Low
)
}
for (i = 0; i < len; i++) {
self.drilldownPlotDataLabels.push(
data.List[i].IncidentMonth
)
}
self.drilldownPlotData.push(
{
name: 'Critical',
data: criticalData,
color: '#fa5a5a',
},
{
name: 'High',
data: highData,
color: '#fea156',
},
{
name: 'Medium',
data: mediumData,
visible: false,
color: '#b191c3',
},
{
name: 'Low',
data: lowData,
visible: false,
color: '#83bfd1',
}
)
}
This creates the initial chart. Once the chart is initialized, I set it to not be recreated every time I have data load from this particular ajax call. I can't seem to get it load the series data in correctly and redraw the chart.
var = subchartCreated = false;
viewModel.isDrilldownLoaded.subscribe(function () {
if (!subchartCreated) {
specificChart();
subchartCreated = true;
}
if (subchartCreated === true)
{
for (var i = 0; i < specificChart.series.length; i++) {
specificChart.series[i].remove(true); //forces the chart to redraw
}
}
});
I have two charts, one chart is the initial chart and that one is loading just fine. The second chart is the one of interest and I would like to have it load once and then simply load the series data, remove it from the second chart and then redraw with the new data. This is the click function that I have in the first chart to load the second chart. Currently, it works on the first load, but will not update data beyond that.
point: {
events: {
click: function () {
viewModel.drilldownLoad(this.category);
$('#drilldownButton').removeClass('hidden');
$('#yearlyincident-container').addClass('hidden');
$('#drilldown-container').removeClass('hidden');
$('#incidentInfoGrid').addClass('hidden');
$('#incidentDrillDownGrid').removeClass('hidden');
getDrilldownData(this.category);
}
}
}
I feel like its a relatively easy fix, but I'm just not getting it right. My initial attempts only removed the click functionality of the first chart. Any help with this would be greatly appreciated. Thanks!
So I'm trying to build a pie chart using chartjs in meteor.
I'm pretty sure the problem is that the order of precedence is talking over here.
I need the object in this order
{
value: 900.65,
color:"#red",
highlight: "#FF5A5E",
label: "income"
}
but i get it in this order
{
color: "#red"
highlight: "#FF5A5E"
label: "income"
value: 900.65
}
This is my loop
function drawExpPie(){
data = [];
var Task = Tasks.find({},{fields:{value:1,text:1}}).fetch();
for(var i = 0; i < Task.length; i++) {
var newdataset = {
label:Task[i].text,
highlight: "#FCA456",
color: "red",
value:Task[i].value,
};
data.push(newdataset);
}
console.log(data);
var context = document.getElementById('myExpChart').getContext('2d');
var myPieChart = new Chart(context).Pie(data);
}
Template.exp.helpers({
exp: function() {return Session.get("exp");}
});
Template.exp.rendered = function(){
drawExpPie();
};
Any help is appreciated. Thanks
Change value:Task[i].value to
value:Task[i].value || 0,
This fixed it...
for(var i = 0; i < Task.length; i++) {
data.push({
label: Task[i].text,
highlight: "#FF5A5E",
color:"#F7464A",
value: Number(Task[i].value)
});
}
Keynote : value: Number(Task[i].value) would likely work as well.