2013-03-20 6 views
12

मेरे पास d3 जेनरेटेड फोर्स लेआउट आरेख है, मुझे वर्तमान (उपयोगकर्ता-चयनित) स्केलिंग बरकरार रखने के साथ इसे png पर निर्यात करने की आवश्यकता है।बरकरार रखने के साथ पूर्ण एसवीजी दिखाएं

मेरे तर्क से यह तो, SVG चौड़ाई और ऊंचाई बढ़ेगा इसलिए यदि svg1920x1080 है और उस में 'जूम' है, निर्यात svg शायद एक बहुत बड़ा चौड़ाई और ऊंचाई इस समायोजित करने के लिए होना चाहिए।

मैंने सब कुछ करने की कोशिश की है, और मुझे कुछ याद आ रहा है, मैं बस आउटपुट के लिए सही मानों की गतिशील गणना की प्रतीत नहीं कर सकता।

यहाँ एक example मेरे निर्यात SVG की है, ध्यान दें कि एक बहुत अधिक जानकारी है, यह सिर्फ है कि बड़े पैमाने पर दिखाई नहीं देता है।

संपादित

यहाँ मेरी बुनियादी निर्यात कोड, ज्यादातर Highcharts से अनुकूलित है:

serializeSvg: function() { 
     /** 
     * serialize a xml object to string 
     * @param {type} xmlNode the node to use 
     * @returns {String|@exp;[email protected];xml|@exp;[email protected];[email protected];@call;serializeToString} 
     */ 
     function serializeXmlNode(xmlNode) { 
      if (typeof window.XMLSerializer !== 'undefined') { 
       return (new window.XMLSerializer()).serializeToString(xmlNode); 
      } else if (typeof xmlNode.xml !== 'undefined') { 
       return xmlNode.xml; 
      } 

      return ''; 
     } 

     var svg = serializeXmlNode(document.getElementsByTagName('svg')[0]), 
      factor = 2; 
     svg = '<svg' 
       + ' xmlns="http://www.w3.org/2000/svg"' // xml namespace 
       + ' version="1.1"' 
       + ' xmlns:xlink="http://www.w3.org/1999/xlink"' // for images 
       + ' ' + svg.substring(svg.indexOf('<svg ') + 5); 

     // highcharts svg sanitizer 
     svg = svg.replace(/width="([^"]+)"/, function(m, width) { 
       return 'width="' + (width * factor) + '"'; 
      }).replace(/height="([^"]+)"/, function(m, height) { 
       return 'height="' + (height * factor) + '"'; 
      }).replace(/<rect class="drag"[^<]+<\/rect>/, '') 

      // IE specific 
      .replace(/<IMG /g, '<image ') 
      .replace(/height=([^" ]+)/g, 'height="$1"') 
      .replace(/width=([^" ]+)/g, 'width="$1"') 
      .replace(/id=([^" >]+)/g, 'id="$1"') 
      .replace(/class=([^" ]+)/g, 'class="$1"') 
      .replace(/ transform /g, ' ') 
      .replace(/:(path|rect)/g, '$1') 
      .replace(/style="([^"]+)"/g, function(s) { 
        return s.toLowerCase(); 
      }); 

     return svg; 
    } 

और मुख्य ज़ूम/d3 लेआउट के लिए स्केलिंग स्टार्टअप:

var layout = d3.layout.force(); 
var DEFAULT_SIZE = 64; 
var GROWTH_SCALE = 1.15; 
var SHRINK_SCALE = 1.05; 

// creates a new force layout 
var force = layout 
    .size([w, h]) 
    .gravity(.06) 
    .distance(110) 
    //.friction(0.6) 
    //.linkStrength(0.4) 
    .charge(-((DEFAULT_SIZE * GROWTH_SCALE) * 10)) 
    .on('tick', tick); 

// creates the svg context 
var svg = d3.select('.la-container').append('svg:svg') 
    .attr('width', w) 
    .attr('height', h) 
    .attr('pointer-events', 'all') // set for the pan/zooming 
    .append('svg:g') // add a g element for capturing zoom and pan 
     .call(d3.behavior.zoom().scaleExtent([0.6, 6.0]).on('zoom', redraw)) 
    .append('svg:g'); 

svg.append('svg:rect') 
    .attr('class', 'drag') 
    .attr('width', w) 
    .attr('height', h) 
    .attr('fill', 'white'); 
+0

क्या आप अपनी छवि को स्केल करने के लिए डी 3 में ज़ूम व्यवहार का उपयोग कर रहे हैं? ज़ूम के स्तर को कैप्चर करने और आउटपुट एसवीजी को उचित रूप से बदलने के लिए आपको zoom.scale() का उपयोग करने में सक्षम होना चाहिए। अधिक जानकारी (और जावास्क्रिप्ट कोड) वास्तव में काम करने के लिए सहायक होगी जो आप करने की कोशिश कर रहे हैं? – RoryB

+0

हां, मैं 'd3.behavior.zoom()' और 'd3.behavior.drag() 'का उपयोग कर रहा हूं, मान लीजिए कि उपयोगकर्ता एक ग्राफ नोड पर ज़ूम किया गया है जिसमें 500 नोड्स प्रत्येक 100 पिक्सेल अलग हैं, उन्हें खींचने की आवश्यकता होगी अन्य नोड्स देखने के लिए, अब मैं जो चाहता हूं वह यह है कि यदि वह ज़ूम इन करते समय निर्यात पर क्लिक करता है, तो पूर्ण 500 नोड ग्राफ को एक एसवीजी में निर्यात किया जाना चाहिए जहां पूरी ज़ूम उस ज़ूम स्तर पर दिखाई देगी – epoch

+0

ज़ूम स्तर को कैप्चर करने में आपकी समस्या है या वास्तविक निर्यात प्रक्रिया के साथ? आपके द्वारा वास्तव में उपयोग किए जा रहे जावास्क्रिप्ट के कुछ विचारों के बिना आपकी सहायता करना मुश्किल होगा, और आपका वर्तमान कोड कौन सा त्रुटि संदेश आदि उत्पन्न कर रहा है। – RoryB

उत्तर

0

से आपकी टिप्पणियां, आप यहां चर्चा की गई कुछ विकल्पों की जांच कर सकते हैं: https://groups.google.com/forum/#!msg/d3-js/tHRV4uvvHFU/yjIAfdQN8WsJ

डी 3 को डोम में विशेषताओं को लिखना चाहिए, सामान्य उम्मीद यह है कि यदि आप एसवीजी को निर्यात करते हैं, तो आपको बिल्कुल वही दृश्य मिलना चाहिए। ऐसा लगता है कि आप जो चाहते हैं वह मौजूदा दृश्य को पीएनजी या इसी तरह के रूप में प्रस्तुत करने की प्रक्रिया है।

यहाँ एक दिलचस्प क्लाइंट साइड केवल लेने है http://html2canvas.hertzen.com/

+0

धन्यवाद, मैं इसके माध्यम से हूं। मुझे svg को प्रस्तुत करने में कोई समस्या नहीं है, मुझे इसे सही पैमाने और स्थिति में प्रस्तुत करने की आवश्यकता है, और इसके लिए मुझे आवेदन करने की आवश्यकता है सही परिवर्तन और आकार – epoch

0

मैं इस परीक्षण किया नहीं किया लेकिन मुझे लगता है आप पहली बार वापस शुरुआती स्तर के लिए ज़ूम आउट करने की आवश्यकता होगी जब आप छवि को निर्यात। फिर XMLNode serialize। फिर उपयोगकर्ता के स्केलिंग स्तर के अनुसार अब आकार को बढ़ाएं। और फिर इसे वापस करें।

आप शुरू में उपयोग करके उपयोगकर्ता की परिवर्तनों प्राप्त करने के लिए सक्षम होना चाहिए:

zoom.scale()

यदि निर्दिष्ट नहीं, 1.

करने के लिए वर्तमान जूम पैमाने है, जो चूक रिटर्न zoom.translate()

यदि निर्दिष्ट नहीं है, तो वर्तमान अनुवाद वेक्टर लौटाता है, जो [0, 0] पर डिफ़ॉल्ट होता है।

+0

मुझे यह सब पता है, लेकिन दुर्भाग्यवश यह अभी भी मेरे प्रश्न का उत्तर नहीं देता है – epoch

+0

मुझे खेद है कि मुझे नहीं लगता कि मैं वास्तव में समस्या को समझता हूं। क्या यह है कि आउटपुट को सही आकार में स्केल किया गया है लेकिन यह केवल एक छोटा सा हिस्सा दिखा रहा है मानचित्र का? या मुझे कुछ याद आया? आप कहां 'serializeSvg()' कह रहे हैं और आप इससे पहले क्या करते हैं? –

+0

आपकी पहली धारणा सही सर है :) serializeSvg एक क्लिक ईवेंट से आता है – epoch

1

तो, अपने डी 3 स्टार्टअप कोड में, आप "zoom" कार्रवाई में "redraw" फ़ंक्शन को बाध्य करने के लिए d3.behaviour.zoom.on() पर कॉल करें।पैमाने और अनुवाद के स्तर पाने के लिए आपको d3.scale और d3.translate मूल्यों, (जैसा कि आप redraw समारोह के लिए कोड पोस्ट नहीं किया है) इस समारोह में कब्जा करने के लिए कुछ इस तरह हैं:

var scale = 1; 
var xtranslate=0; 
var ytranslate=0; 

var redraw = function(){ 
    scale= d3.event.scale; 
    xtranslate=d3.event.translate[0]; 
    ytranslate=d3.event.translate[1]; 

    //your actual code to redraw stufff 
} 

है कि आप मिल जाएगा डी 3 से स्केलिंग और अनुवाद मान: तो आपको निर्यात किए गए svg में उचित परिवर्तन लागू करने की आवश्यकता है: मैंने वास्तव में ऐसा नहीं किया है, लेकिन संभवतः, आप "ऊंचाई" और "चौड़ाई" विशेषताओं को उचित रूप से स्केल करते हैं (मुझे लगता है कि यह होगा केवल वैल्यू वैल्यू द्वारा एट्रिब्यूट वैल्यू गुणा करके, लेकिन मुझे यकीन नहीं है)।

1

एक दृश्य के बॉक्स को लागू करें और पैमाने मूल्य से गुणा करें,

उदाहरण 1920x1080 के लिए

, जब तत्कालीन unzoomed viewbox = 0 0 1920 1080

पैमाने पर

= * 0,5 1080 0,5 1920 * 0,5 viewbox = 0 0 960 540

+0

इससे मुझे हमेशा निर्यात में निर्यात की गई छवि को बाधित करने में मदद मिली लेकिन आकार अभी भी ज़ूम के साथ नहीं बढ़ता है, और ज़ूम को भी अनदेखा किया जाता है – epoch

संबंधित मुद्दे