I am trying to use gRapahel library to create bar chart in my web site project. I need to use this library because standard ajax control doesn't work in IE8. I have added all *.js files to my project and I also added below lines to web.config file:
<codeSubDirectories>
<add directoryName="CSCode"/>
<add directoryName="JSCode"/>
</codeSubDirectories>
When I tried to compile my project I got 3 errors in App_SubCode_JSCode.qgb8opkc.6.js file:
Only primitive types are allowed in a custom attribute
Unknown custom attribute class or constructor
Variable 'System' has not been declared
When I double click on the eroors it redirect me to the file with the erros which contains below lines:
//------------------------------------------------------------------------------
/// <autogenerated>
/// This code was generated by a tool.
/// Runtime Version: 4.0.30319.269
///
/// Changes to this file may cause incorrect behavior and will be lost if
/// the code is regenerated.
/// </autogenerated>
//------------------------------------------------------------------------------
[assembly: System.CodeDom.Compiler.GeneratedCodeAttribute("ASP.NET", "4.0.30319.272")]
[assembly: System.Security.SecurityRulesAttribute(System.Security.SecurityRuleSet.Level2)]
[assembly: System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.0")]
Could You plase help me fix this issue?
Thanks in advance.
EDIT 1:
I have added below code to create chart but I got error:
Microsoft JScript runtime error: Object expected
on line:
var r = Raphael("InputHours"),
<script type="text/javascript">
window.onload = function () {
var r = Raphael("InputHours"),
fin = function () {
this.flag = r.popup(this.bar.x, this.bar.y, this.bar.value || "0").insertBefore(this);
},
fout = function () {
this.flag.animate({ opacity: 0 }, 300, function () { this.remove(); });
},
fin2 = function () {
var y = [], res = [];
for (var i = this.bars.length; i--; ) {
y.push(this.bars[i].y);
res.push(this.bars[i].value || "0");
}
this.flag = r.popup(this.bars[0].x, Math.min.apply(Math, y), res.join(", ")).insertBefore(this);
},
fout2 = function () {
this.flag.animate({ opacity: 0 }, 300, function () { this.remove(); });
},
txtattr = { font: "12px sans-serif" };
r.text(160, 10, "Single Series Chart").attr(txtattr);
r.text(480, 10, "Multiline Series Stacked Chart").attr(txtattr);
r.text(160, 250, "Multiple Series Chart").attr(txtattr);
r.text(480, 250, "Multiline Series Stacked Chart\nColumn Hover").attr(txtattr);
r.barchart(10, 10, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10]]).hover(fin, fout);
r.hbarchart(330, 10, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55]], { stacked: true }).hover(fin, fout);
r.hbarchart(10, 250, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55]]).hover(fin, fout);
var c = r.barchart(330, 250, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55]], { stacked: true, type: "soft" }).hoverColumn(fin2, fout2);
};
</script>
I found sollution for that (I think). I moved CSCode outsede App_Code folder and I am able to compile the project.
Related
I observed one issue with ngx-charts line chart, when i have single data point i.e
[
{
name: 'test',
series: [
{
name: 0,
value: 0,
},
],
},
]
Here is my html code:
#yAxisTicks = [0, 25, 50, 75, 100];
#xAxisTicks = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
#colorScheme: any = { domain: ['red'] };
<ngx-charts-line-chart
#chart
[yAxisTicks]="yAxisTicks"
[xAxisTicks]="xAxisTicks"
[scheme]="colorScheme"
[xAxis]="true"
[yAxis]="true"
[results]="single"
[yScaleMax]="100"
[tooltipDisabled]="true"
[view]="view"
>
</ngx-charts-line-chart>
The xAxisTicks are scattered and looks somewhat like bellow,
Does anyone came across this issue? Are there any fix available without removing the [xAxisTicks]="xAxisTicks"?
When hovering over a line in billboardjs you can see a marker which follows the mouse (a tall vertical line). Is there a function for putting a marker on the x-line which can be used without triggering an automatic marker via onmousemove/hovering over data-points?
var chart = bb.generate({
data: {
columns: [
["data1", 30, 200, 100, 400, 150, 250],
["data2", 50, 20, 10, 40, 15, 25]
],
type: "line", // for ESM specify as: line()
},
bindto: "#lineChart"
});
https://naver.github.io/billboard.js/demo/#Chart.LineChart
So to exemplify. I use an onclick (in the data object) in the chart which defocuses the view and I still want the marker to remain.
So the code would look something like:
var chart = bb.generate({
data: {
columns: [
["data1", 30, 200, 100, 400, 150, 250],
["data2", 50, 20, 10, 40, 15, 25]
],
type: "line", // for ESM specify as: line()
onclick: function (d) {
focusElsewhere()
showMarker(d.x)
}
},
bindto: "#lineChart"
});
So the question is if there is a function for this, or an obvious fix?
I have looked through https://naver.github.io/billboard.js/release/latest/doc/Chart.html but I may of course have missed something.
I found that using xgrids did the trick. I don't think that the documentation gives a good example of how to use it. But basically you can use the "value" field to give which point the line should be on and add a class to show different kinds of lines.
var chart = bb.generate({
data: {
columns: [
["data1", 30, 200, 100, 400, 150, 250],
["data2", 50, 20, 10, 40, 15, 25]
],
type: "line", // for ESM specify as: line()
onclick: function (d) {
focusElsewhere()
this.xgrids.add({ value: d.x, class: "hover-line" }); //showMarker(d.x)
}
},
bindto: "#lineChart"
});
To remove the line or reset the billboard for continued use so to say, you can use
xgrids․remove({}) and add an object with some parameters of what kind of lines you want to remove.
I am creating gauge using this example, but I have to change pointer style.
Is it possible to change pointer style like this?
Chart.Type.extend({
//Passing in a name registers this chart in the Chart namespace
name: "Gauge",
//Providing a defaults will also register the deafults in the chart namespace
defaults : defaultConfig,
initialize: function(data){
//Declare segments as a static property to prevent inheriting across the Chart type prototype
this.segments = [];
var pointerDotRadius = helpers.min([this.chart.width,this.chart.height])/50;
this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2;
this.SegmentArc = Chart.Arc.extend({
ctx : this.chart.ctx,
x : this.chart.width/2,
y : this.chart.height - pointerDotRadius
});
All code:
jsbin.com
There's a similar looking meter chart using the RGraph ( https://www.rgraph.net ) software in the download archive:
demos/meter-needle.html
And here's the code:
var meter = new RGraph.Meter({
id: 'cvs',
min: 0,
max: 100,
value: 75,
options: {
linewidthSegments: 20,
strokestyle: 'white',
segmentRadiusStart: 105,
border: 0,
tickmarksSmallNum: 0,
tickmarksBigNum: 0,
needleRadius: 205,
labels: false,
centerpinFill: 'black',
colorsRanges: [
[0, 30, '#FFC900'],
[30, 60, '#8FCE21'],
[60, 100, '#0094DA']
]
}
}).draw();
I'm seeing an awkward bug using a third party library inside of a react component. I was able to reproduce a contrived demo for this post.
Let me start by explaining that I am using c3js - which is a charting library and rendering it in componentDidMount() and removing it in componentWillUnmount() with the correct calls to this.chart.destroy().
The bug occurs when filtering the components themselves, essentially what happens is the components are filtered correctly but the actual chart that sits inside the component stays the same as the first chart, which is very strange behaviour. Basically it's the wrong chart inside the wrong component!
You can see what I mean by clicking on the Remove all charts except chart 3 button, I have labeled the charts with a chartid and the filtering will correctly remove the other charts.
I am fairly certain it isn't my code because the filtering works correctly and updates the view. You can verify because I have labeled the charts and it is visible in the view. There is no console errors and I have verified my code works.
So my question is - can we work around this limitation using c3js, or is this really a problem with my code and the way I am rendering the charts.
Related demo: https://jsfiddle.net/69z2wepo/38614/
Related code:
var data = [
{
chartid: 1,
columns: [
['x', 0, 1, 2, 3, 4, 5, 6],
['data1', 130, 300, 330, 400, 300, 400, 500],
['data2', 390, 230, 200, 150, 100, 130, 210],
['data3', 290, 430, 300, 160, 210, 170, 190],
['data4', 190, 330, 200, 260, 190, 250, 320]
]
},
{
chartid: 2,
columns: [
['x', 0, 1, 2, 3, 4, 5, 6],
['data1', 130, 300, 330, 400, 300, 400, 500],
['data2', 390, 230, 200, 150, 100, 130, 210],
['data3', 290, 430, 300, 160, 210, 170, 190]
]
},
{
chartid: 3,
columns: [
['x', 0, 1, 2, 3, 4, 5, 6],
['data1', 130, 300, 330, 400, 300, 400, 500],
['data2', 390, 230, 200, 150, 100, 130, 210]
]
}
];
var Button = React.createClass({
handleDelete: function (id) {
this.props.handleDelete(id);
},
render: function() {
return (
<button onClick={this.handleDelete.bind(null, 3)}>
Remove all charts except chart 3
</button>
)
}
});
var Chart = React.createClass({
componentDidMount() {
this.chart = c3.generate({
bindto: '.chart-' + this.props.data.chartid,
data: {
columns: this.props.data.columns
}
});
},
componentWillUnmount() {
this.chart.destroy();
},
render: function() {
return (
<div>
<h4>{"chart-" + this.props.data.chartid}</h4>
<div className={"chart-" + this.props.data.chartid}>
</div>
</div>
)
}
});
var Child = React.createClass({
renderCharts: function(data) {
return data.map(function(metrics, i) {
return (
<Chart key={i} data={metrics} />
)
});
},
handleDelete: function(id) {
this.props.handleDelete(id);
},
render: function() {
return (
<div>
<Button handleDelete={this.handleDelete} />
{this.renderCharts(this.props.data)}
</div>
)
}
})
var App = React.createClass({
getInitialState: function() {
return {
initialData: this.props.data
}
},
handleDelete: function(id) {
var _filterFunc = function(data) {
if (data.chartid == id) return true;
return false;
};
var _filterCharts = Array.prototype.filter.call(this.state.initialData, _filterFunc);
this.setState({
initialData: _filterCharts
})
},
render: function() {
return (
<div>
<Child handleDelete={this.handleDelete} data={this.state.initialData} />
</div>
);
}
});
ReactDOM.render(
<App data={data} />,
document.getElementById('container')
);
The problem is the way you are setting the key on your chart. It's causing the renderer to get confused about which chart you're trying to keep.
Try this:
<Chart key={data[i].chartid} data={metrics} />
instead of <Chart key={i} data={metrics} />
Take a look at how React handles keys. Remember that you're uniquely identifying a child with a key for the lifecycle of the component. So since chart 1 is uniquely identified by key "1", you can't render chart 3 with key "1." My solution above ensures that the chart is uniquely identified by its chart id instead of by its rendering order.
I'm trying to put together a chart with nested elements that connect to each others' endpoints. As you can see in this jsFiddle, it's not going very well. The JS is reproduced below in full:
jsPlumb.ready(function () {
jsPlumb.importDefaults({ ConnectionOverlays: [["Arrow", { location: 1 }]] });
var pinCount = 0;
var pin = {
endpoint: "Dot",
isSource: true,
isTarget: true,
maxConnections: -1,
paintStyle: {
strokeStyle: "#1e8151",
fillStyle: "transparent",
radius: 7,
lineWidth: 2
},
connectorStyle: {
lineWidth: 3,
strokeStyle: "#deea18",
joinstyle: "round",
outlineColor: "#eaedef",
outlineWidth: 0,
overlays: [
["Arrow", {
location: 1
}]
]
},
connectorHoverStyle: {
lineWidth: 4,
strokeStyle: "#5C96BC",
outlineWidth: 2,
outlineColor: "white"
},
connector: ["StateMachine", {
stub: [5, 5],
gap: 10,
cornerRadius: 5,
alwaysRespectStubs: true
}]
}
jsPlumb.draggable($(".container"));
jsPlumb.draggable($(".reactor"), { containment: "parent" });
function rebalance(part, side) {
var ends = $.grep(jsPlumb.getEndpoints(part), function (elem, i) {
return elem.anchor.type == side
});
var len = ends.length + 1;
$.each(ends, function (i, elem) {
elem.anchor.y = (1 / len) * (i + 1);
});
jsPlumb.repaintEverything();
}
function addPin(part, side) {
jsPlumb.addEndpoint(part, pin, { anchor: side, uuid: "pin" + pinCount });
pinCount++;
rebalance(part, side);
}
var $c = $("#container");
var $r1 = $("#child1"), $r2 = $("#child2");
addPin($c, "Left");
addPin($c, "Right");
addPin($r1, "Left");
addPin($r1, "Right");
addPin($r2, "Left");
addPin($r2, "Right");
jsPlumb.connect({uuids: ["pin0", "pin2"]});
jsPlumb.connect({uuids: ["pin3", "pin4"]});
jsPlumb.connect({uuids: ["pin5", "pin1"]});
});
Peer node connections, as in ["pin3", "pin4"], look sane until you move any part of the chart. Then they explode. Connections between parent/child endpoints never really do what they're supposed to. Removing position: absolute; and draggable from all elements involved does something half-way passable, but a) still has some placement issues and b) removing those properties defeats the purpose.
General jsPlumb tips welcome, but specifically: Am I doing something wrong that prevents this from lining up properly? Am I misusing some property of connectors/endpoints? Is there a workaround for the placement issue I'm running into here?