Related
Adopting this example, I get an axis that is incorrect. The axis shows labels for 50 000, 00 000, 50 000, etc, but my data is from 0 - 513836. This is what the axis looks like:
Here's my code and data:
data = [{
"value": "478176",
"date": "2020-06-28"
}, {
"value": "478278",
"date": "2020-06-29"
}, {
"value": "478559",
"date": "2020-06-30"
}, {
"value": "478559",
"date": "2020-07-01"
}, {
"value": "479175",
"date": "2020-07-02"
}, {
"value": "479175",
"date": "2020-07-03"
}, {
"value": "479175",
"date": "2020-07-04"
}, {
"value": "479379",
"date": "2020-07-05"
}, {
"value": "479633",
"date": "2020-07-06"
}, {
"value": "480010",
"date": "2020-07-07"
}, {
"value": "480531",
"date": "2020-07-08"
}, {
"value": "480794",
"date": "2020-07-09"
}, {
"value": "480794",
"date": "2020-07-10"
}, {
"value": "480794",
"date": "2020-07-11"
}, {
"value": "480995",
"date": "2020-07-12"
}, {
"value": "481161",
"date": "2020-07-13"
}, {
"value": "481161",
"date": "2020-07-14"
}, {
"value": "481934",
"date": "2020-07-15"
}, {
"value": "482218",
"date": "2020-07-16"
}, {
"value": "482218",
"date": "2020-07-17"
}, {
"value": "482218",
"date": "2020-07-18"
}, {
"value": "482851",
"date": "2020-07-19"
}, {
"value": "483331",
"date": "2020-07-20"
}, {
"value": "484302",
"date": "2020-07-21"
}, {
"value": "484569",
"date": "2020-07-22"
}, {
"value": "484734",
"date": "2020-07-23"
}, {
"value": "484734",
"date": "2020-07-24"
}, {
"value": "484734",
"date": "2020-07-25"
}, {
"value": "485123",
"date": "2020-07-26"
}, {
"value": "485597",
"date": "2020-07-27"
}, {
"value": "486763",
"date": "2020-07-28"
}, {
"value": "487392",
"date": "2020-07-29"
}, {
"value": "487392",
"date": "2020-07-30"
}, {
"value": "487392",
"date": "2020-07-31"
}, {
"value": "487392",
"date": "2020-08-01"
}, {
"value": "487392",
"date": "2020-08-02"
}, {
"value": "487909",
"date": "2020-08-03"
}, {
"value": "488496",
"date": "2020-08-04"
}, {
"value": "488496",
"date": "2020-08-05"
}, {
"value": "490538",
"date": "2020-08-06"
}, {
"value": "490538",
"date": "2020-08-07"
}, {
"value": "490538",
"date": "2020-08-08"
}, {
"value": "491490",
"date": "2020-08-09"
}, {
"value": "492511",
"date": "2020-08-10"
}, {
"value": "494185",
"date": "2020-08-11"
}, {
"value": "494730",
"date": "2020-08-12"
}, {
"value": "495052",
"date": "2020-08-14"
}, {
"value": "495052",
"date": "2020-08-15"
}, {
"value": "495610",
"date": "2020-08-16"
}, {
"value": "496394",
"date": "2020-08-17"
}, {
"value": "496394",
"date": "2020-08-18"
}, {
"value": "498006",
"date": "2020-08-19"
}, {
"value": "498631",
"date": "2020-08-20"
}, {
"value": "498631",
"date": "2020-08-21"
}, {
"value": "498631",
"date": "2020-08-22"
}, {
"value": "499186",
"date": "2020-08-23"
}, {
"value": "499561",
"date": "2020-08-24"
}, {
"value": "500491",
"date": "2020-08-25"
}, {
"value": "500491",
"date": "2020-08-26"
}, {
"value": "501295",
"date": "2020-08-27"
}, {
"value": "501295",
"date": "2020-08-28"
}, {
"value": "501295",
"date": "2020-08-29"
}, {
"value": "501748",
"date": "2020-08-30"
}, {
"value": "502284",
"date": "2020-08-31"
}, {
"value": "503353",
"date": "2020-09-01"
}, {
"value": "503719",
"date": "2020-09-02"
}, {
"value": "504046",
"date": "2020-09-03"
}, {
"value": "504046",
"date": "2020-09-04"
}, {
"value": "504046",
"date": "2020-09-05"
}, {
"value": "504204",
"date": "2020-09-06"
}, {
"value": "504697",
"date": "2020-09-07"
}, {
"value": "505659",
"date": "2020-09-08"
}, {
"value": "506346",
"date": "2020-09-12"
}, {
"value": "507109",
"date": "2020-09-14"
}, {
"value": "508650",
"date": "2020-09-16"
}, {
"value": "509708",
"date": "2020-09-17"
}, {
"value": "509708",
"date": "2020-09-18"
}, {
"value": "509708",
"date": "2020-09-19"
}, {
"value": "510154",
"date": "2020-09-20"
}, {
"value": "510226",
"date": "2020-09-21"
}, {
"value": "511136",
"date": "2020-09-22"
}, {
"value": "511252",
"date": "2020-09-23"
}, {
"value": "511253",
"date": "2020-09-24"
}, {
"value": "511253",
"date": "2020-09-25"
}, {
"value": "511253",
"date": "2020-09-26"
}, {
"value": "511363",
"date": "2020-09-27"
}, {
"value": "511467",
"date": "2020-09-28"
}, {
"value": "511467",
"date": "2020-09-29"
}, {
"value": "512016",
"date": "2020-09-30"
}, {
"value": "512016",
"date": "2020-10-01"
}, {
"value": "512016",
"date": "2020-10-02"
}, {
"value": "512016",
"date": "2020-10-03"
}, {
"value": "512610",
"date": "2020-10-04"
}, {
"value": "512889",
"date": "2020-10-05"
}, {
"value": "513552",
"date": "2020-10-06"
}, {
"value": "513836",
"date": "2020-10-07"
}];
parseDate = d3.timeParse("%Y-%m-%d");
line = d3.line()
.defined(d => !isNaN(d.value))
.x(d => x(parseDate(d.date)))
.y(d => y(parseInt(d.value)));
margin = ({
top: 20,
right: 30,
bottom: 30,
left: 40
});
height = 500;
width = 500;
x = d3.scaleUtc()
.domain(d3.extent(data, d => parseDate(d.date)))
.range([margin.left, width - margin.right]);
y = d3.scaleLinear()
.domain([0, d3.max(data, d => parseInt(d.value))]).nice()
.range([height - margin.bottom, margin.top]);
xAxis = g => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).ticks(width / 80).tickSizeOuter(0));
yAxis = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y));
svg = d3.select("body").append("svg")
//.attr("viewBox", [0, 0, width, height]);
.attr("width", "100%")
.attr("height", "100%");
svg.append("g")
.call(xAxis);
svg.append("g")
.call(yAxis);
svg.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-width", 1.5)
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("d", line);
<script src="https://d3js.org/d3.v6.min.js"></script>
I play a game which uses skins, around 200'000 of them and the players struggle to find them since there isn't really a search function other than random names.
Each skin has a name chosen by the users who upload them and that's it, others don't know about it untill they see it used by someone else.
I made some tools to make it easier and I wanted to implement a search by tag function, for example you search "dog" and it gives you the skins containing dogs. Is there a program able to automatically give tags to 200k images?
Game: https://Gota.io
My "tool"(badly made website) https://specy.it/SkinGallery.html
And the extension for the game: https://www.dropbox.com/s/36w6dkz22pxksrz/Extension.js?dl=0
This is not my specialty and it's an evolving field, but for the time being there are "image recognition as a service" services such as Google Vision whose rest API you can use to have the machine tag your image according to what it sees.
That being said, I'm not sure if your skins are suit for a good result. If we try it on the "dead mickey" skin, we get:
Well yeah, there's an animal, I guess. If you look at the "labels" tab you'd see it describes mostly colors, but it also mentions "fictional character" in the 12th place or so.
Depending on the skin, different contexts could suit you better. For example, if you use Sage Mode Naruto, Objects, Labels and Logos bring very little information, but Web tab says:
How would you handle the response of the rest service? Well, it's a JSON with the form:
{
"cropHintsAnnotation": {
"cropHints": [...]
},
"fullTextAnnotation": {
"pages": [
{
"blocks": [...],
"height": 512,
"property": {
"detectedLanguages": [
{
"confidence": 0.88,
"languageCode": "en"
}
]
},
"width": 512
}
],
"text": "SUH DUDE\n.\n"
},
"imagePropertiesAnnotation": {
"cropHints": [...],
"dominantColors": {
"colors": [...]
}
},
"labelAnnotations": [
{
"description": "Illustration",
"mid": "/m/01kr8f",
"score": 0.8927454,
"topicality": 0.8927454
},
{
"description": "Cartoon",
"mid": "/m/0215n",
"score": 0.8583309,
"topicality": 0.8583309
},
{
"description": "Circle",
"mid": "/m/01vkl",
"score": 0.70432633,
"topicality": 0.70432633
},
{
"description": "Art",
"mid": "/m/0jjw",
"score": 0.6253477,
"topicality": 0.6253477
},
{
"description": "Clip art",
"mid": "/m/03g09t",
"score": 0.5876344,
"topicality": 0.5876344
},
{
"description": "Fictional character",
"mid": "/m/02h7lkt",
"score": 0.52791756,
"topicality": 0.52791756
}
],
"localizedObjectAnnotations": [...],
"logoAnnotations": [...],
"description": "Los Angeles Rams",
"mid": "/m/06x76",
"score": 0.5958965
}
],
"safeSearchAnnotation": {
"adult": "VERY_UNLIKELY",
"medical": "VERY_UNLIKELY",
"racy": "VERY_UNLIKELY",
"spoof": "VERY_UNLIKELY",
"violence": "VERY_UNLIKELY"
},
"textAnnotations": [...],
{
"boundingPoly": {
"vertices": [
{
"x": 182,
"y": 40
},
{
"x": 295,
"y": 40
},
{
"x": 295,
"y": 111
},
{
"x": 182,
"y": 111
}
]
},
"description": "SUH DUDE\n.\n",
"locale": "en"
},
{
"boundingPoly": {
"vertices": [
{
"x": 182,
"y": 44
},
{
"x": 222,
"y": 43
},
{
"x": 223,
"y": 66
},
{
"x": 183,
"y": 67
}
]
},
"description": "SUH"
},
{
"boundingPoly": {
"vertices": [
{
"x": 237,
"y": 42
},
{
"x": 294,
"y": 40
},
{
"x": 295,
"y": 64
},
{
"x": 238,
"y": 66
}
]
},
"description": "DUDE"
},
{
"boundingPoly": {
"vertices": [
{
"x": 194,
"y": 101
},
{
"x": 196,
"y": 100
},
{
"x": 200,
"y": 111
},
{
"x": 198,
"y": 111
}
]
},
"description": "."
}
"webDetection": {
"bestGuessLabels": [
{
"label": "cartoon"
}
],
"pagesWithMatchingImages": [
{
"pageTitle": "edit #anime #naruto #foryou #foryoupage #narutouzumaki ... - TikTok",
"partialMatchingImages": [
{
"url": "https://p16.muscdn.com/obj/tos-maliva-p-0068/b27c516d2faee4174d0e4a26b7a3d466"
}
],
"url": "https://www.tiktok.com/#sakura._.haruno_editz/video/6777103057055517958?lang=en"
},
{
"pageTitle": "Originalton - edix_official TikTok Music Videos • TikyToky",
"partialMatchingImages": [
{
"url": "https://p16.muscdn.com/obj/tos-maliva-p-0068/b27c516d2faee4174d0e4a26b7a3d466"
}
],
"url": "https://tikytoky.com/music/originalton-6768700410359302918"
},
{
"pageTitle": ".... Wanna gain tons of followers? Follow #dragonballexclusives ...",
"partialMatchingImages": [
{
"url": "https://scontent-frt3-1.cdninstagram.com/vp/cdb9be9aa9707b90d55564a965668b7c/5E881986/t51.2885-19/s150x150/71524634_2513191889001976_2699215275693178880_n.jpg?_nc_ht=scontent-frt3-1.cdninstagram.com"
}
],
"url": "https://www.mystalk.net/detail/1917580489812869720_7212599026"
},
{
"pageTitle": "edit #anime #naruto #foryou #foryoupage #narutouzumaki ... - TikTok",
"partialMatchingImages": [
{
"url": "https://p16.muscdn.com/obj/tos-maliva-p-0068/b27c516d2faee4174d0e4a26b7a3d466"
}
],
"url": "https://www.tiktok.com/#sakura._.haruno_editz/video/6777103057055517958?region=KR&langCountry=pa&source=h5_t&lang=ar"
},
{
"pageTitle": "edit #anime #naruto #foryou #foryoupage #narutouzumaki ... - TikTok",
"partialMatchingImages": [
{
"url": "https://p16.muscdn.com/obj/tos-maliva-p-0068/b27c516d2faee4174d0e4a26b7a3d466"
}
],
"url": "https://www.tiktok.com/#sakura._.haruno_editz/video/6777103057055517958?region=KR&langCountry=pa&source=h5_t&lang=en"
},
{
"pageTitle": "edit #anime #naruto #foryou #foryoupage #narutouzumaki ... - TikTok",
"partialMatchingImages": [
{
"url": "https://p16.muscdn.com/obj/tos-maliva-p-0068/b27c516d2faee4174d0e4a26b7a3d466"
}
],
"url": "https://www.tiktok.com/#sakura._.haruno_editz/video/6777103057055517958?region=JP&langCountry=ja"
},
{
"pageTitle": "edit #anime #naruto #foryou #foryoupage #narutouzumaki ... - TikTok",
"partialMatchingImages": [
{
"url": "https://p16.muscdn.com/obj/tos-maliva-p-0068/b27c516d2faee4174d0e4a26b7a3d466"
}
],
"url": "https://www.tiktok.com/#sakura._.haruno_editz/video/6777103057055517958?lang=de"
}
],
"partialMatchingImages": [
{
"url": "https://p16.muscdn.com/obj/tos-maliva-p-0068/b27c516d2faee4174d0e4a26b7a3d466"
},
{
"url": "https://scontent-frt3-1.cdninstagram.com/vp/cdb9be9aa9707b90d55564a965668b7c/5E881986/t51.2885-19/s150x150/71524634_2513191889001976_2699215275693178880_n.jpg?_nc_ht=scontent-frt3-1.cdninstagram.com"
}
],
"visuallySimilarImages": [
{
"url": "https://previews.123rf.com/images/lenm/lenm1703/lenm170300080/73206609-sketchy-illustration-featuring-a-woman-looking-fondly-at-her-baby-strapped-to-a-carrier.jpg"
},
{
"url": "https://media.gettyimages.com/vectors/cartoon-soccer-football-girl-character-vector-id487299807"
},
{
"url": "https://pbs.twimg.com/profile_images/1062176350797066241/UhaIkhRy_400x400.jpg"
},
{
"url": "https://img.favpng.com/1/13/23/vertebrate-line-art-cartoon-clip-art-png-favpng-2LN24w4JHvqm4VfaF0gq56thE_t.jpg"
},
{
"url": "https://f1.pngfuel.com/png/337/556/27/smile-human-cartoon-character-pink-m-happiness-behavior-purple-png-clip-art-thumbnail.png"
},
{
"url": "https://img.favpng.com/8/3/13/clip-art-illustration-dance-hula-vector-graphics-png-favpng-jPQ56XsgP7Gi2cMLzhxbFApeA_t.jpg"
},
{
"url": "https://img.favpng.com/16/4/23/clip-art-pre-school-illustration-human-behavior-png-favpng-VEBwHZmyxNijn756GP0YUW6BV_t.jpg"
},
{
"url": "https://cdn.imgbin.com/11/5/20/imgbin-blond-girl-woman-blonde-haired-s-vPKgK1yAr3Z1vhLcyBms7tCL0.jpg"
},
{
"url": "https://thumbnail.imgbin.com/3/13/22/imgbin-homo-sapiens-woman-cartoon-gipsy-nCHD5ktXjAryu06DKrqc4cZmR_t.jpg"
},
{
"url": "http://clipartmag.com/images/shocked-clipart-1.jpg"
},
{
"url": "https://i.pinimg.com/236x/10/89/7a/10897abb60aeafad127c8e80c5732001--doodle-kids-muslim-fashion.jpg"
},
{
"url": "https://art.pixilart.com/thumb/0721b071d8ec62a.png"
},
{
"url": "https://img.favpng.com/0/4/24/detective-cartoon-png-favpng-7t1LwLmVSieejTCmm39qDLgQV_t.jpg"
}
],
"webEntities": [
{
"description": "Hinata Hyuga",
"entityId": "/m/04b5nh",
"score": 0.32295
},
{
"description": "Naruto Uzumaki",
"entityId": "/m/02sp46",
"score": 0.31364998
},
{
"description": "Sakura Haruno",
"entityId": "/m/037b28",
"score": 0.30705
},
{
"description": "Naruto",
"entityId": "/m/01hryy",
"score": 0.2758
},
{
"description": "Illustration",
"entityId": "/m/01kr8f",
"score": 0.2729761
},
{
"description": "Cartoon",
"entityId": "/m/0215n",
"score": 0.25171754
},
{
"description": "TikTok",
"entityId": "/g/11f555cn8l",
"score": 0.2241
},
{
"description": "Anime",
"entityId": "/m/0jxy",
"score": 0.207
},
{
"description": "Text",
"entityId": "/m/07s6nbt",
"score": 0.19760928
},
{
"description": "Music video",
"entityId": "/m/0mdxd",
"score": 0.187
},
{
"description": "Dragon Ball",
"entityId": "/m/0k2dm",
"score": 0.1776
},
{
"description": "Character",
"entityId": "/m/0k5v2",
"score": 0.1657
},
{
"description": "Fiction",
"entityId": "/m/02xlf",
"score": 0.1247
}
]
}
}
The image above lists the terms under webDetection -> webEntities.
However, there's no one size fits all. Those terms are irrelevant in mickey's skin), whose tags, albeit loose, should be the ones under localizedObjectAnnotations or labelAnnotations. It would need human moderation to provide real value.
Of course, if you have no tags whatsoever, adding some groups from the response without human moderation would be better than nothing.
Other services from big players you can look at:
Watson Image Recognition (IBM)
Amazon Rekognition
I am new to threejs and I wanted to know if I can add a random jpg picture as my texture. I figured out how to add materials to my model, but I cant really figure out how to add texture. This is a spinet of my json model and my code for changing texture:
"textures": [],
"animations": [{
"fps": 29,
"tracks": [{
"type": "vector3",
"keys": [{
"value": [0.000392,0.249157,-0.004437],
"time": 0
},{
"value": [0.000392,0.249157,-0.004437],
"time": 120
},{
"value": [0.000392,0.249157,-0.004437],
"time": 240
},{
"value": [0.000392,0.249157,-0.004437],
"time": 360
}],
"name": "CameraPreset.position"
},{
"type": "vector3",
"keys": [{
"value": [1,1,1],
"time": 0
},{
"value": [1,1,1],
"time": 120
},{
"value": [1,1,1],
"time": 240
},{
"value": [1,1,1],
"time": 360
}],
"name": "CameraPreset.scale"
},{
"type": "quaternion",
"keys": [{
"value": [0,0.707107,0.707107,0],
"time": 0
},{
"value": [-0.612372,-0.353553,-0.353553,0.612372],
"time": 120
},{
"value": [-0.612372,0.353553,0.353553,0.612372],
"time": 240
},{
"value": [-0,0.707107,0.707107,0],
"time": 360
}],
"name": "CameraPreset.quaternion"
}],
"name": "default"
}],
"materials": [{
"uuid": "36DB0D58-F5EE-366F-9C7F-307076036ACA",
"side": 2,
"blending": "NormalBlending",
"name": "lambert1",
"specular": 1508356,
"shininess": 50,
"emissive": 0,
"ambient": 12531511,
"depthTest": true,
"color": 12531511,
"vertexColors": false,
"depthWrite": true,
"type": "MeshPhongMaterial"
}],
"images": [],
"metadata": {
"generator": "io_three",
"type": "Object",
"version": 4.4
}
This is where I loaded my Json model:
var mesheto;
var loader = new THREE.ObjectLoader();
loader.load(
'models/shirt.json',
function (object) {
globalObject = object;
object.name = 'shirt';
mesheto = object;
scene.add(object);
GameLoop();
}
);
This is the onclick function that changes the texture:
function loadimg(string) {
globalObject.traverse( function ( child ) {
console.log("clicked");
if (child instanceof THREE.Mesh) {
console.log(child instanceof THREE.Mesh);
child.material.map = THREE.TextureLoader('../img/models/check.jpg');
child.material.needsUpdate = true;
}
});
// polo_model.material.map = THREE.TextureLoader('models/check.jpg');
}
You have to add a .load to your new THREE.TextureLoader().load("name of your texture.jpg").
I want to set a hidden ID for each segment in an am-charts gantt chart. So when the user double clicks a segment i want to retrieve data using that ID and show in a popup window.
"dataProvider": [ {
"category": "John",
"segments": [ {
"start": "2018-01-01",
"end": "2018-01-10",
"color": "#f00",
"task": "Task #1",
"key": "1000"
}, {
"start": "2018-01-12",
"end": "2018-01-20",
"color": "#00f",
"task": "Task #2",
"key": "1001"
}, {
"start": "2018-01-25",
"end": "2018-02-10",
"color": "33800F",
"task": "Task #3",
"key": "1002"
} ]
} ]
I am able to get the Category value but don't know how to get Segments values.
Any example would be a great help
If you're using clickGraphItem for your double-click functionality, you can access the segment information through the graph's segmentData property in the event object:
"listeners": [{
"event": "clickGraphItem",
"method": function(e) {
alert(e.graph.segmentData.key)
}
}]
Demo below:
AmCharts.useUTC = true;
var chart = AmCharts.makeChart("chartdiv", {
"type": "gantt",
"theme": "light",
"marginRight": 70,
"period": "hh",
"dataDateFormat": "YYYY-MM-DD",
"balloonDateFormat": "JJ:NN",
"columnWidth": 0.5,
"valueAxis": {
"type": "date",
"minimum": 7,
"maximum": 31
},
"brightnessStep": 10,
"graph": {
"fillAlphas": 1,
"balloonText": "<b>[[task]]</b>: [[open]] [[value]]"
},
"rotate": true,
"categoryField": "category",
"segmentsField": "segments",
"colorField": "color",
"startDate": "2015-01-01",
"startField": "start",
"endField": "end",
"durationField": "duration",
"dataProvider": [{
"category": "John",
"segments": [{
"start": 7,
"duration": 2,
"color": "#46615e",
"task": "Task #1",
"key": "1001"
}, {
"duration": 2,
"color": "#727d6f",
"task": "Task #2",
"key": "1002"
}, {
"duration": 2,
"color": "#8dc49f",
"task": "Task #3",
"key": "1003"
}]
}, {
"category": "Smith",
"segments": [{
"start": 10,
"duration": 2,
"color": "#727d6f",
"task": "Task #2",
"key": "1004"
}, {
"duration": 1,
"color": "#8dc49f",
"task": "Task #3",
"key": "1005"
}, {
"duration": 4,
"color": "#46615e",
"task": "Task #1",
"key": "1006"
}]
}, {
"category": "Ben",
"segments": [{
"start": 12,
"duration": 2,
"color": "#727d6f",
"task": "Task #2",
"key": "1007"
}, {
"start": 16,
"duration": 2,
"color": "#FFE4C4",
"task": "Task #4",
"key": "1008"
}]
}],
"listeners": [{
"event": "clickGraphItem",
"method": function(e) {
alert("key: " + e.graph.segmentData.key)
}
}]
});
body,
html {
width: 100%;
height: 100%;
}
#chartdiv {
width: 100%;
height: 100%;
}
<script src="//www.amcharts.com/lib/3/amcharts.js"></script>
<script src="//www.amcharts.com/lib/3/serial.js"></script>
<script src="//www.amcharts.com/lib/3/themes/light.js"></script>
<script src="//www.amcharts.com/lib/3/gantt.js"></script>
<div id="chartdiv"></div>
I have incorporated ace editor in my project
<div id="page-content-wrapper">
<pre id="editor">
</pre>
</div>
<script src="src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
<script>
var editor = ace.edit("editor");
editor.setTheme("ace/theme/monokai");
editor.getSession().setMode("ace/mode/text");
editor.setShowPrintMargin(false);
$('#mode').on('change', function(){
console.log("Change");
var newMode = document.getElementById('mode').value
console.log(newMode);
editor.getSession().setMode("ace/mode/" + newMode);
});
</script>
I want to store the contents written on this editor as a text file using php or javascript.
Need help on this.
Thanks in advance.
Cheers :)
I have implemented download file from ACE editor using Controller.
<div id="editor"></div>
<form action="downloadFromAce" method="post">
<textarea type="text" hidden id="valueInput" name=value ></textarea>
<button class="btn btn-primary" id="downloadBtn" type="submit">Download</button>
</form>
And on click of download button send this data (setting data in text area using jquery) form ACE editor to controller on POST request.
<script>
let editor = ace.edit("editor");
editor.setTheme("ace/theme/monokai");
editor.getSession().setMode("ace/mode/yaml");
$(document).ready(function () {
$("#downloadBtn").click(function () {
const data = editor.getValue();
$("#valueInput").val(data);
})
})
#PostMapping("/download")
Public void downloadFile(#ModelAttribute DownloadFileContent fileContent,HttpServletResponse response){
try{
response.setContentType("text/plain");
response.setHeader("content-Disposition","attachment;filename=demo.txt");
InputStream is=new ByteArrayInputStream(fileContent.getValue().getBytes());
IOUtils.copy(is,response.getOutputStream());
response.flushBuffer();
}catch(Exception e){
e.printStackTrace();
}
}
}
I have used spring boot for backend. But you can do that using other language also.
Here is a complete example of how to save a file, with a particular extension based on the selected mode.
Populate the mode selection box
Enter text you wish to save
Click the "Save" button in the toolbar
Enter a filename; a default file extension will be provided, based on the mode
Confirm
A dialog will be presented asking where to save the file
I used the following libraries:
jQuery - ace-editor requires it
tingle - nice light-weight plain js modal windows
FileSaver - an HTML5 saveAs() FileSaver implementation
const MODES = getModes();
ace.config.set('basePath', 'https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.11');
$('select[name="sel-mode"]').append(MODES.map(mode => new Option(mode.text, mode.value)));
const defaultMode = 'text';
const editor = ace.edit("editor");
editor.setTheme("ace/theme/monokai");
editor.getSession().setMode(`ace/mode/${defaultMode}`);
editor.setShowPrintMargin(false);
$('select[name="sel-mode"]').on('change', function(e) {
editor.getSession().setMode("ace/mode/" + e.target.value);
}).val(defaultMode);
$('button[name="btn-save"]').on('click', e => saveDialog.open());
const saveDialog = new tingle.modal({
footer: true,
stickyFooter: false,
closeMethods: ['overlay', 'button', 'escape'],
closeLabel: 'Close',
cssClass: ['dialog-save'],
onOpen: function() {
$('input[name="filename"]').val(`*.${lookupFileExtension()}`);
},
onClose: function() {},
beforeClose: function() {
return true;
}
});
saveDialog.addFooterBtn('Confirm', 'tingle-btn tingle-btn--primary tingle-btn--pull-right', function() {
const filename = $('input[name="filename"]').val();
const file = new File([editor.getValue()], filename, {
type: "text/plain;charset=utf-8"
});
saveAs(file);
saveDialog.close();
});
saveDialog.addFooterBtn('Cancel', 'tingle-btn tingle-btn--danger tingle-btn--pull-right', function() {
saveDialog.close();
});
saveDialog.setContent($('<div>')
.append($('<h1>', {
text: 'Enter a filename'
}))
.append($('<input>', {
name: 'filename'
})).unwrap().html());
function lookupFileExtension() {
const selectedMode = $('select[name="sel-mode"]').val();
const mode = MODES.find(currMode => currMode.value === selectedMode);
return mode.extension || mode.value;
}
// TODO: Extensions need some more work.
// Option text/values via: https://ace.c9.io/tool/mode_creator.html
function getModes() {
return [{
"text": "ABAP",
"value": "abap"
}, {
"text": "ABC",
"value": "abc"
}, {
"text": "ActionScript",
"value": "actionscript",
"extension": "as"
}, {
"text": "ADA",
"value": "ada"
}, {
"text": "Alda",
"value": "alda"
}, {
"text": "Apache Conf",
"value": "apache_conf"
}, {
"text": "Apex",
"value": "apex"
}, {
"text": "AQL",
"value": "aql"
}, {
"text": "AsciiDoc",
"value": "asciidoc"
}, {
"text": "ASL",
"value": "asl"
}, {
"text": "Assembly x86",
"value": "assembly_x86"
}, {
"text": "AutoHotkey / AutoIt",
"value": "autohotkey",
"extension": "ahk"
}, {
"text": "BatchFile",
"value": "batchfile",
"extension": "bat"
}, {
"text": "C and C++",
"value": "c_cpp",
"extension": "cpp"
}, {
"text": "C9Search",
"value": "c9search"
}, {
"text": "Cirru",
"value": "cirru"
}, {
"text": "Clojure",
"value": "clojure",
"extension": "clj"
}, {
"text": "Cobol",
"value": "cobol",
"extension": "cob"
}, {
"text": "CoffeeScript",
"value": "coffee"
}, {
"text": "ColdFusion",
"value": "coldfusion",
"extension": "cfm"
}, {
"text": "Crystal",
"value": "crystal",
"extension": "rpt"
}, {
"text": "C#",
"value": "csharp",
"extension": "cs"
}, {
"text": "Csound Document",
"value": "csound_document",
"extension": "csd"
}, {
"text": "Csound",
"value": "csound_orchestra",
"extension": "csd"
}, {
"text": "Csound Score",
"value": "csound_score",
"extension": "csd"
}, {
"text": "CSS",
"value": "css"
}, {
"text": "Curly",
"value": "curly"
}, {
"text": "D",
"value": "d"
}, {
"text": "Dart",
"value": "dart"
}, {
"text": "Diff",
"value": "diff"
}, {
"text": "Dockerfile",
"value": "dockerfile"
}, {
"text": "Dot",
"value": "dot"
}, {
"text": "Drools",
"value": "drools",
"extension": "drl"
}, {
"text": "Edifact",
"value": "edifact",
"extension": "edi"
}, {
"text": "Eiffel",
"value": "eiffel",
"extension": "e"
}, {
"text": "EJS",
"value": "ejs"
}, {
"text": "Elixir",
"value": "elixir",
"extension": "ex"
}, {
"text": "Elm",
"value": "elm"
}, {
"text": "Erlang",
"value": "erlang",
"extension": "erl"
}, {
"text": "Forth",
"value": "forth",
"extension": "4th"
}, {
"text": "Fortran",
"value": "fortran",
"extension": "f90"
}, {
"text": "FSharp",
"value": "fsharp",
"extension": "fs"
}, {
"text": "FSL",
"value": "fsl"
}, {
"text": "FreeMarker",
"value": "ftl"
}, {
"text": "Gcode",
"value": "gcode"
}, {
"text": "Gherkin",
"value": "gherkin"
}, {
"text": "Gitignore",
"value": "gitignore"
}, {
"text": "Glsl",
"value": "glsl"
}, {
"text": "Gobstones",
"value": "gobstones"
}, {
"text": "Go",
"value": "golang",
"extension": "go"
}, {
"text": "GraphQLSchema",
"value": "graphqlschema"
}, {
"text": "Groovy",
"value": "groovy"
}, {
"text": "HAML",
"value": "haml"
}, {
"text": "Handlebars",
"value": "handlebars",
"extension": "hbs"
}, {
"text": "Haskell",
"value": "haskell",
"extension": "hs"
}, {
"text": "Haskell Cabal",
"value": "haskell_cabal",
"extension": "hs"
}, {
"text": "haXe",
"value": "haxe"
}, {
"text": "Hjson",
"value": "hjson"
}, {
"text": "HTML",
"value": "html"
}, {
"text": "HTML (Elixir)",
"value": "html_elixir"
}, {
"text": "HTML (Ruby)",
"value": "html_ruby"
}, {
"text": "INI",
"value": "ini"
}, {
"text": "Io",
"value": "io"
}, {
"text": "Jack",
"value": "jack"
}, {
"text": "Jade",
"value": "jade"
}, {
"text": "Java",
"value": "java"
}, {
"text": "JavaScript",
"value": "javascript",
"extension": "js"
}, {
"text": "JSON",
"value": "json",
"extension": "json"
}, {
"text": "JSON5",
"value": "json5",
"extension": "json"
}, {
"text": "JSONiq",
"value": "jsoniq"
}, {
"text": "JSP",
"value": "jsp",
"extension": "jsp"
}, {
"text": "JSSM",
"value": "jssm"
}, {
"text": "JSX",
"value": "jsx"
}, {
"text": "Julia",
"value": "julia"
}, {
"text": "Kotlin",
"value": "kotlin"
}, {
"text": "LaTeX",
"value": "latex",
"extension": "tex"
}, {
"text": "LESS",
"value": "less"
}, {
"text": "Liquid",
"value": "liquid"
}, {
"text": "Lisp",
"value": "lisp"
}, {
"text": "LiveScript",
"value": "livescript"
}, {
"text": "LogiQL",
"value": "logiql"
}, {
"text": "LSL",
"value": "lsl"
}, {
"text": "Lua",
"value": "lua"
}, {
"text": "LuaPage",
"value": "luapage"
}, {
"text": "Lucene",
"value": "lucene"
}, {
"text": "Makefile",
"value": "makefile"
}, {
"text": "Markdown",
"value": "markdown"
}, {
"text": "Mask",
"value": "mask"
}, {
"text": "MATLAB",
"value": "matlab"
}, {
"text": "Maze",
"value": "maze"
}, {
"text": "MediaWiki",
"value": "mediawiki"
}, {
"text": "MEL",
"value": "mel"
}, {
"text": "MIXAL",
"value": "mixal"
}, {
"text": "MUSHCode",
"value": "mushcode"
}, {
"text": "MySQL",
"value": "mysql",
"extension": "sql"
}, {
"text": "Nginx",
"value": "nginx"
}, {
"text": "Nim",
"value": "nim"
}, {
"text": "Nix",
"value": "nix"
}, {
"text": "NSIS",
"value": "nsis"
}, {
"text": "Nunjucks",
"value": "nunjucks"
}, {
"text": "Objective-C",
"value": "objectivec"
}, {
"text": "OCaml",
"value": "ocaml"
}, {
"text": "Pascal",
"value": "pascal",
"extension": "pas"
}, {
"text": "Perl",
"value": "perl",
"extension": "pl"
}, {
"text": "Perl 6",
"value": "perl6",
"extension": "pl"
}, {
"text": "pgSQL",
"value": "pgsql"
}, {
"text": "PHP",
"value": "php"
}, {
"text": "PHP (Blade Template)",
"value": "php_laravel_blade",
"extension": "php"
}, {
"text": "Pig",
"value": "pig"
}, {
"text": "Powershell",
"value": "powershell"
}, {
"text": "Praat",
"value": "praat"
}, {
"text": "Prisma",
"value": "prisma"
}, {
"text": "Prolog",
"value": "prolog"
}, {
"text": "Properties",
"value": "properties"
}, {
"text": "Protobuf",
"value": "protobuf"
}, {
"text": "Puppet",
"value": "puppet"
}, {
"text": "Python",
"value": "python",
"extension": "py"
}, {
"text": "QML",
"value": "qml"
}, {
"text": "R",
"value": "r"
}, {
"text": "Razor",
"value": "razor"
}, {
"text": "RDoc",
"value": "rdoc"
}, {
"text": "Red",
"value": "red"
}, {
"text": "RHTML",
"value": "rhtml"
}, {
"text": "RST",
"value": "rst"
}, {
"text": "Ruby",
"value": "ruby"
}, {
"text": "Rust",
"value": "rust"
}, {
"text": "SASS",
"value": "sass"
}, {
"text": "SCAD",
"value": "scad"
}, {
"text": "Scala",
"value": "scala"
}, {
"text": "Scheme",
"value": "scheme"
}, {
"text": "SCSS",
"value": "scss"
}, {
"text": "SH",
"value": "sh"
}, {
"text": "SJS",
"value": "sjs"
}, {
"text": "Slim",
"value": "slim"
}, {
"text": "Smarty",
"value": "smarty"
}, {
"text": "snippets",
"value": "snippets"
}, {
"text": "Soy Template",
"value": "soy_template"
}, {
"text": "Space",
"value": "space"
}, {
"text": "SQL",
"value": "sql"
}, {
"text": "SQLServer",
"value": "sqlserver"
}, {
"text": "Stylus",
"value": "stylus"
}, {
"text": "SVG",
"value": "svg"
}, {
"text": "Swift",
"value": "swift"
}, {
"text": "Tcl",
"value": "tcl"
}, {
"text": "Terraform",
"value": "terraform"
}, {
"text": "Tex",
"value": "tex"
}, {
"text": "Text",
"value": "text",
"extension": "txt"
}, {
"text": "Textile",
"value": "textile"
}, {
"text": "Toml",
"value": "toml"
}, {
"text": "TSX",
"value": "tsx"
}, {
"text": "Twig",
"value": "twig"
}, {
"text": "Typescript",
"value": "typescript",
"extension": "ts"
}, {
"text": "Vala",
"value": "vala"
}, {
"text": "VBScript",
"value": "vbscript"
}, {
"text": "Velocity",
"value": "velocity"
}, {
"text": "Verilog",
"value": "verilog"
}, {
"text": "VHDL",
"value": "vhdl"
}, {
"text": "Visualforce",
"value": "visualforce"
}, {
"text": "Wollok",
"value": "wollok"
}, {
"text": "XML",
"value": "xml"
}, {
"text": "XQuery",
"value": "xquery"
}, {
"text": "YAML",
"value": "yaml",
"extension": "yml"
}, {
"text": "Zeek",
"value": "zeek"
}, {
"text": "Django",
"value": "django"
}];
}
html,
body {
height: 100%;
width: 100%;
}
#page-content-wrapper {
height: 100%;
width: 100%;
}
.toolbar {
display: flex;
flex-direction: row;
height: 2em;
background: #111;
padding: 0 0.25em;
}
.toolbar button,
.toolbar select {
display: inline-block;
height: 1.67em;
margin-right: 0.5em;
align-self: center;
}
#editor {
width: 100%;
height: calc(100% - 3.33em);
}
.dialog-save h1 {
font-size: 1.5em;
font-weight: bold;
margin-bottom: 0.5em;
}
.dialog-save .tingle-modal-box__content {
padding: 2rem;
}
.dialog-save .tingle-modal-box__footer {
padding: 1rem;
}
.dialog-save .tingle-btn {
padding: 0.667rem;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/tingle/0.15.2/tingle.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/tingle/0.15.2/tingle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.11/ace.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.11/theme-monokai.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.11/mode-text.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/file-saver#2.0.2/dist/FileSaver.min.js"></script>
<div id="page-content-wrapper">
<div class="toolbar">
<select name="sel-mode"></select>
<button name="btn-save">Save</button>
</div>
<pre id="editor"></pre>
</div>
<input type="text" id="input-fileName" value="Result" placeholder="Enter file name">
<button id="download2" type="submit" class="btn btn-primary">Save</button>
<script type="text/javascript">
document.getElementById("download2").addEventListener("click", ()=>{
var filename = $("#input-fileName").val()
var file = new File([editor.getValue()],filename +".h4c", {type: "text/plain;charset=utf-8"});
saveAs(file);
})
Define a button as shown in the code which will trigger the function and the function gets the user input from ace editor and process it to a file with extension, by default i have set extension to .h4c change it according to your need and for the filename i have provided textbox.