I have the the code below.
And I want to draw 2 lineCharts on the same canvas like here http://prntscr.com/b8oabw
But instead I get this http://prntscr.com/b8o7pg
How to connect all blue parts and all red to make continious lines?
function drawChart() {
// Create the data table.
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('string', 'День');
dataTable.addColumn('number', 'Количество ручных назначений');
dataTable.addColumn('number', 'Количество отложенных задач');
#if (Model.ManualAssingDictionary.Count > 0)
{
foreach (var m in Model.ManualAssingDictionary)
{
#:dataTable.addRow(["#m.Key",#m.Value, undefined]);
}
}
else
{
#:$("#NoManualAssignmentForPeriod").css("display", "block");
}
#if (Model.PostponedDictionary.Count > 0)
{
foreach (var m in Model.PostponedDictionary)
{
#:dataTable.addRow(["#m.Key", undefined,#m.Value]);
}
}
else
{
#:$("#NoStoppedTasksForPeriod").css("display", "block");
}
dataTable.sort([{ column: 0 }]);
// Set chart options
var options =
{
'title': 'График количества ручных назначений',
'width': 800,
'height': 600
};
var chart = new google.visualization.LineChart(document.getElementById('chart'));
chart.draw(dataTable, options);
}
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(drawChart);
As the person above said
try using null instead of undefined -- add this to your options --> interpolateNulls: true
Many thanks to him, it's working.
Related
hi guys i am trying apexchart.js librry to draw a timeline chart.
i want a multiple series depending on tasks i have in sprint in bubble.io in which i want to give name and data parameter dynamically.
following is my code
<div id='chart' style='height: 70vh;'></div>
<script>
var task=[Parent group's Sprint's tasks:each item's Name:formatted as JSON-safe];
var names=[Parent group's Sprint's tasks:each item's developer:unique elements's Fname:formatted as JSON-safe];
var _startDates=[Parent group's Sprint's tasks:each item's Start-date:extract UNIX];
var _endDates=[Parent group's Sprint's tasks:each item's End-date:extract UNIX];
var startDates=[];
var endDates=[];
for(var i=0;i<task.length;i++){
startDates.push(new Date(_startDates[i]));
endDates.push(new Date(_endDates[i]));
}
console.log(names);
function getResult(){
var result=[];
var _data=[];
for (var j=0;j<task.lenght;j++){
_data.push({x:task[i],y:[startDates[i].getTime(), endDates[i].getTime()], fillColor: "#008FFB"})
}
for(var i=0;i<names.length;i++){
result.push({name:names[i],data: _data[i]});
}
return result;
}
var options = {
series:[
getResult()
],
chart: {
height: 450,
type: 'rangeBar'
},
plotOptions: {
bar: {
horizontal: true
}
}, xaxis: {
type: 'datetime'
}
};
var chart = new ApexCharts(document.querySelector("#chart"), options);
chart.render();
</script>
but it is giving me an error saying
It is a possibility that you may have not included 'data' property in series.
i would appreciate if anyone can suggest me where i am making mistake
thanks
I am using highchart-react-official, I am using it draw two charts:
1) Line chart with multiple series
2) Column Chart.
Now I want, if I hover over a point in first chart, it should display highlight point on both lines of first chart and column chart in second chart. Like a synchronized chart: http://jsfiddle.net/doc_snyder/51zdn0jz/6/
This is my code:
((H) => {
H.Pointer.prototype.reset = () => undefined;
/**
* Highlight a point by showing tooltip, setting hover state and
draw crosshair
*/
H.Point.prototype.highlight = function highlight(event) {
event = this.series.chart.pointer.normalize(event);
this.onMouseOver(); // Show the hover marker
this.series.chart.tooltip.refresh(this); // Show the tooltip
this.series.chart.xAxis[0].drawCrosshair(event, this); // Show the crosshair
};
H.syncExtremes = function syncExtremes(e) {
const thisChart = this.chart;
if (e.trigger !== 'syncExtremes') {
// Prevent feedback loop
Highcharts.each(Highcharts.charts, (chart) => {
if (chart && chart !== thisChart) {
if (chart.xAxis[0].setExtremes) {
// It is null while updating
chart.xAxis[0].setExtremes(e.min, e.max, undefined, false, {
trigger: 'syncExtremes',
});
}
}
});
}
};
})(Highcharts);
componentDidMount() {
this.changeChart();
['mousemove', 'touchmove', 'touchstart'].forEach((eventType) => {
document
.getElementById('tab__charts')
.addEventListener(eventType, (e) => {
for (let i = 0; i < Highcharts.charts.length; i += 1) {
const chart = Highcharts.charts[i];
// let secSeriesIndex = 1;
if (chart) {
// Find coordinates within the chart
const event = chart.pointer.normalize(e);
// Get the hovered point
chart.series.forEach(series => {
const point = series.searchPoint(event, true);
if (point) {
point.highlight(e);
}
});
}
}
});
});
}
Some imporant chart config:
tooltip: {
enabled: true,
useHTML: true,
shared: true,
}
xAxis: {
events: {
setExtremes: (e) => {
Highcharts.syncExtremes(e);
},
}
}
Now this code is working perfectly by synchronizing tooltip on both charts. But the issue is in first chart, it has two lines, when I hover over first line it hightlights the point with round circle, but the second line is not getting highlighted.
And the reason I found for that is in point.highlight(e); in componendDidMount
For second series, this line giving error on hover:
More specifically, point.highligh(e) is calling top function: H.Point.prototype.highlight = (), check top of the question, in that function this function call is resulting in error
this.series.chart.tooltip.refresh(this);
Note: I'll try to reproduce and create a jsfiddle or something like that, but posting this just so if anyone can help figure this out.
And I am passing Array of Object in Series data, because I need more informative tooltip on chart point:
data: [{
"x": "2018-12-23T11:00:09.311Z",
"y": 107.54,
"data": {
"Toltip Info 1": "1,884,681,725",
"Tooltip info 2": "158,039,757.99",
"price":"107.54"
}
}]
Here is demo of the issue: https://codesandbox.io/s/pk2w85jpk0
The problem is the data format, x values should be in milliseconds:
data: [
{
x: new Date("2018-12-25T09:00:06.247Z").getTime(),
y: 6609592859.48
},
...
]
Live demo: https://codesandbox.io/s/ovk25m493q
I have a chart in a wrapper:
var wrapper9 = null;
var chartcolors09 = parent.defaultcolors;
var chartEditor9 =null;
function Chart9() {
var data = new google.visualization.DataTable(<?=$jsonTableB9?>);
wrapper9 = new google.visualization.ChartWrapper({
chartType:'BarChart',
dataTable: data,
options: {
'colors': chartcolors09,
'chartArea': {
'left': 40,
'top': 50,
'right': 100,
'bottom': 50
},
'legend' :'Right',
'title':'Chart Title'
}
});
}
I can run a function to update colors of that chart using this function:
function setcolor9(){
wrapper9.setOptions({
'colors': chartcolors09
});
wrapper9.draw(document.getElementById('chart_div9'));
}
and this works just fine. I can also use other functions on that chartin that wrapper to update some other options. BUT when I use the ChartEditor on this chart
function loadEditor9() {
chartEditor9 = new google.visualization.ChartEditor();
google.visualization.events.addListener(chartEditor9, 'ok', redrawChart9);
chartEditor9.openDialog(wrapper9, {});
}
function redrawChart9(){
chartEditor9.getChartWrapper().draw(document.getElementById('chart_div9'));
}
the setcolor9() function stops working. It kinda looks like the ChartEditor created a 2nd chart and put it on top of the first one and the setcolor9() function keeps referring to the first one.
...oh and not sure if this is connected but the chart created by the loadEditor9() and redrawChart9() functions seems to ignore the height and width options set by other functions in the wrapper9 var and goes "outside" of the div container.
So the answer is of course very simple.
I just needed to change the redrawChart9() function to the below and now I can do whatever I want with that chart.
function redrawChart9(){
wrapper9 = chartEditor9.getChartWrapper();
wrapper9.draw();
}
I am making an line chart that will have lines appear and disappear with user interaction. Is there a way to animate the added data like the chart startup animation? Or fade line in and out so that it isn't so abrupt?
One Idea I had was to to set the new data to 0 then have have it animate to the new data but was wondering if there was another way.
Hope that makes sense
to animate from one data set to another, redraw the same chart with new data.
see following, working snippet. the data in each column is "swapped" before redraw...
google.charts.load('current', {
callback: function () {
var data = google.visualization.arrayToDataTable([["PR","CE","PE"],["5500",1875,2025],["6000",61500,104775],["6100",450,13725],["6500",35400,421800],["6600",150,121950],["6700",600,770925],["6800",13650,370425],["6900",33375,586650],["7000",744375,1122075],["7100",229200,355875],["7200",199800,689850],["7300",461550,244425],["7400",442950,439125],["7500",835350,484725],["7600",459000,82800],["7700",482250,48000],["7800",893250,11550],["7900",1215600,13500],["8000",741150,93525],["8100",242325,6150],["8200",326175,1500],["8300",365850,75],["8500",104850,2925],["9000",13050,11775]]);
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
var options = {
animation: {
startup: true,
duration: 2000,
easing: 'linear'
}
};
var redrawTimes = 0;
google.visualization.events.addListener(chart,'animationfinish',function () {
for (var i = 0; i < data.getNumberOfRows(); i++) {
var swap1 = data.getValue(i, 2);
var swap2 = data.getValue(i, 1);
data.setValue(i, 1, swap1);
data.setValue(i, 2, swap2);
}
if (redrawTimes < 5) {
setTimeout(function () {
chart.draw(data, options);
redrawTimes++;
}, 2000);
}
});
chart.draw(data, options);
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
Just add data to your DataTable and the call .draw() on your chart again, using options which contains the animation settings.
Options could look like
var options = {
animation: {
duration: 600
}
};
And then just call chart.draw(DataTable, options) to animate it.
See example live at codepen. Just add data with the button and it'll smoothly be added to the line.
My requirement is,
After a google chart gets loaded, if I click the legend, the legend should be grayed out and its corresponding value in the graph should be removed.
When I click the grayed out legend, the legend should be highlighted as it was before and the removed value should once again be added to the graph.
I am able to do the 50 % of the first part with the below code:
<html>
<head>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.load('visualization', '1.0', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
// Callback that creates and populates a data table,
// instantiates the pie chart, passes in the data and
// draws it.
var duplicateChartData = new Array();
var unSelectedArray = new Array();
function drawChart() {
// Create the data table.
var data = new google.visualization.DataTable();
duplicateChartData = new Array();
data.addColumn('string', 'Topping');
data.addColumn('number', 'Slices');
data.addRows([
['Mushrooms', 3],
['Onions', 1],
['Olives', 1],
['Zucchini', 1],
['Pepperoni', 2]
]);
// Set chart options
var options = {'title':'How Much Pizza I Ate Last Night',
'width':400,
'height':300};
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
duplicateChartData = data;
function selectHandler() {
var selectedItem = chart.getSelection()[0];
var selectedRow = selectedItem.row;
var isUnSelected = unSelectedArray[selectedRow]
if (selectedItem && !isUnSelected) {
data.setValue(selectedRow, 1, 0);
chart.draw(data, options);
unSelectedArray[selectedRow] = true;
}
if(isUnSelected){
data.setValue(selectedRow, 1, duplicateChartData.getValue(selectedRow,1));
unSelectedArray[selectedRow] = false;
}
}
google.visualization.events.addListener(chart, 'select', selectHandler);
chart.draw(data, options);
}
</script>
</head>
<body>
<!--Div that will hold the pie chart-->
<div id="chart_div"></div>
</body>
</html>
I basically setValue as 0 for the selected value and try to reset when clicked again. But whenever a zero is set the legend and data gets deleted. But what I want is thw legend to just gray out. ow to achieve this. Please help me.
I did this for line chart. It satisfies your both requirements. Hope this will help you.
google.visualization.events.addListener(chart, 'select', function () {
var sel = chart.getSelection();
// if selection length is 0, we deselected an element
if (sel.length > 0) {
// if row is undefined, we clicked on the legend
if (typeof sel[0].row === 'undefined') {
var col = sel[0].column;
if (columns[col] == col) {
// hide the data series
columns[col] = {
label: data.getColumnLabel(col),
type: data.getColumnType(col),
calc: function () {
return null;
}
};
// grey out the legend entry
series[col - 1].color = '#CCCCCC';
}
else {
// show the data series
columns[col] = col;
series[col - 1].color = null;
}
var view = new google.visualization.DataView(data);
view.setColumns(columns);
chart.draw(view, options);
}
}
});
Here is the working sample jqfaq.com
Awesome piece of code Abinaya (sorry i cld not +1 im still a newbie here at SO), just what i was looking for, thanks, just a minor correction, based on the comment at jqfaq.com. tried it out and it works 100%.
// if row is undefined, we clicked on the legend
//if (typeof sel[0].row === 'undefined') { *** doesn't seem to work
if (sel[0].row === null) { // this works
checkout the amended jsfiddle
I also had been searching for code on how to get the selected legend label and your code also does that using this line of code
//get selected legend label
data.getColumnLabel(col)
thanks again