I am new to jsxgraph, also not so proficient in js, I hope you could point me in right direction with my problem.
I'm trying to:
1) create intersections of lines that go through a rectangle (there will be a large number of these lines),
2) file the space between them with polygons of different colors.
Here is how the whole piece of code (for some reason the jsfiddle doesn't want to work! :/):
https://jsfiddle.net/czarrna/me55dw4h/4/
My code does not work unfortunatelly :/
var typical_mn = board.create('polygon', [t_1, t_2, t_3, t_4], {
fillColor: '#ff9600',
withLines: false
});
var p1_1 = board.create('intersection', [l_20, typical_mn, 0], {
visible: true
});
var p1_2 = board.create('intersection', [l_20, typical_mn, 1], {
visible: true
});
var p2_1 = board.create('intersection', [l_30, typical_mn, 0], {
visible: true
});
var p2_2 = board.create('intersection', [l_30, typical_mn, 1], {
visible: true
});
var p3_1 = board.create('intersection', [l_40, typical_mn, 0], {
visible: true
});
var p3_2 = board.create('intersection', [l_40, typical_mn, 1], {
visible: true
});
var pol_20_30 = board.create('polygon', [p1_1, p1_2, p2_1, p2_1], {
fillColor: '#555',
withLines: false
});
var pol_30_40 = board.create('polygon', [p2_1, p2_1, p3_1, p3_2], {
fillColor: '#333',
withLines: false
});
<script src="http://czarrna.kei.pl/jsxgraph/src/loadjsxgraph.js"></script>
<script src="http://czarrna.kei.pl/jsxgraph/distrib/jsxgraph.css"></script>
<div id="jxgbox" class="jxgbox" style="width: 500px; height: 500px;"></div>
I hope someone could help me with this please! Would be grateful. Thank you
Nowadays, external libraries in jsfiddle have to be included with https. JSXGraph is available with https for example at https://cdnjs.cloudflare.com/ajax/libs/jsxgraph/0.99.3/jsxgraphcore.js .
At the moment, there is no intersection algorithm between polygons and lines. But one can intersect the polygon borders with lines. For this, the withLines property of the polygon has to be set to true. Then the borders can be accessed with the borders array.
In your example it would look like
var typical_mn = board.create('polygon',[t_1,t_2,t_3, t_4], {fillColor:'#ff9600', withLines:true});
in_20 = board.create('intersection', [l_20, typical_mn.borders[0]],{visible:true});
in_30 = board.create('intersection', [l_30, typical_mn.borders[0]],{visible:true});
in_40 = board.create('intersection', [l_40, typical_mn.borders[0]],{visible:true});
Intersection between lines and polygons is an interesting features, I will create a ticket on github.
Related
I found this amazing javascript gauge meter: http://bernii.github.io/gauge.js/
There's an option to make it looks like a gauge
new Gauge(target).setOptions(opts)
Or like a Donut (the one I need)
new Donut(target).setOptions(opts)
In the "gauge mode" there's an option percentColors that change the gauge color when it change its value. But this parameter doesn't work on "donut mode".
I tried to change the gauge.js but with no success... any javascript wizard could help me on this one?
The gauge.js file is in the link, and my code to "call it" is here:
var opts = {
angle: 0.46,
lineWidth: 0.1,
radiusScale: 1,
pointer: {
length: 0.6,
strokeWidth: 0.035,
color: '#000000'
},
limitMax: false,
limitMin: false,
percentColors: [[0.0, "#ff0000" ], [0.50, "#f9c802"], [1.0, "#a9d70b"]],
strokeColor: '#EEEEEE',
generateGradient: true,
highDpiSupport: true,
};
var target = document.getElementById('graph');
//var gauge = new Gauge(target).setOptions(opts);
var gauge = new Donut(target).setOptions(opts);
gauge.maxValue = 3000;
gauge.setMinValue(0);
gauge.animationSpeed = 32;
gauge.set(3000);
gauge.setTextField(document.getElementById('gauge-value'));
Thank you!
I found myself a simpler solution, instead of using the parentColor function on the Donut mode, I used some ifs/elses to limit the numbers and set the color in that specific location:
if (value<=20)
{
opts.colorStart='#291B00';
opts.colorStop='#FF0000';
}else if (value>20 && value <=60)
{
opts.colorStart='#290000';
opts.colorStop='#FF7E0D';
}
else if (value>60)
{
opts.colorStart='#002903';
opts.colorStop='#00FF00';
}
When i run the code the chart disappears
$(document).ready(function(){
var d1=${views};
var d2=${comoneviews};
var d3=${comtwoviews};
var plot1 = $.jqplot('piechart', [[['Your Organisation',d1],['Competitor#1',d2],['Competitor#2',d3]]], {
gridPadding: {top:0, bottom:38, left:0, right:0},
seriesDefaults:{
renderer:$.jqplot.PieRenderer,
trendline:{ show:false },
rendererOptions: { padding: 7, showDataLabels: true , dataLabels: 'value'}
},
legend:{
show:true,
placement: 'outside',
rendererOptions: {
numberRows: 1
},
location:'s',
marginTop: '15px'
}
});
});
the input values i am getting for d1 is 20700000 , d2 is 2300000, and d3 is 3040000. So does the chart does not appear because of higher values?
Per your comment, you just need to refer to the d1,d2 and d3 array values correctly. As you've mentioned, you are getting them as arrays - so the problem must be with your access to the actual values.
Access them as d1[0] d2[0] d3[0] (assuming you have a one sized array like you wrote)
var d1=[20700000];
var d2=[2300000];
var d3=[3040000];
var plot1 = $.jqplot('piechart', [[['Your Organisation',d1[0]],
['Competitor#1',d2[0]],['Competitor#2',d3[0]]]], {
...rest of plot code...
here is a working example with d1-d3 modified to arrays.
I'm using chart.js, and it's quite handy, but I'm facing an unexpected behavior when I click on arabic. The values change correctly, but if I hover over the bars, it shows the english values, although both of Pages, and views array have the arabic values.
var Pages = [];
var viewers = [];
var keys = [];
var countryvalue = [];
var lang = 'english';
function fillArray(language) {
if (language == 'english') {
Pages = ['home', 'about', 'contact'];
viewers = [5, 2, 3];
} else if (language == 'arabic') {
Pages = ['arabic home', 'arabic about', 'arabic contact'];
viewers = [7, 1, 2];
}
}
function getPages(lang) {
Pages = [];
viewers = [];
fillArray(lang);
drawBar();
}
function drawBar() {
var randomScalingFactor = function() {
return Math.round(Math.random() * 100)
};
var barChartData = {
labels: Pages,
datasets: [{
fillColor: "rgba(151,187,205,0.5)",
strokeColor: "rgba(151,187,205,0.8)",
highlightFill: "rgba(151,187,205,0.75)",
highlightStroke: "rgba(151,187,205,1)",
data: viewers
}]
}
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx).Bar(barChartData, {
responsive: true
});
}
getPages(lang);
$('.languageSwitcher').on('click', function(e) {
e.preventDefault();
if ($(this).data('lang') != lang) {
lang = $(this).data('lang');
getPages(lang);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>
<div class="barContainer">
<canvas id="canvas"></canvas>
</div>
<a class="languageSwitcher" data-lang="english">English</a>
<a class="languageSwitcher" data-lang="arabic">Arabic</a>
Here is a fiddle that shows the problem
You need to destroy the existing chart before creating the new one. So something like
var ctx = document.getElementById("canvas").getContext("2d");
if (window.myBar)
window.myBar.destroy();
...
You could also do a similar thing by updating the points and calling update(), but destroy() is easier by far.
Fiddle - https://jsfiddle.net/jzq5umfm/
Note : while removing the existing canvas element and adding a new one would also seemingly work (as mentioned in your comment and the previous version of your question), with responsive: true, Chart.js cycles through all created instances of the graph to resize them, resulting in a console error for each responsive graph that has been created and removed but not destroyed.
For responsive: false you won't see console errors but you'd still have references to those unused instances.
I want to create a typing game, so my sprites need to be generated in run time, with "labels". a String become a sprite to be typed. Anyone knows how to do this?
You can insert a Q.UI.Text object into a sprite like this:
var Q = Quintus()
.include('Sprites, Scenes, UI')
.setup({ maximize: true })
Q.Sprite.extend('LabelSprite', {
init: function(p) {
this._super(p, {text: 'default text'});
}
});
Q.scene("level1",function(stage) {
var label_sprite = stage.insert(new Q.LabelSprite({
x: 150,
y: 50,
label_text: 'label-text in a sprite',
label_text_color: 'grey',
label_offset_x: 0,
label_offset_y: 0
}));
var label = stage.insert(new Q.UI.Text({
label: label_sprite.p.label_text,
color: label_sprite.p.label_text_color,
x: label_sprite.p.label_offset_x,
y: label_sprite.p.label_offset_y
}), label_sprite);
});
Q.stageScene("level1");
Here is the above code in jsfiddle to demonstrate.
Also, the Scenes page of the Quintus documentation has a section called "Inserting objects into a stage", which is somewhat related to the concept.
Hope that helps!
I am new to client-side programming. Thus far I've been writing only asp and php based solutions. But now I need to retrieve data from json and plot on a map (I don't know how to do that yet, but this is later).
After days of searching, I think OpenLayers can give me what I need.
I have gone through the Examples on dev.openlayers site, (such as this one http://dev.openlayers.org/releases/OpenLayers-2.13.1/examples/vector-features-with-text.html), and also searched (and found some) solutions on stackoverflow, but they don't offer solutions to my problems).
Please view what I've done so far:
http://www.nusantech.com/bangkuujian/openlayer.html
The canvas.js is as follows:
// create some sample features
var Feature = OpenLayers.Feature.Vector;
var Geometry = OpenLayers.Geometry;
var features = [
new Feature(new Geometry.Point(-220, -60),attributes = { name: "Mercury",align: "cm",xOffset:10,yOffset:50 }),
new Feature(new Geometry.Point(-70, 120),attributes = { name: "Venus" }),
new Feature(new Geometry.Point(0, 0),attributes = { name: "Earth" }),
new Feature(new Geometry.Point(160, -100),attributes = { name: "Mars",align: "cm",xOffset:10,yOffset:50 })];
// create rule based styles
var Rule = OpenLayers.Rule;
var Filter = OpenLayers.Filter;
var style = new OpenLayers.Style({
pointRadius: 10,
strokeWidth: 3,
strokeOpacity: 0.7,
strokeColor: "#ffdd77",
fillColor: "#eecc66",
fillOpacity: 1,
label : "${name}",
fontColor: "#f0f0f0",
fontSize: "12px",
fontFamily: "Calibri, monospace",
labelAlign: "${align}",
labelXOffset: "${xOffset}",
labelYOffset: "${yOffset}",
labelOutlineWidth : 1
},
{
rules: [
new Rule({
elseFilter: true,
symbolizer: {graphicName: "circle"}
})
]
});
var layer = new OpenLayers.Layer.Vector(null, {
styleMap: new OpenLayers.StyleMap({'default': style,
select: {
pointRadius: 14,
strokeColor: "#e0e0e0",
strokeWidth: 5
}
}),
isBaseLayer: true,
renderers: ["Canvas"]
});
layer.addFeatures(features);
var map = new OpenLayers.Map({
div: "map",
layers: [layer],
center: new OpenLayers.LonLat(50, 45),
zoom: 0
});
var select = new OpenLayers.Control.SelectFeature(layer);
map.addControl(select);
select.activate();
What I have problems with:
Label offset
In the samples, the labels should offset from the centre by labelXOffset: "(xvalue)", labelYOffset: "(yvalue)", but this is not happening in my page. Is there something I forgot?
Zoom-in
When I click the + button on the map, all the features look like they are zoomed in, however, the sizes of the features stay the same. How do I enlarge the features (circles) too?
Hit Detection
i) When I click on a circle, it is selected as designed. However, is it possible when I select a circle, I also change the right side (now there is a red "text here") and fill it up with html? Can you show me an example how to change the red "text here" to the label-name of the selected circle with a different colour?
ii) Secondly, after I select a circle, how do I add a label under all the other circles denoting the distance between each circle and the selected circle?
Thank you in advance, hopefully these questions are not too much.
I have another question about retrieving an array of coordinates from json to plot the circles, but I will do more research on that. If you can point me in the right direction with regards to this, it would be much appreciated too.
I know how to do them server-side asp or php, but client side is very new to me. However client-side can do all of this much-much faster and can reduce a lot of load.
Cheers,
masCh
I think I have managed to most of it.
Labels not offsetting
Not sure what I did, but I declared a WMS layer and made a few changes to offset and now it is offsetting correctly.
var wms = new OpenLayers.Layer.WMS("NASA Global Mosaic",
"http://hendak.seribudaya.com/starmap.jpg",
{
layers: "modis,global_mosaic",
}, {
opacity: 0.5,
singleTile: true
});
var context = {
getSize: function(feature) {
return feature.attributes["jejari"] / map.getResolution() * .703125;
}
};
var template = {
pointRadius: "${getSize}", // using context.getSize(feature)
label : "\n\n\n\n${name}\n${jarak}",
labelAlign: "left",
labelXOffset: "${xoff}",
labelYOffset: "${yoff}",
labelOutlineWidth : 0
};
var style = new OpenLayers.Style(template, {context: context});
And I declared xoff & yoff under new OpenLayers.Geometry.Point(x,y), { jejari:5, xoff: -10, yoff: -15 }
2) Zoom in on point features.
This was a weird problem. Anyway, I declared a radius called jejari as in the code above next to xoff and yoff. Then modified pointRadius from a static number to "${getSize}" And then added the getSize function to var template which retrieves the current radius. I think that was all I did for that. But the labels were running all over the place, I still haven't solved that.
3) Hit detection and changing another in html
This adds what happens to the once a point feature has been selected
layer.addFeatures(features);
layer.events.on({ "featureselected": function(e) {
kemasMaklumat('maklumat', "<FONT FACE='Calibri' color='#f0f0f0' size=5><center>"+
e.feature.attributes.name+
"<p>This is displayed text when a feature has been selected";
maklumat.style.color="black";
layer.redraw();
}
});
map.addLayers([layer]);
And in the html the and the kemasMaklumat function is declared as
<script type="text/javascript">
function kemasMaklumat(id,content) {
var container = document.getElementById(id);
container.innerHTML = content;
}
</script>
<td valign="top"><div id="maklumat" style="border-radius:25px; background-color:#000000;box-shadow: 8px 8px 4px #686868;">
Write Something Here<P>
</div></td>
The second part of this question was changing the labels of all the UNselected features, i.e. modifying attributes of all features that weren't the selected one. To do this, I added a for loop through all the features and check if it has the same label as the feature that was selected, this was done under the layer.events.on "featureselected" as was done in the above part 1 of this question.
layer.addFeatures(features);
layer.events.on({ "featureselected": function(e) {
kemasMaklumat('maklumat', "<FONT FACE='Calibri' color='#f0f0f0' size=5><center>"+
e.feature.attributes.name+
"<p>This is displayed text when a feature has been selected";
maklumat.style.color="black";
for (var i = 0, l = layer.features.length; i < l; i++) {
var feature = layer.features[i];
if (feature.attributes.name!=e.feature.attributes.name) {
feature.attributes.name="I was not selected"; }}
layer.redraw();
}
});
map.addLayers([layer]);