Compare commits
10 Commits
4e52da5431
...
ab5fe740fd
Author | SHA1 | Date | |
---|---|---|---|
ab5fe740fd | |||
091bacf006 | |||
57298904a0 | |||
6342ebfdc7 | |||
b142e5d906 | |||
b21502526e | |||
5d579ba82a | |||
3a7e0987bd | |||
0b8e986990 | |||
7a6ed915d0 |
@ -5,7 +5,7 @@
|
|||||||
<path id="Y" d="M0 0L20 0" fill="none" stroke-width="2" stroke="#000000" stroke-linecap="square" transform="translate(75 26)" />
|
<path id="Y" d="M0 0L20 0" fill="none" stroke-width="2" stroke="#000000" stroke-linecap="square" transform="translate(75 26)" />
|
||||||
<path id="B" d="M0 0L20 0" fill="none" stroke-width="2" stroke="#000000" stroke-linecap="square" transform="translate(0 52)" />
|
<path id="B" d="M0 0L20 0" fill="none" stroke-width="2" stroke="#000000" stroke-linecap="square" transform="translate(0 52)" />
|
||||||
<path id="ROAD" d="M10.6066 0L0 10.6066" fill="none" stroke-width="2" stroke="#000000" stroke-linecap="square" transform="translate(21 42)" />
|
<path id="ROAD" d="M10.6066 0L0 10.6066" fill="none" stroke-width="2" stroke="#000000" stroke-linecap="square" transform="translate(21 42)" />
|
||||||
<path id="A" d="M0 0L20 0" fill="none" stroke-width="2" stroke="#000000" stroke-linecap="square" />
|
<path id="A" d="M0 0L20 0" fill="none" stroke-width="2" stroke="#000000" stroke-linecap="square"/>
|
||||||
<path id="ROAD" d="M0 0L10.6066 10.61" fill="none" stroke-width="2" stroke="#000000" stroke-linecap="square" transform="translate(21 1)" />
|
<path id="ROAD" d="M0 0L10.6066 10.61" fill="none" stroke-width="2" stroke="#000000" stroke-linecap="square" transform="translate(21 1)" />
|
||||||
<g fill="#279BB0" fill-rule="evenodd" transform="translate(27 2)">
|
<g fill="#279BB0" fill-rule="evenodd" transform="translate(27 2)">
|
||||||
<path id="ge" d="M0 25C0 11.1929 11.1929 0 25 0C38.8071 0 50 11.1929 50 25C50 38.8071 38.8071 50 25 50C11.1929 50 0 38.8071 0 25Z" />
|
<path id="ge" d="M0 25C0 11.1929 11.1929 0 25 0C38.8071 0 50 11.1929 50 25C50 38.8071 38.8071 50 25 50C11.1929 50 0 38.8071 0 25Z" />
|
||||||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.1 KiB |
460
out.svg
Normal file
460
out.svg
Normal file
@ -0,0 +1,460 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:s="https://github.com/nturley/netlistsvg" width="569" height="868.5">
|
||||||
|
<style>svg {
|
||||||
|
stroke:#000;
|
||||||
|
fill:none;
|
||||||
|
}
|
||||||
|
text {
|
||||||
|
fill:#000;
|
||||||
|
stroke:none;
|
||||||
|
font-size:10px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-family: "Courier New", monospace;
|
||||||
|
}
|
||||||
|
.nodelabel {
|
||||||
|
text-anchor: middle;
|
||||||
|
}
|
||||||
|
.inputPortLabel {
|
||||||
|
text-anchor: end;
|
||||||
|
}
|
||||||
|
.splitjoinBody {
|
||||||
|
fill:#000;
|
||||||
|
}</style>
|
||||||
|
<g s:type="add" transform="translate(94.66666666666667,699.5)" s:width="25" s:height="25" id="cell_$add$/dide/user/src/language/vlog/netlistview/netlistview.v:15$3">
|
||||||
|
<s:alias val="$add"/>
|
||||||
|
<circle r="12.5" cx="12.5" cy="12.5" class="cell_$add$/dide/user/src/language/vlog/netlistview/netlistview.v:15$3"/>
|
||||||
|
<line x1="7.5" x2="17.5" y1="12.5" y2="12.5" class="cell_$add$/dide/user/src/language/vlog/netlistview/netlistview.v:15$3"/>
|
||||||
|
<line x1="12.5" x2="12.5" y1="7.5" y2="17.5" class="cell_$add$/dide/user/src/language/vlog/netlistview/netlistview.v:15$3"/>
|
||||||
|
<g s:x="3" s:y="5" s:pid="A"/>
|
||||||
|
<g s:x="3" s:y="20" s:pid="B"/>
|
||||||
|
<g s:x="25" s:y="12.5" s:pid="Y"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="and" transform="translate(365,814)" s:width="30" s:height="25" id="cell_$and$/dide/user/src/language/vlog/netlistview/netlistview.v:31$5">
|
||||||
|
<s:alias val="$and"/>
|
||||||
|
<s:alias val="$logic_and"/>
|
||||||
|
<s:alias val="$_AND_"/>
|
||||||
|
<path d="M0,0 L0,25 L15,25 A15 12.5 0 0 0 15,0 Z" class="cell_$and$/dide/user/src/language/vlog/netlistview/netlistview.v:31$5"/>
|
||||||
|
<g s:x="0" s:y="5" s:pid="A"/>
|
||||||
|
<g s:x="0" s:y="20" s:pid="B"/>
|
||||||
|
<g s:x="30" s:y="12.5" s:pid="Y"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="and" transform="translate(365,19.5)" s:width="30" s:height="25" id="cell_$and$/dide/user/src/language/vlog/netlistview/netlistview.v:32$6">
|
||||||
|
<s:alias val="$and"/>
|
||||||
|
<s:alias val="$logic_and"/>
|
||||||
|
<s:alias val="$_AND_"/>
|
||||||
|
<path d="M0,0 L0,25 L15,25 A15 12.5 0 0 0 15,0 Z" class="cell_$and$/dide/user/src/language/vlog/netlistview/netlistview.v:32$6"/>
|
||||||
|
<g s:x="0" s:y="5" s:pid="A"/>
|
||||||
|
<g s:x="0" s:y="20" s:pid="B"/>
|
||||||
|
<g s:x="30" s:y="12.5" s:pid="Y"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="dff" transform="translate(432,302)" s:width="30" s:height="40" id="cell_$procdff$12">
|
||||||
|
<s:alias val="$dff"/>
|
||||||
|
<s:alias val="$_DFF_"/>
|
||||||
|
<s:alias val="$_DFF_P_"/>
|
||||||
|
<rect width="30" height="40" x="0" y="0" class="cell_$procdff$12"/>
|
||||||
|
<path d="M0,35 L5,30 L0,25" class="cell_$procdff$12"/>
|
||||||
|
<g s:x="30" s:y="10" s:pid="Q"/>
|
||||||
|
<g s:x="0" s:y="30" s:pid="CLK"/>
|
||||||
|
<g s:x="0" s:y="30" s:pid="C"/>
|
||||||
|
<g s:x="0" s:y="10" s:pid="D"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="dff" transform="translate(432,816.5)" s:width="30" s:height="40" id="cell_$procdff$13">
|
||||||
|
<s:alias val="$dff"/>
|
||||||
|
<s:alias val="$_DFF_"/>
|
||||||
|
<s:alias val="$_DFF_P_"/>
|
||||||
|
<rect width="30" height="40" x="0" y="0" class="cell_$procdff$13"/>
|
||||||
|
<path d="M0,35 L5,30 L0,25" class="cell_$procdff$13"/>
|
||||||
|
<g s:x="30" s:y="10" s:pid="Q"/>
|
||||||
|
<g s:x="0" s:y="30" s:pid="CLK"/>
|
||||||
|
<g s:x="0" s:y="30" s:pid="C"/>
|
||||||
|
<g s:x="0" s:y="10" s:pid="D"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="dff" transform="translate(432,22)" s:width="30" s:height="40" id="cell_$procdff$14">
|
||||||
|
<s:alias val="$dff"/>
|
||||||
|
<s:alias val="$_DFF_"/>
|
||||||
|
<s:alias val="$_DFF_P_"/>
|
||||||
|
<rect width="30" height="40" x="0" y="0" class="cell_$procdff$14"/>
|
||||||
|
<path d="M0,35 L5,30 L0,25" class="cell_$procdff$14"/>
|
||||||
|
<g s:x="30" s:y="10" s:pid="Q"/>
|
||||||
|
<g s:x="0" s:y="30" s:pid="CLK"/>
|
||||||
|
<g s:x="0" s:y="30" s:pid="C"/>
|
||||||
|
<g s:x="0" s:y="10" s:pid="D"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="dff" transform="translate(432,162)" s:width="30" s:height="40" id="cell_$procdff$15">
|
||||||
|
<s:alias val="$dff"/>
|
||||||
|
<s:alias val="$_DFF_"/>
|
||||||
|
<s:alias val="$_DFF_P_"/>
|
||||||
|
<rect width="30" height="40" x="0" y="0" class="cell_$procdff$15"/>
|
||||||
|
<path d="M0,35 L5,30 L0,25" class="cell_$procdff$15"/>
|
||||||
|
<g s:x="30" s:y="10" s:pid="Q"/>
|
||||||
|
<g s:x="0" s:y="30" s:pid="CLK"/>
|
||||||
|
<g s:x="0" s:y="30" s:pid="C"/>
|
||||||
|
<g s:x="0" s:y="10" s:pid="D"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="dff" transform="translate(497,731.5)" s:width="30" s:height="40" id="cell_$procdff$16">
|
||||||
|
<s:alias val="$dff"/>
|
||||||
|
<s:alias val="$_DFF_"/>
|
||||||
|
<s:alias val="$_DFF_P_"/>
|
||||||
|
<rect width="30" height="40" x="0" y="0" class="cell_$procdff$16"/>
|
||||||
|
<path d="M0,35 L5,30 L0,25" class="cell_$procdff$16"/>
|
||||||
|
<g s:x="30" s:y="10" s:pid="Q"/>
|
||||||
|
<g s:x="0" s:y="30" s:pid="CLK"/>
|
||||||
|
<g s:x="0" s:y="30" s:pid="C"/>
|
||||||
|
<g s:x="0" s:y="10" s:pid="D"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="dff" transform="translate(497,77)" s:width="30" s:height="40" id="cell_$procdff$17">
|
||||||
|
<s:alias val="$dff"/>
|
||||||
|
<s:alias val="$_DFF_"/>
|
||||||
|
<s:alias val="$_DFF_P_"/>
|
||||||
|
<rect width="30" height="40" x="0" y="0" class="cell_$procdff$17"/>
|
||||||
|
<path d="M0,35 L5,30 L0,25" class="cell_$procdff$17"/>
|
||||||
|
<g s:x="30" s:y="10" s:pid="Q"/>
|
||||||
|
<g s:x="0" s:y="30" s:pid="CLK"/>
|
||||||
|
<g s:x="0" s:y="30" s:pid="C"/>
|
||||||
|
<g s:x="0" s:y="10" s:pid="D"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="dff" transform="translate(497,217)" s:width="30" s:height="40" id="cell_$procdff$18">
|
||||||
|
<s:alias val="$dff"/>
|
||||||
|
<s:alias val="$_DFF_"/>
|
||||||
|
<s:alias val="$_DFF_P_"/>
|
||||||
|
<rect width="30" height="40" x="0" y="0" class="cell_$procdff$18"/>
|
||||||
|
<path d="M0,35 L5,30 L0,25" class="cell_$procdff$18"/>
|
||||||
|
<g s:x="30" s:y="10" s:pid="Q"/>
|
||||||
|
<g s:x="0" s:y="30" s:pid="CLK"/>
|
||||||
|
<g s:x="0" s:y="30" s:pid="C"/>
|
||||||
|
<g s:x="0" s:y="10" s:pid="D"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="eq" transform="translate(162.66666666666666,579)" s:width="25" s:height="25" id="cell_$procmux$10_CMP0">
|
||||||
|
<s:alias val="$eq"/>
|
||||||
|
<circle r="12.5" cx="12.5" cy="12.5" class="cell_$procmux$10_CMP0"/>
|
||||||
|
<line x1="7.5" x2="17.5" y1="10" y2="10" class="cell_$procmux$10_CMP0"/>
|
||||||
|
<line x1="7.5" x2="17.5" y1="15" y2="15" class="cell_$procmux$10_CMP0"/>
|
||||||
|
<g s:x="3" s:y="5" s:pid="A"/>
|
||||||
|
<g s:x="3" s:y="20" s:pid="B"/>
|
||||||
|
<g s:x="25" s:y="12.5" s:pid="Y"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="not" transform="translate(163,639)" s:width="30" s:height="20" id="cell_$procmux$11_CMP0">
|
||||||
|
<s:alias val="$_NOT_"/>
|
||||||
|
<s:alias val="$not"/>
|
||||||
|
<s:alias val="$logic_not"/>
|
||||||
|
<path d="M0,0 L0,20 L20,10 Z" class="cell_$procmux$11_CMP0"/>
|
||||||
|
<circle cx="23" cy="10" r="3" class="cell_$procmux$11_CMP0"/>
|
||||||
|
<g s:x="0" s:y="10" s:pid="A"/>
|
||||||
|
<g s:x="25" s:y="10" s:pid="Y"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="mux" transform="translate(309,292)" s:width="20" s:height="40" id="cell_$procmux$7">
|
||||||
|
<s:alias val="$pmux"/>
|
||||||
|
<s:alias val="$mux"/>
|
||||||
|
<s:alias val="$_MUX_"/>
|
||||||
|
<path d="M0,0 L20,10 L20,30 L0,40 Z" class="cell_$procmux$7"/>
|
||||||
|
<g s:x="0" s:y="10" s:pid="A"/>
|
||||||
|
<g s:x="0" s:y="30" s:pid="B"/>
|
||||||
|
<g s:x="10" s:y="35" s:pid="S"/>
|
||||||
|
<g s:x="20" s:y="20" s:pid="Y"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="eq" transform="translate(162.66666666666666,436.5)" s:width="25" s:height="25" id="cell_$procmux$8_CMP0">
|
||||||
|
<s:alias val="$eq"/>
|
||||||
|
<circle r="12.5" cx="12.5" cy="12.5" class="cell_$procmux$8_CMP0"/>
|
||||||
|
<line x1="7.5" x2="17.5" y1="10" y2="10" class="cell_$procmux$8_CMP0"/>
|
||||||
|
<line x1="7.5" x2="17.5" y1="15" y2="15" class="cell_$procmux$8_CMP0"/>
|
||||||
|
<g s:x="3" s:y="5" s:pid="A"/>
|
||||||
|
<g s:x="3" s:y="20" s:pid="B"/>
|
||||||
|
<g s:x="25" s:y="12.5" s:pid="Y"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="eq" transform="translate(162.66666666666666,496.5)" s:width="25" s:height="25" id="cell_$procmux$9_CMP0">
|
||||||
|
<s:alias val="$eq"/>
|
||||||
|
<circle r="12.5" cx="12.5" cy="12.5" class="cell_$procmux$9_CMP0"/>
|
||||||
|
<line x1="7.5" x2="17.5" y1="10" y2="10" class="cell_$procmux$9_CMP0"/>
|
||||||
|
<line x1="7.5" x2="17.5" y1="15" y2="15" class="cell_$procmux$9_CMP0"/>
|
||||||
|
<g s:x="3" s:y="5" s:pid="A"/>
|
||||||
|
<g s:x="3" s:y="20" s:pid="B"/>
|
||||||
|
<g s:x="25" s:y="12.5" s:pid="Y"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="reduce_xor" transform="translate(364,159.5)" s:width="33" s:height="25" id="cell_$reduce_xor$/dide/user/src/language/vlog/netlistview/netlistview.v:30$4">
|
||||||
|
<s:alias val="$xor"/>
|
||||||
|
<s:alias val="$reduce_xor"/>
|
||||||
|
<s:alias val="$_XOR_"/>
|
||||||
|
<path d="M3,0 A30 25 0 0 1 3,25 A30 25 0 0 0 33,12.5 A30 25 0 0 0 3,0" class="cell_$reduce_xor$/dide/user/src/language/vlog/netlistview/netlistview.v:30$4"/>
|
||||||
|
<path d="M0,0 A30 25 0 0 1 0,25" class="cell_$reduce_xor$/dide/user/src/language/vlog/netlistview/netlistview.v:30$4"/>
|
||||||
|
<g s:x="3" s:y="5" s:pid="A"/>
|
||||||
|
<g s:x="3" s:y="20" s:pid="B"/>
|
||||||
|
<g s:x="33" s:y="12.5" s:pid="Y"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="sub" transform="translate(94.66666666666667,74.5)" s:width="25" s:height="25" id="cell_$sub$/dide/user/src/language/vlog/netlistview/netlistview.v:14$2">
|
||||||
|
<s:alias val="$sub"/>
|
||||||
|
<circle r="12.5" cx="12.5" cy="12.5" class="cell_$sub$/dide/user/src/language/vlog/netlistview/netlistview.v:14$2"/>
|
||||||
|
<line x1="7.5" x2="17.5" y1="12.5" y2="12.5" class="cell_$sub$/dide/user/src/language/vlog/netlistview/netlistview.v:14$2"/>
|
||||||
|
<g s:x="3" s:y="5" s:pid="A"/>
|
||||||
|
<g s:x="3" s:y="20" s:pid="B"/>
|
||||||
|
<g s:x="25" s:y="12.5" s:pid="Y"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="inputExt" transform="translate(367,248)" s:width="30" s:height="20" id="cell_clock">
|
||||||
|
<text x="15" y="-4" class="nodelabel cell_clock" s:attribute="ref">clock</text>
|
||||||
|
<s:alias val="$_inputExt_"/>
|
||||||
|
<path d="M0,0 L0,20 L15,20 L30,10 L15,0 Z" class="cell_clock"/>
|
||||||
|
<g s:x="28" s:y="10" s:pid="Y"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="inputExt" transform="translate(157,381.5)" s:width="30" s:height="20" id="cell_data_in">
|
||||||
|
<text x="15" y="-4" class="nodelabel cell_data_in" s:attribute="ref">data_in</text>
|
||||||
|
<s:alias val="$_inputExt_"/>
|
||||||
|
<path d="M0,0 L0,20 L15,20 L30,10 L15,0 Z" class="cell_data_in"/>
|
||||||
|
<g s:x="28" s:y="10" s:pid="Y"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="inputExt" transform="translate(12,809)" s:width="30" s:height="20" id="cell_up">
|
||||||
|
<text x="15" y="-4" class="nodelabel cell_up" s:attribute="ref">up</text>
|
||||||
|
<s:alias val="$_inputExt_"/>
|
||||||
|
<path d="M0,0 L0,20 L15,20 L30,10 L15,0 Z" class="cell_up"/>
|
||||||
|
<g s:x="28" s:y="10" s:pid="Y"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="inputExt" transform="translate(12,564)" s:width="30" s:height="20" id="cell_down">
|
||||||
|
<text x="15" y="-4" class="nodelabel cell_down" s:attribute="ref">down</text>
|
||||||
|
<s:alias val="$_inputExt_"/>
|
||||||
|
<path d="M0,0 L0,20 L15,20 L30,10 L15,0 Z" class="cell_down"/>
|
||||||
|
<g s:x="28" s:y="10" s:pid="Y"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="outputExt" transform="translate(497,816.5)" s:width="30" s:height="20" id="cell_carry_out">
|
||||||
|
<text x="15" y="-4" class="nodelabel cell_carry_out" s:attribute="ref">carry_out</text>
|
||||||
|
<s:alias val="$_outputExt_"/>
|
||||||
|
<path d="M30,0 L30,20 L15,20 L0,10 L15,0 Z" class="cell_carry_out"/>
|
||||||
|
<g s:x="0" s:y="10" s:pid="A"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="outputExt" transform="translate(497,22)" s:width="30" s:height="20" id="cell_borrow_out">
|
||||||
|
<text x="15" y="-4" class="nodelabel cell_borrow_out" s:attribute="ref">borrow_out</text>
|
||||||
|
<s:alias val="$_outputExt_"/>
|
||||||
|
<path d="M30,0 L30,20 L15,20 L0,10 L15,0 Z" class="cell_borrow_out"/>
|
||||||
|
<g s:x="0" s:y="10" s:pid="A"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="outputExt" transform="translate(497,302)" s:width="30" s:height="20" id="cell_count_out">
|
||||||
|
<text x="15" y="-4" class="nodelabel cell_count_out" s:attribute="ref">count_out</text>
|
||||||
|
<s:alias val="$_outputExt_"/>
|
||||||
|
<path d="M30,0 L30,20 L15,20 L0,10 L15,0 Z" class="cell_count_out"/>
|
||||||
|
<g s:x="0" s:y="10" s:pid="A"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="outputExt" transform="translate(497,162)" s:width="30" s:height="20" id="cell_parity_out">
|
||||||
|
<text x="15" y="-4" class="nodelabel cell_parity_out" s:attribute="ref">parity_out</text>
|
||||||
|
<s:alias val="$_outputExt_"/>
|
||||||
|
<path d="M30,0 L30,20 L15,20 L0,10 L15,0 Z" class="cell_parity_out"/>
|
||||||
|
<g s:x="0" s:y="10" s:pid="A"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="constant" transform="translate(12,709.5)" s:width="30" s:height="20" id="cell_11">
|
||||||
|
<text x="15" y="-4" class="nodelabel cell_11" s:attribute="ref">11</text>
|
||||||
|
<s:alias val="$_constant_"/>
|
||||||
|
<rect width="30" height="20" class="cell_11"/>
|
||||||
|
<g s:x="30" s:y="10" s:pid="Y"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="constant" transform="translate(92,648.5)" s:width="30" s:height="20" id="cell_01">
|
||||||
|
<text x="15" y="-4" class="nodelabel cell_01" s:attribute="ref">01</text>
|
||||||
|
<s:alias val="$_constant_"/>
|
||||||
|
<rect width="30" height="20" class="cell_01"/>
|
||||||
|
<g s:x="30" s:y="10" s:pid="Y"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="constant" transform="translate(92,506.5)" s:width="30" s:height="20" id="cell_10">
|
||||||
|
<text x="15" y="-4" class="nodelabel cell_10" s:attribute="ref">10</text>
|
||||||
|
<s:alias val="$_constant_"/>
|
||||||
|
<rect width="30" height="20" class="cell_10"/>
|
||||||
|
<g s:x="30" s:y="10" s:pid="Y"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="constant" transform="translate(12,84.5)" s:width="30" s:height="20" id="cell_101">
|
||||||
|
<text x="15" y="-4" class="nodelabel cell_101" s:attribute="ref">101</text>
|
||||||
|
<s:alias val="$_constant_"/>
|
||||||
|
<rect width="30" height="20" class="cell_101"/>
|
||||||
|
<g s:x="30" s:y="10" s:pid="Y"/>
|
||||||
|
</g>
|
||||||
|
<g s:type="join" transform="translate(103,563.5)" s:width="4" s:height="40" id="cell_$join$,13,12,">
|
||||||
|
<rect width="5" height="40" class="splitjoinBody" s:generic="body"/>
|
||||||
|
<s:alias val="$_join_"/>
|
||||||
|
<g s:x="5" s:y="20" s:pid="out"/>
|
||||||
|
<g transform="translate(0,10)" s:x="0" s:y="10" s:pid="in0">
|
||||||
|
<text x="-3" y="-4" class="inputPortLabel">0</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(0,30)" s:x="0" s:y="10" s:pid="in0">
|
||||||
|
<text x="-3" y="-4" class="inputPortLabel">1</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g s:type="join" transform="translate(268,301.5)" s:width="4" s:height="40" id="cell_$join$,16,17,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,34,59,60,61,62,63,64,65,66,67,3,4,5,6,7,8,9,10,11,">
|
||||||
|
<rect width="5" height="80" class="splitjoinBody" s:generic="body"/>
|
||||||
|
<s:alias val="$_join_"/>
|
||||||
|
<g s:x="5" s:y="20" s:pid="out"/>
|
||||||
|
<g transform="translate(0,10)" s:x="0" s:y="10" s:pid="in0">
|
||||||
|
<text x="-3" y="-4" class="inputPortLabel">0:8</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(0,30)" s:x="0" s:y="10" s:pid="in0">
|
||||||
|
<text x="-3" y="-4" class="inputPortLabel">9:17</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(0,50)" s:x="0" s:y="10" s:pid="in0">
|
||||||
|
<text x="-3" y="-4" class="inputPortLabel">18:26</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(0,70)" s:x="0" s:y="10" s:pid="in0">
|
||||||
|
<text x="-3" y="-4" class="inputPortLabel">27:35</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g s:type="join" transform="translate(263.75,438.5)" s:width="4" s:height="40" id="cell_$join$,89,90,87,88,">
|
||||||
|
<rect width="5" height="80" class="splitjoinBody" s:generic="body"/>
|
||||||
|
<s:alias val="$_join_"/>
|
||||||
|
<g s:x="5" s:y="20" s:pid="out"/>
|
||||||
|
<g transform="translate(0,10)" s:x="0" s:y="10" s:pid="in0">
|
||||||
|
<text x="-3" y="-4" class="inputPortLabel">0</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(0,30)" s:x="0" s:y="10" s:pid="in0">
|
||||||
|
<text x="-3" y="-4" class="inputPortLabel">1</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(0,50)" s:x="0" s:y="10" s:pid="in0">
|
||||||
|
<text x="-3" y="-4" class="inputPortLabel">2</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(0,70)" s:x="0" s:y="10" s:pid="in0">
|
||||||
|
<text x="-3" y="-4" class="inputPortLabel">3</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g s:type="split" transform="translate(177.66666666666666,691.5)" s:width="5" s:height="40" id="cell_$split$,26,27,28,29,30,31,32,33,34,35,">
|
||||||
|
<rect width="5" height="40" class="splitjoinBody" s:generic="body"/>
|
||||||
|
<s:alias val="$_split_"/>
|
||||||
|
<g s:x="0" s:y="20" s:pid="in"/>
|
||||||
|
<g transform="translate(4,10)" s:x="4" s:y="10" s:pid="out0">
|
||||||
|
<text x="5" y="-4">9</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(4,30)" s:x="4" s:y="10" s:pid="out0">
|
||||||
|
<text x="5" y="-4">0:8</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g s:type="split" transform="translate(177.66666666666666,100)" s:width="5" s:height="40" id="cell_$split$,59,60,61,62,63,64,65,66,67,37,">
|
||||||
|
<rect width="5" height="40" class="splitjoinBody" s:generic="body"/>
|
||||||
|
<s:alias val="$_split_"/>
|
||||||
|
<g s:x="0" s:y="20" s:pid="in"/>
|
||||||
|
<g transform="translate(4,10)" s:x="4" s:y="10" s:pid="out0">
|
||||||
|
<text x="5" y="-4">9</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(4,30)" s:x="4" s:y="10" s:pid="out0">
|
||||||
|
<text x="5" y="-4">0:8</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<line x1="462" x2="472" y1="312" y2="312" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<line x1="472" x2="472" y1="312" y2="678.5" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<line x1="472" x2="82" y1="678.5" y2="678.5" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<line x1="82" x2="82" y1="678.5" y2="704.5" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<line x1="82" x2="97.66666666666667" y1="704.5" y2="704.5" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<line x1="462" x2="472" y1="312" y2="312" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<line x1="472" x2="472" y1="312" y2="278" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<line x1="472" x2="82" y1="278" y2="278" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<line x1="82" x2="82" y1="278" y2="79.5" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<circle cx="472" cy="312" r="2" style="fill:#000" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<line x1="82" x2="97.66666666666667" y1="79.5" y2="79.5" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<line x1="462" x2="497" y1="312" y2="312" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<line x1="462" x2="472" y1="312" y2="312" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<line x1="472" x2="472" y1="312" y2="278" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<line x1="472" x2="349" y1="278" y2="278" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<line x1="349" x2="349" y1="278" y2="678.5" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<line x1="349" x2="219" y1="678.5" y2="678.5" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<line x1="219" x2="219" y1="678.5" y2="312" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<circle cx="219" cy="678.5" r="2" style="fill:#000" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<circle cx="349" cy="678.5" r="2" style="fill:#000" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<circle cx="349" cy="278" r="2" style="fill:#000" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<line x1="219" x2="268" y1="312" y2="312" class="net_16,17,18,19,20,21,22,23,24"/>
|
||||||
|
<line x1="42" x2="97.66666666666667" y1="719.5" y2="719.5" class="net_91,92"/>
|
||||||
|
<line x1="42" x2="62" y1="719.5" y2="719.5" class="net_91,92"/>
|
||||||
|
<line x1="62" x2="62" y1="719.5" y2="456.5" class="net_91,92"/>
|
||||||
|
<circle cx="62" cy="719.5" r="2" style="fill:#000" class="net_91,92"/>
|
||||||
|
<line x1="62" x2="165.66666666666666" y1="456.5" y2="456.5" class="net_91,92"/>
|
||||||
|
<line x1="40" x2="365" y1="819" y2="819" class="net_12"/>
|
||||||
|
<line x1="40" x2="72" y1="819" y2="819" class="net_12"/>
|
||||||
|
<line x1="72" x2="72" y1="819" y2="594" class="net_12"/>
|
||||||
|
<circle cx="72" cy="819" r="2" style="fill:#000" class="net_12"/>
|
||||||
|
<line x1="72" x2="103" y1="594" y2="594" class="net_12"/>
|
||||||
|
<line x1="182.66666666666666" x2="239" y1="702" y2="702" class="net_35"/>
|
||||||
|
<line x1="239" x2="239" y1="702" y2="834" class="net_35"/>
|
||||||
|
<line x1="239" x2="365" y1="834" y2="834" class="net_35"/>
|
||||||
|
<line x1="40" x2="52" y1="574" y2="574" class="net_13"/>
|
||||||
|
<line x1="52" x2="52" y1="574" y2="24.5" class="net_13"/>
|
||||||
|
<circle cx="52" cy="574" r="2" style="fill:#000" class="net_13"/>
|
||||||
|
<line x1="52" x2="365" y1="24.5" y2="24.5" class="net_13"/>
|
||||||
|
<line x1="40" x2="103" y1="574" y2="574" class="net_13"/>
|
||||||
|
<line x1="182.66666666666666" x2="209" y1="110.5" y2="110.5" class="net_37"/>
|
||||||
|
<line x1="209" x2="209" y1="110.5" y2="39.5" class="net_37"/>
|
||||||
|
<line x1="209" x2="365" y1="39.5" y2="39.5" class="net_37"/>
|
||||||
|
<line x1="395" x2="407" y1="258" y2="258" class="net_2"/>
|
||||||
|
<line x1="407" x2="407" y1="258" y2="332" class="net_2"/>
|
||||||
|
<circle cx="407" cy="258" r="2" style="fill:#000" class="net_2"/>
|
||||||
|
<circle cx="407" cy="332" r="2" style="fill:#000" class="net_2"/>
|
||||||
|
<line x1="407" x2="432" y1="332" y2="332" class="net_2"/>
|
||||||
|
<line x1="395" x2="407" y1="258" y2="258" class="net_2"/>
|
||||||
|
<line x1="407" x2="407" y1="258" y2="846.5" class="net_2"/>
|
||||||
|
<line x1="407" x2="432" y1="846.5" y2="846.5" class="net_2"/>
|
||||||
|
<line x1="395" x2="407" y1="258" y2="258" class="net_2"/>
|
||||||
|
<line x1="407" x2="407" y1="258" y2="52" class="net_2"/>
|
||||||
|
<line x1="407" x2="432" y1="52" y2="52" class="net_2"/>
|
||||||
|
<line x1="395" x2="407" y1="258" y2="258" class="net_2"/>
|
||||||
|
<line x1="407" x2="407" y1="258" y2="192" class="net_2"/>
|
||||||
|
<circle cx="407" cy="192" r="2" style="fill:#000" class="net_2"/>
|
||||||
|
<line x1="407" x2="432" y1="192" y2="192" class="net_2"/>
|
||||||
|
<line x1="395" x2="407" y1="258" y2="258" class="net_2"/>
|
||||||
|
<line x1="407" x2="407" y1="258" y2="761.5" class="net_2"/>
|
||||||
|
<circle cx="407" cy="761.5" r="2" style="fill:#000" class="net_2"/>
|
||||||
|
<line x1="407" x2="497" y1="761.5" y2="761.5" class="net_2"/>
|
||||||
|
<line x1="395" x2="407" y1="258" y2="258" class="net_2"/>
|
||||||
|
<line x1="407" x2="407" y1="258" y2="107" class="net_2"/>
|
||||||
|
<circle cx="407" cy="107" r="2" style="fill:#000" class="net_2"/>
|
||||||
|
<line x1="407" x2="497" y1="107" y2="107" class="net_2"/>
|
||||||
|
<line x1="395" x2="472" y1="258" y2="258" class="net_2"/>
|
||||||
|
<line x1="472" x2="472" y1="258" y2="247" class="net_2"/>
|
||||||
|
<line x1="472" x2="497" y1="247" y2="247" class="net_2"/>
|
||||||
|
<line x1="329" x2="432" y1="312" y2="312" class="net_39,40,41,42,43,44,45,46,47"/>
|
||||||
|
<line x1="329" x2="339" y1="312" y2="312" class="net_39,40,41,42,43,44,45,46,47"/>
|
||||||
|
<line x1="339" x2="339" y1="312" y2="227" class="net_39,40,41,42,43,44,45,46,47"/>
|
||||||
|
<circle cx="339" cy="312" r="2" style="fill:#000" class="net_39,40,41,42,43,44,45,46,47"/>
|
||||||
|
<circle cx="339" cy="227" r="2" style="fill:#000" class="net_39,40,41,42,43,44,45,46,47"/>
|
||||||
|
<line x1="339" x2="497" y1="227" y2="227" class="net_39,40,41,42,43,44,45,46,47"/>
|
||||||
|
<line x1="329" x2="339" y1="312" y2="312" class="net_39,40,41,42,43,44,45,46,47"/>
|
||||||
|
<line x1="339" x2="339" y1="312" y2="164.5" class="net_39,40,41,42,43,44,45,46,47"/>
|
||||||
|
<line x1="339" x2="367" y1="164.5" y2="164.5" class="net_39,40,41,42,43,44,45,46,47"/>
|
||||||
|
<line x1="395" x2="432" y1="826.5" y2="826.5" class="net_36"/>
|
||||||
|
<line x1="395" x2="432" y1="32" y2="32" class="net_38"/>
|
||||||
|
<line x1="397" x2="432" y1="172" y2="172" class="net_48"/>
|
||||||
|
<line x1="119.66666666666667" x2="132" y1="712" y2="712" class="net_26,27,28,29,30,31,32,33,34,35"/>
|
||||||
|
<line x1="132" x2="132" y1="712" y2="741.5" class="net_26,27,28,29,30,31,32,33,34,35"/>
|
||||||
|
<circle cx="132" cy="712" r="2" style="fill:#000" class="net_26,27,28,29,30,31,32,33,34,35"/>
|
||||||
|
<line x1="132" x2="497" y1="741.5" y2="741.5" class="net_26,27,28,29,30,31,32,33,34,35"/>
|
||||||
|
<line x1="119.66666666666667" x2="177.66666666666666" y1="712" y2="712" class="net_26,27,28,29,30,31,32,33,34,35"/>
|
||||||
|
<line x1="119.66666666666667" x2="497" y1="87" y2="87" class="net_59,60,61,62,63,64,65,66,67,37"/>
|
||||||
|
<line x1="119.66666666666667" x2="132" y1="87" y2="87" class="net_59,60,61,62,63,64,65,66,67,37"/>
|
||||||
|
<line x1="132" x2="132" y1="87" y2="120.5" class="net_59,60,61,62,63,64,65,66,67,37"/>
|
||||||
|
<circle cx="132" cy="87" r="2" style="fill:#000" class="net_59,60,61,62,63,64,65,66,67,37"/>
|
||||||
|
<line x1="132" x2="177.66666666666666" y1="120.5" y2="120.5" class="net_59,60,61,62,63,64,65,66,67,37"/>
|
||||||
|
<line x1="109" x2="165.66666666666666" y1="584" y2="584" class="net_13,12"/>
|
||||||
|
<line x1="109" x2="142" y1="584" y2="584" class="net_13,12"/>
|
||||||
|
<line x1="142" x2="142" y1="584" y2="649" class="net_13,12"/>
|
||||||
|
<circle cx="142" cy="584" r="2" style="fill:#000" class="net_13,12"/>
|
||||||
|
<line x1="142" x2="163" y1="649" y2="649" class="net_13,12"/>
|
||||||
|
<line x1="109" x2="142" y1="584" y2="584" class="net_13,12"/>
|
||||||
|
<line x1="142" x2="142" y1="584" y2="441.5" class="net_13,12"/>
|
||||||
|
<line x1="142" x2="165.66666666666666" y1="441.5" y2="441.5" class="net_13,12"/>
|
||||||
|
<line x1="109" x2="142" y1="584" y2="584" class="net_13,12"/>
|
||||||
|
<line x1="142" x2="142" y1="584" y2="501.5" class="net_13,12"/>
|
||||||
|
<circle cx="142" cy="501.5" r="2" style="fill:#000" class="net_13,12"/>
|
||||||
|
<line x1="142" x2="165.66666666666666" y1="501.5" y2="501.5" class="net_13,12"/>
|
||||||
|
<line x1="122" x2="132" y1="658.5" y2="658.5" class="net_93,94"/>
|
||||||
|
<line x1="132" x2="132" y1="658.5" y2="599" class="net_93,94"/>
|
||||||
|
<line x1="132" x2="165.66666666666666" y1="599" y2="599" class="net_93,94"/>
|
||||||
|
<line x1="274" x2="309" y1="322" y2="322" class="net_16,17,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,34,59,60,61,62,63,64,65,66,67,3,4,5,6,7,8,9,10,11"/>
|
||||||
|
<line x1="269.75" x2="319" y1="459" y2="459" class="net_89,90,87,88"/>
|
||||||
|
<line x1="319" x2="319" y1="459" y2="327" class="net_89,90,87,88"/>
|
||||||
|
<line x1="122" x2="165.66666666666666" y1="516.5" y2="516.5" class="net_97,98"/>
|
||||||
|
<line x1="42" x2="97.66666666666667" y1="94.5" y2="94.5" class="net_99,100,101"/>
|
||||||
|
<line x1="462" x2="497" y1="826.5" y2="826.5" class="net_14"/>
|
||||||
|
<line x1="462" x2="497" y1="32" y2="32" class="net_15"/>
|
||||||
|
<line x1="462" x2="497" y1="172" y2="172" class="net_25"/>
|
||||||
|
<line x1="182.66666666666666" x2="229" y1="722" y2="722" class="net_26,27,28,29,30,31,32,33,34"/>
|
||||||
|
<line x1="229" x2="229" y1="722" y2="332" class="net_26,27,28,29,30,31,32,33,34"/>
|
||||||
|
<line x1="229" x2="268" y1="332" y2="332" class="net_26,27,28,29,30,31,32,33,34"/>
|
||||||
|
<line x1="182.66666666666666" x2="239" y1="130.5" y2="130.5" class="net_59,60,61,62,63,64,65,66,67"/>
|
||||||
|
<line x1="239" x2="239" y1="130.5" y2="352" class="net_59,60,61,62,63,64,65,66,67"/>
|
||||||
|
<line x1="239" x2="268" y1="352" y2="352" class="net_59,60,61,62,63,64,65,66,67"/>
|
||||||
|
<line x1="185" x2="268.5" y1="391.5" y2="391.5" class="net_3,4,5,6,7,8,9,10,11"/>
|
||||||
|
<line x1="268.5" x2="268.5" y1="391.5" y2="372.5" class="net_3,4,5,6,7,8,9,10,11"/>
|
||||||
|
<line x1="187.66666666666666" x2="263.75" y1="449" y2="449" class="net_89"/>
|
||||||
|
<line x1="187.66666666666666" x2="209" y1="509" y2="509" class="net_90"/>
|
||||||
|
<line x1="209" x2="209" y1="509" y2="469" class="net_90"/>
|
||||||
|
<line x1="209" x2="263.75" y1="469" y2="469" class="net_90"/>
|
||||||
|
<line x1="187.66666666666666" x2="239" y1="591.5" y2="591.5" class="net_87"/>
|
||||||
|
<line x1="239" x2="239" y1="591.5" y2="489" class="net_87"/>
|
||||||
|
<line x1="239" x2="263.75" y1="489" y2="489" class="net_87"/>
|
||||||
|
<line x1="188" x2="264.25" y1="649" y2="649" class="net_88"/>
|
||||||
|
<line x1="264.25" x2="264.25" y1="649" y2="509.5" class="net_88"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 25 KiB |
62
package-lock.json
generated
62
package-lock.json
generated
@ -8,6 +8,7 @@
|
|||||||
"name": "digital-netlist-render",
|
"name": "digital-netlist-render",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"axios": "^1.7.9",
|
||||||
"core-js": "^3.8.3",
|
"core-js": "^3.8.3",
|
||||||
"d3": "^7.9.0",
|
"d3": "^7.9.0",
|
||||||
"d3-drag": "^3.0.0",
|
"d3-drag": "^3.0.0",
|
||||||
@ -15,6 +16,7 @@
|
|||||||
"elkjs": "^0.9.3",
|
"elkjs": "^0.9.3",
|
||||||
"fflate": "^0.8.2",
|
"fflate": "^0.8.2",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
|
"pako": "^2.1.0",
|
||||||
"vue": "^3.2.13",
|
"vue": "^3.2.13",
|
||||||
"vue-i18n": "10.0.5",
|
"vue-i18n": "10.0.5",
|
||||||
"web-worker": "^1.3.0"
|
"web-worker": "^1.3.0"
|
||||||
@ -3498,6 +3500,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
|
||||||
"integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
|
"integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/asynckit": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||||
|
},
|
||||||
"node_modules/at-least-node": {
|
"node_modules/at-least-node": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/at-least-node/-/at-least-node-1.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/at-least-node/-/at-least-node-1.0.0.tgz",
|
||||||
@ -3544,6 +3551,16 @@
|
|||||||
"postcss": "^8.1.0"
|
"postcss": "^8.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/axios": {
|
||||||
|
"version": "1.7.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
|
||||||
|
"integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
|
||||||
|
"dependencies": {
|
||||||
|
"follow-redirects": "^1.15.6",
|
||||||
|
"form-data": "^4.0.0",
|
||||||
|
"proxy-from-env": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/babel-loader": {
|
"node_modules/babel-loader": {
|
||||||
"version": "8.4.1",
|
"version": "8.4.1",
|
||||||
"resolved": "https://registry.npmmirror.com/babel-loader/-/babel-loader-8.4.1.tgz",
|
"resolved": "https://registry.npmmirror.com/babel-loader/-/babel-loader-8.4.1.tgz",
|
||||||
@ -4174,6 +4191,17 @@
|
|||||||
"integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
|
"integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/combined-stream": {
|
||||||
|
"version": "1.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
|
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||||
|
"dependencies": {
|
||||||
|
"delayed-stream": "~1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/commander": {
|
"node_modules/commander": {
|
||||||
"version": "8.3.0",
|
"version": "8.3.0",
|
||||||
"resolved": "https://registry.npmmirror.com/commander/-/commander-8.3.0.tgz",
|
"resolved": "https://registry.npmmirror.com/commander/-/commander-8.3.0.tgz",
|
||||||
@ -5343,6 +5371,14 @@
|
|||||||
"robust-predicates": "^3.0.2"
|
"robust-predicates": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/delayed-stream": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/depd": {
|
"node_modules/depd": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz",
|
||||||
@ -6571,7 +6607,6 @@
|
|||||||
"version": "1.15.9",
|
"version": "1.15.9",
|
||||||
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz",
|
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz",
|
||||||
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
|
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@ -6587,6 +6622,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/form-data": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
|
||||||
|
"dependencies": {
|
||||||
|
"asynckit": "^0.4.0",
|
||||||
|
"combined-stream": "^1.0.8",
|
||||||
|
"mime-types": "^2.1.12"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/forwarded": {
|
"node_modules/forwarded": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz",
|
"resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz",
|
||||||
@ -8097,7 +8145,6 @@
|
|||||||
"version": "1.52.0",
|
"version": "1.52.0",
|
||||||
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
|
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
|
||||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
@ -8106,7 +8153,6 @@
|
|||||||
"version": "2.1.35",
|
"version": "2.1.35",
|
||||||
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
|
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
|
||||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"mime-db": "1.52.0"
|
"mime-db": "1.52.0"
|
||||||
},
|
},
|
||||||
@ -8723,6 +8769,11 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pako": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="
|
||||||
|
},
|
||||||
"node_modules/param-case": {
|
"node_modules/param-case": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmmirror.com/param-case/-/param-case-3.0.4.tgz",
|
"resolved": "https://registry.npmmirror.com/param-case/-/param-case-3.0.4.tgz",
|
||||||
@ -9641,6 +9692,11 @@
|
|||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/proxy-from-env": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||||
|
},
|
||||||
"node_modules/pseudomap": {
|
"node_modules/pseudomap": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmmirror.com/pseudomap/-/pseudomap-1.0.2.tgz",
|
"resolved": "https://registry.npmmirror.com/pseudomap/-/pseudomap-1.0.2.tgz",
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"axios": "^1.7.9",
|
||||||
"core-js": "^3.8.3",
|
"core-js": "^3.8.3",
|
||||||
"d3": "^7.9.0",
|
"d3": "^7.9.0",
|
||||||
"d3-drag": "^3.0.0",
|
"d3-drag": "^3.0.0",
|
||||||
@ -15,6 +16,7 @@
|
|||||||
"elkjs": "^0.9.3",
|
"elkjs": "^0.9.3",
|
||||||
"fflate": "^0.8.2",
|
"fflate": "^0.8.2",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
|
"pako": "^2.1.0",
|
||||||
"vue": "^3.2.13",
|
"vue": "^3.2.13",
|
||||||
"vue-i18n": "10.0.5",
|
"vue-i18n": "10.0.5",
|
||||||
"web-worker": "^1.3.0"
|
"web-worker": "^1.3.0"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: "iconfont"; /* Project id 4797805 */
|
font-family: "iconfont"; /* Project id 4797805 */
|
||||||
src: url('iconfont.woff2?t=1735470843861') format('woff2');
|
src: url('iconfont.woff2?t=1735991360293') format('woff2');
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconfont {
|
.iconfont {
|
||||||
@ -11,6 +11,22 @@
|
|||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-link:before {
|
||||||
|
content: "\e6fa";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-Listinterface:before {
|
||||||
|
content: "\e66b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-info-port:before {
|
||||||
|
content: "\f2e1";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-sanjiao_fill-:before {
|
||||||
|
content: "\e6a0";
|
||||||
|
}
|
||||||
|
|
||||||
.icon-memory-chip:before {
|
.icon-memory-chip:before {
|
||||||
content: "\e600";
|
content: "\e600";
|
||||||
}
|
}
|
||||||
@ -243,3 +259,7 @@
|
|||||||
content: "\e693";
|
content: "\e693";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-info-module:before {
|
||||||
|
content: "\f2e2";
|
||||||
|
}
|
||||||
|
|
||||||
|
Binary file not shown.
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.readNetFile = async () => {
|
window.readNetFile = async () => {
|
||||||
const inputVcdFile = 'IF_ID.json';
|
const inputVcdFile = 'full_adder.json';
|
||||||
const skin = 'dide.skin';
|
const skin = 'dide.skin';
|
||||||
const r1 = await fetch(inputVcdFile);
|
const r1 = await fetch(inputVcdFile);
|
||||||
const r2 = await fetch(skin);
|
const r2 = await fetch(skin);
|
||||||
@ -23,8 +23,7 @@
|
|||||||
const skinBinary = await r2.arrayBuffer();
|
const skinBinary = await r2.arrayBuffer();
|
||||||
return [ netJson, skinBinary ];
|
return [ netJson, skinBinary ];
|
||||||
}
|
}
|
||||||
window.moduleName = 'IF_ID';
|
window.moduleName = 'full_adder';
|
||||||
// window.avoidWasm = 'avoid.wasm';
|
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -13,13 +13,24 @@ exclude_folders = [
|
|||||||
|
|
||||||
os.system('npm run build')
|
os.system('npm run build')
|
||||||
for file in os.listdir('dist'):
|
for file in os.listdir('dist'):
|
||||||
if file in exclude_files or file.endswith('.json'):
|
if file in exclude_files or file.endswith('.json') or file.endswith('.v'):
|
||||||
os.remove('dist/' + file)
|
os.remove('dist/' + file)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
with open('./dist/index.html', 'r', encoding='utf-8') as fp:
|
with open('./dist/index.html', 'r', encoding='utf-8') as fp:
|
||||||
html = fp.read()
|
html = fp.read()
|
||||||
|
index = html.index('</script>')
|
||||||
|
html = html[:index] + '\n' + html[index:]
|
||||||
|
|
||||||
|
new_html = []
|
||||||
|
for line in html.split('\n'):
|
||||||
|
if 'const inputVcdFile =' in line:
|
||||||
|
new_html.append("const inputVcdFile = 'test.json';")
|
||||||
|
elif 'window.moduleName' in line:
|
||||||
|
new_html.append("window.moduleName = 'test.module';")
|
||||||
|
else:
|
||||||
|
new_html.append(line.strip())
|
||||||
|
|
||||||
with open('./dist/index.html', 'w', encoding='utf-8') as fp:
|
with open('./dist/index.html', 'w', encoding='utf-8') as fp:
|
||||||
fp.write(html)
|
fp.write('\n'.join(new_html))
|
@ -1,4 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<!-- 顶部工具栏 -->
|
||||||
|
<ToolBar></ToolBar>
|
||||||
<!-- 渲染区域 -->
|
<!-- 渲染区域 -->
|
||||||
<Render></Render>
|
<Render></Render>
|
||||||
<!-- 右侧工具合集 -->
|
<!-- 右侧工具合集 -->
|
||||||
@ -7,6 +9,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import Render from '@/components/render';
|
import Render from '@/components/render';
|
||||||
|
import ToolBar from '@/components/toolbar';
|
||||||
import RightNav from '@/components/right-nav.vue';
|
import RightNav from '@/components/right-nav.vue';
|
||||||
import { onMounted, watch } from 'vue';
|
import { onMounted, watch } from 'vue';
|
||||||
import { setDefaultCss } from './hook/css';
|
import { setDefaultCss } from './hook/css';
|
||||||
|
81
src/api/definition.js
Normal file
81
src/api/definition.js
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import { globalLookup } from "@/hook/global";
|
||||||
|
import { pinkLog } from "@/hook/utils";
|
||||||
|
import { mode, vscode } from ".";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} definition
|
||||||
|
*/
|
||||||
|
export async function gotoDefinition(definition) {
|
||||||
|
const defs = processDefinition(definition);
|
||||||
|
if (mode === 'debug') {
|
||||||
|
const res = await axios.post('http://localhost:3000/netlist/goto-definition', { defs });
|
||||||
|
} else {
|
||||||
|
vscode.postMessage({
|
||||||
|
command: 'goto-definition',
|
||||||
|
data: { defs }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @typedef FileRange
|
||||||
|
* @property {string} path
|
||||||
|
* @property {import("@/hook/jsdoc").Range} [range]
|
||||||
|
*
|
||||||
|
* @param {string | undefined} definition
|
||||||
|
* @returns {FileRange[]}
|
||||||
|
*/
|
||||||
|
function processDefinition(definition) {
|
||||||
|
if (typeof definition !== 'string') {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if (definition.includes('|')) {
|
||||||
|
const defs = [];
|
||||||
|
for (const def of definition.split('|')) {
|
||||||
|
defs.push(...processDefinition(def));
|
||||||
|
}
|
||||||
|
return defs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (definition.includes(':')) {
|
||||||
|
const [path, rangeString] = definition.split(':');
|
||||||
|
const [startString, endString] = rangeString.split('-');
|
||||||
|
const [startLine, startCharacter] = startString.split('.');
|
||||||
|
const [endLine, endCharacter] = endString.split('.');
|
||||||
|
const range = {
|
||||||
|
start: {
|
||||||
|
line: parseRangeInt(startLine),
|
||||||
|
character: parseRangeInt(startCharacter)
|
||||||
|
},
|
||||||
|
end: {
|
||||||
|
line: parseRangeInt(endLine),
|
||||||
|
character: parseRangeInt(endCharacter)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return [
|
||||||
|
{ path, range }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
path: definition,
|
||||||
|
range: undefined
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseRangeInt(s) {
|
||||||
|
const i = parseInt(s);
|
||||||
|
if (i > 0) {
|
||||||
|
// 因为 yosys 是 one index 的,但是 vscode 内部跳转都是 zero index
|
||||||
|
return i - 1;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
161
src/api/index.js
Normal file
161
src/api/index.js
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
import { colorManager } from "@/components/setting/color";
|
||||||
|
import { increaseBrightness, isLightColorTheme, lowerBrightness, MacroColor, parseColor } from "@/hook/color";
|
||||||
|
import { globalLookup } from "@/hook/global";
|
||||||
|
import { pinkLog } from "@/hook/utils";
|
||||||
|
import axios from 'axios';
|
||||||
|
import pako from 'pako';
|
||||||
|
|
||||||
|
export const mode = window.acquireVsCodeApi === undefined ? 'debug' : 'release';
|
||||||
|
pinkLog('digital-netlist-render mode: ' + mode);
|
||||||
|
|
||||||
|
export let vscode = window.acquireVsCodeApi === undefined ? undefined : acquireVsCodeApi();
|
||||||
|
|
||||||
|
function getColorFromMacro(rootStyles, optionName, theme, isLight) {
|
||||||
|
if (theme === 'dark') {
|
||||||
|
return rootStyles.getPropertyValue(optionName);
|
||||||
|
} else {
|
||||||
|
// 亮色模式,pdf 类型的导出一定是这个颜色,
|
||||||
|
// 此时需要对特殊的几类颜色进行处理
|
||||||
|
// 如果此时的颜色主题本来就是偏亮色的,直接返回如下几个的颜色
|
||||||
|
|
||||||
|
switch (optionName) {
|
||||||
|
case '--foreground':
|
||||||
|
case '--wire-color':
|
||||||
|
case '--cross-dot-color':
|
||||||
|
if (!isLight) {
|
||||||
|
return '#2D323B';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const color = rootStyles.getPropertyValue(optionName);
|
||||||
|
if (!color) {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
const rgb = parseColor(color);
|
||||||
|
|
||||||
|
const { r, g, b } = increaseBrightness(rgb, 10);
|
||||||
|
return `rgb(${r}, ${g}, ${b})`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {import("@/hook/color").GetColorOption} option
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function makeStyleString(option = {}) {
|
||||||
|
// 加入全局颜色宏
|
||||||
|
const colorMacros = [];
|
||||||
|
const macroColor = new MacroColor({
|
||||||
|
BaseForegroundColorMacroName: '--foreground',
|
||||||
|
BaseBackgroundColorMacroName: '--background'
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const item of colorManager.generals) {
|
||||||
|
const colorOption = `--${item.type}-color`;
|
||||||
|
const colorFillOption = `--${item.type}-fill-color`;
|
||||||
|
|
||||||
|
const color = macroColor.getColor(colorOption, option);
|
||||||
|
const colorFill = macroColor.getColor(colorFillOption, option);
|
||||||
|
if (color) {
|
||||||
|
colorMacros.push(`${colorOption}: ${color};`);
|
||||||
|
}
|
||||||
|
if (colorFill) {
|
||||||
|
colorMacros.push(`${colorFillOption}: ${colorFill};`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const item of colorManager.cells) {
|
||||||
|
const colorOption = `--${item.type}-color`;
|
||||||
|
const colorFillOption = `--${item.type}-fill-color`;
|
||||||
|
|
||||||
|
const color = macroColor.getColor(colorOption, option);
|
||||||
|
const colorFill = macroColor.getColor(colorFillOption, option);
|
||||||
|
if (color) {
|
||||||
|
colorMacros.push(`${colorOption}: ${color};`);
|
||||||
|
}
|
||||||
|
if (colorFill) {
|
||||||
|
colorMacros.push(`${colorFillOption}: ${colorFill};`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const globalSetting = [
|
||||||
|
'--foreground',
|
||||||
|
'--background',
|
||||||
|
'--main-color'
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const setting of globalSetting) {
|
||||||
|
const color = macroColor.getColor(setting, option);
|
||||||
|
if (color) {
|
||||||
|
colorMacros.push(`${setting}: ${color};`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const styleString = `:root {\n${colorMacros.join('\n')}\n}`;
|
||||||
|
return styleString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {import("@/hook/color").GetColorOption} option
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function getCompressedSvgBuffer(option = {}) {
|
||||||
|
const selection = globalLookup.netlistRender.selection;
|
||||||
|
const node = selection.node();
|
||||||
|
|
||||||
|
const styleString = makeStyleString(option);
|
||||||
|
const style = document.createElement('style');
|
||||||
|
style.textContent = styleString;
|
||||||
|
node.insertBefore(style, node.firstChild);
|
||||||
|
|
||||||
|
const serializer = new XMLSerializer();
|
||||||
|
const svgString = serializer.serializeToString(node);
|
||||||
|
const array = pako.gzip(svgString);
|
||||||
|
|
||||||
|
// 还原
|
||||||
|
const styleElement = node.querySelector('style');
|
||||||
|
if (styleElement) {
|
||||||
|
styleElement.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function saveAsSvg() {
|
||||||
|
const svgBuffer = getCompressedSvgBuffer();
|
||||||
|
const moduleName = globalLookup.topModuleName;
|
||||||
|
if (mode === 'debug') {
|
||||||
|
const res = await axios.post('http://localhost:3000/netlist/save-as-svg', { svgBuffer, moduleName });
|
||||||
|
if (res.success) {
|
||||||
|
pinkLog('成功保存到”' + res.savePath);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vscode.postMessage({
|
||||||
|
command: 'save-as-svg',
|
||||||
|
data: { svgBuffer, moduleName }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function saveAsPdf() {
|
||||||
|
const svgBuffer = getCompressedSvgBuffer({ mode: 'pdf' });
|
||||||
|
const moduleName = globalLookup.topModuleName;
|
||||||
|
|
||||||
|
const node = globalLookup.netlistRender.selection.node();
|
||||||
|
const width = node.getAttribute('width');
|
||||||
|
const height = node.getAttribute('height');
|
||||||
|
|
||||||
|
if (mode === 'debug') {
|
||||||
|
const res = await axios.post('http://localhost:3000/netlist/save-as-pdf', { svgBuffer, moduleName, width, height });
|
||||||
|
if (res.success) {
|
||||||
|
pinkLog('成功保存到”' + res.savePath);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vscode.postMessage({
|
||||||
|
command: 'save-as-pdf',
|
||||||
|
data: { svgBuffer, moduleName, width, height }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="about-wrapper">
|
<div class="about-wrapper" :style="aboutWrapper">
|
||||||
<div class="usermanual">
|
<div class="usermanual">
|
||||||
<h2>{{ t('usermanual') }}</h2>
|
<h2>{{ t('usermanual') }}</h2>
|
||||||
<div class="usermanual-item">
|
<div class="usermanual-item">
|
||||||
@ -39,8 +39,9 @@
|
|||||||
|
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent, computed } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { horizontalResizer } from '../right-nav';
|
||||||
|
|
||||||
defineComponent({ name: 'dide-about' });
|
defineComponent({ name: 'dide-about' });
|
||||||
|
|
||||||
@ -48,7 +49,9 @@ function goto(url) {
|
|||||||
window.open(url, '_blank');
|
window.open(url, '_blank');
|
||||||
}
|
}
|
||||||
|
|
||||||
const platform = navigator.platform;
|
const aboutWrapper = computed(() => ({
|
||||||
|
width: horizontalResizer.width - 10 + 'px'
|
||||||
|
}));
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
</script>
|
</script>
|
||||||
@ -56,6 +59,7 @@ const { t } = useI18n();
|
|||||||
<style>
|
<style>
|
||||||
.about-wrapper {
|
.about-wrapper {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
min-width: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.version-caption {
|
.version-caption {
|
||||||
|
@ -18,7 +18,7 @@ export const controlPanel = reactive({
|
|||||||
this.currentIndex = -1;
|
this.currentIndex = -1;
|
||||||
} else {
|
} else {
|
||||||
if (horizontalResizer.width < 5) {
|
if (horizontalResizer.width < 5) {
|
||||||
horizontalResizer.width = 362;
|
horizontalResizer.width = 410;
|
||||||
}
|
}
|
||||||
this.currentIndex = index;
|
this.currentIndex = index;
|
||||||
}
|
}
|
||||||
@ -29,7 +29,7 @@ export const controlPanel = reactive({
|
|||||||
export const horizontalResizer = reactive({
|
export const horizontalResizer = reactive({
|
||||||
active: false,
|
active: false,
|
||||||
hover: false,
|
hover: false,
|
||||||
width: 362,
|
width: 400,
|
||||||
mousedown() {
|
mousedown() {
|
||||||
this.active = true;
|
this.active = true;
|
||||||
document.addEventListener('mousemove', resize);
|
document.addEventListener('mousemove', resize);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="setting-wrapper">
|
<div class="setting-wrapper" :style="settingStyle">
|
||||||
<el-scrollbar height="98vh">
|
<el-scrollbar height="98vh">
|
||||||
<div class="setting-section">
|
<div class="setting-section">
|
||||||
<h2>{{ t('general-setting') }}</h2>
|
<h2>{{ t('general-setting') }}</h2>
|
||||||
@ -75,6 +75,7 @@
|
|||||||
{{ t('bold-multi-width-wire') }}
|
{{ t('bold-multi-width-wire') }}
|
||||||
</span>
|
</span>
|
||||||
<el-switch
|
<el-switch
|
||||||
|
@change="onBoldMultiWidthWireChange"
|
||||||
v-model="globalSetting.boldMultiWidthWire"
|
v-model="globalSetting.boldMultiWidthWire"
|
||||||
active-text="ON"
|
active-text="ON"
|
||||||
inactive-text="OFF"
|
inactive-text="OFF"
|
||||||
@ -130,6 +131,7 @@
|
|||||||
v-model="colorManager.generals[colorManager.currentGerneralIndex].color"
|
v-model="colorManager.generals[colorManager.currentGerneralIndex].color"
|
||||||
@change="onGeneralColorChange"
|
@change="onGeneralColorChange"
|
||||||
:predefine="predefinedColors"
|
:predefine="predefinedColors"
|
||||||
|
:teleported="false"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -156,22 +158,35 @@
|
|||||||
v-model="colorManager.cells[colorManager.currentCellIndex].color"
|
v-model="colorManager.cells[colorManager.currentCellIndex].color"
|
||||||
@change="onCellColorChange"
|
@change="onCellColorChange"
|
||||||
:predefine="predefinedColors"
|
:predefine="predefinedColors"
|
||||||
|
:teleported="false"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<div class="setting-option">
|
||||||
|
<span class="option-title">
|
||||||
|
{{ t('setting.pulsation-speed') }}
|
||||||
|
</span>
|
||||||
|
<span style="width: 200px;">
|
||||||
|
<el-slider v-model="globalSetting.pulsationSpeed" show-stops :min="1" :max="11" :step="2"/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
</div>
|
</div>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { globalSetting } from '@/hook/global';
|
import { globalLookup, globalSetting } from '@/hook/global';
|
||||||
import { reactive, defineComponent, watch, ref, onMounted } from 'vue';
|
import { computed, defineComponent, watch, ref, onMounted } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { languageSetting } from './language';
|
import { languageSetting } from './language';
|
||||||
import { crossDotStyle, onConnectStyleChange } from './cross-dot-style';
|
import { crossDotStyle, onConnectStyleChange } from './cross-dot-style';
|
||||||
import { colorManager, onCellColorChange, onGeneralColorChange, predefinedColors } from './color';
|
import { colorManager, onCellColorChange, onGeneralColorChange, predefinedColors } from './color';
|
||||||
|
import { LINE_WIDTH } from '@/hook/render/layout';
|
||||||
|
import { horizontalResizer } from '../right-nav';
|
||||||
|
|
||||||
defineComponent({ name: "dide-setting" });
|
defineComponent({ name: "dide-setting" });
|
||||||
const { t, locale } = useI18n();
|
const { t, locale } = useI18n();
|
||||||
@ -199,7 +214,6 @@ function onlanguagechange(code) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onRenderArrowChange() {
|
function onRenderArrowChange() {
|
||||||
const rootStyles = getComputedStyle(document.documentElement);
|
|
||||||
if (globalSetting.renderArrow) {
|
if (globalSetting.renderArrow) {
|
||||||
document.documentElement.style.setProperty(`--line-arrow-opacity`, '1');
|
document.documentElement.style.setProperty(`--line-arrow-opacity`, '1');
|
||||||
} else {
|
} else {
|
||||||
@ -207,6 +221,32 @@ function onRenderArrowChange() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onBoldMultiWidthWireChange() {
|
||||||
|
const netlist = globalLookup.netlistRender;
|
||||||
|
const renderView = netlist.renderView;
|
||||||
|
const stack = [renderView];
|
||||||
|
while (stack.length > 0) {
|
||||||
|
const view = stack.pop();
|
||||||
|
view.wireRender.lineSelections
|
||||||
|
.attr('stroke-width', d => {
|
||||||
|
console.log('enter');
|
||||||
|
|
||||||
|
const incrementWidth = globalSetting.boldMultiWidthWire ? 2 : 0;
|
||||||
|
return d.width > 1 ? LINE_WIDTH + incrementWidth: LINE_WIDTH;
|
||||||
|
});
|
||||||
|
for (const id of view.id2children.keys()) {
|
||||||
|
const subView = view.getChild(id);
|
||||||
|
stack.push(subView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const settingStyle = computed(() => ({
|
||||||
|
width: horizontalResizer.width - 10 + 'px'
|
||||||
|
}));
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
colorManager.initColor();
|
colorManager.initColor();
|
||||||
});
|
});
|
||||||
@ -215,7 +255,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
.setting-wrapper {
|
.setting-wrapper {
|
||||||
width: fit-content;
|
min-width: 260px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +275,6 @@ onMounted(() => {
|
|||||||
margin: 3px;
|
margin: 3px;
|
||||||
padding: 8px 12px;
|
padding: 8px 12px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
width: 280px !important;
|
|
||||||
border-radius: .5em;
|
border-radius: .5em;
|
||||||
background-color: var(--background);
|
background-color: var(--background);
|
||||||
display: flex;
|
display: flex;
|
||||||
|
5
src/components/toolbar/file-menu/control.js
Normal file
5
src/components/toolbar/file-menu/control.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { reactive } from "vue";
|
||||||
|
|
||||||
|
export const fileMenuContext = reactive({
|
||||||
|
show: false,
|
||||||
|
});
|
101
src/components/toolbar/file-menu/index.vue
Normal file
101
src/components/toolbar/file-menu/index.vue
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<template>
|
||||||
|
<div class="file-menu" :style="btnStyle">
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="btn"
|
||||||
|
@click.stop="fileMenuContext.show = !fileMenuContext.show"
|
||||||
|
>
|
||||||
|
<span class="iconfont icon-menu"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 菜单列表 -->
|
||||||
|
<transition name="collapse-from-top" mode="out-in">
|
||||||
|
<div class="list" v-show="fileMenuContext.show">
|
||||||
|
<SaveAsSvg></SaveAsSvg>
|
||||||
|
<SaveAsPdf></SaveAsPdf>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed, defineComponent } from 'vue';
|
||||||
|
import { fileMenuContext } from './control';
|
||||||
|
import SaveAsSvg from './save-as-svg.vue';
|
||||||
|
import SaveAsPdf from './save-as-pdf.vue';
|
||||||
|
|
||||||
|
|
||||||
|
defineComponent({ name: 'file-menu' });
|
||||||
|
|
||||||
|
const btnStyle = computed(() => ({
|
||||||
|
borderRadius: fileMenuContext.show ? '99em': '.5em'
|
||||||
|
}));
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--menu-btn-width: calc(var(--toolbar-item-height) + 3px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-menu {
|
||||||
|
height: var(--menu-btn-width);
|
||||||
|
width: var(--menu-btn-width);
|
||||||
|
background-color: var(--sidebar);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 这是按钮主体的 css */
|
||||||
|
.file-menu .btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-menu .list {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(var(--menu-btn-width) + 10px);
|
||||||
|
left: 5px;
|
||||||
|
border-radius: .5em;
|
||||||
|
box-shadow: var(--gray-box-shadow-1);
|
||||||
|
background-color: var(--sidebar);
|
||||||
|
border: solid 1px var(--sidebar-border);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 10px 7px;
|
||||||
|
font-size: .9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-menu .list .item {
|
||||||
|
margin: 2.5px;
|
||||||
|
padding: 4px;
|
||||||
|
width: 230px;
|
||||||
|
display: flex;
|
||||||
|
border-radius: .5em;
|
||||||
|
justify-content: space-between;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: var(--animation-3s);
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-menu .list > div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-menu .list .item:hover {
|
||||||
|
background-color: var(--sidebar-item-selected);
|
||||||
|
transition: var(--animation-3s);
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-menu .list .status {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
width: 17px;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
39
src/components/toolbar/file-menu/save-as-pdf.vue
Normal file
39
src/components/toolbar/file-menu/save-as-pdf.vue
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="status"></div>
|
||||||
|
<div class="item" @click="manualLoadView()">
|
||||||
|
<span>{{ t('toolbar.save-as-pdf') }}</span>
|
||||||
|
<span></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { saveAsPdf } from '@/api';
|
||||||
|
import { ElLoading } from 'element-plus';
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
defineComponent({ name: 'save-as-pdf' });
|
||||||
|
|
||||||
|
async function manualLoadView() {
|
||||||
|
const loading = new ElLoading.service({
|
||||||
|
lock: true,
|
||||||
|
text: t('saving'),
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
});
|
||||||
|
|
||||||
|
const res = await saveAsPdf();
|
||||||
|
loading.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// document.addEventListener('keydown', async event => {
|
||||||
|
// if (event.ctrlKey && event.key === 'k') {
|
||||||
|
// event.preventDefault();
|
||||||
|
// manualLoadView();
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
</script>
|
39
src/components/toolbar/file-menu/save-as-svg.vue
Normal file
39
src/components/toolbar/file-menu/save-as-svg.vue
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="status"></div>
|
||||||
|
<div class="item" @click="manualLoadView()">
|
||||||
|
<span>{{ t('toolbar.save-as-svg') }}</span>
|
||||||
|
<span><code>Shift S</code></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { saveAsSvg } from '@/api';
|
||||||
|
import { ElLoading } from 'element-plus';
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
defineComponent({ name: 'save-as-svg' });
|
||||||
|
|
||||||
|
async function manualLoadView() {
|
||||||
|
const loading = new ElLoading.service({
|
||||||
|
lock: true,
|
||||||
|
text: t('saving'),
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
});
|
||||||
|
|
||||||
|
const res = await saveAsSvg();
|
||||||
|
loading.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('keydown', async event => {
|
||||||
|
if (event.ctrlKey && event.key === 's') {
|
||||||
|
event.preventDefault();
|
||||||
|
manualLoadView();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
51
src/components/toolbar/index.vue
Normal file
51
src/components/toolbar/index.vue
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="toolbar-container"
|
||||||
|
@mouseenter="onEnter()"
|
||||||
|
@click="toolBarClick()"
|
||||||
|
>
|
||||||
|
<div class="toolbar-body">
|
||||||
|
<FileMenu></FileMenu>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import { fileMenuContext } from './file-menu/control';
|
||||||
|
import FileMenu from './file-menu';
|
||||||
|
|
||||||
|
/* eslint-disable vue/multi-word-component-names */
|
||||||
|
defineComponent({ name: 'toolbar' });
|
||||||
|
|
||||||
|
function onEnter() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function toolBarClick() {
|
||||||
|
fileMenuContext.show = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.toolbar-container {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 1000px;
|
||||||
|
height: var(--toolbar-height);
|
||||||
|
user-select: none;
|
||||||
|
background-color: var(--background);
|
||||||
|
z-index: 220;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-body {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
align-items: top;
|
||||||
|
padding-left: 7px;
|
||||||
|
padding-top: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,24 +1,36 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="netlist-tree-view">
|
<div class="netlist-tree-view">
|
||||||
<div class="netlist-module-info">
|
<div class="netlist-module-info" :style="netlistModuleStyle">
|
||||||
<div class="netlist-signal-title">{{ t('module') }}</div>
|
<div class="netlist-signal-title">{{ t('module') }}</div>
|
||||||
<hr style="width: 100%;">
|
<hr style="width: 100%;">
|
||||||
<el-scrollbar height="86vh" style="padding-right: 7px;">
|
|
||||||
|
<el-scrollbar height="40vh" style="padding-right: 7px;height: 50%;">
|
||||||
<modules
|
<modules
|
||||||
v-for="mod of treeviewData.modules"
|
v-for="mod of treeviewData.modules"
|
||||||
:key="mod.name"
|
:key="mod.name"
|
||||||
:module="mod"
|
:module="mod"
|
||||||
></modules>
|
></modules>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
|
|
||||||
|
<div class="netlist-signal-title">{{ t('entity-info') }}</div>
|
||||||
|
<hr style="width: 100%;">
|
||||||
|
|
||||||
|
<el-scrollbar height="40vh" style="padding-right: 7px;height: 50%;">
|
||||||
|
<info></info>
|
||||||
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { defineComponent, onMounted } from 'vue';
|
import { defineComponent, onMounted, computed } from 'vue';
|
||||||
|
|
||||||
import modules from './modules.vue';
|
import modules from './modules.vue';
|
||||||
|
import info from './info.vue';
|
||||||
|
|
||||||
import { resize, treeviewData, verticalResizer } from './tree';
|
import { resize, treeviewData, verticalResizer } from './tree';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { horizontalResizer } from '../right-nav';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
@ -31,11 +43,17 @@ onMounted(() => {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const netlistModuleStyle = computed(() => ({
|
||||||
|
width: horizontalResizer.width - 30 + 'px'
|
||||||
|
}));
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.netlist-module-info {
|
.netlist-module-info {
|
||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
|
min-width: 260px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.netlist-signal-title {
|
.netlist-signal-title {
|
||||||
|
116
src/components/treeview/info.js
Normal file
116
src/components/treeview/info.js
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import { globalLookup, globalSetting } from '@/hook/global';
|
||||||
|
import { Cell, ModuleView, Port } from '@/hook/render/yosys';
|
||||||
|
import { SkinManager } from '@/hook/skin';
|
||||||
|
import i18n from '@/i18n';
|
||||||
|
import { reactive } from 'vue';
|
||||||
|
|
||||||
|
|
||||||
|
const { t, locale } = i18n.global;
|
||||||
|
locale.value = globalSetting.language;
|
||||||
|
|
||||||
|
export const infoView = reactive({
|
||||||
|
name: undefined,
|
||||||
|
|
||||||
|
type: undefined,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {'port' | 'module'}
|
||||||
|
*/
|
||||||
|
typeId: undefined,
|
||||||
|
|
||||||
|
module: undefined,
|
||||||
|
definition: undefined,
|
||||||
|
width: undefined,
|
||||||
|
direction: undefined,
|
||||||
|
|
||||||
|
|
||||||
|
// module 渲染属性
|
||||||
|
inputCount: undefined,
|
||||||
|
outputCount: undefined,
|
||||||
|
inoutCount: undefined,
|
||||||
|
instanceCount: undefined,
|
||||||
|
cellCount: undefined,
|
||||||
|
instanceName: undefined,
|
||||||
|
instanceDefinition: undefined,
|
||||||
|
|
||||||
|
// edge 渲染属性
|
||||||
|
from: undefined,
|
||||||
|
to: undefined,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 显示一个 port 到当前信息窗口
|
||||||
|
* @param {Port} port
|
||||||
|
*/
|
||||||
|
displayPort(port) {
|
||||||
|
this.clear();
|
||||||
|
this.name = port.name;
|
||||||
|
this.module = port.view.name;
|
||||||
|
this.type = t("common.port");
|
||||||
|
this.typeId = 'port';
|
||||||
|
|
||||||
|
this.definition = port.definition;
|
||||||
|
this.width = port.width;
|
||||||
|
this.direction = port.direction;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 显示一个 module 到当前窗口
|
||||||
|
* @param {ModuleView} module
|
||||||
|
* @param {Cell} [cell]
|
||||||
|
*/
|
||||||
|
displayModule(module, cell) {
|
||||||
|
this.clear();
|
||||||
|
|
||||||
|
const isTop = (cell === undefined);
|
||||||
|
|
||||||
|
this.name = module.name;
|
||||||
|
this.type = (!isTop) ?
|
||||||
|
t("common.instance"):
|
||||||
|
t('common.top-module');
|
||||||
|
|
||||||
|
this.typeId = 'module';
|
||||||
|
this.definition = module.definition;
|
||||||
|
|
||||||
|
this.instanceName = (cell || {}).name;
|
||||||
|
this.instanceDefinition = (cell || {}).definition;
|
||||||
|
|
||||||
|
const portInfo = module.portInfo;
|
||||||
|
this.inputCount = portInfo.input;
|
||||||
|
this.outputCount = portInfo.output;
|
||||||
|
this.inoutCount = portInfo.inout;
|
||||||
|
|
||||||
|
const skinManager = globalLookup.skinManager;
|
||||||
|
|
||||||
|
let instanceCount = 0;
|
||||||
|
let cellCount = 0;
|
||||||
|
|
||||||
|
this.instanceCount = 0;
|
||||||
|
this.cellCount = 0;
|
||||||
|
|
||||||
|
for (const cellname of module.nameToCell.keys()) {
|
||||||
|
const cell = module.nameToCell.get(cellname);
|
||||||
|
const skin = skinManager.querySkin(cell.type);
|
||||||
|
|
||||||
|
if (skin) {
|
||||||
|
cellCount ++;
|
||||||
|
} else {
|
||||||
|
instanceCount ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.instanceCount = instanceCount;
|
||||||
|
this.cellCount = cellCount;
|
||||||
|
},
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.name = undefined;
|
||||||
|
this.type = undefined;
|
||||||
|
this.module = undefined;
|
||||||
|
this.definition = undefined;
|
||||||
|
this.direction = undefined;
|
||||||
|
this.width = undefined;
|
||||||
|
this.from = undefined;
|
||||||
|
this.to = undefined;
|
||||||
|
this.instanceName = undefined;
|
||||||
|
}
|
||||||
|
});
|
@ -1,14 +1,186 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="treeview-info">
|
||||||
|
|
||||||
|
<div class="treeview-info-blank" v-if="!globalLookup.currentSelectContext">
|
||||||
|
{{ t('info.no-entity-select.cannot-display-view') }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else-if="infoView.typeId === 'module'"
|
||||||
|
class="info-wrapper">
|
||||||
|
<span class="info-item-container">
|
||||||
|
<span>{{ t("common.type") }}</span>
|
||||||
|
<span>
|
||||||
|
<span class="iconfont icon-info-module"></span>{{ infoView.type }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span class="info-item-container">
|
||||||
|
<span>{{ t("common.name") }}</span>
|
||||||
|
<span><code>{{ infoView.name }}</code></span>
|
||||||
|
</span>
|
||||||
|
<span class="info-item-container">
|
||||||
|
<span>
|
||||||
|
{{ t("common.definition") }}
|
||||||
|
</span>
|
||||||
|
<span class="definition" @click="gotoDefinition(infoView.definition)">
|
||||||
|
<span class="iconfont icon-link"></span>{{ renderDefinition(infoView.definition) }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span class="info-item-container" v-if="infoView.instanceName">
|
||||||
|
<span>{{ t('common.instance-name') }}</span>
|
||||||
|
<span><code>{{ infoView.instanceName }}</code></span>
|
||||||
|
</span>
|
||||||
|
<span class="info-item-container" v-if="infoView.instanceDefinition">
|
||||||
|
<span>{{ t('common.instance-definition') }}</span>
|
||||||
|
<span class="definition" @click="gotoDefinition(infoView.instanceDefinition)">
|
||||||
|
<span class="iconfont icon-link"></span>{{ renderDefinition(infoView.instanceDefinition) }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="info-item-container">
|
||||||
|
<span>{{ t('common.input-number') }}</span>
|
||||||
|
<span>{{ infoView.inputCount }}</span>
|
||||||
|
</span>
|
||||||
|
<span class="info-item-container">
|
||||||
|
<span>{{ t('common.output-number') }}</span>
|
||||||
|
<span>{{ infoView.outputCount }}</span>
|
||||||
|
</span>
|
||||||
|
<span class="info-item-container">
|
||||||
|
<span>{{ t('common.inout-number') }}</span>
|
||||||
|
<span>{{ infoView.inoutCount }}</span>
|
||||||
|
</span>
|
||||||
|
<span class="info-item-container">
|
||||||
|
<span>{{ t('common.instance-number') }}</span>
|
||||||
|
<span>{{ infoView.instanceCount }}</span>
|
||||||
|
</span>
|
||||||
|
<span class="info-item-container">
|
||||||
|
<span>{{ t('common.general-cell-number') }}</span>
|
||||||
|
<span>{{ infoView.cellCount }}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else-if="infoView.typeId === 'port'"
|
||||||
|
class="info-wrapper">
|
||||||
|
<span class="info-item-container">
|
||||||
|
<span>{{ t('common.type') }}</span>
|
||||||
|
<span>
|
||||||
|
<span class="iconfont icon-info-port"></span>{{ infoView.type }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span class="info-item-container">
|
||||||
|
<span>{{ t('common.name') }}</span>
|
||||||
|
<span><code>{{ infoView.name }}</code></span>
|
||||||
|
</span>
|
||||||
|
<span class="info-item-container">
|
||||||
|
<span>
|
||||||
|
{{ t('common.definition') }}
|
||||||
|
</span>
|
||||||
|
<span class="definition" @click="gotoDefinition(infoView.definition)">
|
||||||
|
<span class="iconfont icon-link"></span>{{ renderDefinition(infoView.definition) }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span class="info-item-container">
|
||||||
|
<span>{{ t('common.belong-module') }}</span>
|
||||||
|
<span><span class="iconfont icon-info-module"></span><code>{{ infoView.module }}</code></span>
|
||||||
|
</span>
|
||||||
|
<span class="info-item-container">
|
||||||
|
<span>{{ t('common.width') }}</span>
|
||||||
|
<span>{{ infoView.width }}</span>
|
||||||
|
</span>
|
||||||
|
<span class="info-item-container">
|
||||||
|
<span>{{ t('common.direction') }}</span>
|
||||||
|
<span>{{ infoView.direction }}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import { infoView } from './info';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { globalLookup } from '@/hook/global';
|
||||||
|
import { gotoDefinition } from '@/api/definition';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
defineComponent({ name: 'treeview-item-info' });
|
defineComponent({ name: 'treeview-item-info' });
|
||||||
|
|
||||||
|
function renderDefinition(definition) {
|
||||||
|
if (typeof definition !== 'string') {
|
||||||
|
return 'unknown';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (definition.includes('|')) {
|
||||||
|
const filenames = [];
|
||||||
|
for (const def of definition.split('|')) {
|
||||||
|
filenames.push(renderDefinition(def));
|
||||||
|
}
|
||||||
|
return filenames.join('').split(':').at(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const filename = definition.split('/').at(-1);
|
||||||
|
if (!filename) {
|
||||||
|
return definition;
|
||||||
|
}
|
||||||
|
return filename.split(':').at(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.treeview-info {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.treeview-info-blank {
|
||||||
|
font-size: .9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item-container {
|
||||||
|
display: flex;
|
||||||
|
margin: 2px;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: .8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item-container span:nth-child(1) {
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item-container span:nth-child(2) {
|
||||||
|
overflow: hidden;
|
||||||
|
max-width: 220px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-wrapper > span {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
border-bottom: solid 1px var(--sidebar-item-selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-wrapper > span:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-bottom: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item-container .definition {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: var(--animation-3s);
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item-container .iconfont {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item-container .definition:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--main-color);
|
||||||
|
transition: var(--animation-3s);
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,6 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="module">
|
<div class="module">
|
||||||
<div @click="clickItem()" class="netlist-treeview-item">
|
<div @click="clickModule()"
|
||||||
|
class="netlist-treeview-item"
|
||||||
|
:class="{'active': sameModule() }"
|
||||||
|
>
|
||||||
<span class="module-tag-status" @click.stop="expandManage.click">
|
<span class="module-tag-status" @click.stop="expandManage.click">
|
||||||
<div :class="expandManage.expandTagClass"></div>
|
<div :class="expandManage.expandTagClass"></div>
|
||||||
</span>
|
</span>
|
||||||
@ -17,10 +20,14 @@
|
|||||||
<div style="width: 20px;"></div>
|
<div style="width: 20px;"></div>
|
||||||
<div style="width: 100%;">
|
<div style="width: 100%;">
|
||||||
<!-- ports -->
|
<!-- ports -->
|
||||||
<div v-for="port in ports" :key="port.name" class="netlist-treeview-item">
|
<div v-for="port in ports" :key="port.name"
|
||||||
|
class="netlist-treeview-item"
|
||||||
|
:class="{'active': samePort(port)}"
|
||||||
|
@click="clickPort(port)"
|
||||||
|
>
|
||||||
<span class="module-tag-status">
|
<span class="module-tag-status">
|
||||||
</span>
|
</span>
|
||||||
<span class="iconfont icon-wave-square"></span>
|
<span class="iconfont icon-info-port"></span>
|
||||||
 {{ port.name }}
|
 {{ port.name }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -28,6 +35,8 @@
|
|||||||
<modules
|
<modules
|
||||||
v-for="(cell, index) in cells"
|
v-for="(cell, index) in cells"
|
||||||
:module="cell.view"
|
:module="cell.view"
|
||||||
|
:cell="cell.data"
|
||||||
|
:prefix-name="cell.prefixName"
|
||||||
:render-name="cell.renderName"
|
:render-name="cell.renderName"
|
||||||
:key="index"
|
:key="index"
|
||||||
></modules>
|
></modules>
|
||||||
@ -39,8 +48,9 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { globalLookup } from '@/hook/global';
|
import { globalLookup } from '@/hook/global';
|
||||||
import { ModuleView } from '@/hook/render/yosys';
|
import { dotConnect, ModuleView } from '@/hook/render/yosys';
|
||||||
import { defineComponent, reactive, computed } from 'vue';
|
import { defineComponent, reactive, computed } from 'vue';
|
||||||
|
import { infoView } from './info';
|
||||||
|
|
||||||
defineComponent({ name: 'modules' });
|
defineComponent({ name: 'modules' });
|
||||||
|
|
||||||
@ -49,12 +59,19 @@ const props = defineProps({
|
|||||||
type: ModuleView,
|
type: ModuleView,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
cell: {
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
renderName: {
|
renderName: {
|
||||||
type: String
|
type: String
|
||||||
|
},
|
||||||
|
prefixName: {
|
||||||
|
type: String
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const module = props.module;
|
const module = props.module;
|
||||||
|
const id = props.cell ? props.cell.id: module.id;
|
||||||
|
|
||||||
const renderName = computed(() => {
|
const renderName = computed(() => {
|
||||||
return props.renderName ? props.renderName : module.name
|
return props.renderName ? props.renderName : module.name
|
||||||
@ -66,7 +83,16 @@ const cells = [];
|
|||||||
|
|
||||||
// 初始化渲染的子视图 ports & modules
|
// 初始化渲染的子视图 ports & modules
|
||||||
for (const portName of module.nameToPort.keys()) {
|
for (const portName of module.nameToPort.keys()) {
|
||||||
|
const port = module.nameToPort.get(portName);
|
||||||
|
// 根据 prefixName 计算 treeview 中的 port id
|
||||||
|
// 不可以直接使用 port.id , port.id 是我设计用于表征原视图中 port
|
||||||
|
const portId = props.prefixName ?
|
||||||
|
dotConnect(props.prefixName, port.name) :
|
||||||
|
port.id;
|
||||||
|
|
||||||
ports.push({
|
ports.push({
|
||||||
|
id: portId,
|
||||||
|
data: port,
|
||||||
name: portName
|
name: portName
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -79,9 +105,15 @@ for (const cellName of module.nameToCell.keys()) {
|
|||||||
// 防止递归
|
// 防止递归
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cell.isInstantiation) {
|
if (cell.isInstantiation) {
|
||||||
|
const prefixName = props.prefixName ?
|
||||||
|
dotConnect(props.prefixName, cell.name) :
|
||||||
|
cell.id;
|
||||||
|
|
||||||
cells.push({
|
cells.push({
|
||||||
name: cellName,
|
name: cellName,
|
||||||
|
data: cell,
|
||||||
|
prefixName,
|
||||||
view: cell.belongModuleView,
|
view: cell.belongModuleView,
|
||||||
renderName: `${cellName} (${cell.belongModuleView.name})`
|
renderName: `${cellName} (${cell.belongModuleView.name})`
|
||||||
});
|
});
|
||||||
@ -90,8 +122,42 @@ for (const cellName of module.nameToCell.keys()) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
function clickItem() {
|
function sameModule() {
|
||||||
|
if (!globalLookup.currentSelectContext) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return globalLookup.currentSelectContext.id === id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function samePort(port) {
|
||||||
|
if (!globalLookup.currentSelectContext) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return globalLookup.currentSelectContext.id === port.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickPort(port) {
|
||||||
|
const portView = module.nameToPort.get(port.name);
|
||||||
|
infoView.displayPort(portView);
|
||||||
|
|
||||||
|
globalLookup.currentSelectContext = {
|
||||||
|
id: port.id,
|
||||||
|
data: port,
|
||||||
|
type: 'port',
|
||||||
|
moduleView: props.module
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickModule() {
|
||||||
|
infoView.displayModule(module, props.cell);
|
||||||
|
|
||||||
|
globalLookup.currentSelectContext = {
|
||||||
|
id: id,
|
||||||
|
data: props.module,
|
||||||
|
type: 'module',
|
||||||
|
moduleView: props.module,
|
||||||
|
cell: props.cell
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getExpandStatus() {
|
function getExpandStatus() {
|
||||||
@ -110,16 +176,20 @@ const expandManage = reactive({
|
|||||||
});
|
});
|
||||||
|
|
||||||
function makeIconClass() {
|
function makeIconClass() {
|
||||||
return 'icon-memory-chip';
|
return 'icon-info-module';
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.icon-memory-chip {
|
.module .icon-info-module {
|
||||||
color: #FF7043;
|
color: #FF7043;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.module .icon-info-port {
|
||||||
|
color: var(--main-color);
|
||||||
|
}
|
||||||
|
|
||||||
.module {
|
.module {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
@ -148,6 +218,12 @@ function makeIconClass() {
|
|||||||
border-radius: .3em;
|
border-radius: .3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.netlist-treeview-item.active {
|
||||||
|
background-color: var(--sidebar-item-selected);
|
||||||
|
border-radius: .3em;
|
||||||
|
transition: var(--animation-3s);
|
||||||
|
}
|
||||||
|
|
||||||
.netlist-treeview-selected {
|
.netlist-treeview-selected {
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
background-color: var(--button-active) !important;
|
background-color: var(--button-active) !important;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
* @property {number} r
|
* @property {number} r
|
||||||
* @property {number} g
|
* @property {number} g
|
||||||
* @property {number} b
|
* @property {number} b
|
||||||
|
* @property {number} [a] 透明度,值置于 0 - 1 之间
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,7 +30,8 @@ export function parseColor(colorString) {
|
|||||||
const r = parseInt(matches[1], 10);
|
const r = parseInt(matches[1], 10);
|
||||||
const g = parseInt(matches[2], 10);
|
const g = parseInt(matches[2], 10);
|
||||||
const b = parseInt(matches[3], 10);
|
const b = parseInt(matches[3], 10);
|
||||||
return { r, g, b };
|
const a = parseFloat(matches[4]);
|
||||||
|
return { r, g, b, a };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 检查是否是 RGB 颜色
|
// 检查是否是 RGB 颜色
|
||||||
@ -68,6 +70,28 @@ export function increaseBrightness(rgb, percent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 降低颜色的亮度
|
||||||
|
* @param {RgbColor} rgb
|
||||||
|
* @param {number} percent 0 - 100 的数字,代表增强的亮度比例
|
||||||
|
* @returns {RgbColor}
|
||||||
|
*/
|
||||||
|
export function lowerBrightness(rgb, percent) {
|
||||||
|
// 确保 percent 在 0 到 100 之间
|
||||||
|
percent = Math.max(0, Math.min(100, percent));
|
||||||
|
|
||||||
|
// 计算每个颜色分量的增量
|
||||||
|
const increment = (percent / 100) * 255;
|
||||||
|
|
||||||
|
// 提升每个颜色分量的亮度
|
||||||
|
const r = Math.min(255, Math.round(rgb.r - increment));
|
||||||
|
const g = Math.min(255, Math.round(rgb.g - increment));
|
||||||
|
const b = Math.min(255, Math.round(rgb.b - increment));
|
||||||
|
|
||||||
|
return { r, g, b };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description gamma 修正
|
* @description gamma 修正
|
||||||
* @param {number} c 颜色通道值,取值范围为 0 - 255
|
* @param {number} c 颜色通道值,取值范围为 0 - 255
|
||||||
@ -89,4 +113,115 @@ export function isLightColorTheme(r, g, b) {
|
|||||||
b = gammaCorrected(b);
|
b = gammaCorrected(b);
|
||||||
const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||||
return luminance > 0.5;
|
return luminance > 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 导出为 rgb css 样式的字符串
|
||||||
|
* @param {RgbColor} rgb
|
||||||
|
*/
|
||||||
|
export function toRgbCssString(rgb) {
|
||||||
|
const r = rgb.r;
|
||||||
|
const g = rgb.g;
|
||||||
|
const b = rgb.b;
|
||||||
|
return `rgb(${r}, ${g}, ${b})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 导出为 rgba css 样式的字符串
|
||||||
|
* @param {RgbColor} rgb
|
||||||
|
*/
|
||||||
|
export function toRgbaCssString(rgb) {
|
||||||
|
const r = rgb.r;
|
||||||
|
const g = rgb.g;
|
||||||
|
const b = rgb.b;
|
||||||
|
const a = rgb.a;
|
||||||
|
return `rgb(${r}, ${g}, ${b}, ${a})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef ComputedColorOption
|
||||||
|
* @property {string} BaseForegroundColorMacroName
|
||||||
|
* @property {string} BaseBackgroundColorMacroName
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef GetColorOption
|
||||||
|
* @property {'pdf' | 'svg'} mode
|
||||||
|
*/
|
||||||
|
|
||||||
|
export class MacroColor {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {ComputedColorOption} option
|
||||||
|
*/
|
||||||
|
constructor(option = {}) {
|
||||||
|
this.option = option;
|
||||||
|
this.rootStyles = getComputedStyle(document.documentElement);
|
||||||
|
|
||||||
|
const foregroundColorString = this.rootStyles.getPropertyValue(option.BaseForegroundColorMacroName || '--foreground');
|
||||||
|
const backgroundColorString = this.rootStyles.getPropertyValue(option.BaseBackgroundColorMacroName || '--background');
|
||||||
|
const foregroundColor = parseColor(foregroundColorString);
|
||||||
|
const backgroundColor = parseColor(backgroundColorString);
|
||||||
|
// 通过背景颜色来判断当前颜色主题的类别
|
||||||
|
const isLight = isLightColorTheme(backgroundColor.r, backgroundColor.g, backgroundColor.b);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {'light' | 'dark'}
|
||||||
|
*/
|
||||||
|
this.theme = isLight ? 'light' : 'dark';
|
||||||
|
|
||||||
|
this.foregroundColor = foregroundColor;
|
||||||
|
this.backgroundColor = backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} macroName
|
||||||
|
* @param {GetColorOption} option
|
||||||
|
*/
|
||||||
|
getColor(macroName, option = {}) {
|
||||||
|
const theme = this.theme;
|
||||||
|
const rootStyles = this.rootStyles;
|
||||||
|
const mode = option.mode || 'svg';
|
||||||
|
|
||||||
|
if (mode === 'svg') {
|
||||||
|
// svg 模式下,导出的效果和 webview 渲染效果基本一致,直接导出即可
|
||||||
|
return rootStyles.getPropertyValue(macroName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// pdf 模式需要对 黑色主题 的几个特殊颜色进行一定的处理,并对所有透明颜色进行混合处理
|
||||||
|
switch (macroName) {
|
||||||
|
case '--foreground':
|
||||||
|
case '--wire-color':
|
||||||
|
case '--cross-dot-color':
|
||||||
|
if (theme === 'dark') {
|
||||||
|
return '#2D323B';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const colorString = rootStyles.getPropertyValue(macroName);
|
||||||
|
if (!colorString) {
|
||||||
|
// 如果 macroName 不存在,那么此时的 colorString 是空的
|
||||||
|
return colorString;
|
||||||
|
}
|
||||||
|
const color = parseColor(colorString);
|
||||||
|
if (!color.a) {
|
||||||
|
// 不具有透明通道,在 pdf 中渲染效果和 svg 中一致,直接返回即可
|
||||||
|
return toRgbCssString(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 透明度插值公式为 c = c_f * \alpha + c_b * (1 - \alpha)
|
||||||
|
// c_f: 前景颜色
|
||||||
|
// c_b: 背景颜色
|
||||||
|
// alpha: 透明度
|
||||||
|
// 该操作是 channel-wise 的
|
||||||
|
const mixedBg = parseColor('#ffffff');
|
||||||
|
const mixedColor = { r: 0, g: 0, b: 0 };
|
||||||
|
const alpha = color.a;
|
||||||
|
mixedColor.r = color.r * alpha + mixedBg.r * (1 - alpha);
|
||||||
|
mixedColor.g = color.g * alpha + mixedBg.g * (1 - alpha);
|
||||||
|
mixedColor.b = color.b * alpha + mixedBg.b * (1 - alpha);
|
||||||
|
|
||||||
|
return toRgbCssString(mixedColor);
|
||||||
|
}
|
||||||
}
|
}
|
@ -33,9 +33,15 @@ export const globalSetting = reactive({
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 当前交叉点的样式
|
* @description 当前交叉点的样式
|
||||||
* @type {'connect' | 'slice' | 'concat'} currentStyle
|
* @type {'connect' | 'slice' | 'concat'}
|
||||||
*/
|
*/
|
||||||
crossDotStyle: 'connect'
|
crossDotStyle: 'connect',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 脉动动效的速度
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
pulsationSpeed: 5
|
||||||
});
|
});
|
||||||
|
|
||||||
export const globalLookup = reactive({
|
export const globalLookup = reactive({
|
||||||
@ -62,14 +68,15 @@ export const globalLookup = reactive({
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 当前选择的实体,可以是 wire,也可以是 cell
|
* @description 当前选择的实体,可以是 wire,也可以是 cell
|
||||||
|
* @type {import('./jsdoc').ICurrentSelectContext}
|
||||||
*/
|
*/
|
||||||
currentSelectEntity: undefined,
|
currentSelectContext: undefined,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 右侧 treeview 选择的需要展示数据的实体
|
* @description 右侧 treeview 选择的需要展示数据的实体
|
||||||
* @type {Record<string, string>}
|
* @type {Record<string, string>}
|
||||||
*/
|
*/
|
||||||
currentSelectEntityInfo: {}
|
currentSelectContextInfo: {}
|
||||||
});
|
});
|
||||||
|
|
||||||
function loadSetting() {
|
function loadSetting() {
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Module } from "./render/layout";
|
import { Module } from "./render/layout";
|
||||||
|
import { Cell, ModuleView } from "./render/yosys";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {number | string} WireId 信号ID
|
* @typedef {number | string} WireId 信号ID
|
||||||
@ -269,5 +270,27 @@ import { Module } from "./render/layout";
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef ElkMakerConfig
|
* @typedef ElkMakerConfig
|
||||||
* @param {string} [parentId]
|
* @property {string} [parentId]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef ICurrentSelectContext
|
||||||
|
* @property {string} id
|
||||||
|
* @property {any} data
|
||||||
|
* @property {'module' | 'port'} type 类型
|
||||||
|
* @property {ModuleView} moduleView 所在模块的数据视图
|
||||||
|
* @property {Cell} [cell] 例化模块在原模块中的视图
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef Position
|
||||||
|
* @property {number} line
|
||||||
|
* @property {number} charater
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef Range
|
||||||
|
* @property {Position} start
|
||||||
|
* @property {Position} end
|
||||||
*/
|
*/
|
@ -15,6 +15,7 @@ import { dotConnect } from './yosys';
|
|||||||
import { CrossDotRender } from './cross-dot';
|
import { CrossDotRender } from './cross-dot';
|
||||||
import { RangeTreeMap } from '../algorithm/range-tree';
|
import { RangeTreeMap } from '../algorithm/range-tree';
|
||||||
import { ConstantRender } from './constant';
|
import { ConstantRender } from './constant';
|
||||||
|
import { RenderViewNode } from './render-view';
|
||||||
|
|
||||||
export class NetlistRender {
|
export class NetlistRender {
|
||||||
/**
|
/**
|
||||||
@ -206,15 +207,19 @@ export class NetlistRender {
|
|||||||
// debug
|
// debug
|
||||||
console.log(computedLayout);
|
console.log(computedLayout);
|
||||||
|
|
||||||
// 生成连接
|
// 底层模块
|
||||||
await this.renderLine(g, computedLayout);
|
const topModule = this.nameToModule.get(this.topModuleName);
|
||||||
|
|
||||||
// 生成实体
|
|
||||||
await this.renderEntity(g, computedLayout);
|
|
||||||
|
|
||||||
// svg 挂载为全局注册的 selection
|
// svg 挂载为全局注册的 selection
|
||||||
this.selection = svg;
|
this.selection = svg;
|
||||||
this.g = g;
|
|
||||||
|
this.renderView = new RenderViewNode(g);
|
||||||
|
|
||||||
|
// 生成连接
|
||||||
|
await this.renderLine(this.renderView, computedLayout, topModule);
|
||||||
|
|
||||||
|
// 生成实体
|
||||||
|
await this.renderEntity(this.renderView, computedLayout, topModule);
|
||||||
|
|
||||||
// 注册平移和缩放
|
// 注册平移和缩放
|
||||||
this.registerRenderTransform(g);
|
this.registerRenderTransform(g);
|
||||||
@ -232,10 +237,10 @@ export class NetlistRender {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 绘制实体
|
* @description 绘制实体
|
||||||
* @param {d3.Selection} parentSelection
|
* @param {RenderViewNode} view
|
||||||
* @param {import('../jsdoc').ElkNode} computedLayout
|
* @param {import('../jsdoc').ElkNode} computedLayout
|
||||||
*/
|
*/
|
||||||
async renderEntity(parentSelection, computedLayout) {
|
async renderEntity(view, computedLayout) {
|
||||||
// node 可能是如下的几类
|
// node 可能是如下的几类
|
||||||
// - module 的 port
|
// - module 的 port
|
||||||
// - 器件(基础器件 & 例化模块)
|
// - 器件(基础器件 & 例化模块)
|
||||||
@ -243,11 +248,11 @@ export class NetlistRender {
|
|||||||
const skinManager = globalLookup.skinManager;
|
const skinManager = globalLookup.skinManager;
|
||||||
|
|
||||||
// 创建各个主要实体的 render
|
// 创建各个主要实体的 render
|
||||||
this.cellRender = new CellRender(parentSelection, this);
|
view.cellRender = new CellRender(view.g, this);
|
||||||
this.portRender = new PortRender(parentSelection, this);
|
view.portRender = new PortRender(view.g, this);
|
||||||
this.instantiationRender = new InstantiationRender(parentSelection, this);
|
view.instantiationRender = new InstantiationRender(view.g, this);
|
||||||
this.connectionRender = new ConnectionRender(parentSelection, this);
|
view.connectionRender = new ConnectionRender(view.g, this);
|
||||||
this.constantRender = new ConstantRender(parentSelection, this);
|
view.constantRender = new ConstantRender(view.g, this);
|
||||||
|
|
||||||
for (const node of computedLayout.children) {
|
for (const node of computedLayout.children) {
|
||||||
// 只计算形体的,因为 连接点 非常小,几乎不影响布局
|
// 只计算形体的,因为 连接点 非常小,几乎不影响布局
|
||||||
@ -257,41 +262,40 @@ export class NetlistRender {
|
|||||||
if (skin) {
|
if (skin) {
|
||||||
// 具有 skin 的器件
|
// 具有 skin 的器件
|
||||||
const element = skin.meta.svgDoc.documentElement.cloneNode(true);
|
const element = skin.meta.svgDoc.documentElement.cloneNode(true);
|
||||||
this.cellRender.addAsD3DataItem(node, element);
|
view.cellRender.addAsD3DataItem(node, element);
|
||||||
} else {
|
} else {
|
||||||
if (node.renderType === 'port') {
|
if (node.renderType === 'port') {
|
||||||
this.portRender.addAsD3DataItem(node);
|
view.portRender.addAsD3DataItem(node);
|
||||||
} else if (node.renderType === 'instance') {
|
} else if (node.renderType === 'instance') {
|
||||||
// 没有 skin 的器件或者端口
|
// 没有 skin 的器件或者端口
|
||||||
this.instantiationRender.addAsD3DataItem(node);
|
view.instantiationRender.addAsD3DataItem(node);
|
||||||
} else if (node.renderType === 'constant') {
|
} else if (node.renderType === 'constant') {
|
||||||
this.constantRender.addAsD3DataItem(node);
|
view.constantRender.addAsD3DataItem(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果存在 port,绘制 port
|
// 如果存在 port,绘制 port
|
||||||
for (const cellPort of node.ports || []) {
|
for (const cellPort of node.ports || []) {
|
||||||
this.connectionRender.addAsD3DataItem(cellPort, node);
|
view.connectionRender.addAsD3DataItem(cellPort, node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ports = this.portRender.render();
|
view.portRender.render();
|
||||||
const instances = this.instantiationRender.render();
|
view.instantiationRender.render();
|
||||||
const cells = this.cellRender.render();
|
view.cellRender.render();
|
||||||
const connections = this.connectionRender.render();
|
view.connectionRender.render();
|
||||||
const constants = this.constantRender.render();
|
view.constantRender.render();
|
||||||
|
|
||||||
return { ports, instances, cells, connections };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 绘制连线和交叉点
|
* @description 绘制连线和交叉点
|
||||||
* @param {d3.Selection} parentSelection
|
* @param {RenderViewNode} view
|
||||||
* @param {ElkNode} computedLayout
|
* @param {ElkNode} computedLayout
|
||||||
|
* @param {Module} module
|
||||||
*/
|
*/
|
||||||
async renderLine(parentSelection, computedLayout) {
|
async renderLine(view, computedLayout, module) {
|
||||||
this.wireRender = new WireRender(parentSelection, this);
|
view.wireRender = new WireRender(view.g, this);
|
||||||
this.crossDotRender = new CrossDotRender(parentSelection, this);
|
view.crossDotRender = new CrossDotRender(view.g, this);
|
||||||
|
|
||||||
// 建立关于 port 的索引
|
// 建立关于 port 的索引
|
||||||
const id2port = new Map();
|
const id2port = new Map();
|
||||||
@ -304,6 +308,7 @@ export class NetlistRender {
|
|||||||
const rangeTree = new RangeTreeMap();
|
const rangeTree = new RangeTreeMap();
|
||||||
|
|
||||||
for (const edge of computedLayout.edges) {
|
for (const edge of computedLayout.edges) {
|
||||||
|
const width = module.id2EdgeCount.get(edge.id);
|
||||||
for (const section of edge.sections || []) {
|
for (const section of edge.sections || []) {
|
||||||
const points = [];
|
const points = [];
|
||||||
points.push(section.startPoint);
|
points.push(section.startPoint);
|
||||||
@ -311,7 +316,7 @@ export class NetlistRender {
|
|||||||
points.push(point);
|
points.push(point);
|
||||||
}
|
}
|
||||||
points.push(section.endPoint);
|
points.push(section.endPoint);
|
||||||
this.wireRender.addAsD3DataItems(points, edge, id2port);
|
view.wireRender.addAsD3DataItems(points, edge, id2port, width);
|
||||||
|
|
||||||
// 加入 range tree 中
|
// 加入 range tree 中
|
||||||
for (let i = 0; i < points.length - 1; ++ i) {
|
for (let i = 0; i < points.length - 1; ++ i) {
|
||||||
@ -332,14 +337,14 @@ export class NetlistRender {
|
|||||||
for (const point of section.bendPoints || []) {
|
for (const point of section.bendPoints || []) {
|
||||||
const degree = rangeTree.getDegree(point);
|
const degree = rangeTree.getDegree(point);
|
||||||
if (degree >= 3) {
|
if (degree >= 3) {
|
||||||
this.crossDotRender.addAsD3DataItem(point.x, point.y);
|
view.crossDotRender.addAsD3DataItem(point.x, point.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.wireRender.render();
|
view.wireRender.render();
|
||||||
this.crossDotRender.render();
|
view.crossDotRender.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -585,7 +590,6 @@ export class NetlistRender {
|
|||||||
elkNode.edges = [];
|
elkNode.edges = [];
|
||||||
elkNode.layoutOptions = this.defaultLayoutOptions;
|
elkNode.layoutOptions = this.defaultLayoutOptions;
|
||||||
|
|
||||||
|
|
||||||
// elkNode.children.push(...portNodes);
|
// elkNode.children.push(...portNodes);
|
||||||
elkNode.children.push(...cellNodes);
|
elkNode.children.push(...cellNodes);
|
||||||
elkNode.children.push(...constantNodes);
|
elkNode.children.push(...constantNodes);
|
||||||
@ -610,31 +614,31 @@ export class NetlistRender {
|
|||||||
this.zoom.translateBy(this.selection, deltaX, deltaY);
|
this.zoom.translateBy(this.selection, deltaX, deltaY);
|
||||||
|
|
||||||
const svg = this.selection;
|
const svg = this.selection;
|
||||||
const g = this.g;
|
const g = this.renderView.g;
|
||||||
|
|
||||||
g.selectAll('*').remove();
|
g.selectAll('*').remove();
|
||||||
|
this.renderView.id2children.clear();
|
||||||
|
|
||||||
// 开始递归地进行渲染
|
// 开始递归地进行渲染
|
||||||
const renderStack = [
|
const renderStack = [
|
||||||
{
|
{
|
||||||
parentSelection: g,
|
view: this.renderView,
|
||||||
layout: computedLayout
|
layout: computedLayout
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
while (renderStack.length > 0) {
|
while (renderStack.length > 0) {
|
||||||
const s = renderStack.pop();
|
const s = renderStack.pop();
|
||||||
const parentSelection = s.parentSelection;
|
const view = s.view;
|
||||||
const layout = s.layout;
|
const layout = s.layout;
|
||||||
|
|
||||||
await this.renderLine(parentSelection, layout);
|
const layoutName = layout.renderName || this.topModuleName;
|
||||||
const { instances } = await this.renderEntity(parentSelection, layout);
|
const module = this.nameToModule.get(layoutName);
|
||||||
|
|
||||||
|
await this.renderLine(view, layout, module);
|
||||||
|
await this.renderEntity(view, layout, module);
|
||||||
|
|
||||||
const id2selection = new Map();
|
const id2selection = view.instantiationRender.id2selection;
|
||||||
instances.each(function(data) {
|
|
||||||
const selection = d3.select(this);
|
|
||||||
id2selection.set(data.id, selection);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 将需要渲染子图的部分扔进渲染器
|
// 将需要渲染子图的部分扔进渲染器
|
||||||
for (const node of layout.children || []) {
|
for (const node of layout.children || []) {
|
||||||
@ -642,8 +646,10 @@ export class NetlistRender {
|
|||||||
|
|
||||||
if (subChildren.length > 0) {
|
if (subChildren.length > 0) {
|
||||||
const selection = id2selection.get(node.id);
|
const selection = id2selection.get(node.id);
|
||||||
|
const subView = new RenderViewNode(selection);
|
||||||
|
view.setChild(node.id, subView);
|
||||||
renderStack.push({
|
renderStack.push({
|
||||||
parentSelection: selection,
|
view: subView,
|
||||||
layout: node
|
layout: node
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -695,37 +701,41 @@ export class NetlistRender {
|
|||||||
this.zoom.translateBy(this.selection, deltaX, deltaY);
|
this.zoom.translateBy(this.selection, deltaX, deltaY);
|
||||||
|
|
||||||
const svg = this.selection;
|
const svg = this.selection;
|
||||||
const g = this.g;
|
const g = this.renderView.g;
|
||||||
|
|
||||||
g.selectAll('*').remove();
|
g.selectAll('*').remove();
|
||||||
|
this.renderView.id2children.clear();
|
||||||
|
|
||||||
// 开始递归地进行渲染
|
// 开始递归地进行渲染
|
||||||
const renderStack = [
|
const renderStack = [
|
||||||
{
|
{
|
||||||
parentSelection: g,
|
view: this.renderView,
|
||||||
layout: computedLayout
|
layout: computedLayout
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
while (renderStack.length > 0) {
|
while (renderStack.length > 0) {
|
||||||
const s = renderStack.pop();
|
const s = renderStack.pop();
|
||||||
const parentSelection = s.parentSelection;
|
const view = s.view;
|
||||||
const layout = s.layout;
|
const layout = s.layout;
|
||||||
await this.renderLine(parentSelection, layout);
|
|
||||||
const { instances } = await this.renderEntity(parentSelection, layout);
|
const layoutName = layout.renderName || this.topModuleName;
|
||||||
const id2selection = new Map();
|
const module = this.nameToModule.get(layoutName);
|
||||||
instances.each(function(data) {
|
|
||||||
const selection = d3.select(this);
|
await this.renderLine(view, layout, module);
|
||||||
id2selection.set(data.id, selection);
|
await this.renderEntity(view, layout, module);
|
||||||
});
|
|
||||||
|
const id2selection = view.instantiationRender.id2selection;
|
||||||
|
|
||||||
// 将需要渲染子图的部分扔进渲染器
|
// 将需要渲染子图的部分扔进渲染器
|
||||||
for (const node of layout.children || []) {
|
for (const node of layout.children || []) {
|
||||||
const subChildren = node.children || [];
|
const subChildren = node.children || [];
|
||||||
if (subChildren.length > 0) {
|
if (subChildren.length > 0) {
|
||||||
const selection = id2selection.get(node.id);
|
const selection = id2selection.get(node.id);
|
||||||
|
const subView = new RenderViewNode(selection);
|
||||||
|
view.id2children.set(node.id, subView);
|
||||||
renderStack.push({
|
renderStack.push({
|
||||||
parentSelection: selection,
|
view: subView,
|
||||||
layout: node
|
layout: node
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -235,6 +235,15 @@ export class InstantiationRender {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.selections = instantiationSelections;
|
this.selections = instantiationSelections;
|
||||||
|
|
||||||
|
const id2selection = new Map();
|
||||||
|
instantiationSelections.each(function(data) {
|
||||||
|
const selection = d3.select(this);
|
||||||
|
id2selection.set(data.id, selection);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.id2selection = id2selection;
|
||||||
|
|
||||||
return instantiationSelections;
|
return instantiationSelections;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,7 +233,6 @@ export class Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const constantWidth = Math.max(12 * 0.6 * renderString.toString().length + 10, LAYOUT_CONSTANT.CONSTANT_WIDTH);
|
const constantWidth = Math.max(12 * 0.6 * renderString.toString().length + 10, LAYOUT_CONSTANT.CONSTANT_WIDTH);
|
||||||
console.log(constantWidth);
|
|
||||||
|
|
||||||
const constantConnection = {
|
const constantConnection = {
|
||||||
id: dotConnect(id, '0'),
|
id: dotConnect(id, '0'),
|
||||||
@ -330,7 +329,7 @@ export class Module {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn.direction === 'input') {
|
if (connection.direction === 'output') {
|
||||||
const edgeId = makeEdgeId(conn.id, connection.id);
|
const edgeId = makeEdgeId(conn.id, connection.id);
|
||||||
if (!id2EdgeCount.has(edgeId)) {
|
if (!id2EdgeCount.has(edgeId)) {
|
||||||
id2EdgeCount.set(edgeId, 0);
|
id2EdgeCount.set(edgeId, 0);
|
||||||
@ -413,8 +412,6 @@ export class Module {
|
|||||||
for (let i = 0; i < topSideConnections.length; ++ i) {
|
for (let i = 0; i < topSideConnections.length; ++ i) {
|
||||||
const connection = topSideConnections[i];
|
const connection = topSideConnections[i];
|
||||||
const xOffset = meta.getPortXOffset(connection.name);
|
const xOffset = meta.getPortXOffset(connection.name);
|
||||||
|
|
||||||
console.log(xOffset);
|
|
||||||
|
|
||||||
ports.push({
|
ports.push({
|
||||||
id: connection.id,
|
id: connection.id,
|
||||||
|
@ -6,6 +6,7 @@ import { ConnectionRender } from './connection';
|
|||||||
import { CellRender } from './cell';
|
import { CellRender } from './cell';
|
||||||
import { CrossDotRender } from './cross-dot';
|
import { CrossDotRender } from './cross-dot';
|
||||||
import { globalLookup } from '../global';
|
import { globalLookup } from '../global';
|
||||||
|
import { ConstantRender } from './constant';
|
||||||
|
|
||||||
export class RenderViewNode {
|
export class RenderViewNode {
|
||||||
/**
|
/**
|
||||||
@ -45,10 +46,15 @@ export class RenderViewNode {
|
|||||||
*/
|
*/
|
||||||
this.portRender = undefined;
|
this.portRender = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {ConstantRender}
|
||||||
|
*/
|
||||||
|
this.constantRender = undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Map<string, RenderViewNode>}
|
* @type {Map<string, RenderViewNode>}
|
||||||
*/
|
*/
|
||||||
this.id2children = new Map;
|
this.id2children = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
hasChild(id) {
|
hasChild(id) {
|
||||||
@ -119,4 +125,9 @@ export class RenderViewNode {
|
|||||||
this.wireRender.render();
|
this.wireRender.render();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
findNode() {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
@ -5,7 +5,7 @@ import { globalSetting } from '../global';
|
|||||||
import { NetlistRender } from '.';
|
import { NetlistRender } from '.';
|
||||||
import { getMarginParamter, LAYOUT_CONSTANT, LINE_WIDTH } from './layout';
|
import { getMarginParamter, LAYOUT_CONSTANT, LINE_WIDTH } from './layout';
|
||||||
import { svgResource } from '../skin/draw';
|
import { svgResource } from '../skin/draw';
|
||||||
import { PulseLine } from '../skin/plusation';
|
import { PulseLine } from '../skin/pulsation';
|
||||||
|
|
||||||
export class WireRender {
|
export class WireRender {
|
||||||
/**
|
/**
|
||||||
@ -39,8 +39,9 @@ export class WireRender {
|
|||||||
* @param {import('../jsdoc').ElkPoint[]} points 长度至少为 2 的数组,代表经历过的点集
|
* @param {import('../jsdoc').ElkPoint[]} points 长度至少为 2 的数组,代表经历过的点集
|
||||||
* @param {import('../jsdoc').ElkEdge} edge
|
* @param {import('../jsdoc').ElkEdge} edge
|
||||||
* @param {Map<string, import('../jsdoc').ElkPort>} id2port
|
* @param {Map<string, import('../jsdoc').ElkPort>} id2port
|
||||||
|
* @param {number} width
|
||||||
*/
|
*/
|
||||||
addAsD3DataItems(points, edge, id2port) {
|
addAsD3DataItems(points, edge, id2port, width) {
|
||||||
const linePaths = [];
|
const linePaths = [];
|
||||||
|
|
||||||
const beginPoint = points.at(0);
|
const beginPoint = points.at(0);
|
||||||
@ -86,6 +87,7 @@ export class WireRender {
|
|||||||
id: this.idCounter,
|
id: this.idCounter,
|
||||||
svg: lineSvg,
|
svg: lineSvg,
|
||||||
endPoint: points.at(-1),
|
endPoint: points.at(-1),
|
||||||
|
width: width,
|
||||||
arrow: {
|
arrow: {
|
||||||
icon: direction + '-arrow',
|
icon: direction + '-arrow',
|
||||||
x: arrowLocation.x,
|
x: arrowLocation.x,
|
||||||
@ -107,7 +109,6 @@ export class WireRender {
|
|||||||
const arrowHeight = 12;
|
const arrowHeight = 12;
|
||||||
const arrowWidth = 12;
|
const arrowWidth = 12;
|
||||||
|
|
||||||
|
|
||||||
let lineSelections = this.selection.selectAll('path.lines')
|
let lineSelections = this.selection.selectAll('path.lines')
|
||||||
.data(data)
|
.data(data)
|
||||||
.enter()
|
.enter()
|
||||||
@ -115,7 +116,7 @@ export class WireRender {
|
|||||||
.attr('d', d => d.svg)
|
.attr('d', d => d.svg)
|
||||||
.attr('class', 'connection-line')
|
.attr('class', 'connection-line')
|
||||||
.attr("fill", "none")
|
.attr("fill", "none")
|
||||||
.attr('stroke', 'var(--wire-color)');
|
.attr('stroke', 'var(--wire-color)')
|
||||||
|
|
||||||
const arrows = new Map();
|
const arrows = new Map();
|
||||||
|
|
||||||
@ -194,18 +195,23 @@ export class WireRender {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
if (globalSetting.renderAnimation) {
|
// if (globalSetting.renderAnimation) {
|
||||||
lineSelections = lineSelections
|
// lineSelections = lineSelections
|
||||||
.transition()
|
// .transition()
|
||||||
.duration(1000);
|
// .duration(1000);
|
||||||
}
|
// }
|
||||||
|
|
||||||
lineSelections
|
lineSelections
|
||||||
.attr('stroke-width', LINE_WIDTH)
|
.attr('stroke-width', d => {
|
||||||
|
const incrementWidth = globalSetting.boldMultiWidthWire ? 2 : 0;
|
||||||
|
return d.width > 1 ? LINE_WIDTH + incrementWidth: LINE_WIDTH;
|
||||||
|
})
|
||||||
.each(function (data) {
|
.each(function (data) {
|
||||||
const selection = d3.select(this);
|
const selection = d3.select(this);
|
||||||
// const manager = _this.createDataManager(selection, data);
|
// const manager = _this.createDataManager(selection, data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.lineSelections = lineSelections;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -179,6 +179,35 @@ export class ModuleView {
|
|||||||
get id() {
|
get id() {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef ModuleViewPortInfo
|
||||||
|
* @property {number} input
|
||||||
|
* @property {number} output
|
||||||
|
* @property {number} inout
|
||||||
|
*
|
||||||
|
* @returns {ModuleViewPortInfo}
|
||||||
|
*/
|
||||||
|
get portInfo() {
|
||||||
|
if (this._portInfo) {
|
||||||
|
return this._portInfo;
|
||||||
|
}
|
||||||
|
this._portInfo = {
|
||||||
|
input: 0,
|
||||||
|
output: 0,
|
||||||
|
inout: 0
|
||||||
|
};
|
||||||
|
for (const portName of this.nameToPort.keys()) {
|
||||||
|
const port = this.nameToPort.get(portName);
|
||||||
|
this._portInfo[port.direction] ++;
|
||||||
|
}
|
||||||
|
return this._portInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
get definition() {
|
||||||
|
const attributes = this.rawModule.attributes;
|
||||||
|
return definitionFromAttribute(attributes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Port {
|
export class Port {
|
||||||
@ -186,7 +215,7 @@ export class Port {
|
|||||||
* @description port 的抽象
|
* @description port 的抽象
|
||||||
* @param {ModuleView} view
|
* @param {ModuleView} view
|
||||||
* @param {string} name
|
* @param {string} name
|
||||||
* @param {YosysPort} rawPort
|
* @param {import("../jsdoc").YosysPort} rawPort
|
||||||
*/
|
*/
|
||||||
constructor(view, name, rawPort) {
|
constructor(view, name, rawPort) {
|
||||||
this.view = view;
|
this.view = view;
|
||||||
@ -198,6 +227,10 @@ export class Port {
|
|||||||
return this.rawPort.bits;
|
return this.rawPort.bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get width() {
|
||||||
|
return (this.rawPort.bits || []).length;
|
||||||
|
}
|
||||||
|
|
||||||
get direction() {
|
get direction() {
|
||||||
return this.rawPort.direction;
|
return this.rawPort.direction;
|
||||||
}
|
}
|
||||||
@ -205,6 +238,15 @@ export class Port {
|
|||||||
get id() {
|
get id() {
|
||||||
return dotConnect(this.view.id, this.name);
|
return dotConnect(this.view.id, this.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get definition() {
|
||||||
|
const netname = this.view.rawModule.netnames[this.name];
|
||||||
|
if (!netname) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const attributes = netname.attributes;
|
||||||
|
return definitionFromAttribute(attributes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Cell {
|
export class Cell {
|
||||||
@ -257,6 +299,11 @@ export class Cell {
|
|||||||
get id() {
|
get id() {
|
||||||
return dotConnect(this.view.id, this.name);
|
return dotConnect(this.view.id, this.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get definition() {
|
||||||
|
const attributes = this.rawCell.attributes;
|
||||||
|
return definitionFromAttribute(attributes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -325,4 +372,25 @@ export class Wire {
|
|||||||
export function dotConnect(...args) {
|
export function dotConnect(...args) {
|
||||||
const stringArgs = args.map(arg => arg.toString());
|
const stringArgs = args.map(arg => arg.toString());
|
||||||
return stringArgs.join('.');
|
return stringArgs.join('.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {import("../jsdoc").ModuleAttribute} attributes
|
||||||
|
*/
|
||||||
|
function definitionFromAttribute(attributes) {
|
||||||
|
if (!attributes) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const src = attributes.src;
|
||||||
|
if (!src) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (src.startsWith('/dide')) {
|
||||||
|
return src.replace('/dide', '{workspace}');
|
||||||
|
}
|
||||||
|
if (src.startsWith('/lib')) {
|
||||||
|
return src.replace('/lib', '{library}');
|
||||||
|
}
|
||||||
|
return src;
|
||||||
}
|
}
|
@ -81,6 +81,9 @@ class SkinMeta {
|
|||||||
const levelName = path.split('/')[1];
|
const levelName = path.split('/')[1];
|
||||||
const cssName = levelName2CssName[levelName];
|
const cssName = levelName2CssName[levelName];
|
||||||
|
|
||||||
|
this.path = path;
|
||||||
|
this.svgString = svgString;
|
||||||
|
|
||||||
const color = `var(--${cssName}-color)`;
|
const color = `var(--${cssName}-color)`;
|
||||||
const fillColor = `var(--${cssName}-fill-color)`;
|
const fillColor = `var(--${cssName}-fill-color)`;
|
||||||
|
|
||||||
@ -128,9 +131,12 @@ class SkinMeta {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
const transform = pathElement.getAttribute('transform');
|
const transform = pathElement.getAttribute('transform');
|
||||||
const yOffset = parseFloat(transform.split(' ').at(-1));
|
if (transform) {
|
||||||
this.portToYOffset.set(portName, yOffset);
|
const yOffset = parseFloat(transform.split(' ').at(-1));
|
||||||
return yOffset;
|
this.portToYOffset.set(portName, yOffset);
|
||||||
|
return yOffset;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,9 +153,12 @@ class SkinMeta {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
const transform = pathElement.getAttribute('transform');
|
const transform = pathElement.getAttribute('transform');
|
||||||
const offsetnumber = transform.split('(').at(-1).split(' ').at(0);
|
if (transform) {
|
||||||
const xOffset = parseFloat(offsetnumber);
|
const offsetnumber = transform.split('(').at(-1).split(' ').at(0);
|
||||||
this.portToXOffset.set(portName, xOffset);
|
const xOffset = parseFloat(offsetnumber);
|
||||||
return xOffset;
|
this.portToXOffset.set(portName, xOffset);
|
||||||
|
return xOffset;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,5 @@
|
|||||||
import * as d3 from 'd3';
|
import * as d3 from 'd3';
|
||||||
|
import { globalSetting } from '../global';
|
||||||
|
|
||||||
let PluseIDCount = 0;
|
let PluseIDCount = 0;
|
||||||
|
|
||||||
@ -15,10 +16,10 @@ export class PulseLine {
|
|||||||
loadToSelection(parentSelection, data) {
|
loadToSelection(parentSelection, data) {
|
||||||
this.pluseId = data.id;
|
this.pluseId = data.id;
|
||||||
|
|
||||||
const gId = 'pluse-g' + data.id;
|
const gId = 'pulse-g' + data.id;
|
||||||
const pId = 'pluse-p' + data.id;
|
const pId = 'pulse-p' + data.id;
|
||||||
const mId = 'pluse-m' + data.id;
|
const mId = 'pulse-m' + data.id;
|
||||||
const uId = 'pluse-u' + data.id;
|
const uId = 'pulse-u' + data.id;
|
||||||
|
|
||||||
const g = parentSelection.append("g")
|
const g = parentSelection.append("g")
|
||||||
.attr("mask", `url(#${mId})`);
|
.attr("mask", `url(#${mId})`);
|
||||||
@ -94,7 +95,7 @@ export class PulseLine {
|
|||||||
const pathLength = pathElement.getTotalLength();
|
const pathLength = pathElement.getTotalLength();
|
||||||
|
|
||||||
// 600 配合 3000 比较合适
|
// 600 配合 3000 比较合适
|
||||||
const v = 0.5;
|
const v = globalSetting.pulsationSpeed / 10;
|
||||||
const duration = pathLength / v;
|
const duration = pathLength / v;
|
||||||
|
|
||||||
const keyframes = new KeyframeEffect(
|
const keyframes = new KeyframeEffect(
|
@ -40,5 +40,25 @@
|
|||||||
"setting.cell-color-setting": "إعداد لون المكون",
|
"setting.cell-color-setting": "إعداد لون المكون",
|
||||||
"cross-dot-style.slice": "فاصل",
|
"cross-dot-style.slice": "فاصل",
|
||||||
"cross-dot-style.connect": "محول مباشر",
|
"cross-dot-style.connect": "محول مباشر",
|
||||||
"cross-dot-style.concat": "رمز الدمج"
|
"cross-dot-style.concat": "رمز الدمج",
|
||||||
|
"setting.pulsation-speed": "سرعة تأثير النبض",
|
||||||
|
"toolbar.save-as-svg": "حفظ العرض الحالي كـ SVG",
|
||||||
|
"toolbar.save-as-pdf": "حفظ العرض الحالي كـ PDF",
|
||||||
|
"saving": "جارٍ الحفظ",
|
||||||
|
"info.no-entity-select.cannot-display-view": "لم يتم تحديد أي كيان، لا يمكن عرض عرض البيانات",
|
||||||
|
"entity-info": "معلومات الكيان",
|
||||||
|
"common.type": "النوع",
|
||||||
|
"common.name": "الاسم",
|
||||||
|
"common.definition": "تعريف",
|
||||||
|
"common.belong-module": "الوحدة التابعة",
|
||||||
|
"common.width": "عرض البت",
|
||||||
|
"common.direction": "الاتجاه",
|
||||||
|
"common.input-number": "عدد الإدخال",
|
||||||
|
"common.output-number": "عدد الإخراج",
|
||||||
|
"common.inout-number": "الكمية",
|
||||||
|
"common.instance-number": "عدد الوحدات المثبتة",
|
||||||
|
"common.general-cell-number": "عدد الأجهزة العامة",
|
||||||
|
"common.top-module": "الوحدة العلوية",
|
||||||
|
"common.instance-name": "اسم مستعار",
|
||||||
|
"common.instance-definition": "تعريف التمثيل"
|
||||||
}
|
}
|
@ -40,5 +40,25 @@
|
|||||||
"setting.cell-color-setting": "Gerätefarbe einstellen",
|
"setting.cell-color-setting": "Gerätefarbe einstellen",
|
||||||
"cross-dot-style.slice": "Trennzeichen",
|
"cross-dot-style.slice": "Trennzeichen",
|
||||||
"cross-dot-style.connect": "Direktverbinder",
|
"cross-dot-style.connect": "Direktverbinder",
|
||||||
"cross-dot-style.concat": "Zusammenführungszeichen"
|
"cross-dot-style.concat": "Zusammenführungszeichen",
|
||||||
|
"setting.pulsation-speed": "Pulseffektgeschwindigkeit",
|
||||||
|
"toolbar.save-as-svg": "Aktuelle Ansicht als SVG speichern",
|
||||||
|
"toolbar.save-as-pdf": "Aktuelle Ansicht als PDF speichern",
|
||||||
|
"saving": "Wird gespeichert",
|
||||||
|
"info.no-entity-select.cannot-display-view": "Keine Entität ausgewählt, Datenansicht kann nicht angezeigt werden",
|
||||||
|
"entity-info": "Entitätsinformationen",
|
||||||
|
"common.type": "Typ",
|
||||||
|
"common.name": "Name",
|
||||||
|
"common.definition": "Definition",
|
||||||
|
"common.belong-module": "Zugehöriges Modul",
|
||||||
|
"common.width": "Bitbreite",
|
||||||
|
"common.direction": "Richtung",
|
||||||
|
"common.input-number": "Eingabemenge",
|
||||||
|
"common.output-number": "Ausgabemenge",
|
||||||
|
"common.inout-number": "Menge",
|
||||||
|
"common.instance-number": "Anzahl der instanziierten Module",
|
||||||
|
"common.general-cell-number": "Anzahl der allgemeinen Geräte",
|
||||||
|
"common.top-module": "Top-Modul",
|
||||||
|
"common.instance-name": "Pseudonym",
|
||||||
|
"common.instance-definition": "Instanziierungsdefinition"
|
||||||
}
|
}
|
@ -40,5 +40,25 @@
|
|||||||
"setting.cell-color-setting": "Device color setting",
|
"setting.cell-color-setting": "Device color setting",
|
||||||
"cross-dot-style.slice": "Separator",
|
"cross-dot-style.slice": "Separator",
|
||||||
"cross-dot-style.connect": "Direct connector",
|
"cross-dot-style.connect": "Direct connector",
|
||||||
"cross-dot-style.concat": "Combining Character"
|
"cross-dot-style.concat": "Combining Character",
|
||||||
|
"setting.pulsation-speed": "Pulse Effect Speed",
|
||||||
|
"toolbar.save-as-svg": "Save current view as SVG",
|
||||||
|
"toolbar.save-as-pdf": "Save current view as PDF",
|
||||||
|
"saving": "Saving",
|
||||||
|
"info.no-entity-select.cannot-display-view": "No entity selected, unable to display data view",
|
||||||
|
"entity-info": "Entity Information",
|
||||||
|
"common.type": "Type",
|
||||||
|
"common.name": "Name",
|
||||||
|
"common.definition": "Definition",
|
||||||
|
"common.belong-module": "Associated Module",
|
||||||
|
"common.width": "Bit Width",
|
||||||
|
"common.direction": "Direction",
|
||||||
|
"common.input-number": "input quantity",
|
||||||
|
"common.output-number": "output quantity",
|
||||||
|
"common.inout-number": "Quantity",
|
||||||
|
"common.instance-number": "Number of instantiated modules",
|
||||||
|
"common.general-cell-number": "Number of general devices",
|
||||||
|
"common.top-module": "Top Module",
|
||||||
|
"common.instance-name": "Alias",
|
||||||
|
"common.instance-definition": "Instantiation Definition"
|
||||||
}
|
}
|
@ -40,5 +40,25 @@
|
|||||||
"setting.cell-color-setting": "Réglage de la couleur de l'appareil",
|
"setting.cell-color-setting": "Réglage de la couleur de l'appareil",
|
||||||
"cross-dot-style.slice": "Séparateur",
|
"cross-dot-style.slice": "Séparateur",
|
||||||
"cross-dot-style.connect": "Connecteur direct",
|
"cross-dot-style.connect": "Connecteur direct",
|
||||||
"cross-dot-style.concat": "Caractère de combinaison"
|
"cross-dot-style.concat": "Caractère de combinaison",
|
||||||
|
"setting.pulsation-speed": "Vitesse de l'effet de pulsation",
|
||||||
|
"toolbar.save-as-svg": "Enregistrer la vue actuelle au format SVG",
|
||||||
|
"toolbar.save-as-pdf": "Enregistrer la vue actuelle en PDF",
|
||||||
|
"saving": "Enregistrement en cours",
|
||||||
|
"info.no-entity-select.cannot-display-view": "Aucune entité sélectionnée, impossible d'afficher la vue des données",
|
||||||
|
"entity-info": "Informations sur l'entité",
|
||||||
|
"common.type": "Type",
|
||||||
|
"common.name": "Nom",
|
||||||
|
"common.definition": "Définition",
|
||||||
|
"common.belong-module": "Module associé",
|
||||||
|
"common.width": "Largeur de bit",
|
||||||
|
"common.direction": "Direction",
|
||||||
|
"common.input-number": "quantité d'entrée",
|
||||||
|
"common.output-number": "quantité de sortie",
|
||||||
|
"common.inout-number": "Quantité",
|
||||||
|
"common.instance-number": "Nombre de modules instanciés",
|
||||||
|
"common.general-cell-number": "Nombre d'appareils généraux",
|
||||||
|
"common.top-module": "Module supérieur",
|
||||||
|
"common.instance-name": "Pseudonyme",
|
||||||
|
"common.instance-definition": "Définition d'instanciation"
|
||||||
}
|
}
|
@ -40,5 +40,25 @@
|
|||||||
"setting.cell-color-setting": "デバイスの色設定",
|
"setting.cell-color-setting": "デバイスの色設定",
|
||||||
"cross-dot-style.slice": "区切り文字",
|
"cross-dot-style.slice": "区切り文字",
|
||||||
"cross-dot-style.connect": "ダイレクトコネクタ",
|
"cross-dot-style.connect": "ダイレクトコネクタ",
|
||||||
"cross-dot-style.concat": "結合文字"
|
"cross-dot-style.concat": "結合文字",
|
||||||
|
"setting.pulsation-speed": "パルスエフェクト速度",
|
||||||
|
"toolbar.save-as-svg": "現在のビューをSVGとして保存",
|
||||||
|
"toolbar.save-as-pdf": "現在のビューをPDFとして保存",
|
||||||
|
"saving": "保存中",
|
||||||
|
"info.no-entity-select.cannot-display-view": "エンティティが選択されていないため、データビューを表示できません",
|
||||||
|
"entity-info": "エンティティ情報",
|
||||||
|
"common.type": "タイプ",
|
||||||
|
"common.name": "名前",
|
||||||
|
"common.definition": "定義",
|
||||||
|
"common.belong-module": "関連モジュール",
|
||||||
|
"common.width": "ビット幅",
|
||||||
|
"common.direction": "方向",
|
||||||
|
"common.input-number": "入力数量",
|
||||||
|
"common.output-number": "出力数量",
|
||||||
|
"common.inout-number": "数量",
|
||||||
|
"common.instance-number": "インスタンス化されたモジュールの数",
|
||||||
|
"common.general-cell-number": "一般デバイスの数",
|
||||||
|
"common.top-module": "トップモジュール",
|
||||||
|
"common.instance-name": "別名",
|
||||||
|
"common.instance-definition": "インスタンス化定義"
|
||||||
}
|
}
|
@ -40,5 +40,25 @@
|
|||||||
"setting.cell-color-setting": "장치 색상 설정",
|
"setting.cell-color-setting": "장치 색상 설정",
|
||||||
"cross-dot-style.slice": "구분자",
|
"cross-dot-style.slice": "구분자",
|
||||||
"cross-dot-style.connect": "직접 연결기",
|
"cross-dot-style.connect": "직접 연결기",
|
||||||
"cross-dot-style.concat": "결합 문자"
|
"cross-dot-style.concat": "결합 문자",
|
||||||
|
"setting.pulsation-speed": "펄스 효과 속도",
|
||||||
|
"toolbar.save-as-svg": "현재 뷰를 SVG로 저장",
|
||||||
|
"toolbar.save-as-pdf": "현재 보기를 PDF로 저장",
|
||||||
|
"saving": "저장 중",
|
||||||
|
"info.no-entity-select.cannot-display-view": "선택된 엔티티가 없어 데이터 뷰를 표시할 수 없습니다",
|
||||||
|
"entity-info": "엔티티 정보",
|
||||||
|
"common.type": "유형",
|
||||||
|
"common.name": "이름",
|
||||||
|
"common.definition": "정의",
|
||||||
|
"common.belong-module": "소속 모듈",
|
||||||
|
"common.width": "비트 폭",
|
||||||
|
"common.direction": "방향",
|
||||||
|
"common.input-number": "입력 수량",
|
||||||
|
"common.output-number": "출력 수량",
|
||||||
|
"common.inout-number": "수량",
|
||||||
|
"common.instance-number": "인스턴스화된 모듈 수",
|
||||||
|
"common.general-cell-number": "일반 장치 수",
|
||||||
|
"common.top-module": "최상위 모듈",
|
||||||
|
"common.instance-name": "가명",
|
||||||
|
"common.instance-definition": "인스턴스화 정의"
|
||||||
}
|
}
|
@ -40,5 +40,25 @@
|
|||||||
"setting.cell-color-setting": "Настройка цвета устройства",
|
"setting.cell-color-setting": "Настройка цвета устройства",
|
||||||
"cross-dot-style.slice": "Разделитель",
|
"cross-dot-style.slice": "Разделитель",
|
||||||
"cross-dot-style.connect": "Прямой соединитель",
|
"cross-dot-style.connect": "Прямой соединитель",
|
||||||
"cross-dot-style.concat": "Комбинирующий символ"
|
"cross-dot-style.concat": "Комбинирующий символ",
|
||||||
|
"setting.pulsation-speed": "Скорость импульсного эффекта",
|
||||||
|
"toolbar.save-as-svg": "Сохранить текущее представление как SVG",
|
||||||
|
"toolbar.save-as-pdf": "Сохранить текущее представление как PDF",
|
||||||
|
"saving": "Сохранение",
|
||||||
|
"info.no-entity-select.cannot-display-view": "Ни одна сущность не выбрана, невозможно отобразить представление данных",
|
||||||
|
"entity-info": "Информация о сущности",
|
||||||
|
"common.type": "Тип",
|
||||||
|
"common.name": "Имя",
|
||||||
|
"common.definition": "Определение",
|
||||||
|
"common.belong-module": "Связанный модуль",
|
||||||
|
"common.width": "Разрядность",
|
||||||
|
"common.direction": "Направление",
|
||||||
|
"common.input-number": "количество ввода",
|
||||||
|
"common.output-number": "количество вывода",
|
||||||
|
"common.inout-number": "Количество",
|
||||||
|
"common.instance-number": "Количество созданных модулей",
|
||||||
|
"common.general-cell-number": "Количество общих устройств",
|
||||||
|
"common.top-module": "Верхний модуль",
|
||||||
|
"common.instance-name": "Псевдоним",
|
||||||
|
"common.instance-definition": "Определение инстанцирования"
|
||||||
}
|
}
|
@ -40,5 +40,25 @@
|
|||||||
"setting.cell-color-setting": "器件颜色设置",
|
"setting.cell-color-setting": "器件颜色设置",
|
||||||
"cross-dot-style.slice": "拆分符",
|
"cross-dot-style.slice": "拆分符",
|
||||||
"cross-dot-style.connect": "直连符",
|
"cross-dot-style.connect": "直连符",
|
||||||
"cross-dot-style.concat": "合并符"
|
"cross-dot-style.concat": "合并符",
|
||||||
|
"setting.pulsation-speed": "脉冲特效速度",
|
||||||
|
"toolbar.save-as-svg": "将当前视图保存为 svg",
|
||||||
|
"toolbar.save-as-pdf": "将当前视图保存为 pdf",
|
||||||
|
"saving": "保存中",
|
||||||
|
"info.no-entity-select.cannot-display-view": "没有选中任何实体,无法展示数据视图",
|
||||||
|
"entity-info": "实体信息",
|
||||||
|
"common.type": "类型",
|
||||||
|
"common.name": "名字",
|
||||||
|
"common.definition": "定义",
|
||||||
|
"common.belong-module": "所属模块",
|
||||||
|
"common.width": "位宽",
|
||||||
|
"common.direction": "方向",
|
||||||
|
"common.input-number": "input 数量",
|
||||||
|
"common.output-number": "output 数量",
|
||||||
|
"common.inout-number": "inout 数量",
|
||||||
|
"common.instance-number": "例化模块数量",
|
||||||
|
"common.general-cell-number": "通用器件数量",
|
||||||
|
"common.top-module": "顶层模块",
|
||||||
|
"common.instance-name": "例化名",
|
||||||
|
"common.instance-definition": "例化定义"
|
||||||
}
|
}
|
@ -40,5 +40,25 @@
|
|||||||
"setting.cell-color-setting": "器件顏色設置",
|
"setting.cell-color-setting": "器件顏色設置",
|
||||||
"cross-dot-style.slice": "分隔符",
|
"cross-dot-style.slice": "分隔符",
|
||||||
"cross-dot-style.connect": "直連符",
|
"cross-dot-style.connect": "直連符",
|
||||||
"cross-dot-style.concat": "合併符"
|
"cross-dot-style.concat": "合併符",
|
||||||
|
"setting.pulsation-speed": "脈衝特效速度",
|
||||||
|
"toolbar.save-as-svg": "將目前視圖儲存為SVG",
|
||||||
|
"toolbar.save-as-pdf": "將目前視圖儲存為PDF",
|
||||||
|
"saving": "保存中",
|
||||||
|
"info.no-entity-select.cannot-display-view": "沒有選中任何實體,無法展示數據視圖",
|
||||||
|
"entity-info": "實體資訊",
|
||||||
|
"common.type": "類型",
|
||||||
|
"common.name": "名字",
|
||||||
|
"common.definition": "定義",
|
||||||
|
"common.belong-module": "所屬模組",
|
||||||
|
"common.width": "位寬",
|
||||||
|
"common.direction": "方向",
|
||||||
|
"common.input-number": "輸入數量",
|
||||||
|
"common.output-number": "輸出數量",
|
||||||
|
"common.inout-number": "數量",
|
||||||
|
"common.instance-number": "實例化模組數量",
|
||||||
|
"common.general-cell-number": "通用器件數量",
|
||||||
|
"common.top-module": "頂層模組",
|
||||||
|
"common.instance-name": "別名",
|
||||||
|
"common.instance-definition": "實例化定義"
|
||||||
}
|
}
|
@ -17,6 +17,7 @@ module.exports = defineConfig({
|
|||||||
},
|
},
|
||||||
devServer: {
|
devServer: {
|
||||||
hot: false,
|
hot: false,
|
||||||
|
host: 'localhost',
|
||||||
liveReload: false
|
liveReload: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user