Rychlejsi zmereni sirky sloupcu tabulky – JavaScript, AJAX, jQuery – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama

Rychlejsi zmereni sirky sloupcu tabulky – JavaScript, AJAX, jQuery – Fórum – Programujte.comRychlejsi zmereni sirky sloupcu tabulky – JavaScript, AJAX, jQuery – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
peter
~ Anonymní uživatel
2871 příspěvků
10. 5. 2017   #1
-
0
-

Mam funkci pro mereni sloupcu tabulky. Problem je, ze trva 400 jednotek casu. Tabulka samotna se vykresluje asi 40 jednotek. Ma 800 radku, 20 sloupcu. Vsechno se to zkazi az tim cyklem v okamziku, kdy tam dam tds[i].offsetLeft nebo tds[i].offsetWidth. Je uplne jedno, jestli to prirazuji do promenne. Neni nejaky rychlejsi zpusob?

ENG.func.colsWidth = function(table)
{
var theads, trs, tds, i, li, pos;
trs = table.getElementsByTagName('TR');
if (!trs || trs.length==0) {return;}
tds = trs[0].getElementsByTagName('TH');
if (!tds || tds.length==0) {return;}
li = tds.length;
pos = {};
//ENG.func.log('c1=' + PERF.getTime());
for (i=0;i<li;i++)
	{
	pos = {'left':tds[i].offsetLeft, 'width':tds[i].offsetWidth};
	ENG.data.rendered_cols[i].pos = pos;
	}
//ENG.func.log('c2=' + PERF.getTime());
}
Nahlásit jako SPAM
IP: 2001:718:2601:26c:4119:aa...–
Reklama
Reklama
peter
~ Anonymní uživatel
2871 příspěvků
10. 5. 2017   #2
-
0
-

http://mlich.zam.slu.cz/js-zas2/zas2.htm
Kdyz si rozbalite log, tak mezi c1 a c2 je 400 jednotek casu, ktere jen meri sirku bunek.
Nasel jsem ruzne navody podle mereni delky textu, ale to mi prijde nepouzitelne.
Potrebuji to kvuli tomu zahlavi, vyhledavani, pripadne polohu seznamu slov. Nechci to lepit dovnitr te tabulky, co by ji zpomalovalo, si myslim.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:4119:aa...–
weroro0
Newbie
10. 5. 2017   #3
-
0
-

#2 peter
Zdravím Peter.

Nie som si celkom istý, či presne rozumiem problému. Ak je požiadavkou zmerať šírky všetkých stĺpcov v tabuľke, tak stačí zmerať šírky v prvom riadku. Ja som to napísal takto.

/** @type {Element} */
var table = document.querySelector('table');

/**
 * @param tableElement {Element}
 * @returns {Object}
 */
function getColWidth(tableElement) {

    /** @type {Element} */
    var firstRow = tableElement.querySelector('tr');

    /** @type {NodeList} */
    var colsInRow = firstRow.querySelectorAll('td');

    /** @type object {{num_of_cols: number, cols_width: Array, cols_left: Array}} */
    var tableProps = {
        'num_of_cols': 0,
        'cols_width': [],
        'cols_left': [],
    };
    tableProps.num_of_cols = colsInRow.length;

    /** @type {number} */
    var i;
    for (i = 0; i < tableProps.num_of_cols; i++) {

        /** @type {Element} */
        var col = colsInRow[i];
        tableProps.cols_width.push(col.offsetWidth);
        tableProps.cols_left.push(col.offsetLeft);
    }
    return tableProps;
}

console.log(getColWidth(table));
Nahlásit jako SPAM
IP: 91.235.54.–
Front-end web developer at Azet, a.s. & Ringier Axel Springer Slovakia.
peter
~ Anonymní uživatel
2871 příspěvků
10. 5. 2017   #4
-
0
-

Jo, to je presne ten problem. V tom kodu si to muzes debugovat nebo napsat alerty, kdybys chtel. li = 20, takze to prochazi jen prvni radek. ale trva to 0.4s, coz je moc. Ted se mi podarilo najit kod pro mereni textu. Projdu slovo po slove, protoze to mam v poli a cas je 25% :)
V okamziku, kdyz v puvodnim kodu napisi offset, treba pro element table, tak cas vyskoci z 20 na 400.

function getTextWidth(text, font) {
    // re-use canvas object for better performance
    var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
    var context = canvas.getContext("2d");
    context.font = font;
    var metrics = context.measureText(text);
    return metrics.width;
}
getTextWidth.canvas = document.createElement("canvas")

Na te strance stackoverflow je i reseni s divkem, ale to se ukazalo jako stejne pomale, jako je offset pro td.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:4119:aa...–
weroro0
Newbie
10. 5. 2017   #5
-
0
-

#4 peter
0.4 sec (400ms) je obrovské číslo. Samotné meranie tej šírky toľko trvať nemôže. Mne to meria 20 stĺpcov za 4ms čo je 100x rýchlejšie ako tvoje hodnoty. Ukážka tabuľky z 20 stĺpcami http://kod.djpw.cz/cxgc

V tom žltom rámiku pozri na hodnotu exec_time, ktorá je v milisekundách.

Nahlásit jako SPAM
IP: 91.235.54.–
Front-end web developer at Azet, a.s. & Ringier Axel Springer Slovakia.
peter
~ Anonymní uživatel
2871 příspěvků
11. 5. 2017   #6
-
0
-

http://mlich.zam.slu.cz/js-zas2/zas2.htm
Mam to upravene s tim canvas a prochazenim vsech slov. Prvne jsem to udelal se seznamu filtru. Coz samozrejme jelo, 40ms. Ale ukazalo se, ze tam pouzivam pokrocilejsi filtrovani tak, ze slova z filtru vyrazuji, to je ok. Jenze muzu mit nekolik filtru najednou, vyplnene ty kolonky pro vyhledavani a pak mi to rozhazelo sirky bunek te horni tabulky.

To tve reseni, podle mne, dela to same, co dela ten muj puvodni kod s offset. Jen tam mam 800 radku. Jako, zkusim to tam testnout a dam vedet, ale nic si od toho neslibuji. Jen pro klid tve duse, ze je to uplne napikacu a nevymyslim si to i bez toho, ze bych to tam aspon vyzkousel :)
Jak to prohlizec dela, ze jo? Vytvori si treba span, napise tam text, zmeri delku. Totez musi udelat pro vsechna slova ve sloupci. Jaky je rozdil mezi tvou tabulkou a mou? V me ty slova maji nekolik vic moc pismen, ktera musi pres font vykreslit.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:51a1:40...–
peter
~ Anonymní uživatel
2871 příspěvků
11. 5. 2017   #7
-
0
-

Tak, je to tam, viz stale stejny link :) Trochu jsem se s tim pral, protoze nedavam funkci primo table element a pouzivam TH misto TD.

({
num_of_cols:20, 
cols_width:[43, 219, 64, 282, 110, 49, 281, 72, 96, 97, 62, 97, 125, 156, 48, 63, 104, 58, 48, 206], 
cols_left:[2, 45, 265, 329, 611, 721, 771, 1052, 1124, 1221, 1318, 1380, 1477, 1602, 1758, 1806, 1870, 1974, 2032, 2081], 
exec_time:404
})

Snad to uspokoji vsechny tve potreby :)

Nahlásit jako SPAM
IP: 2001:718:2601:26c:51a1:40...–
peter
~ Anonymní uživatel
2871 příspěvků
11. 5. 2017   #8
-
0
-

Spis mne prekvapuje, ze tak zasadni vec o tabulce, sloupcich, se neuklada nekde do elementu table. Ze je treba to znovu prepocitat. Pri vykreslovani tabulky to preci zjistoval, ne?

Nahlásit jako SPAM
IP: 2001:718:2601:26c:51a1:40...–
MilanL+1
Super člen
11. 5. 2017   #9
-
0
-

#8 peter
a zkusil sis v tom cyklu změřit čas jednotlivých řádek, nezdržuje to spíš to přerenderování sloupce?

nebylo by lepší nejdřív v jedné smyčce projít ty bunky na left a width výsledek uložit do pole POS počet prvků=počet sloupců a pak v druhé smyčce ty sloupce vyrenderovat?

Prosím za prominutí jestli je to blbost, je to z mé strany jen nápad, zatím jsem takovouto věc v jQ nepotřeboval použít, ale může se někdy hodit, proto na tohle vlákno vlastně koukám.

Nahlásit jako SPAM
IP: 91.139.9.–
MilanL+1
Super člen
11. 5. 2017   #10
-
0
-

#9 MilanL

nebo druhá rada LEFT stačí zjistit 1 ne? pak už k němu stačí přičítat ty šířky, nebylo by to rychlejší než to zjišťovat přes offset?

 Otázkou je jestli by to sedělo, máš tam v #7 v těch polích rozdíly např 2.sloupec L=45 W=219 (=264) a 3. sloupec má L=265.

MujLeft = 'left':tds[0].offsetLeft;
for (i=0;i<li;i++)
	{
	MujWidth = 'width':tds[i].offsetWidth;
	ENG.data.rendered_cols[i].pos = {MujLeft,MujWidth};
	MujLeft = MujLeft+MujWidth;
	}
//ENG.func.log('c2=' + PERF.getTime());

Nahlásit jako SPAM
IP: 91.139.9.–
peter
~ Anonymní uživatel
2871 příspěvků
11. 5. 2017   #11
-
0
-

Ten alert pro weroro jsem uz zakomentoval. Ale muze si to nahrat k sobe a odkomentovat. Fakt tam pise tech 400.

Unika ti, co jsem napsal driv :) Kdyz pouzijes slovo offset (i bez cyklu), tak nejspis vypocita v cele tabulce offsety. A pritom, pred chvilkou jsem tu tabulku rendroval, takze to mel mit uz prece spocitane, ne? A rendrovani trvalo 0.04s, proc offset trva 10x vic, 0.4s ? :) To je takova trochu nelogika prohlizece.

Nove to resim tak, ze mam seznam slov pro jednotlive sloupce (pouzivam ho pro filtry). Ten seznam pak vyradi rady. Z tech radku vyberu unikatni slova pro sloupec. A pro ty spocitam max sirku.
Zni to slozite, ale jinak to nejde, pokud treba vyradim 3 slova z prvniho sloupce a 2 z druheho, tak muzu vyradit i radky, ktere obsahuji nevyrazene slova. Tak proto si generuji ten seznam znovu.
A kdyz mrknes na js kod, tak mam seznam slov zvlast a tabulka jsou jen cisla, indexy, takze to filtrovani slov mam hodne rychle udelane, protoze pracuje jen s cisly db_filter + db_map.
Driv to bylo pres ten canvas 40 ms, ted je to 100 ms, ale stale lepsi nez 400 ms. Ale ta drivejsi verze taky nemenila sirku tabulky, kdyz se zapl filtr :) Tam jsem bral vsechna slova z db_values

Nahlásit jako SPAM
IP: 2001:718:2601:26c:51a1:40...–
peter
~ Anonymní uživatel
2871 příspěvků
11. 5. 2017   #12
-
0
-

Jo, ten left by to urychlil. Taky to tak delam a pocitam priblizne. Ani na to, ze to canvas spocita dobre nespoleham. Ale priblizne mi to staci.
Normalne pracujes s tabulkou TR a pak TD. Ono by slo vytahnout TD pro celou tabulku a pak to delat po sloupcich, jak rikas. Ale ten cas by to neovlivnilo. Fakt problem dela prvni pouziti slova offset.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:51a1:40...–
peter
~ Anonymní uživatel
2871 příspěvků
11. 5. 2017   #13
-
0
-

Jo, a jestli bys chtel neco podobne pouzit, mozna lepsi si najit nejaky hotovy program googlem :)
Mam spesl pozadavky a hotovy program predelat, aby delal neco jineho je, jako predelat motorku na formuli 1. Oboje umi 300km/h, tak by to nemel byt preci problem, ne? :) Takhle na to kouka zakaznik.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:51a1:40...–
MilanL+1
Super člen
11. 5. 2017   #14
-
0
-

#13 peter
stejně tam máš problémek, tím jak přizpůsobuješ sloupce tabulky se ti při filtrování obvykle redukujou a pak ti nesedí na šířku sloupců filtru. tzn měl bys ten re-rendering použít i na řádku filtru, ale pak ti tam zas při zadávání může utíkat začátek.

Nahlásit jako SPAM
IP: 185.112.167.–
MilanL+1
Super člen
11. 5. 2017   #15
-
0
-

#14 MilanL
a ten offset.. trvá stejně dlouho ikdyž je v tabulce jen 1 řádka?

řešení s tím zjišťováním šířky z toho filtru mě taky napadlo.

jinak nějak ti hapruje řazení, dal jsem řazení podle zásuvky a máš tam pod sebou třeba 3/3/1d5/3/12/3.

Osobně spíš než čas vykreslení <1s bych se dřív snažil vyřešit ujíždějící hlavičku a správnou funkčnost.

V tom původním příspěvku máš TDS - elementy Sloupce tzn ten offset opravdu prochází a počítá maximální šířku ze všech řádků ve sloupcích, proto se tomu času ani nedivím 800*20x zjistit vykreslovanou šířku textu porovnat s dosavadním maximem případně nahradit max.

A tu šířku bych řešil možná při formátování dat do tabulky ukládáním do (počet sloupců) prvkového pole nejdelší slovo a z toho pak zjistil přes canvas  width  (s kontrolou na úzké znaky jako jsou "1 i l" za ty je třeba trošku přidat) nebo ty nejdelší slova do 1 řádkové pomocné tabulky a offset... (to už by mělo bejt rychlý) zjistit lefty a šířky a ty aplikovat na hlavní tabulku.

Nahlásit jako SPAM
IP: 185.112.167.–
peter
~ Anonymní uživatel
2871 příspěvků
12. 5. 2017   #16
-
0
-

funkcnost - hele, je to navrzene pro FF. Ostatni prohlizece mne nezajimaji, uz desitku let.

razeni - u zasuvek je treba pouzit jen spravnou funkci. Pokud si nahore rozkliknes razeni, tak vidis, podle ceho to radi. Muzes tam zadat vice sloupcu. A v kodu bys pak musel pridat novou radici funkci a priradit ji do structure pro ten sloupec.

sirky - to prave musis vsechno vykreslit. jakakoliv slozitejsi logika tam vytvori v kodu brzdu.
MMMMMM - 6
iiiiiiiiii - 10
tolik k nejdelsimu slovu. A to nemluvim o tom, ze tam nemusi byt jen pismenka, ale treba html entity &nbsp; &gt;.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:48f1:6b...–
peter
~ Anonymní uživatel
2871 příspěvků
12. 5. 2017   #17
-
0
-

Ano, slo by pouzit tabulku znaku s delkou, font +-znam, muzu si to po znaku zmerit. Muzou tam byt i rozdilne mezery pro dvojice znaku. proste, touhle cestou bych asi nesel, to by bylo hodne priblizne. Ze to trosku ujizdi, nevadi, nemusi to byt presne. Hlavne, aby to nebylo moc.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:48f1:6b...–
MilanL+1
Super člen
12. 5. 2017   #18
-
0
-

#16 peter
#17 peter
to jsem tam psal, že u toho nejdelšího by se ty úzké znaky museli ošetřit, velká písmena a M nebo W jsem tam v té části kterou jsem prošel nezahléd, nebo jejich výskyt je hodně malý, vše co tam ted viděl jsou HEX čísla s malejma písmenama tzn ošetřit v podstatě jen 1 případně mezery, ostatní jen pro univerzáílnost
Cest je více, ty sis jich několik prošel a vybral. Otázkou je jestli by ty ostatní vůbec ušetřili nějakej další čas a jak velkej. MM používám.

Nahlásit jako SPAM
IP: 185.112.167.–
peter
~ Anonymní uživatel
2871 příspěvků
12. 5. 2017   #19
-
0
-

Text jsou hashe obsahu zkraceny na delku puvodniho textu, ktery nechci zverejnovat. :) Prislo mi to lepsi nez tam davat nahodny text.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:3c3c:98...–
MilanL+1
Super člen
12. 5. 2017   #20
-
0
-

#19 peter
AHA   

hm není možné, že proto v té ukázce nesedí to řazení?

samozřejmě předpokládám že máš ošetřeno v řazení jestli jde o řetězec nebo čísla.

Nahlásit jako SPAM
IP: 193.165.115.–
weroro0
Newbie
13. 5. 2017   #21
-
0
-

Tu sa rozbehla nejaká bujará diskusia. :)
Peter ja si stále stojím za svojím. Buď sa nerozumieme, alebo ty niečo nesprávne implementuješ. Išiel som na ten tvoj web a v konzole som spustil (po miernej uprave, ktorá bola nutná) ten môj script. exec_time som mal 0, takže to dokonca trvá menej ako milisekundu (škoda, že neviem merať v JS mikro-sekundy).
 

Připojen obrázek.

Nahlásit jako SPAM
IP: 89.173.156.–
Front-end web developer at Azet, a.s. & Ringier Axel Springer Slovakia.
peter
~ Anonymní uživatel
2871 příspěvků
15. 5. 2017   #22
-
0
-

Sak dej link na upravu. Na te strance, v kodu, staci odkomentovat jeden radek.
http://mlich.zam.slu.cz/…as2.htm ;

//alert(getColWidth(ENG.obj.table.getElementsByTagName('TABLE')[0]).toSource());

Jestli chces, muzu tam udelat checkbox. Ale resim ted neco jineho, tak se tam objevi fura dalsiho kodu :)

Nahlásit jako SPAM
IP: 2001:718:2601:26c:74a9:9b...–
peter
~ Anonymní uživatel
2871 příspěvků
15. 5. 2017   #23
-
0
-

A urcite se bavime o FF a ne necem jinem? FF umi mikrosekundy pres performance. To tam pouzivam v tom programu, viz radky ve funkci ENG.func.doFilters.

ENG.func.log('fr=' + PERF.getTime());

Nahlásit jako SPAM
IP: 2001:718:2601:26c:74a9:9b...–
peter
~ Anonymní uživatel
2871 příspěvků
15. 5. 2017   #24
-
0
-

Teda, takhle, na moziile pisou, ze ten cas nemusi odpovidat realnemu casovemu razitku. Takze, pokud ti jde jen o presnejsi mereni, tak na to to staci. Ale, tak, ja to spis pouzivam, protoze to mam uz odladene v jinem programu, kde na tech desetinach zalezi :)

Nahlásit jako SPAM
IP: 2001:718:2601:26c:74a9:9b...–
peter
~ Anonymní uživatel
2871 příspěvků
15. 5. 2017   #25
-
0
-

Tak, je to tam, kliknes zahadny checkbox a pak kliknes na zahlavi v tabulce (sipecku), aby se spustilo serazovani. alert mi vyhodi 389 / 400.
Co by mozna bylo velice fajn, zkus napsat prohlizec a pridej vypis z log nahore, kdyz to rozkliknes. Chapu, ze mam v praci srot, takze nekdo muze mit o moc lepsi pc :) Vychazim z toho, ze na screenu mas 12.695 a ja mam 121. Jo, a tez delaji prohlizece ruzne optimalizace, takze treba po par pouziti tam najednou skoci 10x mensi cas.

783 / 783 colsWidth=121.544
783 / 783 render=45.109
783 / 783 val=1.955
783 / 783 uniq=1.659
783 / 783 fr=0.305
783 / 783 fms=29.454
783 / 783 fw=0.195
783 / 783 clone=2.009
Nahlásit jako SPAM
IP: 2001:718:2601:26c:74a9:9b...–
weroro0
Newbie
15. 5. 2017   #26
-
0
-

Modal vyhadzuje exec_time okolo 160ms. Hore mi zobrazuje colsWidth=41.08
Prečo vlastne potrebuješ merať šírku bunky pri každom sorte? Nemám pocit, že by sa menila šírka bunky. Nestačí to urobiť iba raz?

Nahlásit jako SPAM
IP: 91.235.54.–
Front-end web developer at Azet, a.s. & Ringier Axel Springer Slovakia.
peter
~ Anonymní uživatel
2871 příspěvků
15. 5. 2017   #27
-
0
-

Totiz, tys ten program neproklikal, takze nevis, co to umi.
- Zakladni funkce je, ze kdyz kliknes na sipecku u vyhledat, vybali sezna slov a muzes zaskrtat, ktera tam nechces, jako to maji novejsi Excely.
- Dalsi funkci je, ze je mozne napsat text, ktery slova vyradi a to i ve vice kolonkach.
- A pak je tam neco podobne pro sortovani. Je mozne sortovat jako ORDER BY sloupec nebo vice sloupcu. Toto nastaveni neni moc pristupne, ale rozkliknes to po kliknuti na slovo ORDER BY. A mas pravdu, ze se v ani jednom pripade nezmeni sirka jako v pripade slov.
- Ale jeste je tam treti funkce, filtrovani radku, jako sql LIMIT. Tam uz se sirka muze opet menit. Takze na konci scriptu logicky prepocitavam

Nicmene se nad tim zamyslim a melo by to odlehcit prekreslovani v nekterych situacich.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:f14f:e7...–
peter
~ Anonymní uživatel
2871 příspěvků
15. 5. 2017   #28
-
0
-

'Hore mi zobrazuje colsWidth=41.08'
Tam to pocita ten druhy kod, pres canvas a slov.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:f14f:e7...–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 27 hostů

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032017 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý