I have a web HTML page with some client-side JS codes based on dojox.charting. I don't have dojo library in my local web site (actually no web server). I use dojos' xDomain reference feature with src to google's hosting site like this:
<head>
...
<script type="text/javascript"
djConfig1="isDebug:true"
src="http://ajax.googleapis.com/ajax/libs/dojo/1.2.0/dojo/dojo.xd.js">
</script>
<script type="text/javascript"
dojo.require("dojox.gfx");
dojo.require("dojox.gfx.move");
dojo.require("dojo.html");
dojo.require("dojox.charting.Chart2D");
dojo.require("dojox.charting.themes.PlotKit.green");
dojo.require("dojox.charting.action2d.Highlight");
dojo.require("dojox.charting.action2d.Magnify");
dojo.require("dojox.charting.action2d.MoveSlice");
dojo.require("dojox.charting.action2d.Shake");
dojo.require("dojox.charting.action2d.Tooltip");
dojo.require("dojox.charting.themes.MiamiNice");
dojo.require("dojox.charting.widget.Legend");
</script>
....
</head>
Here is the function to create curve chart, based on the codes in Dojo: Now With Drawing Tools.
function drawCurve(nodeChart, nodeLegend) {
var chart1 = new dc.Chart2D(nodeChart)
.setTheme(dc.themes.PlotKit.green)
.addPlot("default", {
type: "Default",
lines: true,
markers: true,
tension: 2
})
.addAxis("x", {
min: 0,
max: 6,
majorTick: { stroke: "black", length: 3 },
minorTick: { stroke: "gray", length: 3 }
})
.addAxis("y", {
vertical: true,
min: 0,
max: 10,
fixLower: "major",
fixUpper: "major",
majorTick: { stroke: "black", length: 3 },
minorTick: { stroke: "gray", length: 3 }
})
.addSeries("Series A", [
{ x: 0.5, y: 5 },
{ x: 1.5, y: 1.5 },
{ x: 2, y: 9 },
{ x: 5, y: 0.3 }
])
.addSeries("Series B", [
{ x: 0.3, y: 8 },
{ x: 4, y: 6, tooltip: "Custom tooltip"},
{ x: 5.5, y: 2 }
]);
var series = chart1.series;
var anim_a = new dc.action2d.Tooltip(chart1, "default");
var anim_c = new dc.action2d.Magnify(chart1, "default"); // not working
chart1.render();
var legendChart = new dc.widget.Legend(
{chart: chart1, horizontal: false}, nodeLegend.id);
}
My first question is that for the curve chart, the numbers along the y axis only displays 0 and 10. All the middle numbers 1 to 9 are not displayed. The values for x axis from 1 to 6 are visible. The original chart snapshot in the article does show y axis values as well, but the one on DojoToolKit Demos does show values along y axis. I am not sure what I missed in my codes. How can I enable displaying y axis values?
The next question is about the Magnify(). The DojoToolKit demo site's curve chart works fine but my chart's magnify feature does not work. I think this may be caused by xDomain reference. I may need to specify some specified js file from xDomain's dojox library. I am not sure which one I have to specify.
One thing I noticed is that my FireBug displays following errors after curve chart is drawn:
_4.fx.combine is not a function http://ajax.googleapis.com/ajax/libs/dojo/1.2.0/dojox/charting/action2d/Magnify.xd.js Line 8
_11.action is undefined http://ajax.googleapis.com/ajax/libs/dojo/1.2.0/dojox/charting/action2d/Magnify.xd.js Line 8
I think those undefined errors may indicate I miss loading some dojox library files in my head section.
By the way, I dont' have a web server and I prefer to use dojo's xDomain reference option. In this way, I can edit a html file in any place and send it to other people. No need to download and install dojo source library.
I think I got the missing part:
dojo.require("dojo.fx");
When I added this line to my HTML's head setction see above, the animation part set by Mangify() is working. This is only for the case you set xDomain reference to dojox for dojox.charting library.
What I found this is by using Firebug to look at DojoToolKit's Event 2D web page. In the head section there is code:
<script src="http://../action2/Magnify.js" type="text/javascript"></script>
That page has debug enabled. As a result, in FireBug window, you will see the source codes of js in a nice layout. I saw three requirements, and one is for "dojo.fx". I tried to add this one in. Then no more errors and I can see animation of magnify effect when I move mouse over points in the curve of the chart.
One thing interesting about <script src=".."> is that if the js is xDomain referenced, the js source codes are displayed partially in one long long time. If you hav the dojo library installed on your web page, ie same domain, the dojo's source codes are displayed nicely.
Regarding the y axis values, I also find out easy way to display them (0 to 9):
.addAxis("y", {
vertical: true,
//min: 0
//max: 10
....
You can also comment out min only and leave max with 10 (0, 1, ... to 10). See DojoCampus.org for more detail information about axis settings.
Related
I am working on getting a basic LightningChart example up and running in electron, looking to write a cross-platform charting app for my industry.
I grabbed the demo HTML code from the website and plopped it into my app, here's how it looks.
As you can see the text is quite pixelated. Is this a Mac thing? Is it a chart setting?
It's not as bad in Windows:
Here's the code in my lightning.js source file.
// Replace the contents of this script tag if you want to test code from our examples:
// https://www.arction.com/lightningchart-js-interactive-examples/
// Extract required parts from LightningChartJS.
const {
lightningChart
} = lcjs //Note: #arction/lcjs is not needed here, when using IIFE assembly
// Create a XY Chart.
const chart = lightningChart().ChartXY({
// Set the chart into a div with id, 'target'.
// Chart's size will automatically adjust to div's size.
container: 'target'
})
.setTitle('My first chart') // Set chart title
const data = [
{ x: 0, y: 1.52 },
{ x: 1, y: 1.56 },
{ x: 2, y: 1.42 },
{ x: 3, y: 1.85 },
{ x: 4, y: 1.62 }
]
// Add a line series.
const lineSeries = chart.addLineSeries()
.setName('My data')
.add(data)
Literally taken right from their website.
It's inserted into this tag in the HTML
<!-- Create div to render the chart into-->
<div id="target" class="row content"></div>
Thanks in advance for the help!
Whelp, I figured it out, had to add this to the tag to enable support for high DPI devices. Jees!
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Is there an easy way to create a border radius for a plot in plotly module? I have tried this with no luck...
var trace1 = {
x: time,
y: scaledData,
mode: 'lines',
type: 'scatter'
};
var layout = {
xaxis: {type: 'date'},
yaxis: {title: 'Moisture %'},
width: 320,
height: 320,
margin: {l: 50, r: 30, b: 50, t: 65, pad: 10},
paper_bgcolor: '#79ff4d',
plot_bgcolor: '#c6ffb3',
borderRadius: '15px',
title:'Past 24 Hours'
}
return (
<Plot data={[trace1]}
layout={layout}
/>
);
I also tried the css method but I think I am doing something wrong here as well. I tried creating a div of same size and position and wrapping the plot in it. Then putting a radius on the div but it is behind my plot so it does me no good. Not sure how to do the css hack but I would accept this answer as well, although more work.
It may be possible to get the element by class name if you are displaying this in an HTML page. In my case the class was main-svg. In the javascript on your page use the following:
<script>
var plotDiv = document.getElementsByClassName('main-svg') //class name of plotly main area
plotDiv[0].style.borderRadius = "15px"; //or however round you want
</script>
I just came across this question as I had the same problem. I just wrapped the plotly plot div with a div and applied a css class with border-radius and overflow: hidden as mentioned before. That worked for me.
What I have
I've created 2 graphs like shown in the first image below. I need these 2 graphs to be perfectly aligned on the 0 axis (which is shown in the section below).
Wanted result
In the image below, the graphs are perfectly aligned and should therefore contain 2 different datasets. One should be placed on the left grid and the other one on the right grid.
The options I thought of
I have not seen a way to implement this in ChartJS. Therefore, I thought of some possible solutions that could solve this issue in a different way.
Because both datasets don't have negative values, I could convert the left dataset to negative values (on the x-axis). The downside is that the range would be incorrect. Also, this would give issues with the popup message if you hover your mouse on a value.
Maybe, two canvas objects can be combined that could result in the wanted result
Question
Is there a way to achieve the wanted result within ChartJS? Or can I perform some wizardry to combine two charts nicely into one? Or should I move to the D3.js library for this particular graph?
I did not find a way to "nicely" implement this. I've changed the source code of the ChartJS library to implement this.
This method uses 2 different graphs that render in 2 different canvas objects. These canvas objects are placed side-by-side to let it look like one graph.
This is my result (The code in here is not exactly like the graph in the picture because I changed it to my specific needs).
I've added a custom variable in the options.layout category named sidePadding.
The code of creating the graph:
new Chart(document.getElementById(this.element), {
type: 'scatter',
data: {
datasets: [{
borderColor: this.lineColor,
borderWidth: 1,
pointBackgroundColor: '#000',
pointBorderColor: '#000',
pointRadius: 0,
fill: false,
tension: 0,
showLine: true,
data: [],
}],
},
options: {
aspectRatio: 0.3,
maintainAspectRatio: false,
responsive: true,
layout: {
sidePadding: {
left: 3,
right: -3,
}
}
}
});
The padding on the sides is by default 3 so it does not touch the border of the canvas. I wanted it to touch the border of the canvas, and therefore set it to -3.
Two different graphs need to be created, one for the left side and one for the right side.
The left graph should have the sidePadding.right set to -3. The right graph should have the sidePadding.left set to -3.
Changes in the ChartJS library
I've worked with ChartJS version v2.9.3. This method will possibly not work anymore in a new version.
I've changed the following in the Chart.js file:
Replace (line number around 11800):
// Adjust padding taking into account changes in offsets
// and add 3 px to move away from canvas edges
me.paddingLeft = Math.max((paddingLeft - offsetLeft) * me.width / (me.width - offsetLeft), 0) + 3;
me.paddingRight = Math.max((paddingRight - offsetRight) * me.width / (me.width - offsetRight), 0) + 3;
to:
// Adjust padding taking into account changes in offsets
// and add 3 px to move away from canvas edges
var layoutOptions = chart.options.layout || {};
var sidePadding = helpers$1.options.toPadding(layoutOptions.sidePadding);
me.paddingLeft = Math.max((paddingLeft - offsetLeft) * me.width / (me.width - offsetLeft), 0) + sidePadding.left;
me.paddingRight = Math.max((paddingRight - offsetRight) * me.width / (me.width - offsetRight), 0) + sidePadding.right;
Also you must add the sidePadding.left and sidePadding.right parameter to ChartJS.
This can be done by changing (line number around 7180):
core_defaults._set('global', {
layout: {
padding: {
top: 0,
right: 0,
bottom: 0,
left: 0
},
// Custom added parameter
sidePadding: {
left: 3,
right: 3,
}
}
});
to:
core_defaults._set('global', {
layout: {
padding: {
top: 0,
right: 0,
bottom: 0,
left: 0
},
// Custom added parameter
sidePadding: {
left: 3,
right: 3,
}
}
});
Note
This is probably not the best way to achieve this. Changing the ChartJS library is bad-practice and updating the library could revert these changes.
If someone has a better way to achieve this, please post your methods or comment below.
I am using Primefaces 6 for my companys charting needs, which relies on jQplot.
For a project, I am trying to overlay a line chart on a stacked bar chart with negative values, to obtain something like this:
The problem is that when I try to add a linechartseries to the same model as the two barchartseries , the linechart becomes a part of the stack when setting setStacked(true); on the model, because Primefaces seems to not allow individual disabling of stacking on series, only per model. So I end up with this when rendering the chart with
<p:chart type="bar" model="#{backingBean.cartesianChartModel}"/>
After some investigation I have notoced that jQplot is capable of disabling Stacking on individual series by passing disableStack : true in the JS options, so the question is if it's posssible to override this in some way on the rendered page,either via PF or via some JS hack? I feel that using the extender only apples to the entire model?
Related issues: Disable individual stacking
By pouring through the documentation I found a solution to the problem, if not the question:
It seems that Primefaces allows for individual series to be excempt from the stack in the series creation in this version, by passing
LineChartSeries.setDisableStack(true);
Simple as that.
I guess it may be possible. I used the extender functionality for some jqPlot hacks in the past.
In my case, for example, I had a Donut Chart defined with an extender function as follows:
private void createDonutModel() {
donutModel = new DonutChartModel();
donutModel.setLegendPosition("s");
donutModel.setLegendPlacement(LegendPlacement.OUTSIDE);
donutModel.setSliceMargin(4);
donutModel.setDataFormat("value");
donutModel.setShadow(false);
donutModel.setExtender("donutExtender");
donutModel.setSeriesColors("B81C40, FFA600, 79B54A");
}
The corresponding javascript was doing some changes to the jqPlot:
/**
* Customized jqPlot JQuery layout of the Donut Chart for Status Dashboard.
*/
function donutExtender() {
this.cfg.seriesDefaults = {
// make this a donut chart.
renderer:$.jqplot.DonutRenderer,
rendererOptions:{
thickness: 26,
ringMargin: 0,
fill: true,
padding: 0,
sliceMargin: 4,
// Pies and donuts can start at any arbitrary angle.
startAngle: -90,
showDataLabels: false,
// By default, data labels show the percentage of the donut/pie.
// You can show the data 'value' or data 'label' instead, or 'percent'
dataLabels: 'value',
shadow: false
}
}
this.cfg.gridPadding = {
top: 0, right: 0, bottom: 0, left: 0
}
this.cfg.legend = {
show: false
}
this.cfg.grid = { drawBorder: false,
shadow: false,
background: "transparent"
};
}
So you may try something like this in your case ?
Leave the extension configuration of your series empty, except for the one you are interested in...
function chartExtender() {
this.cfg.series = [
{ //...
},
{ // ...
},
{
disableStack: true
}
]
}
Worth having a shot ...
I have been going through some of the Dojo 1.8 tutorials, which are great, but have encountered a bug in the basic charting tutorial. The declarative example works fine, but the programmatic example has an error when it tries to render the chart.
Charting tutorial: http://dojotoolkit.org/documentation/tutorials/1.8/charting/
Working declarative example: http://dojotoolkit.org/documentation/tutorials/1.8/charting/demo/basic-declarative.php
Errored programmatic example: http://dojotoolkit.org/documentation/tutorials/1.8/charting/demo/basic-programmatic.php
From my investigations it looks like the problem is with the code trying to use the 'IN' operand on a string, at which point it falls over.
The error in firebug looks like this: "TypeError: invalid 'in' operand t"
You'll need to download the non minified version of dojox/gfx/path.js and look at line 191 where you'll see this snippet of code:
if(t instanceof Array){
this._collectArgs(_12,t);
}else{
if("x" in t&&"y" in t){
_12.push(t.x,t.y);
}
}
I believe that the error is where the logic falls through into the "if("x" in t&&"y" in t)" line.
Any ideas?
it seems its an error in the tutorial, the 'labelOffset' is supposed to take a Number, but they are giving it a string, thus it fails, take the quotes away and it works, see this forum post.
Charting tutorial in 1.7 and 1.8
Right I've found the reason for the bug, but not the remedy.
Its the labelOffset value being a minus number, fancy that!
So if you change the "-20" to "20" it runs without error.
Full example including the minus value causing the bug...
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Basic Programmatic Chart</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../../resources/style/demo.css" media="screen">
</head>
<body>
<h1>Demo: Basic Programmatic Chart</h1>
<!-- create the chart -->
<div id="chartNode" style="width: 550px; height: 550px;"></div>
<!-- load dojo and provide config via data attribute -->
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.8/dojo/dojo.js"></script>
<script>
// x and y coordinates used for easy understanding of where they should display
// Data represents website visits over a week period
chartData = [
{ x: 1, y: 19021 },
{ x: 1, y: 12837 },
{ x: 1, y: 12378 },
{ x: 1, y: 21882 },
{ x: 1, y: 17654 },
{ x: 1, y: 15833 },
{ x: 1, y: 16122 }
];
require([
// Require the basic 2d chart resource
"dojox/charting/Chart",
// Require the theme of our choosing
"dojox/charting/themes/Claro",
// Charting plugins:
//Require the Pie type of Plot
"dojox/charting/plot2d/Pie",
// Wait until the DOM is ready
"dojo/domReady!"
], function(Chart, theme, PiePlot){
// Create the chart within it's "holding" node
var pieChart = new Chart("chartNode");
// Set the theme
pieChart.setTheme(theme);
// Add the only/default plot
pieChart.addPlot("default", {
type: PiePlot, // our plot2d/Pie module reference as type value
radius: 200,
fontColor: "black",
labelOffset: "-20" <-- bug value here
});
// Add the series of data
pieChart.addSeries("January",chartData);
// Render the chart!
pieChart.render();
});
</script>
</body>
</html>
Just make the labelOffset value positive instead, and everything should run ok.
labelOffset: "20"