Shortcode Output Always Before Content [duplicate]

Return the HTML instead of the echo

function dataservices_category($atts)
{

// Attributes
extract(shortcode_atts(array(
    'id' => ''
), $atts));
$html = "";
// Code
if (isset($id)) {

    $categories = get_categories('child_of=" . $id);
    foreach ($categories as $category) {
        if ($category->parent != $id) {
            $html .="<div style="margin-left:50px;">';
            $html .='<h4>' . $category->name . '</h4>';
        } else {
            $html .='<h3>' . $category->name . '</h3>';
        }
        if (category_has_children($category->term_id) == false):
            $html .='<ul>';
            foreach (get_posts('cat=" . $category->term_id) as $post) {
                setup_postdata($post);
                $html .="<li><a href="' . get_permalink($post->ID) . '">' . get_the_title($post->ID) . '</a> </li>';
            }
            $html .='</ul>';
        endif;
        if ($category->parent != $id) {
            $html .='</div>';
        }
    }
}
return $html;
}
add_shortcode('dataservices', 'dataservices_category');