I am basically from 'c language' background, and having no sound idea about scripting.
what i wanted to achieve is this:
There is a bar graph which is presented in the SwapView. Now each time when the user visits this SwapView, i would like to reload the Bargrap with new set of datas. Assume that i have a data globally ie: window.myvalues. Which event i need to capture, and how to do that?
Kindly advice. Here is the sample which i have used from dojo site.
<div id="barview" data-dojo-type="dojox.mobile.SwapView">
<script>
function mybarchartNode(){
require([
// Require the basic chart class
"dojox/charting/Chart",
// Require the theme of our choosing
"dojox/charting/themes/MiamiNice",
// We want to plot Columns
"dojox/charting/plot2d/Columns",
// Require the highlighter
"dojox/charting/action2d/Highlight",
// We want to use Markers
"dojox/charting/plot2d/Markers",
// We'll use default x/y axes
"dojox/charting/axis2d/Default",
// Wait until the DOM is ready
"dojo/domReady!"
], function(Chart, theme, ColumnsPlot, Highlight) {
console.log ("Data set in the bar graph ");
console.log (window.myDatas);
// Define the data
var chartData = [10000,9200,11811,12000,7662,13887,14200,12222,12000,10009,11288,12099];
// Create the chart within it's "holding" node
var chart = new Chart("barchartNode");
// Set the theme
chart.setTheme(theme);
// Add the only/default plot
chart.addPlot("default", {
type: ColumnsPlot,
markers: true,
gap: 5
});
// Add axes
chart.addAxis("x");
chart.addAxis("y", { vertical: true, fixLower: "major", fixUpper: "major" });
// Add the series of data
chart.addSeries("Monthly Sales",chartData);
// Highlight!
new Highlight(chart,"default");
// Render the chart!
chart.render();
});
} /* Function End */
</script>
<div id="barchartNode" style="width: 250px; height: 150px;"></div>
</div> <!- swap space end -->
<!-- configure and load dojo -->
<script src="dojo/dojo.js" data-dojo-config="isDebug:1, async:1"></script>
<script>
require(["dojox/mobile/parser", "dijit/registry", "dojox/mobile", "dojox/mobile/SwapView", "dojox/mobile/TabBar", "dojox/mobile/TreeView", "dijit/tree/TreeStoreModel","dojox/mobile/Button", "dojox/mobile/deviceTheme", "dojox/mobile/compat", "dojo/domReady!"],
function(parser) {
parser.parse();
});
mybarchartNode();
</script>
You may hook up onAfterTransitionIn or onBeforeTransitionIn of dojox/mobile/SwapView
Quote from Dojo Reference
Stub function to connect to from your application.
Called before/after the arriving transition occurs.
Related
I have been trying to solve this problem with ChartJS for a few days now, and I am completely stumped
My program shows the user a set of input elements they use to select data needing to be charted, plus a button that has an event to chart their data. The first chart works great. If they make a change to the data and click the button a second, third, or more time, all the data from the previous charts is plotted, PLUS their most recent selection.
It is behaving exactly like you might expect if the chart.destroy() object is not working, or perhaps would work if I created the chart object using a CONST (and could therefore add new data but not delete the beginning data).
I have tried all combinations of the browsers, chartjs and jquery libraries below:
Three different browsers:
• Chrome: Version 107.0.5304.121 (Official Build) (64-bit)
• Microsoft Edge: Version 107.0.1418.56 (Official build) (64-bit)
• Firefox: 107.0 64-bit
I have tried at least three different versions of Chart.js, including
• Versions 3.9.1
• 3.6.2
• 3.7.0
Jquery.js
• v3.6.1
• v1.11.1
Other things I have tried:
"use strict" (no luck)
In addition to destroying the chart object, removed the div containing the canvas, and appending it again.
using setTimeout() function before updating the chart after destroying it (because I thought maybe giving the destroy method more time might help)
type here
Software:
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/chart.js"></script>
<script type="text/javascript" src="js/dropdownLists.js"></script>
<script type="text/javascript" src="js/chartDataFunctions.js"></script>
<script type="text/javascript" src="js/chartJSFunctions.js"></script>
<body>
<div class = metadatasetup4" id = "buttons">
<button class="download" id="getchart" value="Get Chart">Chart</button>
<button class="download" id="downloadchart" value="Download">Download</button>
</div>
<div id = "bigchartdiv" class="bigchart">
<canvas id="myChart"></canvas>
</div>
</body>
<script>
$(window).on('load',function(){
//NOTE 1: In of my attempts to troubleshoot I tried strict mode (it didn't work)
//"use strict";
let data = {
labels: lbl,
datasets: [
]
};
let config = {
type: 'line',
data: data,
options: {
scales: {
y: {
type: 'linear',
display: true,
position: 'left',
min:0,
pointStyle:'circle',
},
y1: {
type: 'linear',
display: true,
position: 'right',
suggestedMax: 25,
min: 0,
pointStyle: 'cross',
// grid line settings
grid: {
drawOnChartArea: false, // only want the grid lines for one axis to show up
},
},
}
}
};
// NOTE 2: The next line below, beginning with "var bigChartHTML =" was one of my later attempts to
// solve the problem. It didn't work, but my thought process was that if I removed
// the div containing the canvas, AND destroyed the chart object, that appending a "fresh"
// chart div to the body might be a work-around. This did not work.
var bigChartHTML = '<div id = "bigchartdiv" class="bigchart"><canvas id="myChart"></canvas></div>'
let ctx = document.getElementById('myChart').getContext('2d');
let bigChart = null;
// The getChartData() function below uses Ajax to populate various dropdown lists
// which enable the user to select the data is to be charted.
// There are no chartjs-related operations in getChartData()
getChartData();
$('#buttons').on('click','#getchart',function(){
if (bigChart!=null) {
//removeData(bigChart);
bigChart.destroy();
//bigChart = 1;
}
$("#bigchartdiv").empty(); //for this and next 2 lines, see NOTE 2 above
$("#bigchartdiv").remove();
$(bigChartHTML).insertAfter("#chartcontrols");
bigChart = new Chart(document.getElementById('myChart'),config);
//NOTE 3: I thought maybe bigChart.destroy() took time, so I tried
// using the setTimeout function to delay updating the chart
// (didn't work, but I left it in the code, anyway.)
setTimeout(function() {updateChart(bigChart)}, 2000);
//updateChart(bigChart);
});
// NOTE: The updateChart() function is actually included in "js/chartDataFunctions.js"
function updateChart(chart) {
/*
This section of the program reads the HTML elements then uses them
to make an Ajax request to sql server, and these become the
parameters for the newDataSet() function below.
*/
newDataset(chart,firstElement,newdataset,backgroundcolor,color);
}
// NOTE: The newDataSet() function is actually included in "js/chartJSFunctions.js"
// I show it here for brevity.
// It decides which axis (y or y1) to use to plot the datasets
// the dataset is pushed into the data, and chart.update() puts it in the chart object
function newDataset(chart,label,data,bgcolor='white',color='rgb(255,255,255)') {
var maxValue = Math.max(...data);
if (Number.isNaN(maxValue)) {
return;
}
if (maxValue == 0) {
return;
}
var axisID = 'y';
var ptStyle = 'circle';
//var pStyle = 'circle';
if (maxValue < 50) {
axisID = 'y1';
bgcolor = 'white';
//ptStyle = 'Star'
}
chart.data.datasets.push({
label:label,
yAxisID:axisID,
data:data,
borderColor:color,
backgroundColor:bgcolor,
//pointStyle:ptStyle
});
chart.update();
}
});
</script>
I found a work-around that solves my problem, but I still think this is a bug in ChartJS. Before calling bigChart.destroy(), I now do two things: First, reset the data object back to it's original value, and second, reset the config object back to it's original value, THEN call bigChart.destroy().
I think the destroy() method should handle that for me, but in my case, for whatever reason, it doesn't.
So, what I have is a work-around, not really a solution, but I'll take it.
I'm using multiple highChart in a dashboard page e.g linearea, spline, pie and synchronisation of multiple charts
Set tooltip synchronisation for prototype
Highcharts.Pointer.prototype.reset = function () {
return undefined;
};
Highcharts.Point.prototype.highlight = function (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
};
But above function effect all highchart e.g linearea and spline chart etc. what I want to apply on synchronisation only
Refer to this live demo: http://jsfiddle.net/kkulig/eec3mg9t/
I put every chart to a separate container - it's easier to manipulate them then. class="sync" indicates that chart should be synchronized:
<div id="container0"></div>
<div id="container1" class="sync"></div>
<div id="container2" class="sync"></div>
Then I set common events using this class:
$('.sync').bind('mousemove touchmove touchstart', function(e) {
(...)
I applied wrapping instead of overwriting for Highcharts.Pointer.prototype.reset function so that the default action fires for unsynchronized charts.
// Custom wrap
Highcharts.wrap(Highcharts.Pointer.prototype, 'reset', function(proceed, allowMove, delay) {
if (!this.chart.options.chart.isSynchronized) {
proceed.apply(this, allowMove, delay);
}
});
I need to be able to add some custom info to the pie.info.contentsFunction in Zoomcharts. I have multiple charts on the page, each one created like so...
var pc = new PieChart({
pie: {
innerRadius: 0.5,
},
container: chartContainer1,
area: { height: 500 },
data:chartData,
toolbar: {
"fullscreen": true,
"enabled": true
},
info: {
contentsFunction: boomChartTT
}
});
In the "boomChartTT" function I need to know what chart is being hovered upon. I'd like to be able to do something like this...
info: {
contentsFunction: boomChartTT(i)
}
...where 'i' is the index of the chart.
The reason I need to know the chart index is because I have some other data saved in an indexed array for each chart. The index of the chart matches the index of the data.
EXAMPLE: if user hovers on a slice in chart2 I'd want to pass '2' to the boomChartTT function so I can access the totals data for that chart (say, totalsData[2]).
I've done this in the past with other chart libraries by simply adding a data attribute to the chart container to give me the index like so...
<div id="chartContainer1" data-index="1"></div>
...and then I'm able to access the chartContainer from the hover function (contentsFunction) and then get that index.
I don't want to add the totals data to the actual chart data because I'd have to add it to each slice which is redundant.
Is there a way to do this?
Please let me know if my post is unclear.
EDITED TO ADD:
I don't think it matters but here is the boomChartTT function:
function boomChartTT(data,slice){
var tt="<div class=\"charttooltip\">";
if(data.name==="Others" || data.name==="Previous"){return tt+=data.name+"</div>";}
//var thisData=dataSearch(totalsData[i],"REFERRINGSITE",data.id);
tt+="<h5 class=\"strong\">"+data.id+"</h5>"+oHoverTable.render(thisData)+"</div>";
return tt;
}
The commented line is where I would need the index (i) to to get the correct totalsData.
SOLVED. I simply added "chartIndex" to the data like so...
for(var i=0;i<r.length;i++){
var thisDataObj ={
id:r[i].REFERRINGSITE,
value:r[i].PCTOFSALES,
name:r[i].REFERRINGSITE,
chartIndex: arguments[1],//<----- arguments[1] is the chart index
style: { expandable: false, fillColor: dataSearch(dataRSList,"REFERRINGSITE",r[i].REFERRINGSITE)[0].COLOR }
};
chartData.preloaded.subvalues.push(thisDataObj);
}
Then in the boomChartTT function...
function boomChartTT(data,slice){
var tt="<div class=\"charttooltip\">";
if(data.name==="Others" || data.name==="Previous"){return tt+=data.name+"</div>";}
var thisData=dataSearch(totalsData[data.chartIndex-1],"REFERRINGSITE",data.id);
tt+="<h5 class=\"strong\">"+data.id+"</h5>"+oHoverTable.render(thisData)+"</div>";
return tt;
}
I feared that adding custom fields to the chart data would break the chart (which I believe I've experienced with other libraries). So, there you go.
I've just created a simple Chart2d, everything is ok about this chart (data-series are just displayed fine, the theme is ok and etc.) , So I just moved on and tried to add Tooltip and Legend features to this chart. So I come up with below code:
require([
"dojox/charting/Chart",
"dojox/charting/action2d/Tooltip",
"dojox/charting/themes/Tom",
"dojox/charting/widget/SelectableLegend",
"dojox/charting/plot2d/Lines",
"dojox/charting/plot2d/Markers",
"dojox/charting/axis2d/Default",
"dojo/store/JsonRest",
"dojo/store/Memory",
"dojo/store/Cache",
"dojox/charting/StoreSeries",
"dojo/domReady!"
], function(Chart, Tooltip, Tom, SelectableLegend, LinesPlot, JsonRest, StoreSeries){
// ... the data store is initialed here ..
chart.setTheme(Tom);
chart.addPlot("default", {
type: LinesPlot,
markers: true
});
.
.
.
chart.render();
var tip = new Tooltip(chart, "default");
var leg = new dojox.charting.widget.SelectableLegend({ chart: chart, horizontal: true }, "legend1");
});
Now, The problem is that I can see both Legend/Tooltip for this chart, but it seems that the chart theme is not applied for them.
My bad .. I just forgot to add main dojo stylesheet (+ optionally a theme) to my html document:
<style type="text/css">
#import "./res/dojo__1_10_4/dojo/resources/dojo.css";
#import "./res/dojo__1_10_4/dijit/themes/tundra/tundra.css";
</style>
<style>
I'm trying to use the CHAP links library timeline (http://almende.github.io/chap-links-library/timeline.html).
Example17 is using JSON, but it's in the html file itself. I'd like to use an external JSON file sitting on the web server instead.
Here's my example.json:
{"timeline":[
{
"start":"2013,7,26",
"end":"2013,7,26",
"content": "Bleah1"
},
{
"start":"2013,7,26",
"end":"2013,8,2",
"content": "Bleah2"
},
{
"start":"2013,7,26",
"end":"2013,8,2",
"content": "Bleah3"
},
{
"start":"2013,7,26",
"end":"2013,8,2",
"content": "Bleah4"
}
]}
I added this:
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
And here's the modified function:
// Called when the Visualization API is loaded.
function drawVisualization() {
// Create a JSON data table
$.getJSON('example.json', function(jsondata) {
data = jsondata.timeline;
});
// specify options
var options = {
'width': '100%',
'height': '300px',
'editable': true, // enable dragging and editing events
'style': 'box'
};
// Instantiate our timeline object.
timeline = new links.Timeline(document.getElementById('mytimeline'));
function onRangeChanged(properties) {
document.getElementById('info').innerHTML += 'rangechanged ' +
properties.start + ' - ' + properties.end + '<br>';
}
// attach an event listener using the links events handler
links.events.addListener(timeline, 'rangechanged', onRangeChanged);
// Draw our timeline with the created data and options
timeline.draw(data, options);
}
Anyone who can tell me what I'm doing wrong gets a cookie! :-)
Update: I should specify that it's rendering the timeline div correctly, I'm just getting no data showing up.
Your start and end dates need to be parsed as Date objects for use in the timeline
I stumbled on this post as I was implementing similar functionality.
In version 2.6.1 of timeline.js, around line 3439 where the function links.Timeline.Item is declared, you'll notice a comment relating to implementing parseJSONDate.
/* TODO: use parseJSONDate as soon as it is tested and working (in two directions)
this.start = links.Timeline.parseJSONDate(data.start);
this.end = links.Timeline.parseJSONDate(data.end);
*/
I enabled the suggested code and it all works!* (go to the parseJSONDate function to see which formats are accepted)
*(works insofar as dates appear on the timeline.. I'm not using therefore not testing any selection/removal features, images, or anything like that..)