うしブログ

うしブログ

趣味で運営する、GeoGebraの専門ブログ。

(作業メモ)StartPoint要検証(2行の場合;テキスト変更時未定義問題)

(要修復)ToggleButton・RollPolygonWithoutSlipping・貯金時計・直感力トレーニング

GeoGebraのXMLデータを、jQueryで操作する

前提

  • ブラウザ版 GeoGebra Classic 6を前提とした記事である。以下で「GeoGebra」という場合は、特に断らない限り、ブラウザ版 GeoGebra Classic 6を指す。
  • 以下の表中の「jQuery」の列を実行可能にするには、GeoGebraのページで、jQueryの導入が必要である。さらに、以下の変数・関数を使用する箇所があるので、あらかじめ定義しておくとよい。
  • 以下の表中の「g$」は、GeoGebraに、下記記事に示したスクリプト「geoEditor-1-4」を導入することで使用可能になる。

usidesu.hatenablog.com

 

let fullXML = ggbApplet.getXML(); // GeoGebraのXMLデータ
let constructionXML = fullXML.substring(fullXML.indexOf('<construction'), fullXML.lastIndexOf('</construction>') + '</construction>'.length); // constructionタグ(elementタグが内包)を抽出
let xml = $.parseXML(constructionXML);  // パースしたもの

// jQueryオブジェクトのattributesを取り出してオブジェクトリテラル化
function getAttrs(jqObj) {
    let output = {};
    for (let j = 0, lenJ = jqObj.length; j < lenJ; j++) {
        let attributes = jqObj.get(j).attributes;
        let title; // outputオブジェクトの第一階層の見出し名を格納
        if (jqObj.get(j).tagName == 'element') {  // 処理対象がelement要素
            title = "#" + [...jqObj.get(j).attributes].filter(v => v.name == 'label')[0].value;  // #Aとか
        } else {  // 処理対象がelementの子孫である各種スタイル要素
            title = "#" + jqObj.map((i, e) => [...e.parentElement.attributes].filter(v => v.name == 'label')[0].value).get(j) + ' ' + jqObj.get(j).tagName;  // #A showとか
        }
        if (!output[title]) {
            output[title] = {}
        };
        for (let i = 0, lenI = attributes.length; i < lenI; i++) {
            let attr;
            attr = attributes[i];
            output[title][attr.name] = attr.value;
        }
    }
    return output;
}

function wrap (str) {  // 実行したいxmlテキストを定型句で包み、evalXMLを実行できる形にする
    return ggbApplet.getXML().match(/\<\?xml.+?\>/)[0] + '\n'  // XML宣言部分
    + ggbApplet.getXML().match(/\<geogebra.+?\>/)[0] + '\n'  // geogebra開始タグ
    + ggbApplet.getXML().match(/\<construction.+?\>/)[0] + '\n'  // construction開始タグ
        + str + '\n'
        + '</construction>\n'
        + '</geogebra>';
}

GeoGebraオブジェクトの取得

  jQuery g$
全GeoGebraオブジェクトと、すべての設定用要素(XMLのconstructionタグの子要素全て) $(xml).find('*') g$('*')
全GeoGebraオブジェクト(XMLのelementタグ全て) $(xml).find("element") g$('@')
全ての点 $(xml).find('element[type="point"]') g$('.point')
全ての点と直線 $(xml).find('element[type="point"],element[type="line"]') g$('.point, .line')
名前が「A」のオブジェクト $(xml).find('element[label="A"]') g$('#A')
AとB $(xml).find('element[label="A"],element[label="B"]') g$('#A, #B')
Aと直線 $(xml).find('element[label="A"],element[type="line"]') g$('#A, .line')
青い点 $(xml).find('objColor[r="0"][g="0"][b="255"]').parents('element[type="point"]') g$('objColor[r="0"][g="0"][b="255"]').of('.point')
非表示の全オブジェクト $(xml).find('show[object="false"]').parents('element') g$('show[object="false"]').of('@')
A以外の点 $(xml).find('element[type="point"]').not('element[label="A"]') または
$(xml).find('element[type="point"]:not(element[label="A"])')
g$('.point').not('#A')
または
g$('.point:not(#A)')

 

要素の情報(ラベル、オブジェクトタイプ、スタイル)の取得

  jQuery g$
全オブジェクトのタイプと名前 getAttrs($(xml).find('element')) g$('@').attrs()
すべての青い点のタイプと名前 getAttrs($(xml).find('objColor[r="0"][g="0"][b="255"]').parents('element[type="point"]')) g$('objColor[r="0"][g="0"][b="255"]').of('.point').attrs()
Aのタイプと名前 getAttrs($(xml).find('element[label="A"]')) g$('#A').attrs()
Aのタイプ $(xml).find('element[label="A"]').attr('type') g$('#A').attr('type')
全てのオブジェクトの全スタイル getAttrs($(xml).find('element *')) g$('@ *').attrs()
AのobjColorタグの全属性 getAttrs($(xml).find('element[label="A"] objColor')) g$('#A objColor').attrs()
AのobjColorタグのr属性 $(xml).find('element[label="A"] objColor').attr('r') g$('#A objColor').attr('r')

 

要素のスタイルの変更

  jQuery g$
Aの色を緑にする ggbApplet.evalXML( wrap( $(xml).find('element[label="A"]') .find('objColor').remove().prevObject.append('<objColor></objColor>').find('objColor') .attr({ r: 0, g: 255, b: 0, alpha: 0 }) .parent() .map((index, element) => { return $(element).get(0).outerHTML.replace(/\n/g, '').replace(/\t/g, ''); }).toArray().join('\n') ) ); ggbApplet.evalCommand('UpdateConstruction[ ]');

g$('#A').attrs({ objColor: { r: 0, g: 255, b: 0 } });

または

g$('#A objColor').attrs({ r: 0, g: 255, b: 0 });

 

Aの色を赤にして非表示 ggbApplet.evalXML( wrap( $(xml).find('element[label="A"]') .find('objColor').remove().prevObject.append('<objColor></objColor>').find('objColor') .attr({ r: 255, g: 0, b: 0, alpha: 0 }) .parent() .find('show').remove().prevObject.append('<show></show>').find('show') .attr({ object: false, label: true }).parent() .map((index, element) => { return $(element).get(0).outerHTML.replace(/\n/g, '').replace(/\t/g, ''); }).toArray().join('\n') ) ); ggbApplet.evalCommand('UpdateConstruction[ ]');

g$('#A').attrs({ objColor: { r: 255, g: 0, b: 0 }, show: { object: false, label: true } });

Aを赤くしてJavaScriptをセット ggbApplet.evalXML( wrap( $(xml).find('element[label="A"]') .find('objColor').remove().prevObject.append('<objColor></objColor>').find('objColor') .attr({ r: 255, g: 0, b: 0, alpha: 0 }) .parent() .find('javascript[onUpdate]').remove().prevObject.append('<javascript onUpdate=""></javascript>').find('javascript[onUpdate]') .attr({ onUpdate: 'console.log("update-usi");' }).parent() .find('javascript[val]').remove().prevObject.append('<javascript val=""></javascript>').find('javascript[val]') .attr({ val: 'console.log("click-usi");' }).parent() .map((index, element) => { return $(element).get(0).outerHTML.replace(/\n/g, '').replace(/\t/g, ''); }).toArray().join('\n') ) ); ggbApplet.evalCommand('UpdateConstruction[ ]'); g$('#A').attrs({ objColor: { r: 255, g: 0, b: 0 }, show: { object: false, label: true }, javascript: { onUpdate: 'console.log("update-usi");', val: 'console.log("click-usi");' } });
すべての点を赤くする ggbApplet.evalXML( wrap( $(xml).find('element[type="point"]') .find('objColor').remove().prevObject.append('<objColor></objColor>').find('objColor') .attr({ r: 255, g: 0, b: 0, alpha: 0 }) .parent() .map((index, element) => { return $(element).get(0).outerHTML.replace(/\n/g, '').replace(/\t/g, ''); }).toArray().join('\n') ) ); ggbApplet.evalCommand('UpdateConstruction[ ]');

g$('.point').attrs({ objColor: { r: 255, g: 0, b: 0 } });

または

g$('.point objColor').attrs({ r: 255, g: 0, b: 0 });

A以外のすべての点を赤くして非表示 ggbApplet.evalXML( wrap( $(xml).find('element[type="point"]:not(element[label="A"])') .find('objColor').remove().prevObject.append('<objColor></objColor>').find('objColor') .attr({ r: 255, g: 0, b: 0, alpha: 0 }) .parent() .find('show').remove().prevObject.append('<show></show>').find('show') .attr({ object: false, label: true }).parent() .map((index, element) => { return $(element).get(0).outerHTML.replace(/\n/g, '').replace(/\t/g, ''); }).toArray().join('\n') ) ); ggbApplet.evalCommand('UpdateConstruction[ ]'); g$('.point:not(#A)').attrs({ objColor: { r: 255, g: 0, b: 0 }, show: { object: false, label: true } });